5 * AMD WHEA Table Creation API, and related functions.
7 * Contains code that produce the ACPI WHEA related information.
9 * @xrefitem bom "File Content Label" "Release Content"
12 * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
16 *****************************************************************************
18 * Copyright (c) 2011, Advanced Micro Devices, Inc.
19 * All rights reserved.
21 * 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.
32 * 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.
43 * ***************************************************************************
47 /*----------------------------------------------------------------------------------------
48 * M O D U L E S U S E D
49 *----------------------------------------------------------------------------------------
53 #include "OptionWhea.h"
54 #include "cpuLateInit.h"
55 #include "heapManager.h"
56 #include "cpuRegisters.h"
57 #include "cpuFamilyTranslation.h"
63 #define FILECODE PROC_CPU_FEATURE_CPUWHEA_FILECODE
64 /*----------------------------------------------------------------------------------------
65 * D E F I N I T I O N S A N D M A C R O S
66 *---------------------------------------------------------------------------------------
69 extern OPTION_WHEA_CONFIGURATION OptionWheaConfiguration
; // global user config record
71 /*----------------------------------------------------------------------------------------
72 * T Y P E D E F S A N D S T R U C T U R E S
73 *----------------------------------------------------------------------------------------
76 /*----------------------------------------------------------------------------------------
77 * 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
78 *----------------------------------------------------------------------------------------
83 IN AMD_HEST_BANK
*HestBankPtr
,
85 IN AMD_WHEA_INIT_DATA
*WheaInitDataPtr
90 IN OUT AMD_CONFIG_PARAMS
*StdHeader
,
91 IN OUT VOID
**WheaMcePtr
,
92 IN OUT VOID
**WheaCmcPtr
97 IN OUT AMD_CONFIG_PARAMS
*StdHeader
,
98 IN OUT VOID
**WheaMcePtr
,
99 IN OUT VOID
**WheaCmcPtr
102 /*----------------------------------------------------------------------------------------
103 * E X P O R T E D F U N C T I O N S
104 *----------------------------------------------------------------------------------------
106 /*---------------------------------------------------------------------------------------*/
109 * It will create the ACPI table of WHEA and return the pointer to the table.
111 * @param[in, out] StdHeader Standard Head Pointer
112 * @param[in, out] WheaMcePtr Point to Whea Hest Mce table
113 * @param[in, out] WheaCmcPtr Point to Whea Hest Cmc table
115 * @retval AGESA_STATUS
119 IN OUT AMD_CONFIG_PARAMS
*StdHeader
,
120 IN OUT VOID
**WheaMcePtr
,
121 IN OUT VOID
**WheaCmcPtr
124 AGESA_TESTPOINT (TpProcCpuEntryWhea
, StdHeader
);
125 return ((*(OptionWheaConfiguration
.WheaFeature
)) (StdHeader
, WheaMcePtr
, WheaCmcPtr
));
128 /*---------------------------------------------------------------------------------------*/
131 * This is the default routine for use when the WHEA option is NOT requested.
133 * The option install process will create and fill the transfer vector with
134 * the address of the proper routine (Main or Stub). The link optimizer will
135 * strip out of the .DLL the routine that is not used.
137 * @param[in, out] StdHeader Standard Head Pointer
138 * @param[in, out] WheaMcePtr Point to Whea Hest Mce table
139 * @param[in, out] WheaCmcPtr Point to Whea Hest Cmc table
141 * @retval AGESA_STATUS
146 IN OUT AMD_CONFIG_PARAMS
*StdHeader
,
147 IN OUT VOID
**WheaMcePtr
,
148 IN OUT VOID
**WheaCmcPtr
151 return AGESA_UNSUPPORTED
;
154 /*---------------------------------------------------------------------------------------*/
157 * It will create the ACPI tale of WHEA and return the pointer to the table.
159 * @param[in, out] StdHeader Standard Head Pointer
160 * @param[in, out] WheaMcePtr Point to Whea Hest Mce table
161 * @param[in, out] WheaCmcPtr Point to Whea Hest Cmc table
163 * @retval UINT32 AGESA_STATUS
167 IN OUT AMD_CONFIG_PARAMS
*StdHeader
,
168 IN OUT VOID
**WheaMcePtr
,
169 IN OUT VOID
**WheaCmcPtr
174 UINT16 HestMceTableSize
;
175 UINT16 HestCmcTableSize
;
177 AMD_HEST_MCE_TABLE
*HestMceTablePtr
;
178 AMD_HEST_CMC_TABLE
*HestCmcTablePtr
;
179 AMD_HEST_BANK
*HestBankPtr
;
180 AMD_WHEA_INIT_DATA
*WheaInitDataPtr
;
181 ALLOCATE_HEAP_PARAMS AllocParams
;
182 CPU_SPECIFIC_SERVICES
*FamilySpecificServices
;
184 FamilySpecificServices
= NULL
;
186 IDS_HDT_CONSOLE (CPU_TRACE
, " WHEA is created\n");
188 // step 1: calculate Hest table size
189 LibAmdMsrRead (MSR_MCG_CAP
, &MsrData
, StdHeader
);
190 BankNum
= (UINT8
) (((MSR_MCG_CAP_STRUCT
*) (&MsrData
))->Count
);
195 GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES
**)&FamilySpecificServices
, StdHeader
);
196 FamilySpecificServices
->GetWheaInitData (FamilySpecificServices
, (const VOID
**)&WheaInitDataPtr
, &Entries
, StdHeader
);
198 ASSERT (WheaInitDataPtr
->HestBankNum
<= BankNum
);
200 HestMceTableSize
= sizeof (AMD_HEST_MCE_TABLE
) + WheaInitDataPtr
->HestBankNum
* sizeof (AMD_HEST_BANK
);
201 HestCmcTableSize
= sizeof (AMD_HEST_CMC_TABLE
) + WheaInitDataPtr
->HestBankNum
* sizeof (AMD_HEST_BANK
);
203 HestMceTablePtr
= (AMD_HEST_MCE_TABLE
*) *WheaMcePtr
;
204 HestCmcTablePtr
= (AMD_HEST_CMC_TABLE
*) *WheaCmcPtr
;
206 // step 2: allocate a buffer by callback function
207 if ((HestMceTablePtr
== NULL
) || (HestCmcTablePtr
== NULL
)) {
208 AllocParams
.RequestedBufferSize
= (UINT32
) (HestMceTableSize
+ HestCmcTableSize
);
209 AllocParams
.BufferHandle
= AMD_WHEA_BUFFER_HANDLE
;
210 AllocParams
.Persist
= HEAP_SYSTEM_MEM
;
212 AGESA_TESTPOINT (TpProcCpuBeforeAllocateWheaBuffer
, StdHeader
);
213 if (HeapAllocateBuffer (&AllocParams
, StdHeader
) != AGESA_SUCCESS
) {
216 AGESA_TESTPOINT (TpProcCpuAfterAllocateWheaBuffer
, StdHeader
);
218 HestMceTablePtr
= (AMD_HEST_MCE_TABLE
*) AllocParams
.BufferPtr
;
219 HestCmcTablePtr
= (AMD_HEST_CMC_TABLE
*) ((UINT8
*) (HestMceTablePtr
+ 1) + (WheaInitDataPtr
->HestBankNum
* sizeof (AMD_HEST_BANK
)));
222 // step 3: fill in Hest MCE table
223 HestMceTablePtr
->TblLength
= HestMceTableSize
;
224 HestMceTablePtr
->GlobCapInitDataLSD
= WheaInitDataPtr
->GlobCapInitDataLSD
;
225 HestMceTablePtr
->GlobCapInitDataMSD
= WheaInitDataPtr
->GlobCapInitDataMSD
;
226 HestMceTablePtr
->GlobCtrlInitDataLSD
= WheaInitDataPtr
->GlobCtrlInitDataLSD
;
227 HestMceTablePtr
->GlobCtrlInitDataMSD
= WheaInitDataPtr
->GlobCtrlInitDataMSD
;
228 HestMceTablePtr
->NumHWBanks
= WheaInitDataPtr
->HestBankNum
;
230 HestBankPtr
= (AMD_HEST_BANK
*) (HestMceTablePtr
+ 1);
231 CreateHestBank (HestBankPtr
, WheaInitDataPtr
->HestBankNum
, WheaInitDataPtr
);
233 // step 4: fill in Hest CMC table
234 HestCmcTablePtr
->NumHWBanks
= WheaInitDataPtr
->HestBankNum
;
235 HestCmcTablePtr
->TblLength
= HestCmcTableSize
;
237 HestBankPtr
= (AMD_HEST_BANK
*) (HestCmcTablePtr
+ 1);
238 CreateHestBank (HestBankPtr
, WheaInitDataPtr
->HestBankNum
, WheaInitDataPtr
);
240 // step 5: fill in the incoming structure
241 *WheaMcePtr
= HestMceTablePtr
;
242 *WheaCmcPtr
= HestCmcTablePtr
;
244 return (AGESA_SUCCESS
);
247 /*---------------------------------------------------------------------------------------
248 * L O C A L F U N C T I O N S
249 *---------------------------------------------------------------------------------------
252 /*---------------------------------------------------------------------------------------*/
255 * It will create Bank structure for Hest table
257 * @param[in] HestBankPtr Pointer to the Hest Back structure
258 * @param[in] BankNum The number of Bank
259 * @param[in] WheaInitDataPtr Pointer to the AMD_WHEA_INIT_DATA structure
265 IN AMD_HEST_BANK
*HestBankPtr
,
267 IN AMD_WHEA_INIT_DATA
*WheaInitDataPtr
271 for (BankIndex
= 0; BankIndex
< BankNum
; BankIndex
++) {
272 HestBankPtr
->BankNum
= BankIndex
;
273 HestBankPtr
->ClrStatusOnInit
= WheaInitDataPtr
->ClrStatusOnInit
;
274 HestBankPtr
->StatusDataFormat
= WheaInitDataPtr
->StatusDataFormat
;
275 HestBankPtr
->ConfWriteEn
= WheaInitDataPtr
->ConfWriteEn
;
276 HestBankPtr
->CtrlRegMSRAddr
= WheaInitDataPtr
->HestBankInitData
[BankIndex
].CtrlRegMSRAddr
;
277 HestBankPtr
->CtrlInitDataLSD
= WheaInitDataPtr
->HestBankInitData
[BankIndex
].CtrlInitDataLSD
;
278 HestBankPtr
->CtrlInitDataMSD
= WheaInitDataPtr
->HestBankInitData
[BankIndex
].CtrlInitDataMSD
;
279 HestBankPtr
->StatRegMSRAddr
= WheaInitDataPtr
->HestBankInitData
[BankIndex
].StatRegMSRAddr
;
280 HestBankPtr
->AddrRegMSRAddr
= WheaInitDataPtr
->HestBankInitData
[BankIndex
].AddrRegMSRAddr
;
281 HestBankPtr
->MiscRegMSRAddr
= WheaInitDataPtr
->HestBankInitData
[BankIndex
].MiscRegMSRAddr
;