/**
 * Multisocket BSC call to start all system core 0s to perform a standard AP_TASK.
 *
 * This function loops through all possible socket locations, starting core 0 of
 * each populated socket to perform the passed in AP_TASK.  After starting all
 * other core 0s, the BSC will perform the AP_TASK as well.  This must be run by
 * the system BSC only.
 *
 * @param[in]  TaskPtr           Function descriptor
 * @param[in]  StdHeader         Config handle for library and services
 * @param[in]  ConfigParams      AMD entry point's CPU parameter structure
 *
 */
VOID
RunCodeOnAllSystemCore0sMulti (
  IN       AP_TASK *TaskPtr,
  IN       AMD_CONFIG_PARAMS *StdHeader,
  IN       VOID *ConfigParams
  )
{
  UINT32 BscSocket;
  UINT32 BscModule;
  UINT32 BscCoreNum;
  UINT8  Socket;
  UINT32 NumberOfSockets;
  AGESA_STATUS DummyStatus;

  ASSERT (IsBsp (StdHeader, &DummyStatus));

  NumberOfSockets = GetPlatformNumberOfSockets ();

  IdentifyCore (StdHeader, &BscSocket, &BscModule, &BscCoreNum, &DummyStatus);

  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
    if (Socket != BscSocket) {
      if (IsProcessorPresent (Socket, StdHeader)) {
        ApUtilRunCodeOnSocketCore (Socket, 0, TaskPtr, StdHeader);
      }
    }
  }
  ApUtilTaskOnExecutingCore (TaskPtr, StdHeader, ConfigParams);
}
Beispiel #2
0
/**
 * Clear EnableCf8ExtCfg on all socket
 *
 * Clear F3x8C bit 14 EnableCf8ExtCfg
 *
 * @param[in]  StdHeader         Config handle for library and services
 *
 *
 */
VOID
DisableCf8ExtCfg (
  IN       AMD_CONFIG_PARAMS   *StdHeader
  )
{
  AGESA_STATUS  AgesaStatus;
  PCI_ADDR PciAddress;
  UINT32 Socket;
  UINT32 Module;
  UINT32 PciData;
  UINT32 LegacyPciAccess;

  ASSERT (IsBsp (StdHeader, &AgesaStatus));

  for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
    for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
      if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) {
        PciAddress.Address.Function = FUNC_3;
        PciAddress.Address.Register = NB_CFG_HIGH_REG;
        LegacyPciAccess = ((1 << 31) + (PciAddress.Address.Register & 0xFC) + (PciAddress.Address.Function << 8) + (PciAddress.Address.Device << 11) + (PciAddress.Address.Bus << 16) + ((PciAddress.Address.Register & 0xF00) << (24 - 8)));
        // read from PCI register
        LibAmdIoWrite (AccessWidth32, IOCF8, &LegacyPciAccess, StdHeader);
        LibAmdIoRead (AccessWidth32, IOCFC, &PciData, StdHeader);
        // Disable Cf8ExtCfg
        PciData &= 0xFFFFBFFF;
        // write to PCI register
        LibAmdIoWrite (AccessWidth32, IOCF8, &LegacyPciAccess, StdHeader);
        LibAmdIoWrite (AccessWidth32, IOCFC, &PciData, StdHeader);
      }
    }
  }
}
/**
 *
 *  FeatureLeveling
 *
 *    CPU feature leveling. Set least common features set of all CPUs
 *
 *    @param[in,out]   StdHeader   - Pointer to AMD_CONFIG_PARAMS struct.
 *
 */
VOID
FeatureLeveling (
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32 BscSocket;
  UINT32 Ignored;
  UINT32 BscCoreNum;
  UINT32 Socket;
  UINT32 Core;
  UINT32 NumberOfSockets;
  UINT32 NumberOfCores;
  BOOLEAN *FirstTime;
  BOOLEAN *NeedLeveling;
  AGESA_STATUS IgnoredSts;
  CPU_FEATURES_LIST *globalCpuFeatureList;
  AP_TASK  TaskPtr;

  ASSERT (IsBsp (StdHeader, &IgnoredSts));

  GetGlobalCpuFeatureListAddress ((UINT64 **) &globalCpuFeatureList, StdHeader);
  FirstTime = (BOOLEAN *) ((UINT8 *) globalCpuFeatureList + sizeof (CPU_FEATURES_LIST));
  NeedLeveling = (BOOLEAN *) ((UINT8 *) globalCpuFeatureList + sizeof (CPU_FEATURES_LIST) + sizeof (BOOLEAN));

  *FirstTime = TRUE;
  *NeedLeveling = FALSE;

  LibAmdMemFill (globalCpuFeatureList, 0xFF, sizeof (CPU_FEATURES_LIST), StdHeader);
  IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts);
  NumberOfSockets = GetPlatformNumberOfSockets ();

  TaskPtr.FuncAddress.PfApTaskI = SaveFeatures;
  TaskPtr.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (CPU_FEATURES_LIST);
  TaskPtr.ExeFlags = WAIT_FOR_CORE;
  TaskPtr.DataTransfer.DataPtr = globalCpuFeatureList;
  TaskPtr.DataTransfer.DataTransferFlags = DATA_IN_MEMORY;

  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
    if (IsProcessorPresent (Socket, StdHeader)) {
      if (Socket !=  BscSocket) {
        ApUtilRunCodeOnSocketCore ((UINT8)Socket, 0, &TaskPtr, StdHeader);
      }
    }
  }
  ApUtilTaskOnExecutingCore (&TaskPtr, StdHeader, NULL);

  if (*NeedLeveling) {
    TaskPtr.FuncAddress.PfApTaskI  = WriteFeatures;
    for (Socket = 0; Socket < NumberOfSockets; Socket++) {
      if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) {
        for (Core = 0; Core < NumberOfCores; Core++) {
          if ((Socket != BscSocket) || (Core != BscCoreNum)) {
            ApUtilRunCodeOnSocketCore ((UINT8)Socket, (UINT8)Core, &TaskPtr, StdHeader);
          }
        }
      }
    }
    ApUtilTaskOnExecutingCore (&TaskPtr, StdHeader, NULL);
  }
}
Beispiel #4
0
/**
 * 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;
}
Beispiel #5
0
/**
 *
 *  HeapGetBaseAddressInTempMem
 *
 *    This function gets heap base address in HEAP_TEMP_MEM phase
 *
 *    @param[in]   StdHeader   - Pointer to AMD_CONFIG_PARAMS struct.
 *
 *    @retval      UINT64      - Heap base address in HEAP_TEMP_MEM phase
 *
 */
