5 * AMD CPU POST API, and related functions.
7 * Contains code that initialized the CPU after memory init.
9 * @xrefitem bom "File Content Label" "Release Content"
12 * @e \$Revision: 56279 $ @e \$Date: 2011-07-11 13:11:28 -0600 (Mon, 11 Jul 2011) $
16 ****************************************************************************
17 * AMD Generic Encapsulated Software Architecture
19 * Description: cpuPostInit.c - Cpu POST Initialization Functions.
21 ******************************************************************************
23 * Copyright (C) 2012 Advanced Micro Devices, Inc.
24 * All rights reserved.
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions are met:
28 * * Redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer.
30 * * Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in the
32 * documentation and/or other materials provided with the distribution.
33 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
34 * its contributors may be used to endorse or promote products derived
35 * from this software without specific prior written permission.
37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
38 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
39 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
41 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 ******************************************************************************
51 /*----------------------------------------------------------------------------------------
52 * M O D U L E S U S E D
53 *----------------------------------------------------------------------------------------
60 #include "cpuRegisters.h"
61 #include "cpuApicUtilities.h"
62 #include "heapManager.h"
63 #include "cpuServices.h"
64 #include "cpuFeatures.h"
65 #include "GeneralServices.h"
66 #include "cpuPostInit.h"
67 #include "cpuPstateTables.h"
68 #include "cpuFamilyTranslation.h"
72 #define FILECODE PROC_CPU_CPUPOSTINIT_FILECODE
73 /*----------------------------------------------------------------------------------------
74 * D E F I N I T I O N S A N D M A C R O S
75 *----------------------------------------------------------------------------------------
78 /*----------------------------------------------------------------------------------------
79 * T Y P E D E F S A N D S T R U C T U R E S
80 *----------------------------------------------------------------------------------------
83 /*----------------------------------------------------------------------------------------
84 * 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
85 *----------------------------------------------------------------------------------------
90 IN AMD_CONFIG_PARAMS *StdHeader
93 /*----------------------------------------------------------------------------------------
94 * E X P O R T E D F U N C T I O N S
95 *----------------------------------------------------------------------------------------
97 extern BUILD_OPT_CFG UserOptions;
98 extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable;
102 ExecuteWbinvdInstruction (
103 IN OUT AMD_CONFIG_PARAMS *StdHeader
107 PstateCreateHeapInfo (
108 IN PLATFORM_CONFIGURATION *PlatformConfig,
109 IN AMD_CONFIG_PARAMS *StdHeader
112 /*---------------------------------------------------------------------------------------*/
114 * Performs CPU related initialization at the POST entry point
116 * This function performs a large list of initialization items. These items
120 * -2 feature leveling
121 * -3 P-state data gather
122 * -4 P-state leveling
123 * -5 AP cache breakdown & release
125 * @param[in] StdHeader Config handle for library and services
126 * @param[in] PlatformConfig Config handle for platform specific information
128 * @retval AGESA_SUCCESS
133 IN AMD_CONFIG_PARAMS *StdHeader,
134 IN PLATFORM_CONFIGURATION *PlatformConfig
137 AGESA_STATUS AgesaStatus;
138 AGESA_STATUS CalledStatus;
140 AgesaStatus = AGESA_SUCCESS;
142 // Sync variable MTRR
144 AGESA_TESTPOINT (TpProcCpuApMtrrSync, StdHeader);
145 SyncVariableMTRR (StdHeader);
147 AGESA_TESTPOINT (TpProcCpuPostFeatureInit, StdHeader);
148 IDS_HDT_CONSOLE (CPU_TRACE, " Dispatch CPU features after AP MTRR sync\n");
149 CalledStatus = DispatchCpuFeatures (CPU_FEAT_AFTER_POST_MTRR_SYNC, PlatformConfig, StdHeader);
150 if (CalledStatus > AgesaStatus) {
151 AgesaStatus = CalledStatus;
156 AGESA_TESTPOINT (TpProcCpuFeatureLeveling, StdHeader);
157 IDS_HDT_CONSOLE (CPU_TRACE, " Perform feature leveling\n");
158 FeatureLeveling (StdHeader);
160 // P-state Gathered and set heap info
162 IDS_HDT_CONSOLE (CPU_TRACE, " Create P-state info in the heap\n");
163 PstateCreateHeapInfo (PlatformConfig, StdHeader);
165 // Set TscFreqSel at the rate specified by the core P0 after core frequency leveling.
166 SetCoresTscFreqSel (StdHeader);
168 // Dispatch CPU features before relinquishing control of APs
169 AGESA_TESTPOINT (TpProcCpuBeforeRelinquishAPsFeatureInit, StdHeader);
170 IDS_HDT_CONSOLE (CPU_TRACE, " Dispatch CPU features before Relinquishing control of APs\n");
171 CalledStatus = DispatchCpuFeatures (CPU_FEAT_BEFORE_RELINQUISH_AP, PlatformConfig, StdHeader);
172 if (CalledStatus > AgesaStatus) {
173 AgesaStatus = CalledStatus;
176 // Relinquish control of all APs to IBV.
177 IDS_HDT_CONSOLE (CPU_TRACE, " Relinquish control of APs\n");
178 RelinquishControlOfAllAPs (StdHeader);
180 return (AgesaStatus);
183 /*---------------------------------------------------------------------------------------
184 * L O C A L F U N C T I O N S
185 *---------------------------------------------------------------------------------------
188 /*---------------------------------------------------------------------------------------*/
190 * Determines the address in system DRAM that should be used for p-state data
191 * gather and leveling.
193 * @param[out] Ptr Address to utilize
194 * @param[in] StdHeader Config handle for library and services
196 * @retval AGESA_SUCCESS
200 GetPstateGatherDataAddressAtPost (
202 IN AMD_CONFIG_PARAMS *StdHeader
207 AddressValue = P_STATE_DATA_GATHER_TEMP_ADDR;
209 *Ptr = (UINT64 *)(AddressValue);
211 return AGESA_SUCCESS;
215 /*---------------------------------------------------------------------------------------*/
217 * AP task to sync memory subsystem MSRs with the BSC
219 * This function processes a list of MSRs and the BSC's current values for those
220 * MSRs. This will allow the APs to see system RAM.
222 * @param[in] MtrrTable Memory related MSR table
223 * @param[in] StdHeader Config handle for library and services
229 IN AMD_CONFIG_PARAMS *StdHeader
234 for (i = 0; ((BSC_AP_MSR_SYNC *) MtrrTable)[i].RegisterAddress != 0; i++) {
235 LibAmdMsrWrite (((BSC_AP_MSR_SYNC *) MtrrTable)[i].RegisterAddress,
236 &((BSC_AP_MSR_SYNC *) MtrrTable)[i].RegisterValue,
242 /*---------------------------------------------------------------------------------------*/
244 * Creates p-state information on the heap
246 * This function gathers p-state information from all processors in the system,
247 * determines a level set of p-states, and places that information into the
248 * heap. This heap data will be used by GenerateSsdt to generate the
249 * final _PSS and XPSS objects.
251 * @param[in] PlatformConfig Pointer to runtime configuration options
252 * @param[in] StdHeader Config handle for library and services
254 * @retval AGESA_SUCCESS No error
255 * @retval AGESA_ERROR CPU_ERROR_PSTATE_HEAP_NOT_AVAILABLE
258 PstateCreateHeapInfo (
259 IN PLATFORM_CONFIGURATION *PlatformConfig,
260 IN AMD_CONFIG_PARAMS *StdHeader
263 AGESA_STATUS AgesaStatus;
264 S_CPU_AMD_PSTATE *PStateBufferPtr;
265 ALLOCATE_HEAP_PARAMS AllocHeapParams;
266 UINT8 *PStateBufferPtrInHeap;
268 ASSERT (IsBsp (StdHeader, &AgesaStatus));
271 //Get proper address for gather data pool address
272 //Zero P-state gather data pool
274 GetPstateGatherDataAddressAtPost ((UINT64 **)&PStateBufferPtr, StdHeader);
275 LibAmdMemFill (PStateBufferPtr, 0, sizeof (S_CPU_AMD_PSTATE), StdHeader);
278 //Get all the CPUs P-States and fill the PStateBufferPtr for each core
280 AgesaStatus = PStateGatherData (PlatformConfig, PStateBufferPtr, StdHeader);
281 if (AgesaStatus != AGESA_SUCCESS) {
286 //Do Pstate Leveling for each core if needed.
288 AgesaStatus = PStateLeveling (PStateBufferPtr, StdHeader);
291 //Create Heap and store p-state data for ACPI table in CpuLate
293 AllocHeapParams.RequestedBufferSize = PStateBufferPtr->SizeOfBytes;
294 AllocHeapParams.BufferHandle = AMD_PSTATE_DATA_BUFFER_HANDLE;
295 AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
296 AgesaStatus = HeapAllocateBuffer (&AllocHeapParams, StdHeader);
297 if (AgesaStatus == AGESA_SUCCESS) {
301 PStateBufferPtrInHeap = (UINT8 *) AllocHeapParams.BufferPtr;
302 LibAmdMemFill (PStateBufferPtrInHeap, 0, PStateBufferPtr->SizeOfBytes, StdHeader);
303 LibAmdMemCopy (PStateBufferPtrInHeap, PStateBufferPtr, PStateBufferPtr->SizeOfBytes, StdHeader);
306 PutEventLog (AGESA_ERROR,
307 CPU_ERROR_PSTATE_HEAP_NOT_AVAILABLE,
308 0, 0, 0, 0, StdHeader);
316 IN OUT BSC_AP_MSR_SYNC *ApMsrSync,
317 IN AMD_CONFIG_PARAMS *StdHeader
327 UINT32 NumberOfSockets;
328 UINT32 NumberOfCores;
329 AGESA_STATUS IgnoredSts;
331 ASSERT (IsBsp (StdHeader, &IgnoredSts));
333 IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts);
334 NumberOfSockets = GetPlatformNumberOfSockets ();
337 //Sync all MTRR settings with BSP
339 for (i = 0; ApMsrSync[i].RegisterAddress != 0; i++) {
340 LibAmdMsrRead (ApMsrSync[i].RegisterAddress, &ApMsrSync[i].RegisterValue, StdHeader);
343 TaskPtr.FuncAddress.PfApTaskI = SyncAllApMtrrToBsc;
344 TaskPtr.DataTransfer.DataSizeInDwords = (UINT16) ((((sizeof (BSC_AP_MSR_SYNC)) * i) + 4) >> 2);
345 TaskPtr.ExeFlags = WAIT_FOR_CORE;
346 TaskPtr.DataTransfer.DataPtr = ApMsrSync;
347 TaskPtr.DataTransfer.DataTransferFlags = 0;
349 for (Socket = 0; Socket < NumberOfSockets; Socket++) {
350 if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) {
351 for (Core = 0; Core < NumberOfCores; Core++) {
352 if ((Socket != BscSocket) || (Core != BscCoreNum)) {
353 ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, &TaskPtr, StdHeader);
360 /*---------------------------------------------------------------------------------------*/
366 * @param[in] StdHeader Config handle for library and services
372 IN AMD_CONFIG_PARAMS *StdHeader
375 BSC_AP_MSR_SYNC ApMsrSync[20];
377 ApMsrSync[0].RegisterAddress = SYS_CFG;
378 ApMsrSync[1].RegisterAddress = TOP_MEM;
379 ApMsrSync[2].RegisterAddress = TOP_MEM2;
380 ApMsrSync[3].RegisterAddress = 0x200;
381 ApMsrSync[4].RegisterAddress = 0x201;
382 ApMsrSync[5].RegisterAddress = 0x202;
383 ApMsrSync[6].RegisterAddress = 0x203;
384 ApMsrSync[7].RegisterAddress = 0x204;
385 ApMsrSync[8].RegisterAddress = 0x205;
386 ApMsrSync[9].RegisterAddress = 0x206;
387 ApMsrSync[10].RegisterAddress = 0x207;
388 ApMsrSync[11].RegisterAddress = 0x208;
389 ApMsrSync[12].RegisterAddress = 0x209;
390 ApMsrSync[13].RegisterAddress = 0x20A;
391 ApMsrSync[14].RegisterAddress = 0x20B;
392 ApMsrSync[15].RegisterAddress = 0xC0010016;
393 ApMsrSync[16].RegisterAddress = 0xC0010017;
394 ApMsrSync[17].RegisterAddress = 0xC0010018;
395 ApMsrSync[18].RegisterAddress = 0xC0010019;
396 ApMsrSync[19].RegisterAddress = 0;
397 SyncApMsrsToBsc (ApMsrSync, StdHeader);
400 /*---------------------------------------------------------------------------------------*/
402 * The function suppose to do any thing need to be done at the end of AmdInitPost.
404 * @param[in] StdHeader Config handle for library and services
406 * @retval AGESA_SUCCESS
411 IN AMD_CONFIG_PARAMS *StdHeader
415 // Execute wbinvd to ensure heap data in cache write back to memory.
417 ExecuteWbinvdInstruction (StdHeader);
419 return AGESA_SUCCESS;
421 /*---------------------------------------------------------------------------------------*/
423 * Set TSC Frequency Selection.
425 * This function set TSC Frequency Selection.
427 * @param[in] StdHeader Config handle for library and services
433 IN AMD_CONFIG_PARAMS *StdHeader
436 PSTATE_CPU_FAMILY_SERVICES *FamilyServices;
438 FamilyServices = NULL;
440 GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader);
441 if (FamilyServices != NULL) {
442 FamilyServices->CpuSetTscFreqSel (FamilyServices, StdHeader);
447 /*---------------------------------------------------------------------------------------*/
449 * Set TSC Frequency Selection to all cores.
451 * This function set TscFreqSel to all cores in the system.
453 * @param[in] StdHeader Config handle for library and services
458 IN AMD_CONFIG_PARAMS *StdHeader
467 UINT32 NumberOfSockets;
468 UINT32 NumberOfCores;
469 AGESA_STATUS IgnoredSts;
471 ASSERT (IsBsp (StdHeader, &IgnoredSts));
473 IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts);
474 NumberOfSockets = GetPlatformNumberOfSockets ();
476 SetTscFreqSel (StdHeader);
478 TaskPtr.FuncAddress.PfApTask = SetTscFreqSel;
479 TaskPtr.ExeFlags = WAIT_FOR_CORE;
480 TaskPtr.DataTransfer.DataTransferFlags = 0;
481 TaskPtr.DataTransfer.DataSizeInDwords = 0;
482 TaskPtr.DataTransfer.DataPtr = NULL;
484 for (Socket = 0; Socket < NumberOfSockets; Socket++) {
485 if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) {
486 for (Core = 0; Core < NumberOfCores; Core++) {
487 if ((Socket != BscSocket) || (Core != BscCoreNum)) {
488 ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, &TaskPtr, StdHeader);