/** * AgesaDoReset * * Description * Call the host environment interface to perform reset. * * @param[in] ResetType * @param[in,out] *StdHeader * * @return void * */ VOID AgesaDoReset ( IN UINTN ResetType, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { EFI_PEI_SERVICES **PeiServices; UINT8 Value; EFI_STATUS Status; WARM_RESET_REQUEST Request; PeiServices = (EFI_PEI_SERVICES **)StdHeader->ImageBasePtr; GetWarmResetFlag (StdHeader, &Request); Request.RequestBit = FALSE; Request.StateBits = Request.PostStage; SetWarmResetFlag (StdHeader, &Request); // // Perform the RESET based upon the ResetType. In case of // WARM_RESET_WHENVER and COLD_RESET_WHENEVER, the request will go to // AmdResetManager. During the critical condition, where reset is required // immediately, the reset will be invoked directly by writing 0x04 to port // 0xCF9 (Reset Port). // switch (ResetType) { case WARM_RESET_WHENEVER: case COLD_RESET_WHENEVER: (**PeiServices).InstallPpi (PeiServices, &mAmdPeiResetRequestPpi); break; case WARM_RESET_IMMEDIATELY: case COLD_RESET_IMMEDIATELY: Status = (**PeiServices).PeiResetSystem (PeiServices); // // We should not come here if PeiResetSystem is present. // In case it is missing and gets reported through // EFI_NOT_AVAILABLE_YET, perform the force reset // if (EFI_ERROR (Status)) { Value = 0x06; LibAmdIoWrite (AccessWidth8, 0xCf9, &Value, StdHeader); } break; default: (**PeiServices).InstallPpi (PeiServices, &mAmdPeiResetRequestPpi); break; } }
/** * This function will set the CPU register warm reset bits at AmdInitEarly if it is * currently in cold boot. To request for a warm reset, set the RequestBit to TRUE * and the StateBits to (current poststage - 1) * * @param[in] Data The table data value (unused in this routine) * @param[in] StdHeader Config handle for library and services * *--------------------------------------------------------------------------------------- **/ VOID SetWarmResetAtEarly ( IN UINT32 Data, IN AMD_CONFIG_PARAMS *StdHeader ) { WARM_RESET_REQUEST Request; if (!IsWarmReset (StdHeader)) { GetWarmResetFlag (StdHeader, &Request); Request.RequestBit = TRUE; Request.StateBits = (Request.PostStage - 1); SetWarmResetFlag (StdHeader, &Request); } }
/** * * Call the host environment interface to do the warm or cold reset. * * @param[in] ResetType Warm or Cold Reset is requested * @param[in,out] StdHeader Config header * */ VOID AgesaDoReset ( IN UINTN ResetType, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS Status; WARM_RESET_REQUEST Request; // Clear warm request bit and set state bits to the current post stage GetWarmResetFlag (StdHeader, &Request); Request.RequestBit = FALSE; Request.StateBits = Request.PostStage; SetWarmResetFlag (StdHeader, &Request); Status = AmdAgesaCallout (AGESA_DO_RESET, (UINT32)ResetType, (VOID *) StdHeader); }
/** * Main entry point for the AMD_INIT_RESET function. * * This entry point is responsible for establishing the HT links to the program * ROM and for performing basic processor initialization. * * @param[in,out] ResetParams Required input parameters for the AMD_INIT_RESET * entry point. * * @return Aggregated status across all internal AMD reset calls invoked. * */ AGESA_STATUS AmdInitReset ( IN OUT AMD_RESET_PARAMS *ResetParams ) { AGESA_STATUS AgesaStatus; AGESA_STATUS CalledAgesaStatus; WARM_RESET_REQUEST Request; UINT8 PrevRequestBit; UINT8 PrevStateBits; AgesaStatus = AGESA_SUCCESS; // Setup ROM execution cache CalledAgesaStatus = AllocateExecutionCache (&ResetParams->StdHeader, &ResetParams->CacheRegion[0]); if (CalledAgesaStatus > AgesaStatus) { AgesaStatus = CalledAgesaStatus; } // IDS_EXTENDED_HOOK (IDS_INIT_RESET_BEFORE, NULL, NULL, &ResetParams->StdHeader); // Init Debug Print function IDS_HDT_CONSOLE_INIT (&ResetParams->StdHeader); IDS_HDT_CONSOLE (MAIN_FLOW, "\nAmdInitReset: Start\n\n"); IDS_HDT_CONSOLE (MAIN_FLOW, "\n*** %s ***\n\n", (CHAR8 *)&UserOptions.VersionString); AGESA_TESTPOINT (TpIfAmdInitResetEntry, &ResetParams->StdHeader); ASSERT (ResetParams != NULL); PrevRequestBit = FALSE; PrevStateBits = WR_STATE_COLD; if (IsBsp (&ResetParams->StdHeader, &AgesaStatus)) { CalledAgesaStatus = BldoptFchFunction.InitReset (ResetParams); AgesaStatus = (CalledAgesaStatus > AgesaStatus) ? CalledAgesaStatus : AgesaStatus; } // If a previously requested warm reset cannot be triggered in the // current stage, store the previous state of request and reset the // request struct to the current post stage GetWarmResetFlag (&ResetParams->StdHeader, &Request); if (Request.RequestBit == TRUE) { if (Request.StateBits >= Request.PostStage) { PrevRequestBit = Request.RequestBit; PrevStateBits = Request.StateBits; Request.RequestBit = FALSE; Request.StateBits = Request.PostStage - 1; SetWarmResetFlag (&ResetParams->StdHeader, &Request); } } // Initialize the PCI MMIO access mechanism InitializePciMmio (&ResetParams->StdHeader); // Initialize Hyper Transport Registers if (HtOptionInitReset.HtInitReset != NULL) { IDS_HDT_CONSOLE (MAIN_FLOW, "HtInitReset: Start\n"); CalledAgesaStatus = HtOptionInitReset.HtInitReset (&ResetParams->StdHeader, &ResetParams->HtConfig); IDS_HDT_CONSOLE (MAIN_FLOW, "HtInitReset: End\n"); if (CalledAgesaStatus > AgesaStatus) { AgesaStatus = CalledAgesaStatus; } } // Warm Reset, should be at the end of AmdInitReset GetWarmResetFlag (&ResetParams->StdHeader, &Request); // If a warm reset is requested in the current post stage, trigger the // warm reset and ignore the previous request if (Request.RequestBit == TRUE) { if (Request.StateBits < Request.PostStage) { AgesaDoReset (WARM_RESET_WHENEVER, &ResetParams->StdHeader); } } else { // Otherwise, if there's a previous request, restore it // so that the subsequent post stage can trigger the warm reset if (PrevRequestBit == TRUE) { Request.RequestBit = PrevRequestBit; Request.StateBits = PrevStateBits; SetWarmResetFlag (&ResetParams->StdHeader, &Request); } } // Check for Cache As Ram Corruption IDS_CAR_CORRUPTION_CHECK (&ResetParams->StdHeader); IDS_HDT_CONSOLE (MAIN_FLOW, "\nAmdInitReset: End\n\n"); AGESA_TESTPOINT (TpIfAmdInitResetExit, &ResetParams->StdHeader); return AgesaStatus; }
/** * Main entry point for the AMD_INIT_POST function. * * This entry point is responsible for initializing all system memory, * gathering important data out of the pre-memory cache storage into a * temporary holding buffer in main memory. After that APs will be * shutdown in preparation for the host environment to take control. * Note: pre-memory stack will be disabled also. * * @param[in,out] PostParams Required input parameters for the AMD_INIT_POST * entry point. * * @return Aggregated status across all internal AMD POST calls invoked. * */ AGESA_STATUS AmdInitPost ( IN OUT AMD_POST_PARAMS *PostParams ) { AGESA_STATUS AgesaStatus; AGESA_STATUS AmdInitPostStatus; WARM_RESET_REQUEST Request; UINT8 PrevRequestBit; UINT8 PrevStateBits; IDS_PERF_TIMESTAMP (TP_BEGINPROCAMDINITPOST, &PostParams->StdHeader); AGESA_TESTPOINT (TpIfAmdInitPostEntry, &PostParams->StdHeader); IDS_HDT_CONSOLE (MAIN_FLOW, "AmdInitPost: Start\n\n"); ASSERT (PostParams != NULL); AmdInitPostStatus = AGESA_SUCCESS; PrevRequestBit = FALSE; PrevStateBits = WR_STATE_COLD; IDS_OPTION_HOOK (IDS_INIT_POST_BEFORE, PostParams, &PostParams->StdHeader); // If a previously requested warm reset cannot be triggered in the // current stage, store the previous state of request and reset the // request struct to the current post stage GetWarmResetFlag (&PostParams->StdHeader, &Request); if (Request.RequestBit == TRUE) { if (Request.StateBits >= Request.PostStage) { PrevRequestBit = Request.RequestBit; PrevStateBits = Request.StateBits; Request.RequestBit = FALSE; Request.StateBits = Request.PostStage - 1; SetWarmResetFlag (&PostParams->StdHeader, &Request); } } IDS_PERF_TIMESTAMP (TP_BEGINGNBINITATPOST, &PostParams->StdHeader); AgesaStatus = GnbInitAtPost (PostParams); if (AgesaStatus > AmdInitPostStatus) { AmdInitPostStatus = AgesaStatus; } IDS_PERF_TIMESTAMP (TP_ENDGNBINITATPOST, &PostParams->StdHeader); IDS_PERF_TIMESTAMP (TP_BEGINAMDMEMAUTO, &PostParams->StdHeader); IDS_HDT_CONSOLE (MAIN_FLOW, "AmdMemAuto: Start\n"); PostParams->MemConfig.MemData->StdHeader = PostParams->StdHeader; AgesaStatus = AmdMemAuto (PostParams->MemConfig.MemData); IDS_HDT_CONSOLE (MAIN_FLOW, "AmdMemAuto: End\n"); if (AgesaStatus > AmdInitPostStatus) { AmdInitPostStatus = AgesaStatus; } IDS_PERF_TIMESTAMP (TP_ENDAMDMEMAUTO, &PostParams->StdHeader); if (AgesaStatus != AGESA_FATAL) { // Check BIST status AgesaStatus = CheckBistStatus (&PostParams->StdHeader); if (AgesaStatus > AmdInitPostStatus) { AmdInitPostStatus = AgesaStatus; } // // P-State data gathered, then, Relinquish APs // IDS_PERF_TIMESTAMP (TP_BEGINAMDCPUPOST, &PostParams->StdHeader); IDS_HDT_CONSOLE (MAIN_FLOW, "AmdCpuPost: Start\n"); AgesaStatus = AmdCpuPost (&PostParams->StdHeader, &PostParams->PlatformConfig); IDS_HDT_CONSOLE (MAIN_FLOW, "AmdCpuPost: End\n"); if (AgesaStatus > AmdInitPostStatus) { AmdInitPostStatus = AgesaStatus; } IDS_PERF_TIMESTAMP (TP_ENDAMDCPUPOST, &PostParams->StdHeader); // Warm Reset GetWarmResetFlag (&PostParams->StdHeader, &Request); // If a warm reset is requested in the current post stage, trigger the // warm reset and ignore the previous request if (Request.RequestBit == TRUE) { if (Request.StateBits < Request.PostStage) { AgesaDoReset (WARM_RESET_WHENEVER, &PostParams->StdHeader); } } else { // Otherwise, if there's a previous request, restore it // so that the subsequent post stage can trigger the warm reset if (PrevRequestBit == TRUE) { Request.RequestBit = PrevRequestBit; Request.StateBits = PrevStateBits; SetWarmResetFlag (&PostParams->StdHeader, &Request); } } IDS_PERF_TIMESTAMP (TP_BEGINGNBINITATPOSTAFTERDRAM, &PostParams->StdHeader); AgesaStatus = GnbInitAtPostAfterDram (PostParams); if (AgesaStatus > AmdInitPostStatus) { AmdInitPostStatus = AgesaStatus; } IDS_PERF_TIMESTAMP (TP_ENDGNBINITATPOSTAFTERDRAM, &PostParams->StdHeader); IDS_OPTION_HOOK (IDS_INIT_POST_AFTER, PostParams, &PostParams->StdHeader); AGESA_TESTPOINT (TpIfAmdInitPostExit, &PostParams->StdHeader); IDS_HDT_CONSOLE (MAIN_FLOW, "\nAmdInitPost: End\n\n"); IDS_HDT_CONSOLE (MAIN_FLOW, "Heap transfer Start ...\n\n"); //For Heap will be relocate to new address in next stage, flush out debug print buffer if needed IDS_HDT_CONSOLE_FLUSH_BUFFER (&PostParams->StdHeader); // WARNING: IDT will be moved from local cache to temp memory, so restore IDTR for BSP here IDS_EXCEPTION_TRAP (IDS_IDT_RESTORE_IDTR_FOR_BSC, NULL, &PostParams->StdHeader); IDS_PERF_TIMESTAMP (TP_ENDPROCAMDINITPOST, &PostParams->StdHeader); // Copies BSP heap content to RAM, and it should be at the end of AmdInitPost AgesaStatus = CopyHeapToTempRamAtPost (&(PostParams->StdHeader)); if (AgesaStatus > AmdInitPostStatus) { AmdInitPostStatus = AgesaStatus; } PostParams->StdHeader.HeapStatus = HEAP_TEMP_MEM; } // Check for Cache As Ram Corruption IDS_CAR_CORRUPTION_CHECK (&PostParams->StdHeader); // At the end of AmdInitPost, set StateBits to POST to allow any warm reset that occurs outside // of AGESA to be recognized by IsWarmReset() GetWarmResetFlag (&PostParams->StdHeader, &Request); Request.StateBits = Request.PostStage; SetWarmResetFlag (&PostParams->StdHeader, &Request); return AmdInitPostStatus; }
/** * Performs core leveling for the system. * * This function implements the AMD_CPU_EARLY_PARAMS.CoreLevelingMode parameter. * The possible modes are: * -0 CORE_LEVEL_LOWEST Level to lowest common denominator * -1 CORE_LEVEL_TWO Level to 2 cores * -2 CORE_LEVEL_POWER_OF_TWO Level to 1,2,4 or 8 * -3 CORE_LEVEL_NONE Do no leveling * -4 CORE_LEVEL_COMPUTE_UNIT Level cores to one core per compute unit * * @param[in] EntryPoint Timepoint designator. * @param[in] PlatformConfig Contains the leveling mode parameter * @param[in] StdHeader Config handle for library and services * * @return The most severe status of any family specific service. * */ AGESA_STATUS CoreLevelingAtEarly ( IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 CoreNumPerComputeUnit; UINT32 MinNumOfComputeUnit; UINT32 EnabledComputeUnit; UINT32 Socket; UINT32 Module; UINT32 NumberOfSockets; UINT32 NumberOfModules; UINT32 MinCoreCountOnNode; UINT32 MaxCoreCountOnNode; UINT32 LowCore; UINT32 HighCore; UINT32 LeveledCores; UINT32 RequestedCores; UINT32 TotalEnabledCoresOnNode; BOOLEAN RegUpdated; AP_MAIL_INFO ApMailboxInfo; CORE_LEVELING_TYPE CoreLevelMode; CPU_CORE_LEVELING_FAMILY_SERVICES *FamilySpecificServices; WARM_RESET_REQUEST Request; MaxCoreCountOnNode = 0; MinCoreCountOnNode = 0xFFFFFFFF; LeveledCores = 0; CoreNumPerComputeUnit = 1; MinNumOfComputeUnit = 0xFF; ASSERT (PlatformConfig->CoreLevelingMode < CoreLevelModeMax); // Get OEM IO core level mode CoreLevelMode = (CORE_LEVELING_TYPE) PlatformConfig->CoreLevelingMode; // Get socket count NumberOfSockets = GetPlatformNumberOfSockets (); GetApMailbox (&ApMailboxInfo.Info, StdHeader); NumberOfModules = ApMailboxInfo.Fields.ModuleType + 1; // Collect cpu core info for (Socket = 0; Socket < NumberOfSockets; Socket++) { if (IsProcessorPresent (Socket, StdHeader)) { for (Module = 0; Module < NumberOfModules; Module++) { if (GetGivenModuleCoreRange (Socket, Module, &LowCore, &HighCore, StdHeader)) { // Get the highest and lowest core count in all nodes TotalEnabledCoresOnNode = HighCore - LowCore + 1; if (TotalEnabledCoresOnNode < MinCoreCountOnNode) { MinCoreCountOnNode = TotalEnabledCoresOnNode; } if (TotalEnabledCoresOnNode > MaxCoreCountOnNode) { MaxCoreCountOnNode = TotalEnabledCoresOnNode; } EnabledComputeUnit = TotalEnabledCoresOnNode; switch (GetComputeUnitMapping (StdHeader)) { case AllCoresMapping: // All cores are in their own compute unit. break; case EvenCoresMapping: // Cores are paired in compute units. CoreNumPerComputeUnit = 2; EnabledComputeUnit = (TotalEnabledCoresOnNode / 2); break; default: ASSERT (FALSE); } // Get minimum of compute unit. This will either be the minimum number of cores (AllCoresMapping), // or less (EvenCoresMapping). if (EnabledComputeUnit < MinNumOfComputeUnit) { MinNumOfComputeUnit = EnabledComputeUnit; } } } } } // Get LeveledCores switch (CoreLevelMode) { case CORE_LEVEL_LOWEST: if (MinCoreCountOnNode == MaxCoreCountOnNode) { return (AGESA_SUCCESS); } LeveledCores = (MinCoreCountOnNode / CoreNumPerComputeUnit) * CoreNumPerComputeUnit; break; case CORE_LEVEL_TWO: LeveledCores = 2 / NumberOfModules; if (LeveledCores != 0) { LeveledCores = (LeveledCores <= MinCoreCountOnNode) ? LeveledCores : MinCoreCountOnNode; } else { return (AGESA_WARNING); } if ((LeveledCores * NumberOfModules) != 2) { PutEventLog ( AGESA_WARNING, CPU_WARNING_ADJUSTED_LEVELING_MODE, 2, (LeveledCores * NumberOfModules), 0, 0, StdHeader ); } break; case CORE_LEVEL_POWER_OF_TWO: // Level to power of 2 (1, 2, 4, 8...) LeveledCores = 1; while (MinCoreCountOnNode >= (LeveledCores * 2)) { LeveledCores = LeveledCores * 2; } break; case CORE_LEVEL_COMPUTE_UNIT: // Level cores to one core per compute unit, with additional reduction to level // all processors to match the processor with the minimum number of cores. if (CoreNumPerComputeUnit == 1) { // If there is one core per compute unit, this is the same as CORE_LEVEL_LOWEST. if (MinCoreCountOnNode == MaxCoreCountOnNode) { return (AGESA_SUCCESS); } LeveledCores = MinCoreCountOnNode; } else { // If there are more than one core per compute unit, level to the number of compute units. LeveledCores = MinNumOfComputeUnit; } break; case CORE_LEVEL_ONE: LeveledCores = 1; if (NumberOfModules > 1) { PutEventLog ( AGESA_WARNING, CPU_WARNING_ADJUSTED_LEVELING_MODE, 1, NumberOfModules, 0, 0, StdHeader ); } break; case CORE_LEVEL_THREE: case CORE_LEVEL_FOUR: case CORE_LEVEL_FIVE: case CORE_LEVEL_SIX: case CORE_LEVEL_SEVEN: case CORE_LEVEL_EIGHT: case CORE_LEVEL_NINE: case CORE_LEVEL_TEN: case CORE_LEVEL_ELEVEN: case CORE_LEVEL_TWELVE: case CORE_LEVEL_THIRTEEN: case CORE_LEVEL_FOURTEEN: case CORE_LEVEL_FIFTEEN: // MCM processors can not have an odd number of cores. For an odd CORE_LEVEL_N, MCM processors will be // leveled as though CORE_LEVEL_N+1 was chosen. // Processors with compute units disable all cores in an entire compute unit at a time, or on an MCM processor, // two compute units at a time. For example, on an SCM processor with two cores per compute unit, the effective // explicit levels are CORE_LEVEL_ONE, CORE_LEVEL_TWO, CORE_LEVEL_FOUR, CORE_LEVEL_SIX, and // CORE_LEVEL_EIGHT. The same example for an MCM processor with two cores per compute unit has effective // explicit levels of CORE_LEVEL_TWO, CORE_LEVEL_FOUR, CORE_LEVEL_EIGHT, and CORE_LEVEL_TWELVE. RequestedCores = CoreLevelMode - CORE_LEVEL_THREE + 3; LeveledCores = (RequestedCores + NumberOfModules - 1) / NumberOfModules; LeveledCores = (LeveledCores / CoreNumPerComputeUnit) * CoreNumPerComputeUnit; LeveledCores = (LeveledCores <= MinCoreCountOnNode) ? LeveledCores : MinCoreCountOnNode; if (LeveledCores != 1) { LeveledCores = (LeveledCores / CoreNumPerComputeUnit) * CoreNumPerComputeUnit; } if ((LeveledCores * NumberOfModules * CoreNumPerComputeUnit) != RequestedCores) { PutEventLog ( AGESA_WARNING, CPU_WARNING_ADJUSTED_LEVELING_MODE, RequestedCores, (LeveledCores * NumberOfModules * CoreNumPerComputeUnit), 0, 0, StdHeader ); } break; default: ASSERT (FALSE); } // Set down core register for (Socket = 0; Socket < NumberOfSockets; Socket++) { if (IsProcessorPresent (Socket, StdHeader)) { GetFeatureServicesOfSocket (&CoreLevelingFamilyServiceTable, Socket, &FamilySpecificServices, StdHeader); if (FamilySpecificServices != NULL) { for (Module = 0; Module < NumberOfModules; Module++) { RegUpdated = FamilySpecificServices->SetDownCoreRegister (FamilySpecificServices, &Socket, &Module, &LeveledCores, CoreLevelMode, StdHeader); // If the down core register is updated, trigger a warm reset. if (RegUpdated) { GetWarmResetFlag (StdHeader, &Request); Request.RequestBit = TRUE; Request.StateBits = Request.PostStage - 1; SetWarmResetFlag (StdHeader, &Request); } } } } } return (AGESA_SUCCESS); }
/** * Performs core leveling for the system. * * This function implements the AMD_CPU_EARLY_PARAMS.CoreLevelingMode parameter. * The possible modes are: * -0 CORE_LEVEL_LOWEST Level to lowest common denominator * -1 CORE_LEVEL_TWO Level to 2 cores * -2 CORE_LEVEL_POWER_OF_TWO Level to 1,2,4 or 8 * -3 CORE_LEVEL_NONE Do no leveling * -4 CORE_LEVEL_COMPUTE_UNIT Level cores to one core per compute unit * * @param[in] EntryPoint Timepoint designator. * @param[in] PlatformConfig Contains the leveling mode parameter * @param[in] StdHeader Config handle for library and services * * @return The most severe status of any family specific service. * */ AGESA_STATUS CoreLevelingAtEarly ( IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 CoreNumPerComputeUnit; UINT32 EnabledComputeUnit; UINT32 SocketAndModule; UINT32 LowCore; UINT32 HighCore; UINT32 LeveledCores; UINT32 RequestedCores; UINT32 TotalEnabledCoresOnNode; BOOLEAN RegUpdated; CORE_LEVELING_TYPE CoreLevelMode; CPU_CORE_LEVELING_FAMILY_SERVICES *FamilySpecificServices; WARM_RESET_REQUEST Request; IDS_HDT_CONSOLE (CPU_TRACE, "CoreLevelingAtEarly\n CoreLevelMode: %d\n", PlatformConfig->CoreLevelingMode); LeveledCores = 0; SocketAndModule = 0; ASSERT (PlatformConfig->CoreLevelingMode < CoreLevelModeMax); // Get OEM IO core level mode CoreLevelMode = (CORE_LEVELING_TYPE) PlatformConfig->CoreLevelingMode; // Collect cpu core info GetGivenModuleCoreRange (0, 0, &LowCore, &HighCore, StdHeader); // Get the highest and lowest core count in all nodes TotalEnabledCoresOnNode = HighCore - LowCore + 1; switch (GetComputeUnitMapping (StdHeader)) { case AllCoresMapping: // All cores are in their own compute unit. CoreNumPerComputeUnit = 1; EnabledComputeUnit = TotalEnabledCoresOnNode; break; case EvenCoresMapping: // Cores are paired in compute units. CoreNumPerComputeUnit = 2; EnabledComputeUnit = (TotalEnabledCoresOnNode / 2); break; case TripleCoresMapping: // Three cores are grouped in compute units. CoreNumPerComputeUnit = 3; EnabledComputeUnit = (TotalEnabledCoresOnNode / 3); break; case QuadCoresMapping: // Four cores are grouped in compute units. CoreNumPerComputeUnit = 4; EnabledComputeUnit = (TotalEnabledCoresOnNode / 4); break; default: CoreNumPerComputeUnit = 1; EnabledComputeUnit = TotalEnabledCoresOnNode; ASSERT (FALSE); } IDS_HDT_CONSOLE (CPU_TRACE, " TotalEnabledCoresOnNode %d EnabledComputeUnit %d\n", \ TotalEnabledCoresOnNode, EnabledComputeUnit); // Get LeveledCores switch (CoreLevelMode) { case CORE_LEVEL_LOWEST: return (AGESA_SUCCESS); break; case CORE_LEVEL_TWO: LeveledCores = 2; LeveledCores = (LeveledCores <= TotalEnabledCoresOnNode) ? LeveledCores : TotalEnabledCoresOnNode; if (LeveledCores != 2) { PutEventLog ( AGESA_WARNING, CPU_WARNING_ADJUSTED_LEVELING_MODE, 2, LeveledCores, 0, 0, StdHeader ); } break; case CORE_LEVEL_POWER_OF_TWO: // Level to power of 2 (1, 2, 4, 8...) LeveledCores = 1; while (TotalEnabledCoresOnNode >= (LeveledCores * 2)) { LeveledCores = LeveledCores * 2; } break; case CORE_LEVEL_COMPUTE_UNIT: case CORE_LEVEL_COMPUTE_UNIT_TWO: case CORE_LEVEL_COMPUTE_UNIT_THREE: // Level cores to 1~3 core(s) per compute unit, with additional reduction to level // all processors to match the processor with the minimum number of cores. if (CoreNumPerComputeUnit == 1) { // If there is one core per compute unit, this is the same as CORE_LEVEL_LOWEST. return (AGESA_SUCCESS); } else { // If there are more than one core per compute unit, level to the number of compute units * cores per compute unit. LeveledCores = EnabledComputeUnit * (CoreLevelMode - CORE_LEVEL_COMPUTE_UNIT + 1); } break; case CORE_LEVEL_ONE: LeveledCores = 1; break; case CORE_LEVEL_THREE: case CORE_LEVEL_FOUR: case CORE_LEVEL_FIVE: case CORE_LEVEL_SIX: case CORE_LEVEL_SEVEN: case CORE_LEVEL_EIGHT: case CORE_LEVEL_NINE: case CORE_LEVEL_TEN: case CORE_LEVEL_ELEVEN: case CORE_LEVEL_TWELVE: case CORE_LEVEL_THIRTEEN: case CORE_LEVEL_FOURTEEN: case CORE_LEVEL_FIFTEEN: // Processors with compute units disable all cores in an entire compute unit at a time // For example, on a processor with two cores per compute unit, the effective // explicit levels are CORE_LEVEL_ONE, CORE_LEVEL_TWO, CORE_LEVEL_FOUR, CORE_LEVEL_SIX, and // CORE_LEVEL_EIGHT. RequestedCores = CoreLevelMode - CORE_LEVEL_THREE + 3; LeveledCores = RequestedCores; LeveledCores = (LeveledCores / CoreNumPerComputeUnit) * CoreNumPerComputeUnit; LeveledCores = (LeveledCores <= TotalEnabledCoresOnNode) ? LeveledCores : TotalEnabledCoresOnNode; if (LeveledCores != 1) { LeveledCores = (LeveledCores / CoreNumPerComputeUnit) * CoreNumPerComputeUnit; } if (LeveledCores != RequestedCores) { PutEventLog ( AGESA_WARNING, CPU_WARNING_ADJUSTED_LEVELING_MODE, RequestedCores, LeveledCores, 0, 0, StdHeader ); } break; default: ASSERT (FALSE); } // Set down core register GetFeatureServicesOfSocket (&CoreLevelingFamilyServiceTable, 0, (CONST VOID **)&FamilySpecificServices, StdHeader); if (FamilySpecificServices != NULL) { IDS_HDT_CONSOLE (CPU_TRACE, " SetDownCoreRegister: LeveledCores %d CoreLevelMode %d\n", LeveledCores, CoreLevelMode); RegUpdated = FamilySpecificServices->SetDownCoreRegister (FamilySpecificServices, &SocketAndModule, &SocketAndModule, &LeveledCores, CoreLevelMode, StdHeader); // If the down core register is updated, trigger a warm reset. if (RegUpdated) { GetWarmResetFlag (StdHeader, &Request); Request.RequestBit = TRUE; Request.StateBits = Request.PostStage - 1; IDS_HDT_CONSOLE (CPU_TRACE, " Request a warm reset.\n"); SetWarmResetFlag (StdHeader, &Request); } } return (AGESA_SUCCESS); }
/** * Perform initialization services required at the Early Init POST time point. * * Execution Cache, HyperTransport, and AP Init advanced services are performed. * * @param[in] EarlyParams The interface struct for all early services * * @return The most severe AGESA_STATUS returned by any called service. * */ AGESA_STATUS AmdInitEarly ( IN OUT AMD_EARLY_PARAMS *EarlyParams ) { AGESA_STATUS CalledAgesaStatus; AGESA_STATUS EarlyInitStatus; WARM_RESET_REQUEST Request; AGESA_TESTPOINT (TpIfAmdInitEarlyEntry, &EarlyParams->StdHeader); IDS_PERF_TIME_MEASURE (&EarlyParams->StdHeader); ASSERT (EarlyParams != NULL); EarlyInitStatus = AGESA_SUCCESS; GetWarmResetFlag (&EarlyParams->StdHeader, &Request); Request.RequestBit = FALSE; SetWarmResetFlag (&EarlyParams->StdHeader, &Request); IDS_OPTION_HOOK (IDS_INIT_EARLY_BEFORE, EarlyParams, &EarlyParams->StdHeader); // Setup ROM execution cache CalledAgesaStatus = AllocateExecutionCache (&EarlyParams->StdHeader, &EarlyParams->CacheRegion[0]); if (CalledAgesaStatus > EarlyInitStatus) { EarlyInitStatus = CalledAgesaStatus; } // Full Hypertransport Initialization // IMPORTANT: All AP cores call Ht Init. HT Init handles full init for the BSC, and map init for APs. CalledAgesaStatus = AmdHtInitialize (&EarlyParams->StdHeader, &EarlyParams->PlatformConfig, &EarlyParams->HtConfig); if (CalledAgesaStatus > EarlyInitStatus) { EarlyInitStatus = CalledAgesaStatus; } // AP launch CalledAgesaStatus = AmdCpuEarly (&EarlyParams->StdHeader, &EarlyParams->PlatformConfig); if (CalledAgesaStatus > EarlyInitStatus) { EarlyInitStatus = CalledAgesaStatus; } // Warm Rest, should be at the end of AmdInitEarly GetWarmResetFlag (&EarlyParams->StdHeader, &Request); if (Request.RequestBit == TRUE) { Request.RequestBit = FALSE; Request.StateBits = WR_STATE_EARLY; SetWarmResetFlag (&EarlyParams->StdHeader, &Request); AgesaDoReset (WARM_RESET_WHENEVER, &EarlyParams->StdHeader); } else { if (Request.StateBits < WR_STATE_EARLY) { Request.StateBits = WR_STATE_EARLY; SetWarmResetFlag (&EarlyParams->StdHeader, &Request); } } CalledAgesaStatus = GnbInitAtEarly ( &EarlyParams->StdHeader, &EarlyParams->PlatformConfig, &EarlyParams->GnbConfig ); if (CalledAgesaStatus > EarlyInitStatus) { EarlyInitStatus = CalledAgesaStatus; } // Check for Cache As Ram Corruption IDS_CAR_CORRUPTION_CHECK (&EarlyParams->StdHeader); IDS_OPTION_HOOK (IDS_AFTER_WARM_RESET, EarlyParams, &EarlyParams->StdHeader); IDS_OPTION_HOOK (IDS_INIT_EARLY_AFTER, EarlyParams, &EarlyParams->StdHeader); IDS_PERF_TIME_MEASURE (&EarlyParams->StdHeader); AGESA_TESTPOINT (TpIfAmdInitEarlyExit, &EarlyParams->StdHeader); return EarlyInitStatus; }