UINT64
HeapGetBaseAddressInTempMem (
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  EFI_PEI_SERVICES    **PeiServices;
  EFI_PEI_HOB_POINTERS  Hob;
  AGESA_STATUS        IgnoredStatus;
  UINT64              BaseAddress;

  BaseAddress = UserOptions.CfgHeapDramAddress;

  if (IsBsp (StdHeader, &IgnoredStatus) && (StdHeader->HeapStatus != HEAP_LOCAL_CACHE)) {
    PeiServices = (EFI_PEI_SERVICES **) StdHeader->ImageBasePtr;

    //
    // Retrieve the new Heap Manager base in HOB and update StdHeader
    //
    (*PeiServices)->GetHobList (PeiServices, &Hob.Raw);
    while (!END_OF_HOB_LIST (Hob)) {
      if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION &&
          CompareGuid ( &Hob.Guid->Name, &gAmdHeapHobGuid)) {
        BaseAddress = (UINT64) (VOID *) (Hob.Raw +
                        sizeof (EFI_HOB_GENERIC_HEADER) +
                        sizeof (EFI_GUID));
        break;
      }
      Hob.Raw = GET_NEXT_HOB (Hob);
    }
  }
  return BaseAddress;
}
Beispiel #6
0
/**
 * Dispatches all features needing to perform some initialization at
 * this time point.
 *
 * This routine searches the feature table for features needing to
 * run at this time point, and invokes them.
 *
 * @param[in]      EntryPoint     Timepoint designator
 * @param[in]      PlatformConfig Contains the runtime modifiable feature input data.
 * @param[in]      StdHeader      Standard AMD configuration parameters.
 *
 * @return         The most severe status of any called service.
 */
AGESA_STATUS
DispatchCpuFeatures (
  IN       UINT64                 EntryPoint,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINTN i;
  AGESA_STATUS AgesaStatus;
  AGESA_STATUS CalledStatus;
  AGESA_STATUS IgnoredStatus;

  AgesaStatus = AGESA_SUCCESS;

  if (IsBsp (StdHeader, &IgnoredStatus)) {
    for (i = 0; SupportedCpuFeatureList[i] != NULL; i++) {
      if ((SupportedCpuFeatureList[i]->EntryPoint & EntryPoint) != 0) {
        if (SupportedCpuFeatureList[i]->IsEnabled (PlatformConfig, StdHeader)) {
          CalledStatus = SupportedCpuFeatureList[i]->InitializeFeature (EntryPoint, PlatformConfig, StdHeader);
          if (CalledStatus > AgesaStatus) {
            AgesaStatus = CalledStatus;
          }
        }
      }
    }
  }
  return AgesaStatus;
}
Beispiel #7
0
 /**
  *
  * This function checks the status of BIST and places the error status in the event log
  * if there are any errors
  *
  * @param[in]      StdHeader              Header for library and services
  *
  * @retval         AGESA_SUCCESS          No BIST errors have been logged.
  * @retval         AGESA_ALERT            BIST errors have been detected and added to the
  *                                        event log.
  */
AGESA_STATUS
CheckBistStatus (
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32                Socket;
  UINT32                Core;
  UINT32                BscSocket;
  UINT32                BscCoreNum;
  UINT32                NumberOfSockets;
  UINT32                NumberOfCores;
  UINT32                Ignored;
  UINT32                ReturnCode;
  AGESA_STATUS          IgnoredSts;
  AGESA_STATUS          AgesaStatus;
  AP_TASK               TaskPtr;

  // Make sure that Standard Header is valid
  ASSERT (StdHeader != NULL);
  ASSERT (IsBsp (StdHeader, &IgnoredSts));

  AgesaStatus = AGESA_SUCCESS;

  // Get the BscSocket, BscCoreNum and NumberOfSockets in the system
  IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts);
  NumberOfSockets = GetPlatformNumberOfSockets ();

  // Setup TaskPtr struct to execute routine on APs
  TaskPtr.FuncAddress.PfApTaskO = GetBistResults;
  TaskPtr.DataTransfer.DataSizeInDwords = 0;
  TaskPtr.ExeFlags = TASK_HAS_OUTPUT | WAIT_FOR_CORE;

  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
    if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) {
      for (Core = 0; Core < NumberOfCores; Core++) {
        if ((Socket != BscSocket) || (Core != BscCoreNum)) {
          ReturnCode = ApUtilRunCodeOnSocketCore ((UINT8)Socket, (UINT8)Core, &TaskPtr, StdHeader);
        } else {
          ReturnCode = TaskPtr.FuncAddress.PfApTaskO (StdHeader);
        }

        // If BIST value is non-zero, add to BSP's event log
        if (ReturnCode != 0) {
          IDS_HDT_CONSOLE (CPU_TRACE, "  BIST failure: socket %d core %d, status = 0x%x\n", Socket, Core, ReturnCode);
          AgesaStatus = AGESA_ALERT;
          PutEventLog (AGESA_ALERT,
                       CPU_EVENT_BIST_ERROR,
                       ReturnCode, Socket, Core, 0, StdHeader);
        }
      }
    }
  }

  return AgesaStatus;
}
Beispiel #8
0
/**
 *
 *  InitializeCacheFlushOnHaltFeature
 *
 *    CPU feature leveling. Enable Cpu Cache Flush On Halt Function
 *
 *    @param[in]       EntryPoint       Timepoint designator.
 *    @param[in]       PlatformConfig   Contains the runtime modifiable feature input data.
 *    @param[in,out]   StdHeader        Pointer to AMD_CONFIG_PARAMS struct.
 *
 *    @return          The most severe status of any family specific service.
 */
