コード例 #1
0
ファイル: heapManager.c プロジェクト: MikeeHawk/coreboot
/**
 * Determines the base address of the executing core's heap.
 *
 * This function uses the executing core's socket/core numbers to determine
 * where it's heap should be located.
 *
 * @param[in]      StdHeader      Config handle for library and services.
 *
 * @return         A pointer to the executing core's heap.
 *
 */
UINT64
STATIC
HeapGetCurrentBase (
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32      SystemCoreNumber;
  UINT64      ReturnPtr;
  AGESA_STATUS          IgnoredStatus;
  CPU_SPECIFIC_SERVICES *FamilyServices;

  if (IsBsp (StdHeader, &IgnoredStatus)) {
    ReturnPtr = AMD_HEAP_START_ADDRESS;
  } else {
    GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilyServices, StdHeader);
    ASSERT (FamilyServices != NULL);

    SystemCoreNumber = FamilyServices->GetApCoreNumber (FamilyServices, StdHeader);
    ASSERT (SystemCoreNumber != 0);
    ASSERT (SystemCoreNumber < 64);
    ReturnPtr = ((SystemCoreNumber * AMD_HEAP_SIZE_PER_CORE) + AMD_HEAP_START_ADDRESS);
  }
  ASSERT (ReturnPtr <= ((AMD_HEAP_REGION_END_ADDRESS + 1) - AMD_HEAP_SIZE_PER_CORE));
  return ReturnPtr;
}
コード例 #2
0
/**
 * Single socket call to determine the frequency that the northbridges must run.
 *
 * This function simply returns the executing core's NB frequency, and that all
 * 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
GetSystemNbCofSingle (
  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 Ignored;
  PCI_ADDR PciAddress;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0);
  *SystemNbCofsMatch = TRUE;
  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  *NbPstateIsEnabledOnAllCPUs = FamilySpecificServices->GetNbPstateInfo (FamilySpecificServices,
                                                                         PlatformConfig,
                                                                         &PciAddress,
                                                                         NbPstate,
                                                                         SystemNbCofNumerator,
                                                                         SystemNbCofDenominator,
                                                                         &Ignored,
                                                                         StdHeader);
  return *NbPstateIsEnabledOnAllCPUs;
}
コード例 #3
0
ファイル: mnParTrainHy.c プロジェクト: AdriDlu/coreboot
BOOLEAN
STATIC
MemConstructRemoteNBBlockHY (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       DIE_STRUCT *MCTPtr,
  IN       MEM_FEAT_BLOCK_NB *FeatPtr
  )
{
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  NBPtr->MCTPtr = MCTPtr;
  NBPtr->PciAddr.AddressValue = MCTPtr->PciAddr.AddressValue;

  MemNInitNBDataHy (NBPtr);

  FeatPtr->InitCPG (NBPtr);
  NBPtr->FeatPtr = FeatPtr;
  FeatPtr->InitHwRxEn (NBPtr);
  MemNSwitchDCTNb (NBPtr, 0);

  //----------------------------------------------------------------------------
  // Get TSC rate of the this AP
  //----------------------------------------------------------------------------
  GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &NBPtr->MemPtr->StdHeader);
  FamilySpecificServices->GetTscRate (FamilySpecificServices, &NBPtr->MemPtr->TscRate, &NBPtr->MemPtr->StdHeader);

  return TRUE;
}
コード例 #4
0
ファイル: IdsLib.c プロジェクト: Godkey/coreboot
/**
 *  Get the number of P-State to support
 *
 *  @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS.
 *
 *  @retval num    The number of P-State to support.
 *
 **/
UINT8
IdsGetNumPstatesFamCommon (
  IN OUT   AMD_CONFIG_PARAMS  *StdHeader
  )
{
  UINT8 pstatesnum;
  UINT8 i;
  UINT32 IddVal;
  UINT32 IddDiv;
  BOOLEAN PStateEnabled;
  UINT32 TempVar_c;
  CPU_SPECIFIC_SERVICES   *FamilySpecificServices;

  pstatesnum = 0;
  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);

  FamilySpecificServices->GetPstateMaxState (FamilySpecificServices, &TempVar_c, StdHeader);
  for (i = 0; i <= TempVar_c; i++) {
    // Check if PState is enabled
    FamilySpecificServices->GetPstateRegisterInfo (FamilySpecificServices,
                                                   (UINT32) i,
                                                   &PStateEnabled,
                                                   &IddVal,
                                                   &IddDiv,
                                                   StdHeader);
    if (PStateEnabled) {
      pstatesnum++;
    }
  }
  return pstatesnum;
}
コード例 #5
0
ファイル: cpuWarmReset.c プロジェクト: fishbaoz/edk2ml
/**
 *    This function will get the CPU register warm reset bits.
 *
 *    Note: This function will be called by UEFI BIOS's
 *    The UEFI wrapper code should register this function, to be called back later point
 *    in time, before the wrapper code does warm reset.
 *
 *    @param[in] StdHeader Config handle for library and services
 *    @param[out] Request   Indicate warm reset status
 *
 *---------------------------------------------------------------------------------------
 **/
VOID
GetWarmResetFlag (
  IN       AMD_CONFIG_PARAMS *StdHeader,
     OUT   WARM_RESET_REQUEST *Request
  )
{
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  FamilySpecificServices = NULL;

  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  FamilySpecificServices->GetWarmResetFlag (FamilySpecificServices, StdHeader, Request);

  switch (StdHeader->Func) {
  case AMD_INIT_RESET:
    Request->PostStage = (UINT8) WR_STATE_RESET;
    break;
  case AMD_INIT_EARLY:
    Request->PostStage = (UINT8) WR_STATE_EARLY;
    break;
  case AMD_INIT_POST:
    // Fall through to default case
  default:
    Request->PostStage = (UINT8) WR_STATE_POST;
    break;
  }
}
コード例 #6
0
ファイル: IdsPerf.c プロジェクト: fishbaoz/edk2ml
/**
 * Output Test Point function .
 *
 *  @param[in,out] StdHeader    The Pointer of Standard Header.
 *
 *  @retval AGESA_SUCCESS       Success to get the pointer of IDS_CHECK_POINT_PERF_HANDLE.
 *  @retval AGESA_ERROR         Fail to get the pointer of IDS_CHECK_POINT_PERF_HANDLE.
 *
 **/
AGESA_STATUS
IdsPerfAnalyseTimestamp (
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  AGESA_STATUS status;
  LOCATE_HEAP_PTR LocateHeapStructPtr;
  UINT32 TscRateInMhz;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  IDS_CALLOUT_STRUCT IdsCalloutData;
  AGESA_STATUS Status;

  PERFREGBACKUP PerfReg;
  UINT32 CR4reg;
  UINT64 SMsr;

  LocateHeapStructPtr.BufferHandle = IDS_CHECK_POINT_PERF_HANDLE;
  LocateHeapStructPtr.BufferPtr = NULL;
  status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader);
  if (status != AGESA_SUCCESS) {
    return status;
  }
  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  FamilySpecificServices->GetTscRate (FamilySpecificServices, &TscRateInMhz, StdHeader);
  ((TP_Perf_STRUCT *) (LocateHeapStructPtr.BufferPtr)) ->TscInMhz = TscRateInMhz;
  ((TP_Perf_STRUCT *) (LocateHeapStructPtr.BufferPtr)) ->Version = IDS_PERF_VERSION;

  IdsCalloutData.IdsNvPtr = NULL;
  IdsCalloutData.StdHeader = *StdHeader;
  IdsCalloutData.Reserved = 0;
  Status = AgesaGetIdsData (IDS_CALLOUT_GET_PERF_BUFFER, &IdsCalloutData);

  //Check if Platform BIOS provide a buffer to copy
  if ((Status == AGESA_SUCCESS) && (IdsCalloutData.Reserved != 0)) {
    LibAmdMemCopy ((VOID *)IdsCalloutData.Reserved, LocateHeapStructPtr.BufferPtr, sizeof (TP_Perf_STRUCT), StdHeader);
  } else {
    //No platform performance buffer provide, use the default HDTOUT output
    if (AmdIdsHdtOutSupport () == FALSE) {
    //Init break point
      IdsPerfSaveReg (&PerfReg, StdHeader);

      LibAmdMsrRead (0xC001100A, (UINT64 *)&SMsr, StdHeader);
      SMsr |= 1;
      LibAmdMsrWrite (0xC001100A, (UINT64 *)&SMsr, StdHeader);

      LibAmdWriteCpuReg (DR2_REG, 0x99cc);
      LibAmdWriteCpuReg (DR7_REG, 0x02000420);

      LibAmdReadCpuReg (CR4_REG, &CR4reg);
      LibAmdWriteCpuReg (CR4_REG, CR4reg | ((UINT32)1 << 3));

      IdsPerfHdtOut (1, (UINT32) (UINT64) LocateHeapStructPtr.BufferPtr, StdHeader);
      IdsPerfRestoreReg (&PerfReg, StdHeader);
    }
  }
  return status;
}
コード例 #7
0
/**
 * Single socket BSC call to determine the maximum number of steps that any single
 * processor needs to execute.
 *
 * This function simply returns the number of steps that the BSC needs.
 *
 * @param[out] NumSystemSteps    Maximum number of system steps required
 * @param[in]  StdHeader         Config handle for library and services
 *
 */
