blob: 1275d8d8efa641926efc19a0ed1ba0af61a71791 [file] [log] [blame]
zbao7d94cf92012-07-02 14:19:14 +08001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * AMD WHEA Table Creation API, and related functions.
6 *
7 * Contains code that produce the ACPI WHEA related information.
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: CPU
12 * @e \$Revision: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $
13 *
14 */
15/*
16 ******************************************************************************
17 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080018 * Copyright (c) 2008 - 2012, Advanced Micro Devices, Inc.
19 * All rights reserved.
zbao7d94cf92012-07-02 14:19:14 +080020 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080021 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
23 * * Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * * Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
29 * its contributors may be used to endorse or promote products derived
30 * from this software without specific prior written permission.
zbao7d94cf92012-07-02 14:19:14 +080031 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080032 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
zbao7d94cf92012-07-02 14:19:14 +080042 ******************************************************************************
43 */
44
45/*----------------------------------------------------------------------------------------
46 * M O D U L E S U S E D
47 *----------------------------------------------------------------------------------------
48 */
49#include "AGESA.h"
50#include "amdlib.h"
51#include "OptionWhea.h"
52#include "cpuLateInit.h"
53#include "heapManager.h"
54#include "cpuRegisters.h"
55#include "cpuFamilyTranslation.h"
56#include "Ids.h"
57#include "Filecode.h"
58CODE_GROUP (G3_DXE)
59RDATA_GROUP (G3_DXE)
60
61#define FILECODE PROC_CPU_FEATURE_CPUWHEA_FILECODE
62/*----------------------------------------------------------------------------------------
63 * D E F I N I T I O N S A N D M A C R O S
64 *---------------------------------------------------------------------------------------
65 */
66
67extern OPTION_WHEA_CONFIGURATION OptionWheaConfiguration; // global user config record
68
69/*----------------------------------------------------------------------------------------
70 * T Y P E D E F S A N D S T R U C T U R E S
71 *----------------------------------------------------------------------------------------
72 */
73
74/*----------------------------------------------------------------------------------------
75 * P R O T O T Y P E S O F L O C A L F U N C T I O N S
76 *----------------------------------------------------------------------------------------
77 */
78VOID
79STATIC
80CreateHestBank (
81 IN AMD_HEST_BANK *HestBankPtr,
82 IN UINT8 BankNum,
83 IN AMD_WHEA_INIT_DATA *WheaInitDataPtr
84 );
85
86AGESA_STATUS
87GetAcpiWheaStub (
88 IN OUT AMD_CONFIG_PARAMS *StdHeader,
89 IN OUT VOID **WheaMcePtr,
90 IN OUT VOID **WheaCmcPtr
91 );
92
93AGESA_STATUS
94GetAcpiWheaMain (
95 IN OUT AMD_CONFIG_PARAMS *StdHeader,
96 IN OUT VOID **WheaMcePtr,
97 IN OUT VOID **WheaCmcPtr
98 );
99
100/*----------------------------------------------------------------------------------------
101 * E X P O R T E D F U N C T I O N S
102 *----------------------------------------------------------------------------------------
103 */
104/*---------------------------------------------------------------------------------------*/
105/**
106 *
107 * It will create the ACPI table of WHEA and return the pointer to the table.
108 *
109 * @param[in, out] StdHeader Standard Head Pointer
110 * @param[in, out] WheaMcePtr Point to Whea Hest Mce table
111 * @param[in, out] WheaCmcPtr Point to Whea Hest Cmc table
112 *
113 * @retval AGESA_STATUS
114 */
115AGESA_STATUS
116CreateAcpiWhea (
117 IN OUT AMD_CONFIG_PARAMS *StdHeader,
118 IN OUT VOID **WheaMcePtr,
119 IN OUT VOID **WheaCmcPtr
120 )
121{
122 AGESA_TESTPOINT (TpProcCpuEntryWhea, StdHeader);
123 return ((*(OptionWheaConfiguration.WheaFeature)) (StdHeader, WheaMcePtr, WheaCmcPtr));
124}
125
126/*---------------------------------------------------------------------------------------*/
127/**
128 *
129 * This is the default routine for use when the WHEA option is NOT requested.
130 *
131 * The option install process will create and fill the transfer vector with
132 * the address of the proper routine (Main or Stub). The link optimizer will
133 * strip out of the .DLL the routine that is not used.
134 *
135 * @param[in, out] StdHeader Standard Head Pointer
136 * @param[in, out] WheaMcePtr Point to Whea Hest Mce table
137 * @param[in, out] WheaCmcPtr Point to Whea Hest Cmc table
138 *
139 * @retval AGESA_STATUS
140 */
141
142AGESA_STATUS
143GetAcpiWheaStub (
144 IN OUT AMD_CONFIG_PARAMS *StdHeader,
145 IN OUT VOID **WheaMcePtr,
146 IN OUT VOID **WheaCmcPtr
147 )
148{
149 return AGESA_UNSUPPORTED;
150}
151
152/*---------------------------------------------------------------------------------------*/
153/**
154 *
155 * It will create the ACPI tale of WHEA and return the pointer to the table.
156 *
157 * @param[in, out] StdHeader Standard Head Pointer
158 * @param[in, out] WheaMcePtr Point to Whea Hest Mce table
159 * @param[in, out] WheaCmcPtr Point to Whea Hest Cmc table
160 *
161 * @retval UINT32 AGESA_STATUS
162 */
163AGESA_STATUS
164GetAcpiWheaMain (
165 IN OUT AMD_CONFIG_PARAMS *StdHeader,
166 IN OUT VOID **WheaMcePtr,
167 IN OUT VOID **WheaCmcPtr
168 )
169{
170 UINT8 BankNum;
171 UINT8 Entries;
172 UINT16 HestMceTableSize;
173 UINT16 HestCmcTableSize;
174 UINT64 MsrData;
175 AMD_HEST_MCE_TABLE *HestMceTablePtr;
176 AMD_HEST_CMC_TABLE *HestCmcTablePtr;
177 AMD_HEST_BANK *HestBankPtr;
178 AMD_WHEA_INIT_DATA *WheaInitDataPtr;
179 ALLOCATE_HEAP_PARAMS AllocParams;
180 CPU_SPECIFIC_SERVICES *FamilySpecificServices;
181
182 FamilySpecificServices = NULL;
183
184 IDS_HDT_CONSOLE (CPU_TRACE, " WHEA is created\n");
185
186 // step 1: calculate Hest table size
187 LibAmdMsrRead (MSR_MCG_CAP, &MsrData, StdHeader);
188 BankNum = (UINT8) (((MSR_MCG_CAP_STRUCT *) (&MsrData))->Count);
189 if (BankNum == 0) {
190 return AGESA_ERROR;
191 }
192
193 GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
194 FamilySpecificServices->GetWheaInitData (FamilySpecificServices, (CONST VOID **) &WheaInitDataPtr, &Entries, StdHeader);
195
196 ASSERT (WheaInitDataPtr->HestBankNum <= BankNum);
197
198 HestMceTableSize = sizeof (AMD_HEST_MCE_TABLE) + WheaInitDataPtr->HestBankNum * sizeof (AMD_HEST_BANK);
199 HestCmcTableSize = sizeof (AMD_HEST_CMC_TABLE) + WheaInitDataPtr->HestBankNum * sizeof (AMD_HEST_BANK);
200
201 HestMceTablePtr = (AMD_HEST_MCE_TABLE *) *WheaMcePtr;
202 HestCmcTablePtr = (AMD_HEST_CMC_TABLE *) *WheaCmcPtr;
203
204 // step 2: allocate a buffer by callback function
205 if ((HestMceTablePtr == NULL) || (HestCmcTablePtr == NULL)) {
206 AllocParams.RequestedBufferSize = (UINT32) (HestMceTableSize + HestCmcTableSize);
207 AllocParams.BufferHandle = AMD_WHEA_BUFFER_HANDLE;
208 AllocParams.Persist = HEAP_SYSTEM_MEM;
209
210 AGESA_TESTPOINT (TpProcCpuBeforeAllocateWheaBuffer, StdHeader);
211 if (HeapAllocateBuffer (&AllocParams, StdHeader) != AGESA_SUCCESS) {
212 return AGESA_ERROR;
213 }
214 AGESA_TESTPOINT (TpProcCpuAfterAllocateWheaBuffer, StdHeader);
215
216 HestMceTablePtr = (AMD_HEST_MCE_TABLE *) AllocParams.BufferPtr;
217 HestCmcTablePtr = (AMD_HEST_CMC_TABLE *) ((UINT8 *) (HestMceTablePtr + 1) + (WheaInitDataPtr->HestBankNum * sizeof (AMD_HEST_BANK)));
218 }
219
220 // step 3: fill in Hest MCE table
221 HestMceTablePtr->TblLength = HestMceTableSize;
222 HestMceTablePtr->GlobCapInitDataLSD = WheaInitDataPtr->GlobCapInitDataLSD;
223 HestMceTablePtr->GlobCapInitDataMSD = WheaInitDataPtr->GlobCapInitDataMSD;
224 HestMceTablePtr->GlobCtrlInitDataLSD = WheaInitDataPtr->GlobCtrlInitDataLSD;
225 HestMceTablePtr->GlobCtrlInitDataMSD = WheaInitDataPtr->GlobCtrlInitDataMSD;
226 HestMceTablePtr->NumHWBanks = WheaInitDataPtr->HestBankNum;
227
228 HestBankPtr = (AMD_HEST_BANK *) (HestMceTablePtr + 1);
229 CreateHestBank (HestBankPtr, WheaInitDataPtr->HestBankNum, WheaInitDataPtr);
230
231 // step 4: fill in Hest CMC table
232 HestCmcTablePtr->NumHWBanks = WheaInitDataPtr->HestBankNum;
233 HestCmcTablePtr->TblLength = HestCmcTableSize;
234
235 HestBankPtr = (AMD_HEST_BANK *) (HestCmcTablePtr + 1);
236 CreateHestBank (HestBankPtr, WheaInitDataPtr->HestBankNum, WheaInitDataPtr);
237
238 // step 5: fill in the incoming structure
239 *WheaMcePtr = HestMceTablePtr;
240 *WheaCmcPtr = HestCmcTablePtr;
241
242 return (AGESA_SUCCESS);
243}
244
245/*---------------------------------------------------------------------------------------
246 * L O C A L F U N C T I O N S
247 *---------------------------------------------------------------------------------------
248 */
249
250/*---------------------------------------------------------------------------------------*/
251/**
252 *
253 * It will create Bank structure for Hest table
254 *
255 * @param[in] HestBankPtr Pointer to the Hest Back structure
256 * @param[in] BankNum The number of Bank
257 * @param[in] WheaInitDataPtr Pointer to the AMD_WHEA_INIT_DATA structure
258 *
259 */
260VOID
261STATIC
262CreateHestBank (
263 IN AMD_HEST_BANK *HestBankPtr,
264 IN UINT8 BankNum,
265 IN AMD_WHEA_INIT_DATA *WheaInitDataPtr
266 )
267{
268 UINT8 BankIndex;
269 for (BankIndex = 0; BankIndex < BankNum; BankIndex++) {
270 HestBankPtr->BankNum = BankIndex;
271 HestBankPtr->ClrStatusOnInit = WheaInitDataPtr->ClrStatusOnInit;
272 HestBankPtr->StatusDataFormat = WheaInitDataPtr->StatusDataFormat;
273 HestBankPtr->ConfWriteEn = WheaInitDataPtr->ConfWriteEn;
274 HestBankPtr->CtrlRegMSRAddr = WheaInitDataPtr->HestBankInitData[BankIndex].CtrlRegMSRAddr;
275 HestBankPtr->CtrlInitDataLSD = WheaInitDataPtr->HestBankInitData[BankIndex].CtrlInitDataLSD;
276 HestBankPtr->CtrlInitDataMSD = WheaInitDataPtr->HestBankInitData[BankIndex].CtrlInitDataMSD;
277 HestBankPtr->StatRegMSRAddr = WheaInitDataPtr->HestBankInitData[BankIndex].StatRegMSRAddr;
278 HestBankPtr->AddrRegMSRAddr = WheaInitDataPtr->HestBankInitData[BankIndex].AddrRegMSRAddr;
279 HestBankPtr->MiscRegMSRAddr = WheaInitDataPtr->HestBankInitData[BankIndex].MiscRegMSRAddr;
280 HestBankPtr++;
281 }
282}
283