STATIC AGESA_STATUS
InitializeCacheFlushOnHaltFeature (
  IN       UINT64                 EntryPoint,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN OUT   AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINT32 Socket;
  UINT32 Module;
  UINT32 AndMask;
  UINT32 OrMask;
  UINT32 PciRegister;
  PCI_ADDR PciAddress;
  PCI_ADDR CfohPciAddress;
  AGESA_STATUS AgesaStatus;
  CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices;

  ASSERT (IsBsp (StdHeader, &AgesaStatus));

  FamilySpecificServices = NULL;
  AndMask = 0xFFFFFFFF;
  OrMask = 0x00000000;
  PciRegister = 0;
  AgesaStatus = AGESA_SUCCESS;

  for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
    if (IsProcessorPresent (Socket, StdHeader)) {

      // Get services for the socket
      GetFeatureServicesOfSocket (&CacheFlushOnHaltFamilyServiceTable, Socket, (CONST VOID **)&FamilySpecificServices, StdHeader);
      if (FamilySpecificServices != NULL) {
        FamilySpecificServices->GetCacheFlushOnHaltRegister (FamilySpecificServices, &CfohPciAddress, &AndMask, &OrMask, StdHeader);

        // Get the Or Mask value from IDS
        IDS_OPTION_HOOK (IDS_CACHE_FLUSH_HLT, &OrMask, StdHeader);

        // Set Cache Flush On Halt register
        for (Module = 0; Module < (UINT8)GetPlatformNumberOfModules (); Module++) {
          if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) {
            PciAddress.Address.Function = CfohPciAddress.Address.Function;
            PciAddress.Address.Register = CfohPciAddress.Address.Register;
            LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
            PciRegister &= AndMask;
            PciRegister |= OrMask;
            LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader);
          }
        }
      }
    }
  }
  return AgesaStatus;
}
Beispiel #9
0
/**
 * Init GNB at Early before CPU
 *
 *
 *
 * @param[in,out] EarlyParamsPtr    Pointer to early configuration params.
 * @retval                          Initialization status.
 */
AGESA_STATUS
GnbInitAtEarlier (
  IN OUT   AMD_EARLY_PARAMS        *EarlyParamsPtr
  )
{
  AGESA_STATUS            Status;

  // Only run code on BSP
  if (IsBsp (&EarlyParamsPtr->StdHeader, &Status)) {
    Status = GnbLibDispatchFeatures (&GnbEarlierFeatureTable[0], &EarlyParamsPtr->StdHeader);
  }

  return  Status;
}
Beispiel #10
0
/**
 *
 *  Exit function for HDT out Function of S3 Resume
 *
 *  Restore debug register and Deallocate heap, and will also fire a HDTOUT
 *  Command to let hdtout script do corresponding things.
 *
 *  @param[in,out] StdHeader    The Pointer of AGESA Header
 *
 **/
VOID
AmdIdsHdtOutS3Exit (
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  AGESA_STATUS AgesaStatus;

  if (AmdIdsHdtOutSupport ()) {
    //Ap debug print exit have been done at the end of AmdInitResume, so we only BSP at here
    AmdIdsHdtOutExitCoreTask (NULL, StdHeader);
    if (IsBsp (StdHeader, &AgesaStatus)) {
      HeapDeallocateBuffer (IDS_HDT_OUT_BUFFER_HANDLE, StdHeader);
    }
  }
}
Beispiel #11
0
/**
 * Ids code for parse IDS feat table.
 *
 * Feat table in IDS is used to decribe the IDS support feat and its according family,handler.
 *
 * @param[in]     PIdsFeatTbl point to Ids Feat table
 * @param[in]     IdsOption IDS indicator value, see @ref AGESA_IDS_OPTION
 * @param[in,out] DataPtr   Data pointer.
 * @param[in]     IdsNvPtr   Ids Nvram pointer.
 * @param[in,out] StdHeader    The Pointer of AMD_CONFIG_PARAMS.
 *
 *  @retval IDS_SUCCESS         Backend function is called successfully.
 *  @retval IDS_UNSUPPORTED     No Backend function is found.
 **/