VOID
GetNumberOfSystemPmStepsPtrSingle (
     OUT   UINT8 *NumSystemSteps,
  IN       AMD_CONFIG_PARAMS   *StdHeader
  )
{
  SYS_PM_TBL_STEP *Ignored;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  FamilySpecificServices->GetSysPmTableStruct (FamilySpecificServices, (CONST VOID **) &Ignored, NumSystemSteps, StdHeader);
}
コード例 #8
0
ファイル: cpuPowerMgmt.c プロジェクト: B-Rich/coreboot
/**
 * Transitions the executing core to the desired P-state.
 *
 * This function implements the AMD_CPU_EARLY_PARAMS.MemInitPState parameter, and is
 * run by all system cores.
 *
 * @param[in]  StdHeader         Config handle for library and services
 * @param[in]  CpuEarlyParamsPtr Required input parameters for early CPU initialization
 *
 */
VOID
STATIC
GoToMemInitPstateCore (
  IN       AMD_CONFIG_PARAMS    *StdHeader,
  IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
  )
{
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
  FamilySpecificServices->TransitionPstate (FamilySpecificServices, CpuEarlyParamsPtr->MemInitPState, (BOOLEAN) FALSE, StdHeader);
}
コード例 #9
0
ファイル: cpuWarmReset.c プロジェクト: fishbaoz/edk2ml
/**
 *    This function will set the CPU register warm reset bits.
 *
 *    Note: This function will be called by UEFI BIOS's
 *    The UEFI wrapper code should register this function, to be called back later point
 *    in time, before the wrapper code does warm reset.
 *
 *    @param[in] StdHeader Config handle for library and services
 *    @param[in] Request   Indicate warm reset status
 *
 *---------------------------------------------------------------------------------------
 **/
VOID
SetWarmResetFlag (
  IN       AMD_CONFIG_PARAMS *StdHeader,
  IN       WARM_RESET_REQUEST *Request
  )
{
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  FamilySpecificServices = NULL;

  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  FamilySpecificServices->SetWarmResetFlag (FamilySpecificServices, StdHeader, Request);
}
コード例 #10
0
/**
 *
 *  WriteFeatures
 *
 *    Write out least common features set of all CPUs
 *
 *    @param[in,out]  cpuFeatureListPtr  - Pointer to CPU Feature List.
 *    @param[in,out]  StdHeader          - Pointer to AMD_CONFIG_PARAMS struct.
 *
 */
VOID
STATIC
WriteFeatures (
  IN OUT   VOID *cpuFeatureListPtr,
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  FamilySpecificServices = NULL;

  GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
  FamilySpecificServices->WriteFeatures (FamilySpecificServices, cpuFeatureListPtr, StdHeader);
}
コード例 #11
0
/**
 * Single socket call to determine if the BIOS is responsible for updating the
 * northbridge operating frequency and voltage.
 *
 * This function simply returns whether or not the executing core needs NB COF
 * VID programming.
 *
 * @param[in]  StdHeader              Config handle for library and services
 *
 * @retval     TRUE    BIOS needs to set up NB frequency and voltage
 * @retval     FALSE   BIOS does not need to set up NB frequency and voltage
 *
 */
BOOLEAN
GetSystemNbCofVidUpdateSingle (
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  BOOLEAN   Ignored;
  PCI_ADDR PciAddress;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0);
  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  return (FamilySpecificServices->IsNbCofInitNeeded (FamilySpecificServices, &PciAddress, &Ignored, StdHeader));
}
コード例 #12
0
ファイル: IdsCtrl.c プロジェクト: AdriDlu/coreboot
/**
 *  IDS Backend Function for Target Pstate
 *
 *
 *  @param[in,out]   DataPtr      The Pointer of AMD_CPU_EARLY_PARAMS.
 *  @param[in,out]   StdHeader    The Pointer of AMD_CONFIG_PARAMS.
 *  @param[in]     IdsNvPtr     The Pointer of NV Table.
 *
 *  @retval IDS_SUCCESS         Backend function is called successfully.
 *  @retval IDS_UNSUPPORTED     No Backend function is found.
 *
 **/
IDS_STATUS
IdsSubTargetPstate (
  IN OUT   VOID *DataPtr,
  IN OUT   AMD_CONFIG_PARAMS *StdHeader,
  IN       IDS_NV_ITEM *IdsNvPtr
  )
{
  IDS_STATUS tarpst;
  CPU_SPECIFIC_SERVICES   *FamilySpecificServices;

  IDS_NV_READ_SKIP (tarpst, AGESA_IDS_NV_TARGET_PSTATE, IdsNvPtr) {
    GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
    FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) tarpst, (BOOLEAN) FALSE, StdHeader);
  }
コード例 #13
0
ファイル: cpuPowerMgmt.c プロジェクト: B-Rich/coreboot
/**
 * Performs the next step in the executing core 0's family specific power
 * management table.
 *
 * This function determines if the input step is valid, and invokes the power
 * management step if appropriate.  This must be run by processor core 0s only.
 *
 * @param[in]  Step              Zero based step number
 * @param[in]  StdHeader         Config handle for library and services
 * @param[in]  CpuEarlyParamsPtr Required input parameters for early CPU initialization
 *
 */
VOID
STATIC
PerformThisPmStep (
  IN       VOID *Step,
  IN       AMD_CONFIG_PARAMS    *StdHeader,
  IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
  )
{
  UINT8           MyNumberOfSteps;
  UINT32          ExeResetFlags;
  SYS_PM_TBL_STEP *FamilyTablePtr;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  BOOLEAN         ThisIsWarmReset;
  BOOLEAN         NoResetLimit;
  BOOLEAN         NotConflictResetLimit;
  BOOLEAN         WarmResetOnly;
  BOOLEAN         ColdResetOnly;

  GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
  FamilySpecificServices->GetSysPmTableStruct (FamilySpecificServices, (CONST VOID **) &FamilyTablePtr, &MyNumberOfSteps, StdHeader);

  if (*(UINT8 *)Step < MyNumberOfSteps) {
    if (FamilyTablePtr[*(UINT8 *)Step].FuncPtr != NULL) {
      ExeResetFlags = FamilyTablePtr[*(UINT8 *)Step].ExeFlags & (PM_EXEFLAGS_COLD_ONLY | PM_EXEFLAGS_WARM_ONLY);
      ThisIsWarmReset = IsWarmReset (StdHeader);
      NoResetLimit = (ExeResetFlags == 0) ? TRUE : FALSE;
      NotConflictResetLimit = (BOOLEAN) (ExeResetFlags != (PM_EXEFLAGS_COLD_ONLY | PM_EXEFLAGS_WARM_ONLY));
      WarmResetOnly = (BOOLEAN) ((ExeResetFlags & PM_EXEFLAGS_WARM_ONLY) == PM_EXEFLAGS_WARM_ONLY);
      ColdResetOnly = (BOOLEAN) ((ExeResetFlags & PM_EXEFLAGS_COLD_ONLY) == PM_EXEFLAGS_COLD_ONLY);

      IDS_HDT_CONSOLE (CPU_TRACE, "  \tIsWarmReset = %d.\n", ThisIsWarmReset);
      IDS_HDT_CONSOLE (CPU_TRACE, "  \tNoResetLimit = %d\n", NoResetLimit);
      IDS_HDT_CONSOLE (CPU_TRACE, "  \tNotConflictResetLimit = %d\n", NotConflictResetLimit);
      IDS_HDT_CONSOLE (CPU_TRACE, "  \tWarmResetOnly = %d\n", WarmResetOnly);
      IDS_HDT_CONSOLE (CPU_TRACE, "  \tColdResetOnly = %d\n", ColdResetOnly);

      ASSERT (NotConflictResetLimit);

      if (NoResetLimit ||
          (NotConflictResetLimit &&
           ((WarmResetOnly && ThisIsWarmReset) || (ColdResetOnly && !ThisIsWarmReset)))) {
        FamilyTablePtr[*(UINT8 *)Step].FuncPtr (FamilySpecificServices, CpuEarlyParamsPtr, StdHeader);
      } else {
        IDS_HDT_CONSOLE (CPU_TRACE, "  \t\tThis PM init step was skipped!\n");
      }
    }
  }
}
コード例 #14
0
/**
 * Single socket call to loop through all Nb Pstates, comparing the NB frequencies
 * to determine the slowest in the system. This routine also returns the NB P0 frequency.
 *
 * @param[in]  PlatformConfig      Platform profile/build option config structure.
 * @param[out] MinSysNbFreq        NB frequency numerator for the system in MHz
 * @param[out] MinP0NbFreq         NB frequency numerator for P0 in MHz
 * @param[in]  StdHeader           Config handle for library and services
 */
