BOOLEAN
MemNWritePmuSramMsgBlockKV (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  UINT16 i;
  UINT16 *ImagePtr;
  LOCATE_HEAP_PTR LocHeap;

  LocHeap.BufferHandle = AMD_MEM_PMU_SRAM_MSG_BLOCK_HANDLE;

  if (HeapLocateBuffer (&LocHeap, &(NBPtr->MemPtr->StdHeader)) != AGESA_SUCCESS) {
    return FALSE; // Could not locate heap for PMU SRAM Message BLock.
  }

  ImagePtr = (UINT16 *) LocHeap.BufferPtr;

  MemNSetBitFieldNb (NBPtr, BFPmuReset, 0);

  // Write the word to D18F2x[B,0]9C_x0005_[27FF:0800]_dct[3:0] (using the broadcast port for all phys at
  // D18F2xB98_dct[MaxDctMstr:0], and using the autoincrement feature).
  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tStart writing PMU SRAM Message Block...\n");

  MemNSetBitFieldNb (NBPtr, RegDctAddlOffset, PMU_FIRMWARE_SRAM_START | DCT_ACCESS_WRITE | DCT_OFFSET_AUTO_INC_EN);

  for (i = 0; i < sizeof (PMU_SRAM_MSG_BLOCK_KV) / sizeof (ImagePtr[0]); i++) {
    MemNSetBitFieldNb (NBPtr, RegDctAddlData, ImagePtr[i]);
    IDS_HDT_CONSOLE (MEM_SETREG, "~F2_9C_%x = %04x\n", PMU_FIRMWARE_SRAM_START + i, ImagePtr[i]);
  }

  IDS_HDT_CONSOLE (MEM_FLOW, "\t\tEnd writing PMU SRAM Message Block!\n");
  MemNSetBitFieldNb (NBPtr, RegDctAddlOffset, 0);

  return TRUE;
}
Exemple #2
0
STATIC VOID
RetrieveDataBlockFromInitReset (
  IN       FCH_DATA_BLOCK       *FchParams
  )
{
  LOCATE_HEAP_PTR           LocHeapPtr;
  FCH_RESET_DATA_BLOCK      *ResetDb;
  AGESA_STATUS              AgesaStatus;

  LocHeapPtr.BufferHandle = AMD_FCH_RESET_DATA_BLOCK_HANDLE;
  AgesaStatus = HeapLocateBuffer (&LocHeapPtr, FchParams->StdHeader);
  if (AgesaStatus == AGESA_SUCCESS) {
    ASSERT (LocHeapPtr.BufferPtr != NULL);
    ResetDb = (FCH_RESET_DATA_BLOCK *) (LocHeapPtr.BufferPtr - sizeof (ResetDb) + sizeof (UINT32));
    // Override FchParams with contents in ResetDb

    FchParams->Usb.Xhci0Enable              = ResetDb->FchReset.Xhci0Enable;
    FchParams->Usb.Xhci1Enable              = ResetDb->FchReset.Xhci1Enable;
    FchParams->Spi.SpiFastSpeed             = ResetDb->FastSpeed;
    FchParams->Spi.WriteSpeed               = ResetDb->WriteSpeed;
    FchParams->Spi.SpiMode                  = ResetDb->Mode;
    FchParams->Spi.AutoMode                 = ResetDb->AutoMode;
    FchParams->Spi.SpiBurstWrite            = ResetDb->BurstWrite;
    FchParams->Sata.SataMode.Sata6AhciCap   = (UINT8) ResetDb->Sata6AhciCap;
    FchParams->Misc.Cg2Pll                  = ResetDb->Cg2Pll;
    FchParams->Sata.SataMode.SataSetMaxGen2 = ResetDb->SataSetMaxGen2;
    FchParams->Sata.SataMode.SataClkMode    = ResetDb->SataClkMode;
    FchParams->Sata.SataMode.SataModeReg    = ResetDb->SataModeReg;
    FchParams->Sata.SataInternal100Spread   = (UINT8) ResetDb->SataInternal100Spread;
    FchParams->Spi.SpiSpeed                 = ResetDb->SpiSpeed;
    FchParams->Gpp                          = ResetDb->Gpp;
  }
}
BOOLEAN
MemNInitPmuSramMsgBlockKV (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  LOCATE_HEAP_PTR LocHeap;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;
  PMU_SRAM_MSG_BLOCK_KV *PmuSramMsgBlockPtr;

  LocHeap.BufferHandle = AMD_MEM_PMU_SRAM_MSG_BLOCK_HANDLE;
  if (HeapLocateBuffer (&LocHeap, &(NBPtr->MemPtr->StdHeader)) == AGESA_SUCCESS) {
    PmuSramMsgBlockPtr = (PMU_SRAM_MSG_BLOCK_KV *) LocHeap.BufferPtr;
  } else {
    // Allocate temporary buffer for PMU SRAM Message Block
    AllocHeapParams.RequestedBufferSize = sizeof (PMU_SRAM_MSG_BLOCK_KV);
    AllocHeapParams.BufferHandle = AMD_MEM_PMU_SRAM_MSG_BLOCK_HANDLE;
    AllocHeapParams.Persist = HEAP_LOCAL_CACHE;

    if (HeapAllocateBuffer (&AllocHeapParams, &(NBPtr->MemPtr->StdHeader)) != AGESA_SUCCESS) {
      return FALSE; // Could not allocate heap for PMU SRAM Message BLock.
    }

    PmuSramMsgBlockPtr = (PMU_SRAM_MSG_BLOCK_KV *) AllocHeapParams.BufferPtr;
  }

  LibAmdMemFill ((VOID *)PmuSramMsgBlockPtr, 0, (UINTN)sizeof (PMU_SRAM_MSG_BLOCK_KV), &(NBPtr->MemPtr->StdHeader));

  return TRUE;
}
Exemple #4
0
//
// Private Function Declaration
//
FCH_DATA_BLOCK*
FchLocateHeapBuffer ( VOID )
{
  LOCATE_HEAP_PTR              LocateHeapPtr;
  AMD_CONFIG_PARAMS            StdHeader;
  AGESA_STATUS                 AgesaStatus;
  EFI_STATUS                   Status;

  Status = gBS->LocateProtocol (
                  &gAmdBufferManagerProtocolGuid,
                  NULL,
                  &mBufferMgr
                  );
  if (EFI_ERROR (Status)) {
    return NULL;
  }
  mDxeBufferManager = mBufferMgr->DxeBufferManager;

  StdHeader = mBufferMgr->StdHeader;
  StdHeader.HeapStatus = HEAP_SYSTEM_MEM;
  LocateHeapPtr.BufferHandle = AMD_FCH_DATA_BLOCK_HANDLE;
  AgesaStatus = HeapLocateBuffer (&LocateHeapPtr, &StdHeader);
  ASSERT (!AgesaStatus);
  return (FCH_DATA_BLOCK *) LocateHeapPtr.BufferPtr;
}
Exemple #5
0
/**
 *
 *
 *   This function determines if the revision S3 data blob matches the S3 engine
 *
 *      @param[in]       Storage    - Beginning of the device list.
 *      @param[in]       *StdHeader - Config handle for library and services.
 *
 *      @return          AGESA_STATUS
 *                          - AGESA_FATAL
 *                          - AGESA_SUCCESS
 */