IDS_STATUS
IdsParseFeatTbl (
  IN       AGESA_IDS_OPTION IdsOption,
  IN       CONST IDS_FEAT_STRUCT * PIdsFeatTbl[],
  IN OUT   VOID *DataPtr,
  IN       IDS_NV_ITEM *IdsNvPtr,
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT16 i;
  AGESA_STATUS Tmpsts;
  CPU_LOGICAL_ID CpuLogicalId;
  BOOLEAN No_Check_Bsp;
  CONST IDS_FEAT_STRUCT *PIdsFeat;
  IDS_STATUS ReturnFlag;
  IDS_STATUS status;

  status = IDS_SUCCESS;
  ReturnFlag = IDS_SUCCESS;

  for (i = 0; PIdsFeatTbl[i] != NULL; i++) {
    PIdsFeat = PIdsFeatTbl[i];
    //Does specified IdsOption reached
    if (PIdsFeat->IdsOption == IdsOption) {
      //check if bsp only
      if (PIdsFeat->IsBsp) {
        No_Check_Bsp = 0;
      } else {
        No_Check_Bsp = 1;
      }
      if (No_Check_Bsp || IsBsp (StdHeader, &Tmpsts)) {
        //Does Family Match required
        GetLogicalIdOfCurrentCore (&CpuLogicalId, StdHeader);
        if ((CpuLogicalId.Family) & (PIdsFeat->CpuFamily)) {
          //Excute the code for specific Ids Feat
          status = PIdsFeat->pf_idsoption (DataPtr, StdHeader, IdsNvPtr);
          if (status != IDS_SUCCESS) {
            ReturnFlag = status;
          }
        }
      }
    }
  }
  return ReturnFlag;
}
Beispiel #12
0
/**
 *
 * Run code on every AP in the system.
 *
 * @param[in] ApParams       AP task pointer.
 * @param[in] StdHeader      Handle to config for library and services
 *
 * @return    The most severe AGESA_STATUS returned by an AP.
 *
 */
AGESA_STATUS
RunLateApTaskOnAllAPs (
  IN       AP_EXE_PARAMS     *ApParams,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32                  NumberOfSockets;
  UINT32                  NumberOfCores;
  UINT8                   Socket;
  UINT8                   Core;
  UINT8                   ApicId;
  UINT32                  BscSocket;
  UINT32                  Ignored;
  UINT32                  BscCoreNum;
  AGESA_STATUS            CalledStatus;
  AGESA_STATUS            IgnoredStatus;
  AGESA_STATUS            AgesaStatus;

  ASSERT (IsBsp (StdHeader, &IgnoredStatus));

  AgesaStatus = AGESA_SUCCESS;

  IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredStatus);
  NumberOfSockets = GetPlatformNumberOfSockets ();

  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
    if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) {
      for (Core = 0; Core < NumberOfCores; Core++) {
        if ((Socket != BscSocket) || (Core != BscCoreNum)) {
          GetApicId (StdHeader, Socket, Core, &ApicId, &IgnoredStatus);
          AGESA_TESTPOINT (TpIfBeforeRunApFromAllAps, StdHeader);
          CalledStatus = AgesaRunFcnOnAp ((UINTN) ApicId, ApParams);
          AGESA_TESTPOINT (TpIfAfterRunApFromAllAps, StdHeader);
          if (CalledStatus > AgesaStatus) {
            AgesaStatus = CalledStatus;
          }
        }
      }
    }
  }
  return AgesaStatus;
}
/**
 * Single socket call to determine the most severe AGESA_STATUS return value after
 * processing the power management initialization tables.
 *
 * This function searches the event log for the most severe error and returns
 * the status code.  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
GetEarlyPmErrorsSingle (
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT16       i;
  AGESA_EVENT  EventLogEntry;
  AGESA_STATUS ReturnCode;

  ASSERT (IsBsp (StdHeader, &ReturnCode));

  ReturnCode = AGESA_SUCCESS;
  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);
}
Beispiel #14
0
/**
 *
 * Run code on core 0 of every socket in the system.
 *
 * @param[in] ApParams       AP task pointer.
 * @param[in] StdHeader      Handle to config for library and services
 *
 * @return    The most severe AGESA_STATUS returned by an AP.
 *
 */
AGESA_STATUS
RunLateApTaskOnAllCore0s (
  IN       AP_EXE_PARAMS     *ApParams,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32                  NumberOfSockets;
  UINT8                   Socket;
  UINT8                   ApicId;
  UINT32                  BscSocket;
  UINT32                  IgnoredModule;
  UINT32                  IgnoredCore;
  AGESA_STATUS            CalledStatus;
  AGESA_STATUS            IgnoredStatus;
  AGESA_STATUS            AgesaStatus;

  ASSERT (IsBsp (StdHeader, &IgnoredStatus));

  AgesaStatus = AGESA_SUCCESS;

  IdentifyCore (StdHeader, &BscSocket, &IgnoredModule, &IgnoredCore, &IgnoredStatus);
  NumberOfSockets = GetPlatformNumberOfSockets ();

  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
    if (IsProcessorPresent (Socket, StdHeader)) {
      if (Socket != BscSocket) {
        GetApicId (StdHeader, Socket, 0, &ApicId, &IgnoredStatus);
        AGESA_TESTPOINT (TpIfBeforeRunApFromAllCore0s, StdHeader);
        CalledStatus = AgesaRunFcnOnAp ((UINTN) ApicId, ApParams);
        AGESA_TESTPOINT (TpIfAfterRunApFromAllCore0s, StdHeader);
        if (CalledStatus > AgesaStatus) {
          AgesaStatus = CalledStatus;
        }
      }
    }
  }
  return AgesaStatus;
}
Beispiel #15
0
/**
  Break the other processor by send IPI.

  @param[in] CurrentProcessorIndex  Current processor index value.

**/
VOID
HaltOtherProcessors (
  IN UINT32             CurrentProcessorIndex
  )
{
  DebugAgentMsgPrint (DEBUG_AGENT_INFO, "processor[%x]:Try to halt other processors.\n", CurrentProcessorIndex);
  if (!IsBsp (CurrentProcessorIndex)) {
    SetIpiSentByApFlag (TRUE);;
  }

  mDebugMpContext.BreakAtCpuIndex = CurrentProcessorIndex;

  //
  // Set the debug viewpoint to the current breaking CPU.
  //
  SetDebugViewPoint (CurrentProcessorIndex);

  //
  // Send fixed IPI to other processors.
  //
  SendFixedIpiAllExcludingSelf (DEBUG_TIMER_VECTOR);

}
Beispiel #16
0
/**
 * 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;
}
Beispiel #17
0
/**
 *
 *  CopyHeapToTempRamAtPost
 *
 *     This function copies BSP heap content to RAM
 *
 *    @param[in,out]   StdHeader   - Pointer to AMD_CONFIG_PARAMS struct.
 *
 *    @retval          AGESA_STATUS
 *
 */
