/** * 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; }
/** * IdsOptionCallout * * Description * Call the host environment interface to provide a user hook opportunity. * * @param[in] CallOutId This parameter indicates the IDS Call-Out-function desired. * @param[in,out] DataPtr The pointer for callout function use * @param[in,out] StdHeader Config handle for library and services * * @retval AGESA_SUCCESS Success * @retval AGESA_ERROR meet some error * */ AGESA_STATUS IdsOptionCallout ( IN UINTN CallOutId, IN OUT VOID *DataPtr, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { IDS_CALLOUT_STRUCT IdsCalloutData; IDS_NV_ITEM NullEntry; NullEntry.IdsNvId = 0xFFFF; NullEntry.IdsNvValue = 0xFFFF; IdsCalloutData.StdHeader = *StdHeader; IdsCalloutData.IdsNvPtr = &NullEntry; IdsCalloutData.Reserved = (UINTN) DataPtr; return AgesaGetIdsData (CallOutId, &IdsCalloutData); }
AGESA_STATUS AmdIdsCtrlInitialize ( IN OUT AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS status; 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; //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) { NvTable = IdsCalloutData.IdsNvPtr; NvPtr = NvTable; while (NvPtr->IdsNvId != AGESA_IDS_NV_END) { 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->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 { status = AGESA_ERROR; } AGESA_TESTPOINT (TpIfAfterGetIdsData, StdHeader); return status; }