AGESA_STATUS
AmdMemS3DatablobRevMatch (
  IN   VOID              *Storage,
  IN   AMD_CONFIG_PARAMS *StdHeader
  )
{
  S3_MEM_NB_BLOCK *S3NBPtr;
  LOCATE_HEAP_PTR LocHeap;
  DEVICE_BLOCK_HEADER *DeviceList;

  DeviceList = (DEVICE_BLOCK_HEADER *) Storage;

  LocHeap.BufferHandle = AMD_MEM_S3_NB_HANDLE;
  S3NBPtr = NULL;
  if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) {
    S3NBPtr = (S3_MEM_NB_BLOCK *)LocHeap.BufferPtr;
  } else {
    ASSERT (FALSE) ; // No match for heap status, but could not locate "AMD_MEM_S3_NB_HANDLE" in heap for S3GetMsr
    return AGESA_FATAL;
  }

  if (S3NBPtr[BSP_DIE].S3DatablobRev == DeviceList->Revision) {
    return AGESA_SUCCESS;
  } else {
    ASSERT (FALSE);
    return AGESA_FATAL;
  }
}
Exemple #6
0
/**
 *
 *
 *   This function determines if the PSP is present
 *
 *      @param[in]       *StdHeader - Config handle for library and services.
 *
 *      @return          AGESA_STATUS
 *                          - AGESA_FATAL
 *                          - AGESA_SUCCESS
 */
AGESA_STATUS
AmdMemDoResume (
  IN   AMD_CONFIG_PARAMS *StdHeader
  )
{
  S3_MEM_NB_BLOCK *S3NBPtr;
  MEM_NB_BLOCK *NBPtr;
  LOCATE_HEAP_PTR LocHeap;

  LocHeap.BufferHandle = AMD_MEM_S3_NB_HANDLE;
  S3NBPtr = NULL;
  if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) {
    S3NBPtr = (S3_MEM_NB_BLOCK *)LocHeap.BufferPtr;
    NBPtr = ((S3_MEM_NB_BLOCK *)S3NBPtr)->NBPtr;
  } else {
    ASSERT (FALSE) ; // No match for heap status, but could not locate "AMD_MEM_S3_NB_HANDLE" in heap for S3GetMsr
    return AGESA_FATAL;
  }

  if (S3NBPtr[BSP_DIE].MemS3PspPlatformSecureBootEn (S3NBPtr[BSP_DIE].NBPtr) == NBPtr->MemRunningOnPsp (NBPtr)) {
    return AGESA_SUCCESS;
  } else {
    return AGESA_FATAL;
  }
}
Exemple #7
0
/**
 *
 *
 *      This function returns the conditional MSR device register list according
 *      to the register list ID.
 *
 *      @param[in]       *Device - pointer to the CONDITIONAL_PCI_DEVICE_DESCRIPTOR
 *      @param[out]      **RegisterHdr - pointer to the address of the register list
 *      @param[in]       *StdHeader - Config handle for library and services
 *
 *      @return          AGESA_STATUS
 *                          - AGESA_ALERT
 *                          - AGESA_FATAL
 *                          - AGESA_SUCCESS
 *                          - AGESA_WARNING
 */
AGESA_STATUS
MemFS3GetCMsrDeviceRegisterList (
  IN       CONDITIONAL_MSR_DEVICE_DESCRIPTOR     *Device,
     OUT   CMSR_REGISTER_BLOCK_HEADER            **RegisterHdr,
  IN       AMD_CONFIG_PARAMS                     *StdHeader
  )
{
  AGESA_STATUS RetVal;
  S3_MEM_NB_BLOCK *S3NBPtr;
  VOID *RegisterHeader;
  LOCATE_HEAP_PTR LocHeap;
  AGESA_BUFFER_PARAMS LocBufferParams;

  LibAmdMemCopy (&LocBufferParams.StdHeader, StdHeader, sizeof (AMD_CONFIG_PARAMS), StdHeader);
  LocHeap.BufferHandle = AMD_MEM_S3_NB_HANDLE;
  LocBufferParams.BufferHandle = AMD_MEM_S3_NB_HANDLE;


  AGESA_TESTPOINT (TpIfBeforeLocateS3CMsrBuffer, StdHeader);
  if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) {
    S3NBPtr = (S3_MEM_NB_BLOCK *)LocHeap.BufferPtr;
  } else {
    ASSERT(FALSE) ; // No match for heap status, but could not locate "AMD_MEM_S3_NB_HANDLE" in heap for S3GetMsr
    return AGESA_FATAL;
  }
  AGESA_TESTPOINT (TpIfAfterLocateS3CMsrBuffer, StdHeader);

  // NB block has already been constructed by main block.
  // No need to construct it here.
  RetVal = S3NBPtr[BSP_DIE].MemS3GetDeviceRegLst (Device->RegisterListID, &RegisterHeader);
  *RegisterHdr = (CMSR_REGISTER_BLOCK_HEADER *)RegisterHeader;
  return RetVal;
}
Exemple #8
0
/**
 *
 *  Get Ids Performance analysis table pointer in the AGESA Heap.
 *
 *  @param[in,out] StdHeader    The Pointer of AGESA Header
 *  @param[in] TestPoint  Progress indicator value, see @ref AGESA_TP
 *
 *  @retval AGESA_SUCCESS       Success to get the pointer of Performance analysis Table.
 *  @retval AGESA_ERROR         Fail to get the pointer of Performance analysis Table.
 *  @retval AGESA_UNSUPPORTED   Get an exclude testpoint
 *
 **/
AGESA_STATUS
IdsPerfTimestamp (
  IN OUT   AMD_CONFIG_PARAMS *StdHeader,
  IN       AGESA_TP TestPoint
   )
{
  AGESA_STATUS status;
  UINT8 Index;
  UINT8 i;
  TP_Perf_STRUCT *PerfTableEntry;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;
  LOCATE_HEAP_PTR LocateHeapStructPtr;
  UINT64 CurrentTsc;


  // Exclude some testpoint which may cause deadloop
  for (i = 0; i < (sizeof (IdsPerfExcludeTp) / sizeof (AGESA_TP)); i++) {
    if (TestPoint == IdsPerfExcludeTp[i]) {
      return AGESA_UNSUPPORTED;
    }
  }
  //if heap is not ready yet, don't invoke locate buffer, or else will cause event log & locate heap dead loop
  if (StdHeader->HeapStatus != HEAP_DO_NOT_EXIST_YET ) {
    LibAmdMsrRead (TSC, &CurrentTsc, StdHeader);

    LocateHeapStructPtr.BufferHandle = IDS_CHECK_POINT_PERF_HANDLE;
    LocateHeapStructPtr.BufferPtr = NULL;

    status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader);
    if (status == AGESA_SUCCESS) {
      PerfTableEntry = (TP_Perf_STRUCT *) (LocateHeapStructPtr.BufferPtr);
    } else {
      AllocHeapParams.RequestedBufferSize = sizeof (TP_Perf_STRUCT);
      AllocHeapParams.BufferHandle = IDS_CHECK_POINT_PERF_HANDLE;
      AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
      status = HeapAllocateBuffer (&AllocHeapParams, StdHeader);
      if (status != AGESA_SUCCESS) {
        return status;
      }
      PerfTableEntry = (TP_Perf_STRUCT *) (AllocHeapParams.BufferPtr);
      LibAmdMemFill (PerfTableEntry, 0, sizeof (TP_Perf_STRUCT), StdHeader);
    }

    Index = PerfTableEntry ->Index;
//TPPerfUnit doesn't need to check, it may used for multiple time, used to check the time
// consumption of each perf measure routine.
    if ((TestPoint != TpPerfUnit)) {
      for (i = 0; i < Index; i++) {
        if ((UINT8) TestPoint == PerfTableEntry ->TP[i].TestPoint) {
          return AGESA_SUCCESS;
        }
      }
    }
    PerfTableEntry ->TP[Index].TestPoint = (UINT8) TestPoint;
    PerfTableEntry ->TP[Index].StartTsc = CurrentTsc;
    PerfTableEntry ->Index = ++Index;
  }
  return AGESA_SUCCESS;
}
Exemple #9
0
/**
 * 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;
}
Exemple #10
0
/**
 *
 *  Get Ids Performance analysis table pointer in the AGESA Heap.
 *
 *  @param[in] LineInFile  ((FILECODE) shift 16)+ Line number
 *  @param[in] Description  ID for Description define idsperf.h
 *  @param[in,out] StdHeader    The Pointer of AGESA Header
 *
 *  @retval AGESA_SUCCESS       Success to get the pointer of Performance analysis Table.
 *  @retval AGESA_ERROR         Fail to get the pointer of Performance analysis Table.
 *  @retval AGESA_UNSUPPORTED   Get an exclude testpoint
 *
 **/