AGESA_STATUS
CopyHeapToTempRamAtPost (
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  EFI_PEI_SERVICES    **PeiServices;
  EFI_STATUS          Status;
  UINT32              SizeOfHeapNode;
  UINT32              HeapBaseInCache;
  UINT8               *HeapBaseInTempMem;
  UINT8               *Source;
  UINT8               *Destination;
  UINT8               AlignTo16ByteInCache;
  UINT32              SizeOfNodeData;
  UINT32              TotalSize;
  UINT32              HeapInCacheOffset;
  HEAP_MANAGER        *HeapManagerInCache;
  BUFFER_NODE         *HeapInCache;
  HEAP_MANAGER        *HeapManagerInTempMem;
  BUFFER_NODE         *HeapInTempMem;
  BUFFER_NODE         *EndNodeInTempMem;

  //
  // Only BSP is expected to run this routine
  //
  if (IsBsp (StdHeader)) {
    if (StdHeader->HeapStatus != HEAP_LOCAL_CACHE) {
      //
      // System memory range is out of PEI, we don't have to copy any thing into HOB.
      //
      return AGESA_UNSUPPORTED;
    }

    PeiServices = (EFI_PEI_SERVICES **) StdHeader->ImageBasePtr;

    Status = EFI_SUCCESS;
    HeapInCache = NULL;
    HeapManagerInCache = NULL;
    SizeOfHeapNode = 0;

    TotalSize = sizeof (HEAP_MANAGER);
    SizeOfNodeData = 0;

    // Heap in cache variables
    HeapBaseInCache = (UINT32) StdHeader->HeapBasePtr;
    HeapManagerInCache = (HEAP_MANAGER *) HeapBaseInCache;
    HeapInCacheOffset = HeapManagerInCache->FirstActiveBufferOffset;
    HeapInCache = (BUFFER_NODE*) (HeapBaseInCache + HeapInCacheOffset);
    // Heap in temp buffer variables
    HeapBaseInTempMem = (UINT8 *) GLOBAL_CPU_UEFI_HOB_LIST_TEMP_ADDR;
    HeapManagerInTempMem = (HEAP_MANAGER *) HeapBaseInTempMem;
    HeapInTempMem = (BUFFER_NODE *) (HeapBaseInTempMem + TotalSize);
    EndNodeInTempMem = HeapInTempMem;

    //
    // Calculate the whole size of heap that need to transferred.
    //
    while (HeapInCacheOffset != AMD_HEAP_INVALID_HEAP_OFFSET) {
      //
      // Copy nodes that will persist in system memory
      //
      if (HeapInCache->Persist > HEAP_LOCAL_CACHE) {
        AlignTo16ByteInCache = HeapInCache->PadSize;

        SizeOfNodeData = HeapInCache->BufferSize - AlignTo16ByteInCache;
        SizeOfHeapNode = SizeOfNodeData + sizeof (BUFFER_NODE);

        TotalSize += SizeOfHeapNode;
        //
        // Copy heap in cache with 16-byte alignment to temp buffer compactly.
        //
        Source = (UINT8 *) HeapInCache + sizeof (BUFFER_NODE) + AlignTo16ByteInCache;
        Destination = (UINT8 *) HeapInTempMem + sizeof (BUFFER_NODE);
        LibAmdMemCopy  (HeapInTempMem, HeapInCache, sizeof (BUFFER_NODE), StdHeader);
        LibAmdMemCopy  (Destination, Source, SizeOfNodeData, StdHeader);
        //
        // Fix buffer size in temp memory which has no 16-byte alignment.
        // Next node offset is the total size used.
        //
        HeapInTempMem->BufferSize = SizeOfNodeData;
        HeapInTempMem->OffsetOfNextNode = TotalSize;
        HeapInTempMem->PadSize = 0;
        EndNodeInTempMem = HeapInTempMem;
        HeapInTempMem = (BUFFER_NODE *) (HeapBaseInTempMem + TotalSize);
      }
      //
      // Point to the next buffer node
      //
      HeapInCacheOffset = HeapInCache->OffsetOfNextNode;
      HeapInCache = (BUFFER_NODE *) (HeapBaseInCache + HeapInCacheOffset);
    }

    //
    // Finalize new heap manager in temp memory
    // No free space node is reserved for temp memory.
    //
    HeapManagerInTempMem->FirstFreeSpaceOffset = AMD_HEAP_INVALID_HEAP_OFFSET;
    if (TotalSize == sizeof (HEAP_MANAGER)) {
      HeapManagerInTempMem->UsedSize = sizeof (HEAP_MANAGER);
      HeapManagerInTempMem->FirstActiveBufferOffset = AMD_HEAP_INVALID_HEAP_OFFSET;
    } else {
      HeapManagerInTempMem->UsedSize = TotalSize;
      HeapManagerInTempMem->FirstActiveBufferOffset = sizeof (HEAP_MANAGER);
      //
      // Last Node has no next node.
      //
      EndNodeInTempMem->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET;
    }
    HeapManagerInCache->Signature = HEAP_SIGNATURE_INVALID;
    HeapManagerInTempMem->Signature = HEAP_SIGNATURE_VALID;

    //
    // Start to copy data into UEFI HOB.
    //
    Status = PeiBuildHobGuidData (PeiServices, &gAmdHeapHobGuid, HeapBaseInTempMem, (UINTN) TotalSize);
    if (EFI_ERROR (Status)) {
      return AGESA_ERROR;
    }
    //
    // Update StdHeader with new heap status and base address
    //
    StdHeader->HeapStatus = HEAP_TEMP_MEM;
    StdHeader->HeapBasePtr = HeapGetBaseAddressInTempMem (StdHeader);
  }
  return AGESA_SUCCESS;
}
Beispiel #18
0
/**
 *  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.  Initialize a couple heap items
 *  all cores need, for convenience.  Currently these are caching the AP mailbox info and
 *  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;
  AGESA_STATUS          IgnoredSts;
  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 ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
  FamilySpecificServices->GetCacheInfo (FamilySpecificServices, (CONST VOID **) &CacheInfoPtr, &Ignored, StdHeader);
  HeapBufferPtr = (UINT8 *)(UINTN) StdHeader->HeapBasePtr;

  // Check whether the heap manager is already initialized
  LibAmdMsrRead (AMD_MTRR_VARIABLE_HEAP_MASK, &MsrData, 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
  MsrData = (UINT64) (AMD_TEMP_TOM);
  LibAmdMsrWrite (TOP_MEM, &MsrData, StdHeader);

  // Enable variable MTRRs
  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;
  if (!IsBsp (StdHeader, &IgnoredSts)) {
    // The BSP's hardware mailbox has not been initialized, so only APs
    // can do this at this point.
    CacheApMailbox (StdHeader);
  }
  EventLogInitialization (StdHeader);
  return AGESA_SUCCESS;
}
Beispiel #19
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);
}
Beispiel #20
0
/**
 *
 *  Initial function for HDT out Function.
 *
 *  Init required Debug register & heap, and will also fire a HDTOUT
 *  Command to let hdtout script do corresponding things.
 *
 *  @param[in,out] StdHeader    The Pointer of AGESA Header
 *
 **/