VOID
GetMinNbCofSingle (
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
     OUT   UINT32                 *MinSysNbFreq,
     OUT   UINT32                 *MinP0NbFreq,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  PCI_ADDR              PciAddress;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0);
  GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **) &FamilySpecificServices, StdHeader);
  FamilySpecificServices->GetMinMaxNbFrequency (FamilySpecificServices,
                                             PlatformConfig,
                                             &PciAddress,
                                             MinSysNbFreq,
                                             MinP0NbFreq,
                                             StdHeader);
}
コード例 #15
0
ファイル: F10PmNbCofVidInit.c プロジェクト: Godkey/coreboot
/**
 * Cold reset support routine for F10PmNbCofVidInit.
 *
 * This function implements steps 3, 4, & 5 on each core.
 *
 * @param[in]  NewNbVid           NewNbVid determined by core 0 in step 2.
 * @param[in]  StdHeader          Config handle for library and services.
 *
 */
VOID
STATIC
PmNbCofVidInitP0P1Core (
  IN       VOID *NewNbVid,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32 MsrAddress;
  UINT64 MsrRegister;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices = NULL;

  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  LibAmdMsrRead (MSR_COFVID_STS, &MsrRegister, StdHeader);
  MsrAddress = (UINT32) ((((COFVID_STS_MSR *) &MsrRegister)->StartupPstate) + PS_REG_BASE);
  LibAmdMsrRead (MsrAddress, &MsrRegister, StdHeader);
  LibAmdMsrWrite ((UINT32) (PS_REG_BASE + 1), &MsrRegister, StdHeader);
  ((PSTATE_MSR *) &MsrRegister)->NbVid = *(UINT8 *) NewNbVid;
  LibAmdMsrWrite (PS_REG_BASE, &MsrRegister, StdHeader);
  FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 1, (BOOLEAN) FALSE, StdHeader);
}
コード例 #16
0
ファイル: mfs3.c プロジェクト: 0ida/coreboot
VOID
MemFS3Wait10ns (
  IN       UINT32 Count,
  IN OUT   MEM_DATA_STRUCT *MemPtr
  )
{
  UINT32 TscRate;
  UINT64 TargetTsc;
  UINT64 CurrentTsc;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  ASSERT (Count <= 1000000);
  GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &MemPtr->StdHeader);
  FamilySpecificServices->GetTscRate (FamilySpecificServices, &TscRate, &MemPtr->StdHeader);

  LibAmdMsrRead (TSC, &CurrentTsc, &MemPtr->StdHeader);
  TargetTsc = CurrentTsc + ((Count * TscRate + 99) / 100);
  do {
    LibAmdMsrRead (TSC, &CurrentTsc, &MemPtr->StdHeader);
  } while (CurrentTsc < TargetTsc);
}
コード例 #17
0
ファイル: F16MlPsi.c プロジェクト: fishbaoz/edk2ml
/**
 * Entry point for enabling Power Status Indicator
 *
 * This function must be run after all P-State routines have been executed
 *
 * @param[in]  PsiServices             The current CPU's family services.
 * @param[in]  EntryPoint              Timepoint designator.
 * @param[in]  PlatformConfig          Contains the runtime modifiable feature input data.
 * @param[in]  StdHeader               Config handle for library and services.
 *
 * @retval     AGESA_SUCCESS           Always succeeds.
 *
 */
AGESA_STATUS
STATIC
F16MlInitializePsi (
    IN       PSI_FAMILY_SERVICES    *PsiServices,
    IN       UINT64                  EntryPoint,
    IN       PLATFORM_CONFIGURATION *PlatformConfig,
    IN       AMD_CONFIG_PARAMS      *StdHeader
)
{
    PCI_ADDR                  PciAddress;
    CPU_SPECIFIC_SERVICES     *FamilySpecificServices;

    if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) {
        GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
        PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0);
        // Configure PsiVid
        F16MlPmVrmLowPowerModeEnable (FamilySpecificServices, PlatformConfig, PciAddress, StdHeader);
    }

    return AGESA_SUCCESS;
}
コード例 #18
0
/**
 *---------------------------------------------------------------------------------------
 *
 *  PutCoreInPState0
 *
 *  Description:
 *    This function will take the CPU core into P0
 *
 *  Parameters:
 *    @param[in]         *PStateBuffer
 *    @param[in]         *StdHeader
 *
 *    @retval         VOID
 *
 *---------------------------------------------------------------------------------------
 **/
VOID
STATIC
PutCoreInPState0 (
  IN       VOID   *PStateBuffer,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  CPU_SPECIFIC_SERVICES   *FamilySpecificServices;
  PSTATE_LEVELING         *PStateBufferPtr;

  PStateBufferPtr = (PSTATE_LEVELING *) PStateBuffer;

  if ((PStateBufferPtr[0].SetPState0 == PSTATE_FLAG_1 ) ||
     (PStateBufferPtr[0].SetPState0 == PSTATE_FLAG_2)) {
    return;
  }

  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);

  FamilySpecificServices->TransitionPstate  (FamilySpecificServices, (UINT8) 0, (BOOLEAN) FALSE, StdHeader);
}
コード例 #19
0
ファイル: IdsPerf.c プロジェクト: Godkey/coreboot
/**
 * Output Test Point function .
 *
 *  @param[in,out] StdHeader    The Pointer of Standard Header.
 *
 *  @retval AGESA_SUCCESS       Success to get the pointer of IDS_CHECK_POINT_PERF_HANDLE.
 *  @retval AGESA_ERROR         Fail to get the pointer of IDS_CHECK_POINT_PERF_HANDLE.
 *
 **/
AGESA_STATUS
IdsPerfAnalyseTimestamp (
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  AGESA_STATUS status;
  LOCATE_HEAP_PTR LocateHeapStructPtr;
  UINT32 TscRateInMhz;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  PERFREGBACKUP PerfReg;
  UINT32 CR4reg;
  UINT64 SMsr;

  LocateHeapStructPtr.BufferHandle = IDS_CHECK_POINT_PERF_HANDLE;
  LocateHeapStructPtr.BufferPtr = NULL;
  status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader);
  if (status != AGESA_SUCCESS) {
    return status;
  }
  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  FamilySpecificServices->GetTscRate (FamilySpecificServices, &TscRateInMhz, StdHeader);
  ((TP_Perf_STRUCT *) (LocateHeapStructPtr.BufferPtr)) ->TscInMhz = TscRateInMhz;
//Init break point
  IdsPerfSaveReg (&PerfReg, StdHeader);

  LibAmdMsrRead (0xC001100A, (UINT64 *)&SMsr, StdHeader);
  SMsr |= 1;
  LibAmdMsrWrite (0xC001100A, (UINT64 *)&SMsr, StdHeader);

  LibAmdWriteCpuReg (DR0_REG, 0x8899);
  LibAmdWriteCpuReg (DR7_REG, 0x00020402);

  LibAmdReadCpuReg (CR4_REG, &CR4reg);
  LibAmdWriteCpuReg (CR4_REG, CR4reg | ((UINT32)1 << 3));

  IdsPerfHdtOut (1, (UINT32) LocateHeapStructPtr.BufferPtr, StdHeader);
  IdsPerfRestoreReg (&PerfReg, StdHeader);
  return status;
}
コード例 #20
0
/**
 * Single socket call to loop through all Nb Pstates, comparing the NB frequencies
 * to determine the slowest in the system. This routine also returns the NB P0 frequency.
 *
 * @param[in]  PlatformConfig      Platform profile/build option config structure.
 * @param[out] MinSysNbFreq        NB frequency numerator for the system in MHz
 * @param[out] MinP0NbFreq         NB frequency numerator for P0 in MHz
 * @param[in]  StdHeader           Config handle for library and services
 */
VOID
GetMinNbCofSingle (
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
     OUT   UINT32                 *MinSysNbFreq,
     OUT   UINT32                 *MinP0NbFreq,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  PCI_ADDR              PciAddress;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  AGESA_STATUS AgesaStatus;

  PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0);
  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  AgesaStatus = FamilySpecificServices->GetMinMaxNbFrequency (FamilySpecificServices,
                                             PlatformConfig,
                                             &PciAddress,
                                             MinSysNbFreq,
                                             MinP0NbFreq,
                                             StdHeader);
  ASSERT (AgesaStatus == AGESA_SUCCESS);
  ASSERT ((MinSysNbFreq != 0) && (MinP0NbFreq != 0));
}
コード例 #21
0
ファイル: heapManager.c プロジェクト: fishbaoz/edk2ml
/**
 * Determines the base address of the executing core's heap.
 *
 * This function uses the executing core's socket/core numbers to determine
 * where it's heap should be located.
 *
 * @param[in]      StdHeader      Config handle for library and services.
 *
 * @return         A pointer to the executing core's heap.
 *
 */