AGESA_STATUS
IdsPerfTimestamp (
  IN       UINT32 LineInFile,
  IN       UINT32 Description,
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  AGESA_STATUS status;
  UINT32 Index;
  TP_Perf_STRUCT *PerfTableEntry;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;
  LOCATE_HEAP_PTR LocateHeapStructPtr;
  UINT64 TscAtBegining;
  UINT64 TscAtEnd;

  //if heap is not ready yet, don't invoke locate buffer, or else will cause event log & locate heap dead loop
  if (StdHeader->HeapStatus != HEAP_DO_NOT_EXIST_YET ) {
    IdsGetGtsc (&TscAtBegining, StdHeader);

    LocateHeapStructPtr.BufferHandle = IDS_CHECK_POINT_PERF_HANDLE;
    LocateHeapStructPtr.BufferPtr = NULL;
    status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader);
    if (status == AGESA_SUCCESS) {
      PerfTableEntry = (TP_Perf_STRUCT *) (LocateHeapStructPtr.BufferPtr);
    } else {
      AllocHeapParams.RequestedBufferSize = sizeof (TP_Perf_STRUCT);
      AllocHeapParams.BufferHandle = IDS_CHECK_POINT_PERF_HANDLE;
      AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
      status = HeapAllocateBuffer (&AllocHeapParams, StdHeader);
      if (status != AGESA_SUCCESS) {
        return status;
      }
      PerfTableEntry = (TP_Perf_STRUCT *) (AllocHeapParams.BufferPtr);
      LibAmdMemFill (PerfTableEntry, 0, sizeof (TP_Perf_STRUCT), StdHeader);
      PerfTableEntry->Signature = 'FREP';
      PerfTableEntry->Version = IDS_PERF_VERSION;
    }

    Index = PerfTableEntry ->Index;
    if (Index >= MAX_PERFORMANCE_UNIT_NUM - 1) {
      ASSERT (FALSE);
      return AGESA_WARNING;
    }
    // Read GTSC again, so we could calculate the time consumed by this routine
    IdsGetGtsc (&TscAtEnd, StdHeader);

    PerfTableEntry ->TP[Index].LineInFile = LineInFile;
    PerfTableEntry ->TP[Index].Description = Description;
    PerfTableEntry ->TP[Index].StartTsc = TscAtBegining - PerfTableEntry ->TP[MAX_PERFORMANCE_UNIT_NUM - 1].StartTsc;
    PerfTableEntry ->TP[MAX_PERFORMANCE_UNIT_NUM - 1].StartTsc += TscAtEnd - TscAtBegining; // Using the last TP to record the total time consumed by this routine
    PerfTableEntry ->Index = ++Index;
  }
  return AGESA_SUCCESS;
}
Exemple #11
0
/**
 *
 *  Get Ids Performance analysis table pointer in the AGESA Heap.
 *
 *  @param[in] LineInFile  ((FILECODE) shift 16)+ Line number
 *  @param[in] Description  ID for Description define idsperf.h
 *  @param[in,out] StdHeader    The Pointer of AGESA Header
 *
 *  @retval AGESA_SUCCESS       Success to get the pointer of Performance analysis Table.
 *  @retval AGESA_ERROR         Fail to get the pointer of Performance analysis Table.
 *  @retval AGESA_UNSUPPORTED   Get an exclude testpoint
 *
 **/
AGESA_STATUS
IdsPerfTimestamp (
  IN       UINT32 LineInFile,
  IN       UINT32 Description,
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  AGESA_STATUS status;
  UINT32 Index;
  TP_Perf_STRUCT *PerfTableEntry;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;
  LOCATE_HEAP_PTR LocateHeapStructPtr;
  UINT64 CurrentTsc;

  //if heap is not ready yet, don't invoke locate buffer, or else will cause event log & locate heap dead loop
  if (StdHeader->HeapStatus != HEAP_DO_NOT_EXIST_YET ) {
    LibAmdMsrRead (TSC, &CurrentTsc, StdHeader);

    LocateHeapStructPtr.BufferHandle = IDS_CHECK_POINT_PERF_HANDLE;
    LocateHeapStructPtr.BufferPtr = NULL;
    status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader);
    if (status == AGESA_SUCCESS) {
      PerfTableEntry = (TP_Perf_STRUCT *) (LocateHeapStructPtr.BufferPtr);
    } else {
      AllocHeapParams.RequestedBufferSize = sizeof (TP_Perf_STRUCT);
      AllocHeapParams.BufferHandle = IDS_CHECK_POINT_PERF_HANDLE;
      AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
      status = HeapAllocateBuffer (&AllocHeapParams, StdHeader);
      if (status != AGESA_SUCCESS) {
        return status;
      }
      PerfTableEntry = (TP_Perf_STRUCT *) (AllocHeapParams.BufferPtr);
      LibAmdMemFill (PerfTableEntry, 0, sizeof (TP_Perf_STRUCT), StdHeader);
      PerfTableEntry->Signature = 'FREP';
      PerfTableEntry->Version = IDS_PERF_VERSION;
    }

    Index = PerfTableEntry ->Index;
    if (Index >= MAX_PERFORMANCE_UNIT_NUM) {
      return AGESA_WARNING;
    }
    ASSERT (Index < MAX_PERFORMANCE_UNIT_NUM);
    PerfTableEntry ->TP[Index].LineInFile = LineInFile;
    PerfTableEntry ->TP[Index].Description = Description;
    PerfTableEntry ->TP[Index].StartTsc = CurrentTsc;
    PerfTableEntry ->Index = ++Index;
  }
  return AGESA_SUCCESS;
}
Exemple #12
0
VOID *
GnbLocateHeapBuffer (
  IN      UINT32              Handle,
  IN      AMD_CONFIG_PARAMS   *StdHeader
  )
{
  AGESA_STATUS          Status;
  LOCATE_HEAP_PTR       LocHeapParams;
  LocHeapParams.BufferHandle = Handle;
  Status = HeapLocateBuffer (&LocHeapParams, StdHeader);
  if (Status != AGESA_SUCCESS) {
    return NULL;
  }
  return LocHeapParams.BufferPtr;
}
Exemple #13
0
/**
 *
 * Find out the pointer to the BufferHandle which contains
 * Node Topology information
 *
 *    @param[in, out] StdHeader         Standard Head Pointer
 *    @param[in] SocketTopologyPtr      Point to the address of Socket Topology
 *
 */
