/** * 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; }
/** * * Exit function for HDT out Function. * * 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 AmdIdsHdtOutExit ( IN OUT AMD_CONFIG_PARAMS *StdHeader ) { IDSAPLATETASK IdsApLateTask; if (AmdIdsHdtOutSupport ()) { IdsApLateTask.ApTask = (PF_IDS_AP_TASK) AmdIdsHdtOutExitCoreTask; IdsApLateTask.ApTaskPara = NULL; IdsAgesaRunFcnOnAllCoresLate (&IdsApLateTask, StdHeader); HeapDeallocateBuffer (IDS_HDT_OUT_BUFFER_HANDLE, StdHeader); } }
/** * * 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); } } }
/** * * Flush all HDTOUT buffer data before HOB transfer * * @param[in,out] StdHeader The Pointer of AGESA Header * **/ VOID AmdIdsHdtOutBufferFlush ( IN OUT AMD_CONFIG_PARAMS *StdHeader ) { HDTOUT_HEADER *HdtoutHeaderPtr ; if (AmdIdsHdtOutSupport ()) { if (AmdIdsHdtoutGetHeader (&HdtoutHeaderPtr, StdHeader)) { if ((HdtoutHeaderPtr->PrintCtrl == HDTOUT_PRINTCTRL_ON) && (HdtoutHeaderPtr->OutBufferMode == HDTOUT_BUFFER_MODE_ON)) { IdsOutPort (HDTOUT_PRINT, (UINTN)HdtoutHeaderPtr->Data, HdtoutHeaderPtr->DataIndex); HdtoutHeaderPtr->DataIndex = 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 AmdIdsHdtOutS3ApExit ( IN OUT AMD_CONFIG_PARAMS *StdHeader ) { AP_TASK TaskPtr; UINT32 Ignored; UINT32 BscSocket; UINT32 BscCoreNum; UINT32 Core; UINT32 Socket; UINT32 NumberOfSockets; UINT32 NumberOfCores; AGESA_STATUS IgnoredSts; if (AmdIdsHdtOutSupport ()) { // run code on all APs except BSP TaskPtr.FuncAddress.PfApTaskI = (PF_AP_TASK_I)AmdIdsHdtOutExitCoreTask; TaskPtr.DataTransfer.DataSizeInDwords = 0; TaskPtr.DataTransfer.DataPtr = NULL; TaskPtr.DataTransfer.DataTransferFlags = 0; TaskPtr.ExeFlags = WAIT_FOR_CORE; NumberOfSockets = GetPlatformNumberOfSockets (); IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts); for (Socket = 0; Socket < NumberOfSockets; Socket++) { if (IsProcessorPresent (Socket, StdHeader)) { if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { for (Core = 0; Core < NumberOfCores; Core++) { if ((Socket != BscSocket) || (Core != BscCoreNum)) { ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, &TaskPtr, StdHeader); } } } } } } }
/** * * 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); } } }