UINT64
STATIC
HeapGetCurrentBase (
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32      SystemCoreNumber;
  UINT64      ReturnPtr;
  UINTN       FcnData;
  AGESA_STATUS          IgnoredStatus;
  AGESA_REBASE_PARAMS   HeapRebaseParams;
  CPU_SPECIFIC_SERVICES *FamilyServices;

  HeapRebaseParams.HeapAddress = AMD_HEAP_START_ADDRESS;
  HeapRebaseParams.StdHeader = *StdHeader;
  FcnData = 0;
  AgesaHeapRebase (FcnData, &HeapRebaseParams);

  if (IsBsp (StdHeader, &IgnoredStatus)) {
    ReturnPtr = HeapRebaseParams.HeapAddress;
  } else {
    GetCpuServicesOfCurrentCore (&FamilyServices, StdHeader);
    ASSERT (FamilyServices != NULL);

    SystemCoreNumber = FamilyServices->GetApCoreNumber (FamilyServices, StdHeader);
    ASSERT (SystemCoreNumber != 0);
    ASSERT (SystemCoreNumber < 64);
    ReturnPtr = ((SystemCoreNumber * AMD_HEAP_SIZE_PER_CORE) + HeapRebaseParams.HeapAddress);
  }
  // Normally, HeapRebaseParams.HeapAddress = AMD_HEAP_START_ADDRESS
  // But due to SecureS3, HeapAddress would be changed during run-time
  // So below checking for ReturnPtr needs to be run only if HeapRebaseParams.HeapAddress = AMD_HEAP_START_ADDRESS
  if (HeapRebaseParams.HeapAddress == AMD_HEAP_START_ADDRESS) {
    ASSERT (ReturnPtr <= ((AMD_HEAP_REGION_END_ADDRESS + 1) - AMD_HEAP_SIZE_PER_CORE));
  }
  return ReturnPtr;
}
コード例 #22
0
ファイル: cpuWarmReset.c プロジェクト: fishbaoz/edk2ml
/**
 * Is this boot a warm reset?
 *
 * This function reads the CPU register warm reset bit that is preserved after a warm reset.
 * Which in fact gets set before issuing warm reset.  We just use the BSP's register always.
 *
 * @param[in]       StdHeader       Config handle for library and services
 *
 * @retval      TRUE            Warm Reset
 * @retval      FALSE           Not Warm Reset
 *
 */
BOOLEAN
IsWarmReset (
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT8 PostStage;
  WARM_RESET_REQUEST Request;
  BOOLEAN  WarmReset;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  FamilySpecificServices = NULL;

  switch (StdHeader->Func) {
  case AMD_INIT_RESET:
    PostStage = WR_STATE_RESET;
    break;
  case AMD_INIT_EARLY:
    PostStage = WR_STATE_EARLY;
    break;
  case AMD_INIT_POST:
  default:
    PostStage = WR_STATE_POST;
    break;
  }

  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  FamilySpecificServices->GetWarmResetFlag (FamilySpecificServices, StdHeader, &Request);

  if (Request.StateBits >= PostStage) {
    WarmReset = TRUE;
  } else {
    WarmReset = FALSE;
  }

  return WarmReset;
}
コード例 #23
0
ファイル: F10PmNbCofVidInit.c プロジェクト: Godkey/coreboot
/**
 * Warm reset support routine for F10PmNbCofVidInit.
 *
 * This function implements steps 8 & 9 on each core.
 *
 * @param[in]  FunctionData       Contains NewNbVid determined by core 0 in step
 *                                2, and NbVidUpdateAll.
 * @param[in]  StdHeader          Config handle for library and services.
 *
 */
VOID
STATIC
PmNbCofVidInitWarmCore (
  IN       VOID *FunctionData,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32 MsrAddress;
  UINT64 MsrRegister;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  for (MsrAddress = PS_REG_BASE; MsrAddress <= PS_MAX_REG; MsrAddress++) {
    LibAmdMsrRead (MsrAddress, &MsrRegister, StdHeader);
    if (((PSTATE_MSR *) &MsrRegister)->PsEnable == 1) {
      if ((((PSTATE_MSR *) &MsrRegister)->NbDid == 0) || ((NB_COF_VID_INIT_WARM *) FunctionData)->NbVidUpdateAll) {
        ((PSTATE_MSR *) &MsrRegister)->NbVid = ((NB_COF_VID_INIT_WARM *) FunctionData)->NewNbVid;
        LibAmdMsrWrite (MsrAddress, &MsrRegister, StdHeader);
      }
    }
  }
  LibAmdMsrRead (MSR_COFVID_STS, &MsrRegister, StdHeader);
  FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) (((COFVID_STS_MSR *) &MsrRegister)->StartupPstate), (BOOLEAN) FALSE, StdHeader);
}
コード例 #24
0
ファイル: cpuPowerMgmt.c プロジェクト: michaelforney/coreboot
/**
 * Performs the next step in the executing core 0's family specific power
 * management table.
 *
 * This function determines if the input step is valid, and invokes the power
 * management step if appropriate.  This must be run by processor core 0s only.
 *
 * @param[in]  Step              Zero based step number
 * @param[in]  StdHeader         Config handle for library and services
 * @param[in]  CpuEarlyParamsPtr Required input parameters for early CPU initialization
 *
 */
VOID
STATIC
PerformThisPmStep (
  IN       VOID *Step,
  IN       AMD_CONFIG_PARAMS    *StdHeader,
  IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
  )
{
  UINT8  MyNumberOfSteps;
  SYS_PM_TBL_STEP *FamilyTablePtr;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  FamilySpecificServices->GetSysPmTableStruct (FamilySpecificServices, &FamilyTablePtr, &MyNumberOfSteps, StdHeader);

  if (*(UINT8 *)Step < MyNumberOfSteps) {
    if (FamilyTablePtr[*(UINT8 *)Step].FuncPtr != NULL) {
      if (!(BOOLEAN) (FamilyTablePtr[*(UINT8 *)Step].ExeFlags & PM_EXEFLAGS_WARM_ONLY) ||
          IsWarmReset (StdHeader)) {
        FamilyTablePtr[*(UINT8 *)Step].FuncPtr (FamilySpecificServices, CpuEarlyParamsPtr, StdHeader);
      }
    }
  }
}
コード例 #25
0
ファイル: cpuF15CzPsi.c プロジェクト: fishbaoz/CarrizoPI
/**
 * Entry point for enabling Power Status Indicator
 *
 * This function must be run after all P-State routines have been executed
 *
 * @param[in]  PsiServices             The current CPU's family services.
 * @param[in]  EntryPoint              Timepoint designator.
 * @param[in]  PlatformConfig          Contains the runtime modifiable feature input data.
 * @param[in]  StdHeader               Config handle for library and services.
 *
 * @retval     AGESA_SUCCESS           Always succeeds.
 *
 */