VOID
STATIC
AcpiCditHBufferFind (
  IN OUT   AMD_CONFIG_PARAMS *StdHeader,
  IN       UINT8 **SocketTopologyPtr
  )
{
  LOCATE_HEAP_PTR LocateBuffer;

  LocateBuffer.BufferHandle = HOP_COUNT_TABLE_HANDLE;
  if (HeapLocateBuffer (&LocateBuffer, StdHeader) == AGESA_SUCCESS) {
    *SocketTopologyPtr = (UINT8 *) LocateBuffer.BufferPtr;
  }

  return;
}
/**
 * Family 15h Trinity core 0 entry point for performing the necessary steps after
 * a warm reset has occurred.
 *
 * The steps are as follows:
 *
 *   1.    Temp1=D18F5x170[SwNbPstateLoDis].
 *   2.    Temp2=D18F5x170[NbPstateDisOnP0].
 *   3.    Temp3=D18F5x170[NbPstateThreshold].
 *   4.    Temp4=D18F5x170[NbPstateGnbSlowDis].
 *   5.    If MSRC001_0070[NbPstate]=0, go to step 6. If MSRC001_0070[NbPstate]=1, go to step 11.
 *   6.    Write 1 to D18F5x170[NbPstateGnbSlowDis].
 *   7.    Write 0 to D18F5x170[SwNbPstateLoDis, NbPstateDisOnP0, NbPstateThreshold].
 *   8.    Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateLo] and D18F5x174[CurNbFid, CurNb-
 *         Did]=[NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateLo].
 *   9.    Set D18F5x170[SwNbPstateLoDis]=1.
 *   10.   Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateHi] and D18F5x174[CurNbFid, CurNb-
 *         Did]=[NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateHi]. Go to step 15.
 *   11.   Write 1 to D18F5x170[SwNbPstateLoDis].
 *   12.   Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateHi] and D18F5x174[CurNbFid, CurNb-
 *         Did]=[NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateHi].
 *   13.   Write 0 to D18F5x170[SwNbPstateLoDis, NbPstateDisOnP0, NbPstateThreshold].
 *   14.   Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateLo] and D18F5x174[CurNbFid, CurNb-
 *         Did]=[NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateLo].
 *   15.   Set D18F5x170[SwNbPstateLoDis]=Temp1, D18F5x170[NbPstateDisOnP0]=Temp2, D18F5x170[NbP-
 *         stateThreshold]=Temp3, and D18F5x170[NbPstateGnbSlowDis]=Temp4.
 *
 * @param[in]  FamilySpecificServices  The current Family Specific Services.
 * @param[in]  CpuEarlyParamsPtr       Service parameters
 * @param[in]  StdHeader               Config handle for library and services.
 *
 */
VOID
F15TnPmNbAfterReset (
  IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
  IN       AMD_CPU_EARLY_PARAMS  *CpuEarlyParamsPtr,
  IN       AMD_CONFIG_PARAMS     *StdHeader
  )
{
  UINT32    Socket;
  UINT32    Module;
  UINT32    Core;
  UINT32    TaskedCore;
  UINT32    Ignored;
  AP_TASK   TaskPtr;
  PCI_ADDR  PciAddress;
  AGESA_STATUS IgnoredSts;
  LOCATE_HEAP_PTR Locate;

  IDS_HDT_CONSOLE (CPU_TRACE, "  F15TnPmNbAfterReset\n");

  IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts);

  ASSERT (Core == 0);

  if (FamilySpecificServices->IsNbPstateEnabled (FamilySpecificServices, &CpuEarlyParamsPtr->PlatformConfig, StdHeader)) {
    PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR;
    Locate.BufferHandle = AMD_CPU_NB_PSTATE_FIXUP_HANDLE;
    if (HeapLocateBuffer (&Locate, StdHeader) == AGESA_SUCCESS) {
      LibAmdPciWrite (AccessWidth32, PciAddress, Locate.BufferPtr, StdHeader);
    } else {
      ASSERT (FALSE);
    }
  }

  // Launch one core per node.
  TaskPtr.FuncAddress.PfApTask = F15TnPmNbAfterResetOnCore;
  TaskPtr.DataTransfer.DataSizeInDwords = 0;
  TaskPtr.ExeFlags = WAIT_FOR_CORE;
  for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
    if (GetGivenModuleCoreRange (Socket, Module, &TaskedCore, &Ignored, StdHeader)) {
      if (TaskedCore != 0) {
        ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) TaskedCore, &TaskPtr, StdHeader);
      }
    }
  }
  ApUtilTaskOnExecutingCore (&TaskPtr, StdHeader, (VOID *) CpuEarlyParamsPtr);
}
Exemple #15
0
/**
 * Initialize S3 Script framework
 *
 *
 *
 * @param[in]  StdHeader          Pointer to standard header
 * @param[out] S3SaveTable        S3 save table header
 */
AGESA_STATUS
S3ScriptGetS3SaveTable (
  IN       AMD_CONFIG_PARAMS     *StdHeader,
     OUT   S3_SAVE_TABLE_HEADER  **S3SaveTable
  )
{
  AGESA_STATUS          Status;
  LOCATE_HEAP_PTR       LocHeapParams;
  LocHeapParams.BufferHandle = AMD_S3_SCRIPT_SAVE_TABLE_HANDLE;
  Status = HeapLocateBuffer (&LocHeapParams, StdHeader);
  if (Status != AGESA_SUCCESS) {
    *S3SaveTable = NULL;
    return Status;
  }
  *S3SaveTable = (S3_SAVE_TABLE_HEADER *) LocHeapParams.BufferPtr;
  return AGESA_SUCCESS;
}
Exemple #16
0
/**
 *
 * This function gets the Event Log pointer.
 *
 * It will locate the Event Log on the heap using the heap locate service.  If the Event
 * Log is not located, NULL is returned.
 *
 * @param[out]  EventLog  Pointer to the Event Log, or NULL.
 * @param[in]   StdHeader Our Configuration, for passing to services.
 *
 */
VOID
STATIC
GetEventLogHeapPointer (
     OUT   AGESA_STRUCT_BUFFER **EventLog,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  LOCATE_HEAP_PTR LocateHeapStruct;

  LocateHeapStruct.BufferHandle = EVENT_LOG_BUFFER_HANDLE;
  LocateHeapStruct.BufferPtr = NULL;
  if ((HeapLocateBuffer (&LocateHeapStruct, StdHeader)) == AGESA_SUCCESS) {
    *EventLog = (AGESA_STRUCT_BUFFER *)LocateHeapStruct.BufferPtr;
  } else {
    *EventLog = NULL;
  }
}
Exemple #17
0
/**
 *
 *
 *   This function stores special case register on the heap.
 *
 *     @param[in,out]  *NBPtr - Pointer to the northbridge block.
 *     @param[in,out]  *StdHeader - Config handle for library and services.
 *     @return         none
 */
