/** * 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); }
/** * Multisocket call to determine the frequency that the northbridges must run. * * This function loops through all possible socket locations, comparing the * maximum NB frequencies to determine the slowest. This function also * determines if all coherent NB frequencies are equivalent. * * @param[in] NbPstate NB P-state number to check (0 = fastest) * @param[in] PlatformConfig Platform profile/build option config structure. * @param[out] SystemNbCofNumerator NB frequency numerator for the system in MHz * @param[out] SystemNbCofDenominator NB frequency denominator for the system * @param[out] SystemNbCofsMatch Whether or not all NB frequencies are equivalent * @param[out] NbPstateIsEnabledOnAllCPUs Whether or not NbPstate is valid on all CPUs * @param[in] StdHeader Config handle for library and services * * @retval TRUE At least one processor has NbPstate enabled. * @retval FALSE NbPstate is disabled on all CPUs * */ BOOLEAN GetSystemNbCofMulti ( IN UINT32 NbPstate, IN PLATFORM_CONFIGURATION *PlatformConfig, OUT UINT32 *SystemNbCofNumerator, OUT UINT32 *SystemNbCofDenominator, OUT BOOLEAN *SystemNbCofsMatch, OUT BOOLEAN *NbPstateIsEnabledOnAllCPUs, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Socket; UINT8 Module; UINT32 CurrentNbCof; UINT32 CurrentDivisor; UINT32 CurrentFreq; UINT32 LowFrequency; UINT32 Ignored32; BOOLEAN FirstCofNotFound; BOOLEAN NbPstateDisabled; BOOLEAN IsNbPstateEnabledOnAny; PCI_ADDR PciAddress; AGESA_STATUS Ignored; CPU_SPECIFIC_SERVICES *FamilySpecificServices; // Find the slowest NB COF in the system & whether or not all are equivalent LowFrequency = 0xFFFFFFFF; *SystemNbCofsMatch = TRUE; *NbPstateIsEnabledOnAllCPUs = FALSE; IsNbPstateEnabledOnAny = FALSE; FirstCofNotFound = TRUE; NbPstateDisabled = FALSE; for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { if (IsProcessorPresent (Socket, StdHeader)) { GetCpuServicesOfSocket (Socket, (CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &Ignored)) { break; } } if (FamilySpecificServices->GetNbPstateInfo (FamilySpecificServices, PlatformConfig, &PciAddress, NbPstate, &CurrentNbCof, &CurrentDivisor, &Ignored32, StdHeader)) { ASSERT (CurrentDivisor != 0); CurrentFreq = (CurrentNbCof / CurrentDivisor); if (FirstCofNotFound) { *SystemNbCofNumerator = CurrentNbCof; *SystemNbCofDenominator = CurrentDivisor; LowFrequency = CurrentFreq; IsNbPstateEnabledOnAny = TRUE; if (!NbPstateDisabled) { *NbPstateIsEnabledOnAllCPUs = TRUE; } FirstCofNotFound = FALSE; } else { if (CurrentFreq != LowFrequency) { *SystemNbCofsMatch = FALSE; if (CurrentFreq < LowFrequency) { LowFrequency = CurrentFreq; *SystemNbCofNumerator = CurrentNbCof; *SystemNbCofDenominator = CurrentDivisor; } } } } else { NbPstateDisabled = TRUE; *NbPstateIsEnabledOnAllCPUs = FALSE; } } } return IsNbPstateEnabledOnAny; }
/** * Enable the C6 C-state * * @param[in] EntryPoint Timepoint designator. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] StdHeader Config Handle for library, services. * * @retval AGESA_SUCCESS Always succeeds. * */ AGESA_STATUS STATIC InitializeC6Feature ( IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 BscSocket; UINT32 Ignored; UINT32 BscCoreNum; UINT32 Core; UINT32 Socket; UINT32 NumberOfSockets; UINT32 NumberOfCores; AP_TASK TaskPtr; AMD_CPU_EARLY_PARAMS CpuEarlyParams; C6_FAMILY_SERVICES *C6FamilyServices; AGESA_STATUS IgnoredSts; CpuEarlyParams.PlatformConfig = *PlatformConfig; TaskPtr.FuncAddress.PfApTaskIC = EnableC6OnSocket; TaskPtr.DataTransfer.DataSizeInDwords = 2; TaskPtr.DataTransfer.DataPtr = &EntryPoint; TaskPtr.DataTransfer.DataTransferFlags = 0; TaskPtr.ExeFlags = PASS_EARLY_PARAMS; OptionMultiSocketConfiguration.BscRunCodeOnAllSystemCore0s (&TaskPtr, StdHeader, &CpuEarlyParams); if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { // Load any required microcode patches on both normal boot and resume from S3. IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts); GetFeatureServicesOfSocket (&C6FamilyServiceTable, BscSocket, (const VOID **)&C6FamilyServices, StdHeader); if (C6FamilyServices != NULL) { C6FamilyServices->ReloadMicrocodePatchAfterMemInit (StdHeader); } // run code on all APs TaskPtr.DataTransfer.DataSizeInDwords = 0; TaskPtr.ExeFlags = 0; NumberOfSockets = GetPlatformNumberOfSockets (); for (Socket = 0; Socket < NumberOfSockets; Socket++) { if (IsProcessorPresent (Socket, StdHeader)) { GetFeatureServicesOfSocket (&C6FamilyServiceTable, Socket, (const VOID **)&C6FamilyServices, StdHeader); if (C6FamilyServices != NULL) { // run code on all APs TaskPtr.FuncAddress.PfApTask = C6FamilyServices->ReloadMicrocodePatchAfterMemInit; if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { for (Core = 0; Core < NumberOfCores; Core++) { if ((Socket != BscSocket) || (Core != BscCoreNum)) { ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, &TaskPtr, StdHeader); } } } } } } } return AGESA_SUCCESS; }
/** * Should message-based C1e be enabled * * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] StdHeader Config Handle for library, services. * * @retval TRUE Message-based C1e is supported. * @retval FALSE Message-based C1e cannot be enabled. * */ BOOLEAN STATIC IsMsgBasedC1eFeatureEnabled ( IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { UINTN Link; UINTN LinkCount; UINT32 Socket; UINT32 Module; BOOLEAN IsEnabled; PCI_ADDR PciAddress; AGESA_STATUS AgesaStatus; HT_HOST_FEATS HtHostFeats; CPU_SPECIFIC_SERVICES *CpuServices; MSG_BASED_C1E_FAMILY_SERVICES *FamilyServices; ASSERT (PlatformConfig->C1eMode < MaxC1eMode); IsEnabled = FALSE; if (PlatformConfig->C1eMode == C1eModeMsgBased) { ASSERT (PlatformConfig->C1ePlatformData < 0x10000); ASSERT (PlatformConfig->C1ePlatformData != 0); if ((PlatformConfig->C1ePlatformData != 0) && (PlatformConfig->C1ePlatformData < 0xFFFE)) { IsEnabled = TRUE; for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { if (IsProcessorPresent (Socket, StdHeader)) { GetFeatureServicesOfSocket (&MsgBasedC1eFamilyServiceTable, Socket, (CONST VOID **)&FamilyServices, StdHeader); if ((FamilyServices == NULL) || !FamilyServices->IsMsgBasedC1eSupported (FamilyServices, Socket, StdHeader)) { IsEnabled = FALSE; break; } else { // If the CPU revision supports message-based C1e, check whether the feature should // be disabled based on the speed of ncHT links (HT1). GetCpuServicesOfSocket (Socket, &CpuServices, StdHeader); for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) { HtHostFeats.HtHostValue = 0; for (LinkCount = 0; LinkCount < 8; LinkCount++) { if (FindHtHostCapability (LinkCount, &PciAddress, StdHeader)) { CpuServices->GetHtLinkFeatures (CpuServices, &Link, &PciAddress, &HtHostFeats, StdHeader); if ((HtHostFeats.HtHostFeatures.NonCoherent == 1) && (HtHostFeats.HtHostFeatures.Ht1 == 1)) { IsEnabled = FALSE; break; } } } } // Exit for (Module = 0; Module < GetPlatformNumberOfModules; Module++) if (!IsEnabled) { break; } } } } // Exit for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) if (!IsEnabled) { break; } } } } return IsEnabled; }
/** * Multisocket call to determine the most severe AGESA_STATUS return value after * processing the power management initialization tables. * * This function loops through all possible socket locations, collecting any * power management initialization errors that may have occurred. These errors * are transferred from the core 0s of the socket in which the errors occurred * to the BSC's heap. The BSC's heap is then searched for the most severe error * that occurred, and returns it. This function must be called by the BSC only. * * @param[in] StdHeader Config handle for library and services * * @return The most severe error code from power management init * */ AGESA_STATUS GetEarlyPmErrorsMulti ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINT16 i; UINT32 BscSocket; UINT32 BscModule; UINT32 BscCoreNum; UINT32 Socket; UINT32 NumberOfSockets; AP_TASK TaskPtr; AGESA_EVENT EventLogEntry; AGESA_STATUS ReturnCode; AGESA_STATUS DummyStatus; ASSERT (IsBsp (StdHeader, &ReturnCode)); ReturnCode = AGESA_SUCCESS; EventLogEntry.EventClass = AGESA_SUCCESS; EventLogEntry.EventInfo = 0; EventLogEntry.DataParam1 = 0; EventLogEntry.DataParam2 = 0; EventLogEntry.DataParam3 = 0; EventLogEntry.DataParam4 = 0; NumberOfSockets = GetPlatformNumberOfSockets (); IdentifyCore (StdHeader, &BscSocket, &BscModule, &BscCoreNum, &DummyStatus); TaskPtr.FuncAddress.PfApTaskI = GetNextEvent; TaskPtr.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (AGESA_EVENT); TaskPtr.DataTransfer.DataPtr = &EventLogEntry; TaskPtr.DataTransfer.DataTransferFlags = 0; TaskPtr.ExeFlags = WAIT_FOR_CORE | RETURN_PARAMS; for (Socket = 0; Socket < NumberOfSockets; Socket++) { if (Socket != BscSocket) { if (IsProcessorPresent (Socket, StdHeader)) { do { ApUtilRunCodeOnSocketCore ((UINT8)Socket, (UINT8) 0, &TaskPtr, StdHeader); if ((EventLogEntry.EventInfo & CPU_EVENT_PM_EVENT_MASK) == CPU_EVENT_PM_EVENT_CLASS) { PutEventLog ( EventLogEntry.EventClass, EventLogEntry.EventInfo, EventLogEntry.DataParam1, EventLogEntry.DataParam2, EventLogEntry.DataParam3, EventLogEntry.DataParam4, StdHeader ); } } while (EventLogEntry.EventInfo != 0); } } } for (i = 0; PeekEventLog (&EventLogEntry, i, StdHeader); i++) { if ((EventLogEntry.EventInfo & CPU_EVENT_PM_EVENT_MASK) == CPU_EVENT_PM_EVENT_CLASS) { if (EventLogEntry.EventClass > ReturnCode) { ReturnCode = EventLogEntry.EventClass; } } } return (ReturnCode); }
AGESA_STATUS PcieConfigurationInit ( IN AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS Status; PCIe_PLATFORM_CONFIG *Pcie; PCIe_SILICON_CONFIG *Silicon; UINT8 SocketId; UINTN CurrentComplexesDataLength; UINTN ComplexesDataLength; UINT8 ComplexIndex; VOID *Buffer; ComplexesDataLength = 0; Status = AGESA_SUCCESS; IDS_HDT_CONSOLE (GNB_TRACE, "PcieConfigurationInit Enter\n"); for (SocketId = 0; SocketId < GetPlatformNumberOfSockets (); SocketId++) { if (IsProcessorPresent (SocketId, StdHeader)) { Status = PcieFmGetComplexDataLength (SocketId, &CurrentComplexesDataLength, StdHeader); ASSERT (Status == AGESA_SUCCESS); ComplexesDataLength += CurrentComplexesDataLength; } } ComplexIndex = 0; Pcie = GnbAllocateHeapBufferAndClear (AMD_PCIE_COMPLEX_DATA_HANDLE, sizeof (PCIe_PLATFORM_CONFIG) + ComplexesDataLength, StdHeader); ASSERT (Pcie != NULL); if (Pcie != NULL) { PcieConfigAttachChild (&Pcie->Header, &Pcie->ComplexList[ComplexIndex].Header); PcieConfigSetDescriptorFlags (Pcie, DESCRIPTOR_PLATFORM | DESCRIPTOR_TERMINATE_LIST | DESCRIPTOR_TERMINATE_TOPOLOGY); Buffer = (UINT8 *) (Pcie) + sizeof (PCIe_PLATFORM_CONFIG); for (SocketId = 0; SocketId < GetPlatformNumberOfSockets (); SocketId++) { if (IsProcessorPresent (SocketId, StdHeader)) { Pcie->ComplexList[ComplexIndex].SocketId = SocketId; //Attache Comples to Silicon which will be created by PcieFmBuildComplexConfiguration PcieConfigAttachChild (&Pcie->ComplexList[ComplexIndex].Header, &((PCIe_SILICON_CONFIG *) Buffer)->Header); //Attach Comples to Pcie PcieConfigAttachParent (&Pcie->Header, &Pcie->ComplexList[ComplexIndex].Header); PcieConfigSetDescriptorFlags (&Pcie->ComplexList[ComplexIndex], DESCRIPTOR_COMPLEX | DESCRIPTOR_TERMINATE_LIST | DESCRIPTOR_TERMINATE_GNB | DESCRIPTOR_TERMINATE_TOPOLOGY); PcieFmBuildComplexConfiguration (SocketId, Buffer, StdHeader); Silicon = PcieConfigGetChildSilicon (&Pcie->ComplexList[ComplexIndex]); while (Silicon != NULL) { PcieConfigAttachParent (&Pcie->ComplexList[ComplexIndex].Header, &Silicon->Header); GetNodeId (SocketId, Silicon->SiliconId, &Silicon->NodeId, StdHeader); GnbFmGetLinkId ((GNB_HANDLE*) Silicon, &Silicon->LinkId, StdHeader); Silicon = (PCIe_SILICON_CONFIG *) PcieConfigGetNextTopologyDescriptor (Silicon, DESCRIPTOR_TERMINATE_TOPOLOGY); } if (ComplexIndex > 0) { PcieConfigAttachComplexes (&Pcie->ComplexList[ComplexIndex - 1], &Pcie->ComplexList[ComplexIndex]); } PcieFmGetComplexDataLength (SocketId, &CurrentComplexesDataLength, StdHeader); Buffer = (VOID *) ((UINT8 *) Buffer + CurrentComplexesDataLength); ComplexIndex++; } } } else { Status = AGESA_FATAL; } IDS_HDT_CONSOLE (GNB_TRACE, "PcieConfigurationInit Exit [0x%x]\n", Status); return Status; }
/** * Enable L3 dependent features. * * L3 features initialization requires the following series of steps. * 1. Disable L3 and DRAM scrubbers on all nodes * 2. Wait 40us for outstanding scrub results to complete * 3. Disable all cache activity in the system * 4. Issue WBINVD on all active cores * 5. Initialize Probe Filter, if supported * 6. Initialize ATM Mode, if supported * 7. Enable all cache activity in the system * 8. Restore L3 and DRAM scrubber register values * * @param[in] EntryPoint Timepoint designator. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] StdHeader Config Handle for library, services. * * @retval AGESA_SUCCESS Always succeeds. * */ AGESA_STATUS STATIC InitializeL3Feature ( IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 CpuCount; UINT32 Socket; BOOLEAN HtAssistEnabled; BOOLEAN AtmModeEnabled; AGESA_STATUS AgesaStatus; AP_MAILBOXES ApMailboxes; AP_EXE_PARAMS ApParams; UINT32 Scrubbers[MAX_SOCKETS_SUPPORTED][L3_SCRUBBER_CONTEXT_ARRAY_SIZE]; L3_FEATURE_FAMILY_SERVICES *FamilyServices[MAX_SOCKETS_SUPPORTED]; AgesaStatus = AGESA_SUCCESS; HtAssistEnabled = TRUE; AtmModeEnabled = TRUE; IDS_HDT_CONSOLE (CPU_TRACE, " Enabling L3 dependent features\n"); // There are many family service call outs. Initialize the family service array while // cache is still enabled. for (Socket = 0; Socket < MAX_SOCKETS_SUPPORTED; Socket++) { if (IsProcessorPresent (Socket, StdHeader)) { GetFeatureServicesOfSocket (&L3FeatureFamilyServiceTable, Socket, (const VOID **) &FamilyServices[Socket], StdHeader); } else { FamilyServices[Socket] = NULL; } } if (EntryPoint == CPU_FEAT_AFTER_POST_MTRR_SYNC) { // Check for optimal settings GetApMailbox (&ApMailboxes.ApMailInfo.Info, StdHeader); CpuCount = GetNumberOfProcessors (StdHeader); if (((CpuCount == 1) && (ApMailboxes.ApMailInfo.Fields.ModuleType == 1)) || ((CpuCount == 2) && (ApMailboxes.ApMailInfo.Fields.ModuleType == 0))) { for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { // Only check for non-optimal HT Assist setting is if's supported. if ((FamilyServices[Socket] != NULL) && (FamilyServices[Socket]->IsHtAssistSupported (FamilyServices[Socket], PlatformConfig, StdHeader))) { if (FamilyServices[Socket]->IsNonOptimalConfig (FamilyServices[Socket], Socket, StdHeader)) { // Non-optimal settings. Log an event. AgesaStatus = AGESA_WARNING; PutEventLog (AgesaStatus, CPU_WARNING_NONOPTIMAL_HT_ASSIST_CFG, 0, 0, 0, 0, StdHeader); break; } } } } } else { // Disable the scrubbers. for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { if (FamilyServices[Socket] != NULL) { FamilyServices[Socket]->GetL3ScrubCtrl (FamilyServices[Socket], Socket, &Scrubbers[Socket][0], StdHeader); // If any node in the system does not support Probe Filter, disable it on the system if (!FamilyServices[Socket]->IsHtAssistSupported (FamilyServices[Socket], PlatformConfig, StdHeader)) { HtAssistEnabled = FALSE; } // If any node in the system does not support ATM mode, disable it on the system if (!FamilyServices[Socket]->IsAtmModeSupported (FamilyServices[Socket], PlatformConfig, StdHeader)) { AtmModeEnabled = FALSE; } } } // Wait for 40us WaitMicroseconds ((UINT32) 40, StdHeader); // Run DisableAllCaches on AP cores. ApParams.StdHeader = *StdHeader; ApParams.FunctionNumber = AP_LATE_TASK_DISABLE_CACHE; ApParams.RelatedDataBlock = (VOID *) &HtAssistEnabled; ApParams.RelatedBlockLength = sizeof (BOOLEAN); RunLateApTaskOnAllAPs (&ApParams, StdHeader); // Run DisableAllCaches on core 0. DisableAllCaches (&ApParams); // Family hook before initialization. for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { if (FamilyServices[Socket] != NULL) { FamilyServices[Socket]->HookBeforeInit (FamilyServices[Socket], Socket, StdHeader); } } // Activate Probe Filter & ATM mode. for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { if (FamilyServices[Socket] != NULL) { if (HtAssistEnabled) { FamilyServices[Socket]->HtAssistInit (FamilyServices[Socket], Socket, StdHeader); } if (AtmModeEnabled) { FamilyServices[Socket]->AtmModeInit (FamilyServices[Socket], Socket, StdHeader); } } } // Family hook after initialization. for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { if (FamilyServices[Socket] != NULL) { FamilyServices[Socket]->HookAfterInit (FamilyServices[Socket], Socket, StdHeader); } } // Run EnableAllCaches on core 0. EnableAllCaches (&ApParams); // Run EnableAllCaches on every core. ApParams.FunctionNumber = AP_LATE_TASK_ENABLE_CACHE; RunLateApTaskOnAllAPs (&ApParams, StdHeader); // Restore the scrubbers. for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { if (FamilyServices[Socket] != NULL) { FamilyServices[Socket]->SetL3ScrubCtrl (FamilyServices[Socket], Socket, &Scrubbers[Socket][0], StdHeader); } } } return AgesaStatus; }