AGESA_STATUS
STATIC
F15CzInitializePsi (
  IN       PSI_FAMILY_SERVICES    *PsiServices,
  IN       UINT64                  EntryPoint,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  PCI_ADDR                              PciAddress;
  CPU_SPECIFIC_SERVICES                 *FamilySpecificServices;
  UINT32                                HwPstateMaxVal;
  F15_CZ_CLK_PWR_TIMING_CTRL2_REGISTER  ClkPwrTimingCtrl2;
  UINT32                                CoreVrmLowPowerThreshold;
  UINT32                                Pstate;
  UINT32                                PstateCurrent;
  UINT32                                NextPstateCurrent;
  PSTATE_MSR                            PstateMsr;
  UINT32                                CurrentVid;
  UINT32                                PreviousVid;
  NB_PSTATE_REGISTER                    NbPstateReg;
  NB_PSTATE_CTRL_REGISTER               NbPsCtrl;
  UINT32                                NbVrmLowPowerThreshold;
  UINT32                                NbPstate;
  UINT32                                NbPstateMaxVal;
  UINT32                                NbPstateCurrent;
  UINT32                                NextNbPstateCurrent;
  UINT32                                PreviousNbVid;
  UINT32                                CurrentNbVid;
  SMUSVI_MISC_VID_STATUS_REGISTER       SmuSviMiscVidStatus;
  SMUSVI_POWER_CONTROL_MISC_REGISTER    SmuSviPowerCtrlMisc;

  if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) {
    // Configure PsiVid
    GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **) &FamilySpecificServices, StdHeader);

    IDS_HDT_CONSOLE (CPU_TRACE, "  F15CzPmVrmLowPowerModeEnable\n");

    if (PlatformConfig->VrmProperties[CoreVrm].LowPowerThreshold != 0) {
      // Set up PSI0_L for VDD
      CoreVrmLowPowerThreshold = PlatformConfig->VrmProperties[CoreVrm].LowPowerThreshold;
      IDS_HDT_CONSOLE (CPU_TRACE, "    Core VRM - LowPowerThreshold: %d \n", CoreVrmLowPowerThreshold);
      PreviousVid = 0xFF;

      PciAddress.AddressValue = CPTC2_PCI_ADDR;
      LibAmdPciRead (AccessWidth32, PciAddress, &ClkPwrTimingCtrl2, StdHeader);
      HwPstateMaxVal = ClkPwrTimingCtrl2.HwPstateMaxVal;

      IDS_HDT_CONSOLE (CPU_TRACE, "    HwPstateMaxVal %d\n", HwPstateMaxVal);
      for (Pstate = 0; Pstate <= HwPstateMaxVal; Pstate++) {
        // Check only valid P-state
        if (FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) Pstate, &PstateCurrent, StdHeader) != TRUE) {
          continue;
        }

        LibAmdMsrRead ((UINT32) (Pstate + PS_REG_BASE), (UINT64 *) &PstateMsr, StdHeader);
        CurrentVid = (UINT32) PstateMsr.CpuVid;

        if (Pstate == HwPstateMaxVal) {
          NextPstateCurrent = 0;
        } else {
          // Check P-state from P1 to HwPstateMaxVal
          if (FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) (Pstate + 1), &NextPstateCurrent, StdHeader) != TRUE) {
            continue;
          }
        }

        if ((PstateCurrent <= CoreVrmLowPowerThreshold) &&
            (NextPstateCurrent <= CoreVrmLowPowerThreshold) &&
            (CurrentVid != PreviousVid)) {
          // Program PsiVid and PsiVidEn if PSI state is found and stop searching.
          GnbLibPciIndirectRead (MAKE_SBDFO (0, 0, 0, 0, 0xB8), SMUSVI_POWER_CONTROL_MISC, AccessWidth32, &SmuSviPowerCtrlMisc, StdHeader);
          SmuSviPowerCtrlMisc.PSIVID = CurrentVid;
          SmuSviPowerCtrlMisc.PSIVIDEN = 1;
          GnbLibPciIndirectWrite (MAKE_SBDFO (0, 0, 0, 0, 0xB8), SMUSVI_POWER_CONTROL_MISC, AccessWidth32, &SmuSviPowerCtrlMisc, StdHeader);

          IDS_HDT_CONSOLE (CPU_TRACE, "    PsiVid is enabled at P-state %d. PsiVid: %d\n", Pstate, CurrentVid);
          break;
        } else {
          PreviousVid = CurrentVid;
        }
      }
    }

    if (PlatformConfig->VrmProperties[NbVrm].LowPowerThreshold != 0) {
      // Set up NBPSI0_L for VDDNB
      NbVrmLowPowerThreshold = PlatformConfig->VrmProperties[NbVrm].LowPowerThreshold;
      IDS_HDT_CONSOLE (CPU_TRACE, "    NB VRM - LowPowerThreshold: %d\n", NbVrmLowPowerThreshold);
      PreviousNbVid = 0xFF;

      PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR;
      LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader);
      NbPstateMaxVal = NbPsCtrl.NbPstateMaxVal;
      ASSERT (NbPstateMaxVal < NM_NB_PS_REG);

      IDS_HDT_CONSOLE (CPU_TRACE, "    NbPstateMaxVal %d\n", NbPstateMaxVal);
      for (NbPstate = 0; NbPstate <= NbPstateMaxVal; NbPstate++) {
        // Check only valid NB P-state
        if (FamilySpecificServices->GetNbIddMax (FamilySpecificServices, (UINT8) NbPstate, &NbPstateCurrent, StdHeader) != TRUE) {
          continue;
        }

        PciAddress.Address.Register = (NB_PSTATE_0 + (sizeof (NB_PSTATE_REGISTER) * NbPstate));
        LibAmdPciRead (AccessWidth32, PciAddress, &NbPstateReg, StdHeader);
        CurrentNbVid = (UINT32) GetF15CzNbVid (&NbPstateReg);

        if (NbPstate == NbPstateMaxVal) {
          NextNbPstateCurrent = 0;
        } else {
          // Check only valid NB P-state
          if (FamilySpecificServices->GetNbIddMax (FamilySpecificServices, (UINT8) (NbPstate + 1), &NextNbPstateCurrent, StdHeader) != TRUE) {
            continue;
          }
        }

        if ((NbPstateCurrent <= NbVrmLowPowerThreshold) &&
            (NextNbPstateCurrent <= NbVrmLowPowerThreshold) &&
            (CurrentNbVid != PreviousNbVid)) {
          // Program NbPsi0Vid and NbPsi0VidEn if PSI state is found and stop searching.
          GnbLibPciIndirectRead (MAKE_SBDFO (0, 0, 0, 0, 0xB8), SMUSVI_MISC_VID_STATUS, AccessWidth32, &SmuSviMiscVidStatus, StdHeader);
          SmuSviMiscVidStatus.NB_PSI_VID = CurrentNbVid;
          SmuSviMiscVidStatus.NB_PSI_VID_EN = 1;
          GnbLibPciIndirectWrite (MAKE_SBDFO (0, 0, 0, 0, 0xB8), SMUSVI_MISC_VID_STATUS, AccessWidth32, &SmuSviMiscVidStatus, StdHeader);

          IDS_HDT_CONSOLE (CPU_TRACE, "    NbPsi0Vid is enabled at NB P-state %d. NbPsi0Vid: %d\n", NbPstate, CurrentNbVid);
          break;
        } else {
          PreviousNbVid = CurrentNbVid;
        }
      }
    }
  }

  return AGESA_SUCCESS;
}
コード例 #26
0
ファイル: cpuWhea.c プロジェクト: michaelforney/coreboot
/**
 *
 * It will create the ACPI tale of WHEA and return the pointer to the table.
 *
 *    @param[in, out]  StdHeader        Standard Head Pointer
 *    @param[in, out]  WheaMcePtr       Point to Whea Hest Mce table
 *    @param[in, out]  WheaCmcPtr       Point to Whea Hest Cmc table
 *
 *    @retval         UINT32  AGESA_STATUS
 */
AGESA_STATUS
GetAcpiWheaMain (
  IN OUT   AMD_CONFIG_PARAMS    *StdHeader,
  IN OUT   VOID                 **WheaMcePtr,
  IN OUT   VOID                 **WheaCmcPtr
  )
{
  UINT8  BankNum;
  UINT8  Entries;
  UINT16 HestMceTableSize;
  UINT16 HestCmcTableSize;
  UINT64 MsrData;
  AMD_HEST_MCE_TABLE *HestMceTablePtr;
  AMD_HEST_CMC_TABLE *HestCmcTablePtr;
  AMD_HEST_BANK *HestBankPtr;
  AMD_WHEA_INIT_DATA *WheaInitDataPtr;
  ALLOCATE_HEAP_PARAMS AllocParams;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  FamilySpecificServices = NULL;

  IDS_HDT_CONSOLE (CPU_TRACE, "  WHEA is created\n");

  // step 1: calculate Hest table size
  LibAmdMsrRead (MSR_MCG_CAP, &MsrData, StdHeader);
  BankNum = (UINT8) (((MSR_MCG_CAP_STRUCT *) (&MsrData))->Count);
  if (BankNum == 0) {
    return AGESA_ERROR;
  }

  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  FamilySpecificServices->GetWheaInitData (FamilySpecificServices, &WheaInitDataPtr, &Entries, StdHeader);

  ASSERT (WheaInitDataPtr->HestBankNum <= BankNum);

  HestMceTableSize = sizeof (AMD_HEST_MCE_TABLE) + WheaInitDataPtr->HestBankNum * sizeof (AMD_HEST_BANK);
  HestCmcTableSize = sizeof (AMD_HEST_CMC_TABLE) + WheaInitDataPtr->HestBankNum * sizeof (AMD_HEST_BANK);

  HestMceTablePtr = (AMD_HEST_MCE_TABLE *) *WheaMcePtr;
  HestCmcTablePtr = (AMD_HEST_CMC_TABLE *) *WheaCmcPtr;

  // step 2: allocate a buffer by callback function
  if ((HestMceTablePtr == NULL) || (HestCmcTablePtr == NULL)) {
    AllocParams.RequestedBufferSize = (UINT32) (HestMceTableSize + HestCmcTableSize);
    AllocParams.BufferHandle = AMD_WHEA_BUFFER_HANDLE;
    AllocParams.Persist = HEAP_SYSTEM_MEM;

    AGESA_TESTPOINT (TpProcCpuBeforeAllocateWheaBuffer, StdHeader);
    if (HeapAllocateBuffer (&AllocParams, StdHeader) != AGESA_SUCCESS) {
      return AGESA_ERROR;
    }
    AGESA_TESTPOINT (TpProcCpuAfterAllocateWheaBuffer, StdHeader);

    HestMceTablePtr = (AMD_HEST_MCE_TABLE *) AllocParams.BufferPtr;
    HestCmcTablePtr = (AMD_HEST_CMC_TABLE *) ((UINT8 *) (HestMceTablePtr + 1) + (WheaInitDataPtr->HestBankNum * sizeof (AMD_HEST_BANK)));
  }

  // step 3: fill in Hest MCE table
  HestMceTablePtr->TblLength = HestMceTableSize;
  HestMceTablePtr->GlobCapInitDataLSD = WheaInitDataPtr->GlobCapInitDataLSD;
  HestMceTablePtr->GlobCapInitDataMSD = WheaInitDataPtr->GlobCapInitDataMSD;
  HestMceTablePtr->GlobCtrlInitDataLSD = WheaInitDataPtr->GlobCtrlInitDataLSD;
  HestMceTablePtr->GlobCtrlInitDataMSD = WheaInitDataPtr->GlobCtrlInitDataMSD;
  HestMceTablePtr->NumHWBanks = WheaInitDataPtr->HestBankNum;

  HestBankPtr = (AMD_HEST_BANK *) (HestMceTablePtr + 1);
  CreateHestBank (HestBankPtr, WheaInitDataPtr->HestBankNum, WheaInitDataPtr);

  // step 4: fill in Hest CMC table
  HestCmcTablePtr->NumHWBanks = WheaInitDataPtr->HestBankNum;
  HestCmcTablePtr->TblLength = HestCmcTableSize;

  HestBankPtr = (AMD_HEST_BANK *) (HestCmcTablePtr + 1);
  CreateHestBank (HestBankPtr, WheaInitDataPtr->HestBankNum, WheaInitDataPtr);

  // step 5: fill in the incoming structure
  *WheaMcePtr = HestMceTablePtr;
  *WheaCmcPtr = HestCmcTablePtr;

  return (AGESA_SUCCESS);
}
コード例 #27
0
ファイル: mmflow.c プロジェクト: B-Rich/coreboot
/**
 *
 *
 *      This function is the main memory configuration function for DR DDR3
 *
 *      Requirements:
 *
 *      Run-Time Requirements:
 *      1. Complete Hypertransport Bus Configuration
 *      2. AmdMemInitDataStructDef must be run to set default values
 *      3. MSR bit to allow access to high PCI regs set on all nodes
 *      4. BSP in Big Real Mode
 *      5. Stack available
 *      6. MCG_CTL=-1, MC4_EN=0 for all CPUs
 *      7. MCi_STS from shutdown/warm reset recorded (if desired) prior to entry
 *      8. All var MTRRs reset to zero
 *      9. State of NB_CFG.DisDatMsk set properly on all CPUs
 *
 *     @param[in,out]   *MemPtr   - Pointer to the MEM_DATA_STRUCT
 *
 *     @return          AGESA_STATUS
 *                          - AGESA_ALERT
 *                          - AGESA_FATAL
 *                          - AGESA_SUCCESS
 *                          - AGESA_WARNING
 */