VOID
STATIC
MemNS3ExitSelfRefRegC32 (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  LOCATE_HEAP_PTR LocateBufferPtr;
  UINT8 i;
  PCI_ADDR PciAddr;
  UINT32 Value;
  UINT8 NodeID;
  UINT8 Offset;
  S3_SPECIAL_CASE_HEAP_HEADER *SpecialHeapHeader;

  Offset = 0;
  PciAddr.Address.Device = NBPtr->PciAddr.Address.Device;
  PciAddr.Address.Bus = NBPtr->PciAddr.Address.Bus;
  PciAddr.Address.Segment = NBPtr->PciAddr.Address.Segment;
  PciAddr.Address.Function = 2;
  LocateBufferPtr.BufferHandle = AMD_MEM_S3_DATA_HANDLE;
  if (HeapLocateBuffer (&LocateBufferPtr, StdHeader) == AGESA_SUCCESS) {
    SpecialHeapHeader = (S3_SPECIAL_CASE_HEAP_HEADER *) LocateBufferPtr.BufferPtr;
    // Get the node ID of the target die.
    NodeID = (UINT8) (PciAddr.Address.Device - 24);
    for (i = 0; i < MAX_NODES_SUPPORTED_C32; i ++) {
      if (SpecialHeapHeader[i].Node == NodeID) {
        // Get the offset in the heap for the target die.
        Offset = SpecialHeapHeader[i].Offset;
        break;
      }
    }
    ASSERT (i < MAX_NODES_SUPPORTED_C32);
    // Restore the value one by one in the sequence of the special case register array.
    if (Offset != 0) {
      for (i = 0; i < (sizeof (SpecialCasePCIRegC32) / sizeof (UINT16)); i ++) {
        PciAddr.Address.Register = SpecialCasePCIRegC32[i];
        Value = *(UINT32 *) (LocateBufferPtr.BufferPtr + Offset + (i << 2));
        MemNS3SetCSRNb (AccessS3SaveWidth32, PciAddr, &Value, StdHeader);
      }
    }
  }
}
Exemple #18
0
/**
 *
 *  Get IDS NV table pointer in the AGESA Heap.
 *
 *  @param[in,out] IdsNvTable   The Pointer of IDS NV Table.
 *  @param[in,out] StdHeader    The Pointer of Standard Header.
 *
 *  @retval AGESA_SUCCESS       Success to get the pointer of NV Table.
 *  @retval AGESA_ERROR         Fail to get the pointer of NV Table.
 **/
AGESA_STATUS
AmdGetIdsNvTable (
  IN OUT   VOID  **IdsNvTable,
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  AGESA_STATUS status;
  LOCATE_HEAP_PTR LocateHeapStructPtr;
  IDS_CONTROL_STRUCT *IdsCtrlPtr;

  LocateHeapStructPtr.BufferHandle = IDS_CONTROL_HANDLE;
  LocateHeapStructPtr.BufferPtr = NULL;
  status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader);
  if (status == AGESA_SUCCESS) {
    IdsCtrlPtr = (IDS_CONTROL_STRUCT *) LocateHeapStructPtr.BufferPtr;
    *IdsNvTable = LocateHeapStructPtr.BufferPtr + IdsCtrlPtr->IdsNvTableOffset;
  }
  return status;
}
Exemple #19
0
/**
 *
 * Read IDS NV value in NV table.
 *
 * It searches the table until the Nv Id is found and return the NV value
 * in the table. Otherwise, return IDS_UNSUPPORTED.
 *
 * @param[in] IdsNvId       IDS NV ID
 * @param[in] NvTablePtr    NV Table pointer.
 * @param[in,out] StdHeader    The Pointer of Standard Header.
 *
 * @retval IDS_UNSUPPORTED  NV ID is not found in the table
 *         Other Value      The NV value
 *
 **/
IDS_STATUS
AmdIdsNvReader (
  IN       UINT16 IdsNvId,
  IN       IDS_NV_ITEM *NvTablePtr,
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  IDS_STATUS Status;
  IDS_NV_ITEM *NvPtr;
  BOOLEAN IgnoreIdsDefault;
  AGESA_STATUS status;
  LOCATE_HEAP_PTR LocateHeapStructPtr;
  IDS_CONTROL_STRUCT *IdsCtrlPtr;

  IgnoreIdsDefault = FALSE;
  Status = IDS_UNSUPPORTED;
  NvPtr = NvTablePtr;

  if (NvPtr != NULL) {
    while (NvPtr->IdsNvId != AGESA_IDS_NV_END) {
      if (NvPtr->IdsNvId == IdsNvId) {
        break;
      } else {
        NvPtr ++;
      }
    }
    if ((NvPtr->IdsNvId != AGESA_IDS_NV_END)) {
      //Get IgnoreIdsDefault from heap
      LocateHeapStructPtr.BufferHandle = IDS_CONTROL_HANDLE;
      LocateHeapStructPtr.BufferPtr = NULL;
      status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader);
      if (status == AGESA_SUCCESS) {
        IdsCtrlPtr = (IDS_CONTROL_STRUCT *) LocateHeapStructPtr.BufferPtr;
        IgnoreIdsDefault = IdsCtrlPtr->IgnoreIdsDefault;
      }

      if (IgnoreIdsDefault || (NvPtr->IdsNvValue != AGESA_IDS_DFT_VAL)) {
        Status = NvPtr->IdsNvValue;
      }
    }
  }
  return Status;
}
Exemple #20
0
AGESA_STATUS
AmdGetIdsImagebase (
  IN OUT   UINT64 *IdsImageBase,
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  AGESA_STATUS status;
  LOCATE_HEAP_PTR LocateHeapStructPtr;
  IDS_CONTROL_STRUCT *IdsCtrlPtr;

  LocateHeapStructPtr.BufferHandle = IDS_CONTROL_HANDLE;
  LocateHeapStructPtr.BufferPtr = NULL;
  status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader);
  if (status == AGESA_SUCCESS) {
    IdsCtrlPtr = (IDS_CONTROL_STRUCT *) LocateHeapStructPtr.BufferPtr;
    *IdsImageBase = IdsCtrlPtr->IdsImageBase;
  }
  return status;
}
Exemple #21
0
/**
 *
 *
 *   This function stores special case register on the heap.
 *
 *     @param[in]   AccessWidth - Access width of the register
 *     @param[in]   Address - address of the CSR register in PCI_ADDR format.
 *     @param[in, out]  *Value - Pointer to the value be read.
 *     @param[in, out]  *ConfigPtr - Pointer to Config handle.
 *     @return         none
 */