VOID
AmdIdsHdtOutInit (
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  ALLOCATE_HEAP_PARAMS AllocHeapParams;
  HDTOUT_HEADER HdtoutHeader;
  UINT8  Persist;
  AGESA_STATUS IgnoreSts;
  HDTOUT_HEADER *pHdtoutHeader;

  IDS_FUNCLIST_EXTERN ();
  if (AmdIdsHdtOutSupport ()) {
    AmdIdsHdtOutRegisterInit (StdHeader);
    // Initialize HDTOUT Header
    HdtoutHeader.Signature = HDTOUT_HEADER_SIGNATURE;
    HdtoutHeader.Version = HDTOUT_VERSION;
    HdtoutHeader.BufferSize = HDTOUT_DEFAULT_BUFFER_SIZE;
    HdtoutHeader.DataIndex = 0;
    HdtoutHeader.PrintCtrl = HDTOUT_PRINTCTRL_ON;
    HdtoutHeader.NumBreakpointUnit = 0;
    HdtoutHeader.FuncListAddr = (UINTN)IDS_FUNCLIST_ADDR;
    HdtoutHeader.StatusStr[0] = 0;
    HdtoutHeader.OutBufferMode = HDTOUT_BUFFER_MODE_ON;
    HdtoutHeader.EnableMask = 0;
    HdtoutHeader.ConsoleFilter = IDS_DEBUG_PRINT_MASK;

    // Trigger HDTOUT breakpoint to get inputs from script
    IdsOutPort (HDTOUT_INIT, (UINTN) &HdtoutHeader, 0);
    // Disable AP HDTOUT if set BspOnlyFlag
    if (HdtoutHeader.BspOnlyFlag == HDTOUT_BSP_ONLY) {
      if (!IsBsp (StdHeader, &IgnoreSts)) {
        AmdIdsHdtOutRegisterRestore (StdHeader);
        return;
      }
    }
    // Convert legacy EnableMask to new ConsoleFilter
    HdtoutHeader.ConsoleFilter |= HdtoutHeader.EnableMask;

    // Disable the buffer if the size is not large enough
    if (HdtoutHeader.BufferSize < 128) {
      HdtoutHeader.BufferSize = 0;
      HdtoutHeader.OutBufferMode = HDTOUT_BUFFER_MODE_OFF;
    } else {
      HdtoutHeader.OutBufferMode = HDTOUT_BUFFER_MODE_ON;
    }

    // Check if Hdtout header have been initialed, if so it must 2nd time come here
    if (AmdIdsHdtoutGetHeader (&pHdtoutHeader, StdHeader)) {
      Persist = HEAP_SYSTEM_MEM;
    } else {
      Persist = HEAP_LOCAL_CACHE;
    }

    // Allocate heap
    do {
      AllocHeapParams.RequestedBufferSize = HdtoutHeader.BufferSize + sizeof (HdtoutHeader) - 2;
      AllocHeapParams.BufferHandle = IDS_HDT_OUT_BUFFER_HANDLE;
      AllocHeapParams.Persist = Persist;
      if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) {
        break;
      } else {
        IdsOutPort (HDTOUT_ERROR, HDTOUT_ERROR_HEAP_ALLOCATION, AllocHeapParams.RequestedBufferSize);
        HdtoutHeader.BufferSize -= 256;
      }
    } while ((HdtoutHeader.BufferSize & 0x8000) == 0);
    // If the buffer have been successfully allocated?
    if ((HdtoutHeader.BufferSize & 0x8000) == 0) {
      LibAmdWriteCpuReg (DR3_REG, (UINTN)AllocHeapParams.BufferPtr);
      LibAmdMemCopy (AllocHeapParams.BufferPtr, &HdtoutHeader, sizeof (HdtoutHeader) - 2, StdHeader);
    } else {
      /// Clear DR3_REG
      IdsOutPort ((UINT32)HDTOUT_ERROR, (UINT32)HDTOUT_ERROR_HEAP_AllOCATE_FAIL, (UINT32)IDS_DEBUG_PRINT_MASK);
      LibAmdWriteCpuReg (DR3_REG, 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;
}
/**
 * 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);
}
Beispiel #23
0
/**
 * North bridge bufer allocation for Family14h ON.
 *
 * This function programs North bridge buffer allocation registers and provides
 * hook routine for override at AmdInitEarly.
 *
 *  @param[in]   FamilyServices      The current Family Specific Services.
 *  @param[in]   EarlyParams         Service parameters.
 *  @param[in]   StdHeader           Config handle for library and services.
 *
 */
VOID
F14NbBufferAllocationAtEarly (
  IN       CPU_SPECIFIC_SERVICES  *FamilyServices,
  IN       AMD_CPU_EARLY_PARAMS   *EarlyParams,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  //Buffer allocations cannot be decreased through software, so move these register setting from register table
  //to here to make IDS easy override
  NB_BUFFER_ALLOCATION NbBufAllocation;
  PCI_ADDR PciAddr;
  AGESA_STATUS Ignored;

  if (IsBsp (StdHeader, &Ignored)) {
    PciAddr.AddressValue = MAKE_SBDFO (0, 0, 24, FUNC_3, D18F3x6C_ADDRESS);
    LibAmdPciRead (AccessWidth32, PciAddr, &NbBufAllocation.D18F3x6C.Value, StdHeader);
    PciAddr.Address.Register = D18F3x74_ADDRESS;
    LibAmdPciRead (AccessWidth32, PciAddr, &NbBufAllocation.D18F3x74.Value, StdHeader);
    PciAddr.Address.Register = D18F3x7C_ADDRESS;
    LibAmdPciRead (AccessWidth32, PciAddr, &NbBufAllocation.D18F3x7C.Value, StdHeader);
    PciAddr.Address.Register = D18F3x17C_ADDRESS;
    LibAmdPciRead (AccessWidth32, PciAddr, &NbBufAllocation.D18F3x17C.Value, StdHeader);
    //Recommend value for NB buffer allocation
    // D18F3x6C - Upstream Data Buffer Count
    // bits[3:0]   UpLoPreqDBC = 0x0E
    // bits[7:4]   UpLoNpReqDBC = 1
    // bits[11:8]  UpLoRespDBC = 1
    // bits[19:16] UpHiPreqDBC = 0
    // bits[23:20] UpHiNpReqDBC = 0
    NbBufAllocation.D18F3x6C.Field.UpLoPreqDBC = 0x0E;
    NbBufAllocation.D18F3x6C.Field.UpLoNpreqDBC = 1;
    NbBufAllocation.D18F3x6C.Field.UpLoRespDBC = 1;
    NbBufAllocation.D18F3x6C.Field.UpHiPreqDBC = 0;
    NbBufAllocation.D18F3x6C.Field.UpHiNpreqDBC = 0;

    // D18F3x74 - Upstream Command Buffer Count
    // bits[3:0]   UpLoPreqCBC = 7
    // bits[7:4]   UpLoNpreqCBC = 9
    // bits[11:8]  UpLoRespCBC = 8
    // bits[19:16] UpHiPreqCBC = 0
    // bits[23:20] UpHiNpreqCBC = 0
    NbBufAllocation.D18F3x74.Field.UpLoPreqCBC = 7;
    NbBufAllocation.D18F3x74.Field.UpLoNpreqCBC = 9;
    NbBufAllocation.D18F3x74.Field.UpLoRespCBC = 8;
    NbBufAllocation.D18F3x74.Field.UpHiPreqCBC = 0;
    NbBufAllocation.D18F3x74.Field.UpHiNpreqCBC = 0;

    // D18F3x7C - In-Flight Queue Buffer Allocation
    // bits[5:0]  CpuBC = 1
    // bits[13:8] LoPriPBC = 1
    // bits[21:16] LoPriNPBC = 1
    // bits[29:24] FreePoolBC = 0x19
    NbBufAllocation.D18F3x7C.Field.CpuBC = 1;
    NbBufAllocation.D18F3x7C.Field.LoPriPBC = 1;
    NbBufAllocation.D18F3x7C.Field.LoPriNPBC = 1;
    NbBufAllocation.D18F3x7C.Field.FreePoolBC = 0x19;

    // D18F3x17C - In-Flight Queue Extended Buffer Allocation
    // bits[5:0]  HiPriPBC = 0
    // bits[13:8] HiPriNPBC = 0
    NbBufAllocation.D18F3x17C.Field.HiPriPBC = 0;
    NbBufAllocation.D18F3x17C.Field.HiPriNPBC = 0;

    IDS_OPTION_HOOK (IDS_NBBUFFERALLOCATIONATEARLY, &NbBufAllocation, StdHeader);

    PciAddr.AddressValue = MAKE_SBDFO (0, 0, 24, FUNC_3, D18F3x6C_ADDRESS);
    LibAmdPciWrite (AccessWidth32, PciAddr, &NbBufAllocation.D18F3x6C.Value, StdHeader);
    PciAddr.Address.Register = D18F3x74_ADDRESS;
    LibAmdPciWrite (AccessWidth32, PciAddr, &NbBufAllocation.D18F3x74.Value, StdHeader);
    PciAddr.Address.Register = D18F3x7C_ADDRESS;
    LibAmdPciWrite (AccessWidth32, PciAddr, &NbBufAllocation.D18F3x7C.Value, StdHeader);
    PciAddr.Address.Register = D18F3x17C_ADDRESS;
    LibAmdPciWrite (AccessWidth32, PciAddr, &NbBufAllocation.D18F3x17C.Value, StdHeader);
  }
}
Beispiel #24
0
/**
 * 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;
}
Beispiel #25
0
AGESA_STATUS
AmdIdsCtrlInitialize (
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  AGESA_STATUS status;
  AGESA_STATUS IgnoreStatus;
  UINT16 NvTblSize;
  UINT16 i;
  IDS_NV_ITEM IdsNvTable[IDS_NUM_NV_ITEM];
  IDS_NV_ITEM *NvTable;
  IDS_NV_ITEM *NvPtr;
  IDS_CONTROL_STRUCT *IdsCtrlPtr;
  IDS_CALLOUT_STRUCT IdsCalloutData;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;
  UINT16 MemTblSize;
  UINT8 HeapPersist;

  NvTblSize = 0;
  MemTblSize = 0;
  HeapPersist = HEAP_SYSTEM_MEM;
  //Heap status with HEAP_LOCAL_CACHE, will allocate heap with HEAP_LOCAL_CACHE
  //with HEAP_TEMP_MEM  HEAP_SYSTEM_MEM  HEAP_DO_NOT_EXIST_ANYMORE  HEAP_S3_RESUME
  // with allocate with HEAP_SYSTEM_MEM
  if (StdHeader->HeapStatus == HEAP_LOCAL_CACHE) {
    MemTblSize = IDS_MAX_MEM_ITEMS;
    HeapPersist = IDS_HEAP_PERSIST_EARLY;
  } else if ((StdHeader->HeapStatus == HEAP_DO_NOT_EXIST_YET) || (StdHeader->HeapStatus == HEAP_DO_NOT_EXIST_ANYMORE)) {
    return AGESA_ERROR;
  } else {
    IDS_HEAP_ASSERTION_LATE;
  }

  IdsCalloutData.IdsNvPtr = IdsNvTable;
  IdsCalloutData.StdHeader = *StdHeader;
  IdsCalloutData.Reserved = FALSE;
//init IDS_CALLOUT_STRUCT before calling out, give NVITEM default value
  for (i = AGESA_IDS_EXT_ID_START; i < IDS_NUM_NV_ITEM; i++) {
    IdsNvTable[i].IdsNvId = i;
    IdsNvTable[i].IdsNvValue = AGESA_IDS_DFT_VAL;
  }

  AGESA_TESTPOINT (TpIfBeforeGetIdsData, StdHeader);
  if (AgesaGetIdsData (IDS_CALLOUT_INIT, &IdsCalloutData) == AGESA_SUCCESS) {
    IDS_HDT_CONSOLE (IDS_TRACE , "Get IDS options from CBS Done\n");
    NvTable = IdsCalloutData.IdsNvPtr;
    NvPtr = NvTable;
    while (NvPtr->IdsNvId != AGESA_IDS_NV_END) {
      IDS_HDT_CONSOLE (IDS_TRACE , "\tIDS_ID (%X) = %X\n", NvPtr->IdsNvId, NvPtr->IdsNvValue);
      NvTblSize  ++;
      NvPtr ++;
    }
    NvTblSize  ++;

    AllocHeapParams.RequestedBufferSize = sizeof (IDS_CONTROL_STRUCT);
    AllocHeapParams.RequestedBufferSize += NvTblSize  * sizeof (IDS_NV_ITEM);
    AllocHeapParams.RequestedBufferSize += MemTblSize * sizeof (MEM_TABLE_ALIAS);
    AllocHeapParams.RequestedBufferSize += IDS_EXTENDED_HEAP_SIZE;
    AllocHeapParams.BufferHandle = IDS_CONTROL_HANDLE;
    AllocHeapParams.Persist = HeapPersist;

    //
    // Allocate data buffer in heap
    //
    if (HeapAllocateBuffer (&AllocHeapParams, (AMD_CONFIG_PARAMS *) StdHeader) == AGESA_SUCCESS) {
      //
      // Initialize IDS Date Buffer
      //
      IdsCtrlPtr = (IDS_CONTROL_STRUCT *) AllocHeapParams.BufferPtr;
      IdsCtrlPtr->IgnoreIdsDefault = (BOOLEAN) IdsCalloutData.Reserved;
      IdsCtrlPtr->IdsHeapMemSize = AllocHeapParams.RequestedBufferSize;
      IdsCtrlPtr->IdsNvTableOffset = sizeof (IDS_CONTROL_STRUCT);
      IdsCtrlPtr->IdsMemTableOffset = IdsCtrlPtr->IdsNvTableOffset + NvTblSize  * sizeof (IDS_NV_ITEM);
      IdsCtrlPtr->IdsExtendOffset = IdsCtrlPtr->IdsMemTableOffset + MemTblSize * sizeof (MEM_TABLE_ALIAS);

      NvPtr = (IDS_NV_ITEM *) (AllocHeapParams.BufferPtr + IdsCtrlPtr->IdsNvTableOffset);
      for (i = 0; i < NvTblSize ; i++) {
        NvPtr->IdsNvId = NvTable->IdsNvId;
        NvPtr->IdsNvValue = NvTable->IdsNvValue;
        NvPtr ++;
        NvTable ++;
      }
      status = AGESA_SUCCESS;
    } else {
      status = AGESA_ERROR;
    }
  } else {
    if (!IsBsp (StdHeader, &IgnoreStatus)) {
      status = IDS_AP_GET_NV_FROM_CMOS (StdHeader);
    } else {
      IDS_HDT_CONSOLE (IDS_TRACE , "Get IDS options from CBS Fail\n");
      status = AGESA_ERROR;
    }
  }
  AGESA_TESTPOINT (TpIfAfterGetIdsData, StdHeader);

  return status;
}