AGESA_STATUS
AmdMemAuto (
  IN OUT   MEM_DATA_STRUCT *MemPtr
  )
{
  MEM_SHARED_DATA  mmSharedData;
  MEM_MAIN_DATA_BLOCK mmData;
  MEM_NB_BLOCK *NBPtr;
  MEM_TECH_BLOCK *TechPtr;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;
  AGESA_STATUS Retval;
  UINT8 i;
  UINT8 Die;
  UINT8 DieCount;
  UINT8 Tab;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  ASSERT (MemPtr != NULL);

  AGESA_TESTPOINT (TpProcMemAmdMemAuto, &MemPtr->StdHeader);

  IDS_HDT_CONSOLE (MEM_FLOW, "MEM PARAMS:\n");
  IDS_HDT_CONSOLE (MEM_FLOW, "\tBottomIo : %04x\n", MemPtr->ParameterListPtr->BottomIo);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tMemHoleRemap : %d\n", MemPtr->ParameterListPtr->MemHoleRemapping);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tLimitBelow1TB : %d\n", MemPtr->ParameterListPtr->LimitMemoryToBelow1Tb);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tUserTimingMode : %d\n", MemPtr->ParameterListPtr->UserTimingMode);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tMemClockValue : %d\n", MemPtr->ParameterListPtr->MemClockValue);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tBankIntlv : %d\n", MemPtr->ParameterListPtr->EnableBankIntlv);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tNodeIntlv : %d\n", MemPtr->ParameterListPtr->EnableNodeIntlv);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tChannelIntlv : %d\n", MemPtr->ParameterListPtr->EnableChannelIntlv);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tEccFeature : %d\n", MemPtr->ParameterListPtr->EnableEccFeature);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tPowerDown : %d\n", MemPtr->ParameterListPtr->EnablePowerDown);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tOnLineSpare : %d\n", MemPtr->ParameterListPtr->EnableOnLineSpareCtl);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tParity : %d\n", MemPtr->ParameterListPtr->EnableParity);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tBankSwizzle : %d\n", MemPtr->ParameterListPtr->EnableBankSwizzle);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tMemClr : %d\n", MemPtr->ParameterListPtr->EnableMemClr);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tUmaMode : %d\n", MemPtr->ParameterListPtr->UmaMode);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tUmaSize : %d\n", MemPtr->ParameterListPtr->UmaSize);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tMemRestoreCtl : %d\n", MemPtr->ParameterListPtr->MemRestoreCtl);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tSaveMemContextCtl : %d\n", MemPtr->ParameterListPtr->SaveMemContextCtl);
  IDS_HDT_CONSOLE (MEM_FLOW, "\tExternalVrefCtl : %d\n", MemPtr->ParameterListPtr->ExternalVrefCtl );
  IDS_HDT_CONSOLE (MEM_FLOW, "\tForceTrainMode : %d\n\n", MemPtr->ParameterListPtr->ForceTrainMode );

  //----------------------------------------------------------------------------
  // Get TSC rate, which will be used later in Wait10ns routine
  //----------------------------------------------------------------------------
  GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &MemPtr->StdHeader);
  FamilySpecificServices->GetTscRate (FamilySpecificServices, &MemPtr->TscRate, &MemPtr->StdHeader);

  //----------------------------------------------------------------------------
  // Read In SPD Data
  //----------------------------------------------------------------------------
  AGESA_TESTPOINT (TpProcMemBeforeSpdProcessing, &MemPtr->StdHeader);
  MemSPDDataProcess (MemPtr);

  //----------------------------------------------------------------
  // Initialize Main Data Block
  //----------------------------------------------------------------
  mmData.MemPtr = MemPtr;
  mmData.mmSharedPtr = &mmSharedData;
  LibAmdMemFill (&mmSharedData, 0, sizeof (mmSharedData), &MemPtr->StdHeader);
  mmSharedData.DimmExcludeFlag = NORMAL;
  mmSharedData.NodeIntlv.IsValid = FALSE;
  //----------------------------------------------------------------
  // Discover populated CPUs
  //
  //----------------------------------------------------------------
  Retval = MemSocketScan (&mmData);
  if (Retval == AGESA_FATAL) {
    return Retval;
  }
  DieCount = mmData.DieCount;
  //----------------------------------------------------------------
  //
  // Allocate Memory for NB and Tech Blocks
  //
  //  NBPtr[Die]----+
  //                |
  //                V
  //  +---+---+---+---+---+---+---+---+
  //  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |   NB Blocks
  //  +---+---+---+---+---+---+---+---+
  //    |   |   |   |   |   |   |   |
  //    |   |   |   |   |   |   |   |
  //    v   v   v   v   v   v   v   v
  //  +---+---+---+---+---+---+---+---+
  //  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |   Tech Blocks
  //  +---+---+---+---+---+---+---+---+
  //
  //
  //----------------------------------------------------------------
  AllocHeapParams.RequestedBufferSize = (DieCount * (sizeof (MEM_NB_BLOCK) + sizeof (MEM_TECH_BLOCK)));
  AllocHeapParams.BufferHandle = AMD_MEM_AUTO_HANDLE;
  AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
  if (AGESA_SUCCESS != HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader)) {
    ASSERT(FALSE); // NB and Tech Block Heap allocate error
    return AGESA_FATAL;
  }
  NBPtr = (MEM_NB_BLOCK *)AllocHeapParams.BufferPtr;
  TechPtr = (MEM_TECH_BLOCK *) (&NBPtr[DieCount]);
  mmData.NBPtr = NBPtr;
  mmData.TechPtr = TechPtr;

  //----------------------------------------------------------------
  // Create NB Blocks
  //
  //----------------------------------------------------------------
  for (Die = 0 ; Die < DieCount ; Die++ ) {
    i = 0;
    while (memNBInstalled[i].MemConstructNBBlock != 0) {
      if (memNBInstalled[i].MemConstructNBBlock (&NBPtr[Die], MemPtr, memNBInstalled[i].MemFeatBlock, &mmSharedData, Die) == TRUE) {
        break;
      }
      i++;
    }
    // Couldn't find a NB which supported this family
    if (memNBInstalled[i].MemConstructNBBlock == 0) {
      return AGESA_FATAL;
    }
  }
  //----------------------------------------------------------------
  // Create Technology Blocks
  //
  //----------------------------------------------------------------
  for (Die = 0 ; Die < DieCount ; Die++ ) {
    i = 0;
    while (memTechInstalled[i] != NULL) {
      if (memTechInstalled[i] (&TechPtr[Die], &NBPtr[Die])) {
        NBPtr[Die].TechPtr = &TechPtr[Die];
        break;
      }
      i++;
    }
    // Couldn't find a Tech block which supported this family
    if (memTechInstalled[i] == NULL) {
      return AGESA_FATAL;
    }
  }
  //----------------------------------------------------------------
  //
  //                 MEMORY INITIALIZATION TASKS
  //
  //----------------------------------------------------------------
  i = 0;
  while (memFlowControlInstalled[i] != NULL) {
    Retval = memFlowControlInstalled[i] (&mmData);
    if (MemPtr->IsFlowControlSupported == TRUE) {
      break;
    }
    i++;
  }

  //----------------------------------------------------------------
  // Deallocate NB register tables
  //----------------------------------------------------------------
  for (Tab = 0; Tab < NumberOfNbRegTables; Tab++) {
    HeapDeallocateBuffer (GENERATE_MEM_HANDLE (ALLOC_NB_REG_TABLE, Tab, 0, 0), &MemPtr->StdHeader);
  }

  //----------------------------------------------------------------
  // Check for errors and return
  //----------------------------------------------------------------
  AGESA_TESTPOINT (TpProcMemEnd, &MemPtr->StdHeader);
  for (Die = 0; Die < DieCount; Die++) {
    if (NBPtr[Die].MCTPtr->ErrCode > Retval) {
      Retval = NBPtr[Die].MCTPtr->ErrCode;
    }
  }
  return Retval;
}
コード例 #28
0
/**
 * Performs CPU related initialization at the early entry point
 *
 * This function performs a large list of initialization items.  These items
 * include:
 *
 *    -1      local APIC initialization
 *    -2      MSR table initialization
 *    -3      PCI table initialization
 *    -4      HT Phy PCI table initialization
 *    -5      microcode patch loading
 *    -6      namestring determination/programming
 *    -7      AP initialization
 *    -8      power management initialization
 *    -9      core leveling
 *
 * This routine must be run by all cores in the system.  Please note that
 * all APs that enter will never exit.
 *
 * @param[in]  StdHeader         Config handle for library and services
 * @param[in]  PlatformConfig    Config handle for platform specific information
 *
 * @retval     AGESA_SUCCESS
 *
 */