VOID
STATIC
MemNS3SetSpecialPCIRegC32 (
  IN       ACCESS_WIDTH AccessWidth,
  IN       PCI_ADDR Address,
  IN       VOID *Value,
  IN OUT   VOID *ConfigPtr
  )
{
  LOCATE_HEAP_PTR LocateBufferPtr;
  UINT8 i;
  UINT8 NodeID;
  UINT8 Offset;
  S3_SPECIAL_CASE_HEAP_HEADER *SpecialHeapHeader;

  Offset = 0;
  LocateBufferPtr.BufferHandle = AMD_MEM_S3_DATA_HANDLE;
  if (HeapLocateBuffer (&LocateBufferPtr, ConfigPtr) == AGESA_SUCCESS) {
    SpecialHeapHeader = (S3_SPECIAL_CASE_HEAP_HEADER *) LocateBufferPtr.BufferPtr;
    // Get the node ID of the target die.
    NodeID = (UINT8) (Address.Address.Device - 24);
    for (i = 0; i < MAX_NODES_SUPPORTED_C32; i ++) {
      if (SpecialHeapHeader[i].Node == NodeID) {
        // Get the offset in the heap for the target die.
        Offset = SpecialHeapHeader[i].Offset;
        break;
      }
    }
    ASSERT (i < MAX_NODES_SUPPORTED_C32);
    // Save the value in the heap at appropriate offset based on the index
    // of the target register in the special case array.
    if (Offset != 0) {
      for (i = 0; i < (sizeof (SpecialCasePCIRegC32) / sizeof (UINT16)); i ++) {
        if (SpecialCasePCIRegC32[i] == Address.Address.Register) {
          *(UINT32 *) (LocateBufferPtr.BufferPtr + Offset + (i << 2)) = *(UINT32 *) Value;
        }
      }
    }
  }
}
Exemple #22
0
/**
 * 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;
}
Exemple #23
0
FCH_DATA_BLOCK*
FchInitLoadDataBlock (
  IN       FCH_INTERFACE        *FchInterface,
  IN       AMD_CONFIG_PARAMS    *StdHeader
  )
{
  FCH_DATA_BLOCK            *FchParams;
  LOCATE_HEAP_PTR           LocHeapPtr;
  AMD_CONFIG_PARAMS         TempStdHeader;
  AGESA_STATUS              AgesaStatus;

  TempStdHeader = *StdHeader;
  TempStdHeader.HeapStatus = HEAP_SYSTEM_MEM;

  // Locate the internal data block via heap manager
  LocHeapPtr.BufferHandle = AMD_FCH_DATA_BLOCK_HANDLE;
  AgesaStatus = HeapLocateBuffer (&LocHeapPtr, &TempStdHeader);
  ASSERT (!AgesaStatus);

  FchParams = (FCH_DATA_BLOCK *) LocHeapPtr.BufferPtr;
  ASSERT (FchParams != NULL);
  FchParams->StdHeader = StdHeader;
  return FchParams;
}
Exemple #24
0
AGESA_STATUS
AmdMemRecovery (
  IN OUT   MEM_DATA_STRUCT *MemPtr
  )
{
  UINT8 Socket;
  UINT8 Module;
  UINT8 i;
  AGESA_STATUS AgesaStatus;
  PCI_ADDR Address;
  MEM_NB_BLOCK NBBlock;
  MEM_TECH_BLOCK TechBlock;
  LOCATE_HEAP_PTR  SocketWithMem;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;


  //
  // Read SPD data
  //
  MemRecSPDDataProcess (MemPtr);

  //
  // Get the socket id from heap.
  //
  SocketWithMem.BufferHandle = AMD_REC_MEM_SOCKET_HANDLE;
  if (HeapLocateBuffer (&SocketWithMem, &MemPtr->StdHeader) == AGESA_SUCCESS) {
    Socket = *(UINT8 *) SocketWithMem.BufferPtr;
  } else {
    ASSERT(FALSE);  // Socket handle not found
    return AGESA_FATAL;
  }

  //
  // Allocate buffer for memory init structures
  //
  AllocHeapParams.RequestedBufferSize = MAX_DIES_PER_SOCKET * sizeof (DIE_STRUCT);
  AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DIE_STRUCT_HANDLE, 0, 0, 0);
  AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
  if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
    ASSERT(FALSE); // Heap allocation failed to allocate Die struct
    return AGESA_FATAL;
  }
  MemPtr->DiesPerSystem = (DIE_STRUCT *)AllocHeapParams.BufferPtr;

  //
  // Discover populated CPUs
  //
  for (Module = 0; Module < MAX_DIES_PER_SOCKET; Module++) {
    if (GetPciAddress ((VOID *)MemPtr, Socket, Module, &Address, &AgesaStatus)) {
      MemPtr->DiesPerSystem[Module].SocketId = Socket;
      MemPtr->DiesPerSystem[Module].DieId = Module;
      MemPtr->DiesPerSystem[Module].PciAddr.AddressValue = Address.AddressValue;
    }
  }

  i = 0;
  while (MemRecNBInstalled[i] != NULL) {
    if (MemRecNBInstalled[i] (&NBBlock, MemPtr, 0) == TRUE) {
      break;
    }
    i++;
  };
  if (MemRecNBInstalled[i] == NULL) {
    ASSERT(FALSE);    // No NB installed
    return AGESA_FATAL;
  }
  MemRecTechInstalled[0] (&TechBlock, &NBBlock);
  NBBlock.TechPtr = &TechBlock;

  return NBBlock.InitRecovery (&NBBlock);
}
Exemple #25
0
/**
 *
 *
 *      This function initialize needed data structures for S3 resume.
 *
 *      @param[in, out]  **S3NBPtr - Pointer to the pointer of northbridge block.
 *      @param[in, out]  *MemPtr - Pointer to MEM_DATA_STRUCT.
 *      @param[in, out]  *mmData - Pointer to MEM_MAIN_DATA_BLOCK.
 *      @param[in]       *StdHeader - Config handle for library and services.
 *
 *      @return          AGESA_STATUS
 *                          - AGESA_ALERT
 *                          - AGESA_FATAL
 *                          - AGESA_SUCCESS
 *                          - AGESA_WARNING
 */
AGESA_STATUS
MemS3InitNB (
  IN OUT   S3_MEM_NB_BLOCK **S3NBPtr,
  IN OUT   MEM_DATA_STRUCT **MemPtr,
  IN OUT   MEM_MAIN_DATA_BLOCK *mmData,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT8 i;
  AGESA_STATUS RetVal;
  LOCATE_HEAP_PTR LocHeap;
  MEM_NB_BLOCK *NBPtr;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;
  UINT8 Die;
  UINT8 DieCount;
  BOOLEAN SkipScan;

  SkipScan = FALSE;
  LocHeap.BufferHandle = AMD_MEM_DATA_HANDLE;
  if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) {
    // NB block has already been constructed by main block.
    // No need to construct it here.
    *MemPtr = (MEM_DATA_STRUCT *)LocHeap.BufferPtr;
    SkipScan = TRUE;
  } else {
    AllocHeapParams.RequestedBufferSize = sizeof (MEM_DATA_STRUCT);
    AllocHeapParams.BufferHandle = AMD_MEM_DATA_HANDLE;
    AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
    if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) != AGESA_SUCCESS) {
      ASSERT(FALSE); // Allocate failed for MEM_DATA_STRUCT
      return AGESA_FATAL;
    }
    *MemPtr = (MEM_DATA_STRUCT *)AllocHeapParams.BufferPtr;
  }
  LibAmdMemCopy (&(*MemPtr)->StdHeader, StdHeader, sizeof (AMD_CONFIG_PARAMS), StdHeader);
  mmData->MemPtr = *MemPtr;

  if (!SkipScan) {
    RetVal = MemSocketScan (mmData);
    if (RetVal == AGESA_FATAL) {
      return RetVal;
    }
  } else {
    // We already have initialize data block, no need to do it again.
    mmData->DieCount = mmData->MemPtr->DieCount;
  }
  DieCount = mmData->DieCount;

  //---------------------------------------------
  //  Creation of NB Block for S3 resume
  //---------------------------------------------
  // Search for AMD_MEM_AUTO_HANDLE on the heap first.
  // Only apply for space on the heap if cannot find AMD_MEM_AUTO_HANDLE on the heap.
  LocHeap.BufferHandle = AMD_MEM_S3_NB_HANDLE;
  if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) {
    // NB block has already been constructed by main block.
    // No need to construct it here.
    *S3NBPtr = (S3_MEM_NB_BLOCK *)LocHeap.BufferPtr;
  } else {
    AllocHeapParams.RequestedBufferSize = (DieCount * (sizeof (S3_MEM_NB_BLOCK)));
    AllocHeapParams.BufferHandle = AMD_MEM_S3_NB_HANDLE;
    AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
    if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) != AGESA_SUCCESS) {
      ASSERT(FALSE); // Could not allocate space for "S3_MEM_NB_BLOCK"
      return AGESA_FATAL;
    }
    *S3NBPtr = (S3_MEM_NB_BLOCK *)AllocHeapParams.BufferPtr;

    LocHeap.BufferHandle = AMD_MEM_AUTO_HANDLE;
    if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) {
      // NB block has already been constructed by main block.
      // No need to construct it here.
      NBPtr = (MEM_NB_BLOCK *)LocHeap.BufferPtr;
    } else {
      AllocHeapParams.RequestedBufferSize = (DieCount * (sizeof (MEM_NB_BLOCK)));
      AllocHeapParams.BufferHandle = AMD_MEM_AUTO_HANDLE;
      AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
      if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) != AGESA_SUCCESS) {
        ASSERT(FALSE); // Allocate failed for "MEM_NB_BLOCK"
        return AGESA_FATAL;
      }
      NBPtr = (MEM_NB_BLOCK *)AllocHeapParams.BufferPtr;
    }
    // Construct each die.
    for (Die = 0; Die < DieCount; Die ++) {
      i = 0;
      ((*S3NBPtr)[Die]).NBPtr = &NBPtr[Die];
      while (memNBInstalled[i].MemS3ResumeConstructNBBlock != 0) {
        if (memNBInstalled[i].MemS3ResumeConstructNBBlock ((VOID *)&((*S3NBPtr)[Die]), *MemPtr, Die)) {
          break;
        }
        i++;
      };
      if (memNBInstalled[i].MemS3ResumeConstructNBBlock == 0) {
        ASSERT(FALSE); // S3 resume NB constructor not found
        return AGESA_FATAL;
      }
    }
  }
  return AGESA_SUCCESS;
}
Exemple #26
0
/**
 *
 *  This function handle errors occur in memory code.
 *
 *
 *     @param[in,out]   *MCTPtr - pointer to DIE_STRUCT.
 *     @param[in,out]   DCT - DCT that needs to be handled.
 *     @param[in,out]   ChipSelMask - Chip select mask that needs to be handled
 *     @param[in,out]   *StdHeader - pointer to AMD_CONFIG_PARAMS
 *
 *     @return          TRUE -  No fatal error occurs.
 *     @return          FALSE - Fatal error occurs.
 */
BOOLEAN
MemErrHandle (
  IN       DIE_STRUCT *MCTPtr,
  IN       UINT8  DCT,
  IN       UINT16  ChipSelMask,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  BOOLEAN ErrorRecovery;
  BOOLEAN IgnoreErr;
  DCT_STRUCT *DCTPtr;
  UINT8 CurrentDCT;
  LOCATE_HEAP_PTR LocHeap;
  MEM_NB_BLOCK *NBPtr;
  MEM_MAIN_DATA_BLOCK mmData;

  DCTPtr = MCTPtr->DctData;
  ErrorRecovery = TRUE;
  IgnoreErr = FALSE;
  IDS_OPTION_HOOK (IDS_MEM_ERROR_RECOVERY, &ErrorRecovery, StdHeader);

  if (ErrorRecovery) {
    if (DCT == EXCLUDE_ALL_DCT) {
      // Exclude all DCTs on a node
      for (CurrentDCT = 0; CurrentDCT < MCTPtr->DctCount; CurrentDCT++) {
        DCTPtr[CurrentDCT].Timings.CsTestFail = DCTPtr[CurrentDCT].Timings.CsPresent;
      }
    } else if (ChipSelMask == EXCLUDE_ALL_CHIPSEL) {
      // Exclude the specified DCT
      DCTPtr[DCT].Timings.CsTestFail = DCTPtr[DCT].Timings.CsPresent;
    } else {
      // Exclude the chip select that has been marked out
      DCTPtr[DCT].Timings.CsTestFail |= ChipSelMask & DCTPtr[DCT].Timings.CsPresent;
      IDS_OPTION_HOOK (IDS_LOADCARD_ERROR_RECOVERY, &DCTPtr[DCT], StdHeader);
    }

    // Exclude the failed dimm to recovery from error
    if (MCTPtr->NodeMemSize != 0) {
      LocHeap.BufferHandle = AMD_MEM_AUTO_HANDLE;
      if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) {
        // NB block has already been constructed by main block.
        // No need to construct it here.
        NBPtr = (MEM_NB_BLOCK *)LocHeap.BufferPtr;
        if (!NBPtr->SharedPtr->NodeMap[MCTPtr->NodeId].IsValid) {
          // Memory map has not been calculated, no need to remap memory across node here.
          // Only need to remap memory within the node.
          NBPtr = &NBPtr[MCTPtr->NodeId];
          NBPtr->FeatPtr->ExcludeDIMM (NBPtr);
        } else {
          // Need to remap memory across the whole system.
          mmData.MemPtr = NBPtr->MemPtr;
          mmData.mmSharedPtr = NBPtr->SharedPtr;
          mmData.NBPtr = NBPtr;
          mmData.TechPtr = (MEM_TECH_BLOCK *) (&NBPtr[NBPtr->MemPtr->DieCount]);
          mmData.DieCount = NBPtr->MemPtr->DieCount;
          if (!MemFeatMain.ExcludeDIMM (&mmData)) {
            return FALSE;
          }
        }
      }
      // If allocation fails, that means the code is not running at BSP.
      // Parallel training is in process.
      // Remap for parallel training will be done when control returns to BSP.
    }
    return TRUE;
  } else {
    IDS_OPTION_HOOK (IDS_MEM_IGNORE_ERROR, &IgnoreErr, StdHeader);
    if (IgnoreErr) {
      return TRUE;
    }
    SetMemError (AGESA_FATAL, MCTPtr);
    ASSERT(FALSE); // ErrorRecovery is FALSE
    return FALSE;
  }
}
Exemple #27
0
AGESA_STATUS
AmdIdentifyDimm (
  IN OUT   AMD_IDENTIFY_DIMM *AmdDimmIdentify
  )
{
  UINT8 i;
  AGESA_STATUS RetVal;
  MEM_MAIN_DATA_BLOCK mmData;             // Main Data block
  MEM_NB_BLOCK *NBPtr;
  MEM_DATA_STRUCT MemData;
  LOCATE_HEAP_PTR LocHeap;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;
  UINT8 Node;
  UINT8 Dct;
  UINT8 Die;
  UINT8 DieCount;

  LibAmdMemCopy (&(MemData.StdHeader), &(AmdDimmIdentify->StdHeader), sizeof (AMD_CONFIG_PARAMS), &(AmdDimmIdentify->StdHeader));
  mmData.MemPtr = &MemData;
  RetVal = MemSocketScan (&mmData);
  if (RetVal == AGESA_FATAL) {
    return RetVal;
  }
  DieCount = mmData.DieCount;

  // Search for AMD_MEM_AUTO_HANDLE on the heap first.
  // Only apply for space on the heap if cannot find AMD_MEM_AUTO_HANDLE on the heap.
  LocHeap.BufferHandle = AMD_MEM_AUTO_HANDLE;
  if (HeapLocateBuffer (&LocHeap, &AmdDimmIdentify->StdHeader) == AGESA_SUCCESS) {
    // NB block has already been constructed by main block.
    // No need to construct it here.
    NBPtr = (MEM_NB_BLOCK *)LocHeap.BufferPtr;
    mmData.NBPtr = NBPtr;
  } else {
    AllocHeapParams.RequestedBufferSize = (DieCount * (sizeof (MEM_NB_BLOCK)));
    AllocHeapParams.BufferHandle = AMD_MEM_AUTO_HANDLE;
    AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
    if (HeapAllocateBuffer (&AllocHeapParams, &AmdDimmIdentify->StdHeader) != AGESA_SUCCESS) {
      PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_IDENTIFY_DIMM_MEM_NB_BLOCK, 0, 0, 0, 0, &AmdDimmIdentify->StdHeader);
      ASSERT(FALSE); // Could not allocate heap space for NB block for Identify DIMM
      return AGESA_FATAL;
    }
    NBPtr = (MEM_NB_BLOCK *)AllocHeapParams.BufferPtr;
    mmData.NBPtr = NBPtr;
    // Construct each die.
    for (Die = 0; Die < DieCount; Die ++) {
      i = 0;
      while (memNBInstalled[i].MemIdentifyDimmConstruct != 0) {
        if (memNBInstalled[i].MemIdentifyDimmConstruct (&NBPtr[Die], &MemData, Die)) {
          break;
        }
        i++;
      };
      if (memNBInstalled[i].MemIdentifyDimmConstruct == 0) {
        PutEventLog (AGESA_FATAL, MEM_ERROR_NO_CONSTRUCTOR_FOR_IDENTIFY_DIMM, Die, 0, 0, 0, &AmdDimmIdentify->StdHeader);
        ASSERT(FALSE); // No Identify DIMM constructor found
        return AGESA_FATAL;
      }
    }
  }

  i = 0;
  while (memNBInstalled[i].MemIdentifyDimmConstruct != 0) {
    if ((RetVal = memNBInstalled[i].MemTransSysAddrToCs (AmdDimmIdentify, &mmData)) == AGESA_SUCCESS) {
      // Translate Node, DCT and Chip select number to Socket, Channel and Dimm number.
      Node = AmdDimmIdentify->SocketId;
      Dct = AmdDimmIdentify->MemChannelId;
      AmdDimmIdentify->SocketId = MemData.DiesPerSystem[Node].SocketId;
      AmdDimmIdentify->MemChannelId = NBPtr[Node].GetSocketRelativeChannel (&NBPtr[Node], Dct, 0);
      AmdDimmIdentify->DimmId = AmdDimmIdentify->ChipSelect / 2;
      AmdDimmIdentify->ChipSelect %= 2;
      break;
    }
    i++;
  };

  return RetVal;
}
Exemple #28
0
/**
 *  Save and Restore or Initialize the content of the mailbox registers.
 *
 * The registers used for AP mailbox should have the content related to their function
 * preserved.
 *
 * @param[in]    EntryPoint         Timepoint designator.
 * @param[in]    PlatformConfig     Contains the runtime modifiable feature input data.
 * @param[in]    StdHeader          Config Handle for library, services.
 *
 * @return       AGESA_SUCCESS      Always succeeds.
 *
 */