AGESA_STATUS
AmdCpuEarly (
  IN       AMD_CONFIG_PARAMS      *StdHeader,
  IN       PLATFORM_CONFIGURATION *PlatformConfig
  )
{
  UINT8         WaitStatus;
  UINT8         i;
  UINT8         StartCore;
  UINT8         EndCore;
  UINT32        NodeNum;
  UINT32        PrimaryCore;
  UINT32        SocketNum;
  UINT32        ModuleNum;
  UINT32        HighCore;
  UINT32        ApHeapIndex;
  UINT32        CurrentPerformEarlyFlag;
  UINT32        TargetApicId;
  AP_WAIT_FOR_STATUS WaitForStatus;
  AGESA_STATUS  Status;
  AGESA_STATUS  CalledStatus;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  AMD_CPU_EARLY_PARAMS CpuEarlyParams;
  S_PERFORM_EARLY_INIT_ON_CORE *EarlyTableOnCore;

  Status = AGESA_SUCCESS;
  CalledStatus = AGESA_SUCCESS;

  AmdCpuEarlyInitializer (StdHeader, PlatformConfig, &CpuEarlyParams);

  IDS_OPTION_HOOK (IDS_CPU_Early_Override, &CpuEarlyParams, StdHeader);

  GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
  EarlyTableOnCore = NULL;
  FamilySpecificServices->GetEarlyInitOnCoreTable (FamilySpecificServices, (CONST S_PERFORM_EARLY_INIT_ON_CORE **)&EarlyTableOnCore, &CpuEarlyParams, StdHeader);
  if (EarlyTableOnCore != NULL) {
    GetPerformEarlyFlag (&CurrentPerformEarlyFlag, StdHeader);
    for (i = 0; EarlyTableOnCore[i].PerformEarlyInitOnCore != NULL; i++) {
      if ((EarlyTableOnCore[i].PerformEarlyInitFlag & CurrentPerformEarlyFlag) != 0) {
        IDS_HDT_CONSOLE (CPU_TRACE, "  Perform core init step %d\n", i);
        EarlyTableOnCore[i].PerformEarlyInitOnCore (FamilySpecificServices, &CpuEarlyParams, StdHeader);
      }
    }
  }

  // B S P    C O D E    T O    I N I T I A L I Z E    A Ps
  // -------------------------------------------------------
  // -------------------------------------------------------
  // IMPORTANT: Here we determine if we are BSP or AP
  if (IsBsp (StdHeader, &CalledStatus)) {

    // Even though the bsc does not need to send itself a heap index, this sequence performs other important initialization.
    // Use '0' as a dummy heap index value.
    GetSocketModuleOfNode (0, &SocketNum, &ModuleNum, StdHeader);
    GetCpuServicesOfSocket (SocketNum, (CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
    FamilySpecificServices->SetApCoreNumber (FamilySpecificServices, SocketNum, ModuleNum, 0, StdHeader);
    FamilySpecificServices->TransferApCoreNumber (FamilySpecificServices, StdHeader);

    // Clear BSP's Status Byte
    ApUtilWriteControlByte (CORE_ACTIVE, StdHeader);

    NodeNum = 0;
    ApHeapIndex = 1;
    while (NodeNum < MAX_NODES &&
          GetSocketModuleOfNode (NodeNum, &SocketNum, &ModuleNum, StdHeader)) {
      GetCpuServicesOfSocket (SocketNum, (CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
      GetGivenModuleCoreRange (SocketNum, ModuleNum, &PrimaryCore, &HighCore, StdHeader);
      if (NodeNum == 0) {
        StartCore = (UINT8) PrimaryCore + 1;
      } else {
        StartCore = (UINT8) PrimaryCore;
      }

      EndCore = (UINT8) HighCore;
      for (i = StartCore; i <= EndCore; i++) {
        FamilySpecificServices->SetApCoreNumber (FamilySpecificServices, SocketNum, ModuleNum, ApHeapIndex, StdHeader);
        IDS_HDT_CONSOLE (CPU_TRACE, "  Launch socket %d core %d\n", SocketNum, i);
        if (FamilySpecificServices->LaunchApCore (FamilySpecificServices, SocketNum, ModuleNum, i, PrimaryCore, StdHeader)) {
          IDS_HDT_CONSOLE (CPU_TRACE, "  Waiting for socket %d core %d\n", SocketNum, i);
          GetLocalApicIdForCore (SocketNum, i, &TargetApicId, StdHeader);
          WaitStatus = CORE_IDLE;
          WaitForStatus.Status = &WaitStatus;
          WaitForStatus.NumberOfElements = 1;
          WaitForStatus.RetryCount = WAIT_INFINITELY;
          WaitForStatus.WaitForStatusFlags = WAIT_STATUS_EQUALITY;
          ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader);
          ApHeapIndex++;
        }
      }
      NodeNum++;
    }

    // B S P    P h a s e - 1   E N D

    IDS_OPTION_HOOK (IDS_BEFORE_PM_INIT, &CpuEarlyParams, StdHeader);

    AGESA_TESTPOINT (TpProcCpuBeforePMFeatureInit, StdHeader);
    IDS_HDT_CONSOLE (CPU_TRACE, "  Dispatch CPU features before early power mgmt init\n");
    CalledStatus = DispatchCpuFeatures (CPU_FEAT_BEFORE_PM_INIT, PlatformConfig, StdHeader);
    if (CalledStatus > Status) {
      Status = CalledStatus;
    }

    AGESA_TESTPOINT (TpProcCpuPowerMgmtInit, StdHeader);
    CalledStatus = PmInitializationAtEarly (&CpuEarlyParams, StdHeader);
    if (CalledStatus > Status) {
      Status = CalledStatus;
    }

    AGESA_TESTPOINT (TpProcCpuEarlyFeatureInit, StdHeader);
    IDS_HDT_CONSOLE (CPU_TRACE, "  Dispatch CPU features after early power mgmt init\n");
    CalledStatus = DispatchCpuFeatures (CPU_FEAT_AFTER_PM_INIT, PlatformConfig, StdHeader);

    IDS_OPTION_HOOK (IDS_BEFORE_AP_EARLY_HALT, &CpuEarlyParams, StdHeader);

    // Sleep all APs
    IDS_HDT_CONSOLE (CPU_TRACE, "  Halting all APs\n");
    ApUtilWriteControlByte (CORE_IDLE_HLT, StdHeader);
  } else {
    ApEntry (StdHeader, &CpuEarlyParams);
  }

  if (CalledStatus > Status) {
    Status = CalledStatus;
  }

  return (Status);
}
コード例 #29
0
ファイル: heapManager.c プロジェクト: fishbaoz/edk2ml
/**
 *  This function initializes the heap for each CPU core.
 *
 *  Check for already initialized.  If not, determine offset of local heap in CAS and
 *  setup initial heap markers and bookkeeping status.  Also create an initial event log.
 *
 *  @param[in]  StdHeader          Handle of Header for calling lib functions and services.
 *
 *  @retval     AGESA_SUCCESS      This core's heap is initialized
 *  @retval     AGESA_FATAL        This core's heap cannot be initialized due to any reasons below:
 *                                 - current processor family cannot be identified.
 *
 */
AGESA_STATUS
HeapManagerInit (
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  // First Time Initialization
  // Note: First 16 bytes of buffer is reserved for Heap Manager use
  UINT16                HeapAlreadyInitSizeDword;
  UINT32                HeapAlreadyRead;
  UINT8                 L2LineSize;
  UINT8                 *HeapBufferPtr;
  UINT8                 *HeapInitPtr;
  UINT32                *HeapDataPtr;
  UINT64                MsrData;
  UINT64                MsrMask;
  UINT8                 Ignored;
  CPUID_DATA            CpuId;
  BUFFER_NODE           *FreeSpaceNode;
  CACHE_INFO            *CacheInfoPtr;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;
  CPU_LOGICAL_ID        CpuFamilyRevision;

  // Check whether this is a known processor family.
  GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
  if ((CpuFamilyRevision.Family == 0) && (CpuFamilyRevision.Revision == 0)) {
    IDS_ERROR_TRAP;
    return AGESA_FATAL;
  }

  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  FamilySpecificServices->GetCacheInfo (FamilySpecificServices, (CONST VOID **) &CacheInfoPtr, &Ignored, StdHeader);
  HeapBufferPtr = (UINT8 *) StdHeader->HeapBasePtr;

  // Check whether the heap manager is already initialized
  LibAmdMsrRead (AMD_MTRR_VARIABLE_HEAP_MASK, &MsrData, StdHeader);

  if (!IsSecureS3 (StdHeader)) {
    if (MsrData == (CacheInfoPtr->VariableMtrrMask & AMD_HEAP_MTRR_MASK)) {
      LibAmdMsrRead (AMD_MTRR_VARIABLE_HEAP_BASE, &MsrData, StdHeader);
      if ((MsrData & CacheInfoPtr->HeapBaseMask) == ((UINT64) (UINTN) HeapBufferPtr & CacheInfoPtr->HeapBaseMask)) {
        if (((HEAP_MANAGER *) HeapBufferPtr)->Signature == HEAP_SIGNATURE_VALID) {
          // This is not a bug, there are multiple premem basic entry points,
          // and each will call heap init to make sure create struct will succeed.
          // If that is later deemed a problem, there needs to be a reasonable test
          // for the calling code to make to determine if it needs to init heap or not.
          // In the mean time, add this to the event log
          PutEventLog (AGESA_SUCCESS,
                      CPU_ERROR_HEAP_IS_ALREADY_INITIALIZED,
                      0, 0, 0, 0, StdHeader);
          return AGESA_SUCCESS;
        }
      }
    }

    // Set variable MTRR base and mask
    MsrData = ((UINT64) (UINTN) HeapBufferPtr & CacheInfoPtr->HeapBaseMask);
    MsrMask = CacheInfoPtr->VariableMtrrHeapMask & AMD_HEAP_MTRR_MASK;

    MsrData |= 0x06;
    LibAmdMsrWrite (AMD_MTRR_VARIABLE_HEAP_BASE, &MsrData, StdHeader);
    LibAmdMsrWrite (AMD_MTRR_VARIABLE_HEAP_MASK, &MsrMask, StdHeader);

    // Set top of memory to a temp value
    LibAmdMsrRead (TOP_MEM, &MsrData, StdHeader);
    if (AMD_TEMP_TOM > MsrData) {
      MsrData = (UINT64) (AMD_TEMP_TOM);
      LibAmdMsrWrite (TOP_MEM, &MsrData, StdHeader);
    }
  }

  // Enable variable MTTRs
  LibAmdMsrRead (SYS_CFG, &MsrData, StdHeader);
  MsrData |= AMD_VAR_MTRR_ENABLE_BIT;
  LibAmdMsrWrite (SYS_CFG, &MsrData, StdHeader);

  // Initialize Heap Space
  // BIOS may store to a line only after it has been allocated by a load
  LibAmdCpuidRead (AMD_CPUID_L2L3Cache_L2TLB, &CpuId, StdHeader);
  L2LineSize = (UINT8) (CpuId.ECX_Reg);
  HeapInitPtr = HeapBufferPtr ;
  for (HeapAlreadyRead = 0; HeapAlreadyRead < AMD_HEAP_SIZE_PER_CORE;
      (HeapAlreadyRead = HeapAlreadyRead + L2LineSize)) {
    Ignored = *HeapInitPtr;
    HeapInitPtr += L2LineSize;
  }

  HeapDataPtr = (UINT32 *) HeapBufferPtr;
  for (HeapAlreadyInitSizeDword = 0; HeapAlreadyInitSizeDword < AMD_HEAP_SIZE_DWORD_PER_CORE; HeapAlreadyInitSizeDword++) {
    *HeapDataPtr = 0;
    HeapDataPtr++;
  }

  // Note: We are reserving the first 16 bytes for Heap Manager use
  // UsedSize indicates the size of heap spaced is used for HEAP_MANAGER, BUFFER_NODE,
  //   Pad for 16-byte alignment, buffer data, and IDS SENTINEL.
  // FirstActiveBufferOffset is initalized as invalid heap offset, AMD_HEAP_INVALID_HEAP_OFFSET.
  // FirstFreeSpaceOffset is initalized as the byte right after HEAP_MANAGER header.
  // Then we set Signature of HEAP_MANAGER header as valid, HEAP_SIGNATURE_VALID.
  ((HEAP_MANAGER*) HeapBufferPtr)->UsedSize = sizeof (HEAP_MANAGER);
  ((HEAP_MANAGER*) HeapBufferPtr)->FirstActiveBufferOffset = AMD_HEAP_INVALID_HEAP_OFFSET;
  ((HEAP_MANAGER*) HeapBufferPtr)->FirstFreeSpaceOffset = sizeof (HEAP_MANAGER);
  ((HEAP_MANAGER*) HeapBufferPtr)->Signature = HEAP_SIGNATURE_VALID;
  // Create free space link
  FreeSpaceNode = (BUFFER_NODE *) (HeapBufferPtr + sizeof (HEAP_MANAGER));
  FreeSpaceNode->BufferSize = AMD_HEAP_SIZE_PER_CORE - sizeof (HEAP_MANAGER) - sizeof (BUFFER_NODE);
  FreeSpaceNode->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET;

  StdHeader->HeapStatus = HEAP_LOCAL_CACHE;

  EventLogInitialization (StdHeader);
  return AGESA_SUCCESS;
}
コード例 #30
0
/**
 *  Returns the family specific properties of the cache, and its usage.
 *
 *  @CpuServiceMethod{::F_CPU_GET_FAMILY_SPECIFIC_ARRAY}.
 *
 *  @param[in]   FamilySpecificServices   The current Family Specific Services.
 *  @param[out]  CacheInfoPtr             Points to the cache info properties on exit.
 *  @param[out]  NumberOfElements         Will be one to indicate one entry.
 *  @param[in]   StdHeader                Header for library and services.
 *
 */
VOID
GetF15CacheInfo (
  IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
     OUT   CONST VOID **CacheInfoPtr,
     OUT   UINT8 *NumberOfElements,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32 Enabled;
  UINT32 DualCore;
  UINT32 Node;
  PCI_ADDR  PciAddress;
  CPU_SPECIFIC_SERVICES *FamilyServices;
  AP_MAILBOXES     ApMailboxes;
  CORE_PAIR_MAP *CorePairMap;
  AGESA_STATUS IgnoredStatus;

  if (!IsBsp (StdHeader, &IgnoredStatus)) {
    GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilyServices, StdHeader);
    ASSERT (FamilyServices != NULL);

    FamilyServices->GetApMailboxFromHardware (FamilyServices, &ApMailboxes, StdHeader);
    Node = ApMailboxes.ApMailInfo.Fields.Node;

    // Since pre-heap, get compute unit status from hardware, using mailbox info.
    PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0);
    PciAddress.Address.Device = PciAddress.Address.Device + Node;
    PciAddress.Address.Function = FUNC_5;
    PciAddress.Address.Register = COMPUTE_UNIT_STATUS;
    LibAmdPciReadBits (PciAddress, 3, 0, &Enabled, StdHeader);
    LibAmdPciReadBits (PciAddress, 19, 16, &DualCore, StdHeader);

    // Find the core to compute unit mapping for this node.
    CorePairMap = FamilyServices->CorePairMap;
    if ((Enabled != 0) && (CorePairMap != NULL)) {
      while (CorePairMap->Enabled != 0xFF) {
        if ((Enabled == CorePairMap->Enabled) && (DualCore == CorePairMap->DualCore)) {
          break;
        }
        CorePairMap++;
      }
      // The assert is for finding a processor configured in a way the core pair map doesn't support.
      ASSERT (CorePairMap->Enabled != 0xFF);
      switch (CorePairMap->Mapping) {
      case AllCoresMapping:
        // No cores are sharing a compute unit
        *CacheInfoPtr = &CpuF15CacheInfo;
        break;
      case EvenCoresMapping:
        // Cores are paired into compute units
        *CacheInfoPtr = &CpuF15CacheInfoCP;
        break;
      default:
        ASSERT (FALSE);
      }
    }
  } else {
    // the BSC is always just the first slice, we could return either one. Return the non for safest.
    *CacheInfoPtr = &CpuF15CacheInfo;
  }
  *NumberOfElements = 1;
}