AGESA_STATUS
STATIC
PreserveMailboxes (
  IN       UINT64                 EntryPoint,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  PRESERVE_MAILBOX_FAMILY_SERVICES *FamilySpecificServices;
  UINT32 Socket;
  UINT32 Module;
  PCI_ADDR BaseAddress;
  PCI_ADDR MailboxRegister;
  PCI_ADDR *NextRegister;
  AGESA_STATUS IgnoredStatus;
  AGESA_STATUS HeapStatus;
  UINT32 Value;
  ALLOCATE_HEAP_PARAMS AllocateParams;
  LOCATE_HEAP_PTR LocateParams;
  UINT32 RegisterEntryIndex;

  BaseAddress.AddressValue = ILLEGAL_SBDFO;

  if (EntryPoint == CPU_FEAT_AFTER_COHERENT_DISCOVERY) {
    // The save step.  Save either the register content or zero (for cold boot, if family specifies that).
    AllocateParams.BufferHandle = PRESERVE_MAIL_BOX_HANDLE;
    AllocateParams.RequestedBufferSize = (sizeof (UINT32) * (MAX_PRESERVE_REGISTER_ENTRIES * (MAX_SOCKETS * MAX_DIES)));
    AllocateParams.Persist = HEAP_SYSTEM_MEM;
    HeapStatus = HeapAllocateBuffer (&AllocateParams, StdHeader);
    ASSERT ((HeapStatus == AGESA_SUCCESS) && (AllocateParams.BufferPtr != NULL));
    LibAmdMemFill (AllocateParams.BufferPtr, 0xFF, AllocateParams.RequestedBufferSize, StdHeader);
    RegisterEntryIndex = 0;
    for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
      for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
        if (GetPciAddress (StdHeader, Socket, Module, &BaseAddress, &IgnoredStatus)) {
          GetFeatureServicesOfSocket (&PreserveMailboxFamilyServiceTable, Socket, (const VOID **)&FamilySpecificServices, StdHeader);
          ASSERT (FamilySpecificServices != NULL);
          NextRegister = FamilySpecificServices->RegisterList;
          while (NextRegister->AddressValue != ILLEGAL_SBDFO) {
            ASSERT (RegisterEntryIndex <
                    (MAX_PRESERVE_REGISTER_ENTRIES * GetPlatformNumberOfSockets () * GetPlatformNumberOfModules ()));
            if (FamilySpecificServices->IsZeroOnCold && (!IsWarmReset (StdHeader))) {
              Value = 0;
            } else {
              MailboxRegister = BaseAddress;
              MailboxRegister.Address.Function = NextRegister->Address.Function;
              MailboxRegister.Address.Register = NextRegister->Address.Register;
              LibAmdPciRead (AccessWidth32, MailboxRegister, &Value, StdHeader);
            }
            (* (MAILBOX_REGISTER_SAVE_ENTRY) AllocateParams.BufferPtr) [RegisterEntryIndex] = Value;
            RegisterEntryIndex++;
            NextRegister++;
          }
        }
      }
    }
  } else if ((EntryPoint == CPU_FEAT_INIT_LATE_END) || (EntryPoint == CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) {
    // The restore step.  Just write out the saved content in the buffer.
    LocateParams.BufferHandle = PRESERVE_MAIL_BOX_HANDLE;
    HeapStatus = HeapLocateBuffer (&LocateParams, StdHeader);
    ASSERT ((HeapStatus == AGESA_SUCCESS) && (LocateParams.BufferPtr != NULL));
    RegisterEntryIndex = 0;
    for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
      for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
        if (GetPciAddress (StdHeader, Socket, Module, &BaseAddress, &IgnoredStatus)) {
          GetFeatureServicesOfSocket (&PreserveMailboxFamilyServiceTable, Socket, (const VOID **)&FamilySpecificServices, StdHeader);
          NextRegister = FamilySpecificServices->RegisterList;
          while (NextRegister->AddressValue != ILLEGAL_SBDFO) {
            ASSERT (RegisterEntryIndex <
                    (MAX_PRESERVE_REGISTER_ENTRIES * GetPlatformNumberOfSockets () * GetPlatformNumberOfModules ()));
            MailboxRegister = BaseAddress;
            MailboxRegister.Address.Function = NextRegister->Address.Function;
            MailboxRegister.Address.Register = NextRegister->Address.Register;
            Value = (* (MAILBOX_REGISTER_SAVE_ENTRY) LocateParams.BufferPtr) [RegisterEntryIndex];
            LibAmdPciWrite (AccessWidth32, MailboxRegister, &Value, StdHeader);
            RegisterEntryIndex++;
            NextRegister++;
          }
        }
      }
    }
    HeapStatus = HeapDeallocateBuffer (PRESERVE_MAIL_BOX_HANDLE, StdHeader);
  }
  return AGESA_SUCCESS;
}