/** * Print formated string to HDTOUT * * @param[in] Buffer - Point to input buffer * @param[in] BufferSize - Buffer size * @param[in] debugPrintPrivate - Option * **/ STATIC VOID AmdIdsHdtOutPrint ( IN CHAR8 *Buffer, IN UINTN BufferSize, IN IDS_DEBUG_PRINT_PRIVATE_DATA *debugPrintPrivate ) { HDTOUT_HEADER *HdtoutHeaderPtr; if (AmdIdsHdtoutGetHeader (&HdtoutHeaderPtr, NULL)) { //Print Function if (HdtoutHeaderPtr->PrintCtrl == HDTOUT_PRINTCTRL_ON) { if (HdtoutHeaderPtr->OutBufferMode == HDTOUT_BUFFER_MODE_ON) { AmdIdsHdtOutPrintWithBuffer (Buffer, BufferSize, HdtoutHeaderPtr); } else { IdsOutPort (HDTOUT_PRINT, (UINT32) (UINTN) Buffer, (UINT32) BufferSize); } } //Check BreakPoint if (HdtoutHeaderPtr->NumBreakpointUnit) { AmdIdsHdtOutBreakPoint (Buffer, BufferSize, HdtoutHeaderPtr); if (debugPrintPrivate->saveContext) { AmdIdsHdtOutSaveContext (Buffer, BufferSize, HdtoutHeaderPtr); debugPrintPrivate->saveContext = FALSE; } } } else { //No HDTOUT header found print directly without buffer IdsOutPort (HDTOUT_PRINT, (UINT32) (UINTN) Buffer, (UINT32) BufferSize); } }
/** * * IDS Performance function for Output to HDT. * * Invoke communications with the HDT environment to allow the user to issue * debug commands. If the sign = 0x0, HDT Control Register will be initialized to * catch the special I/O for HDT_OUT. Otherwise, it will inform HDT script * function what is meaning for the value to output to HDT. * * @param[in] Command HDT_OUT Command. * @param[in] Data The Data to output to HDT. * @param[in,out] StdHeader The Pointer of AGESA Header * **/ STATIC VOID IdsPerfHdtOut ( IN UINT16 Command, IN UINT32 Data, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { IdsOutPort (((UINT32)Command << 16) | 0x8899, Data, 0); }
VOID IdsPerfHdtOut ( IN UINT16 Command, IN UINT32 Data, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { IdsOutPort (HDTOUT_TIME_ANALYSE, Data, 0); }
/** * Exit function for HDT out Function for each cores * * @param[in] Ignored no used * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. * * @retval AGESA_SUCCESS Success * @retval AGESA_ERROR meet some error * **/ STATIC AGESA_STATUS AmdIdsHdtOutExitCoreTask ( IN VOID *Ignored, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { HDTOUT_HEADER *HdtoutHeaderPtr; if (AmdIdsHdtoutGetHeader (&HdtoutHeaderPtr, StdHeader)) { if ((HdtoutHeaderPtr->PrintCtrl == HDTOUT_PRINTCTRL_ON) && (HdtoutHeaderPtr->OutBufferMode == HDTOUT_BUFFER_MODE_ON)) { IdsOutPort (HDTOUT_PRINT, (UINTN)HdtoutHeaderPtr->Data, HdtoutHeaderPtr->DataIndex); } } IdsOutPort (HDTOUT_EXIT, (UINTN)HdtoutHeaderPtr, 0); AmdIdsHdtOutRegisterRestore (StdHeader); return AGESA_SUCCESS; }
/** * * 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; } } } }
/** * Print formated string with accerate buffer * Flow out only when buffer will full * * @param[in] Buffer - Point to input buffer * @param[in] BufferSize - Buffer size * @param[in] HdtoutHeaderPtr - Point to Hdtout Header * **/ STATIC VOID AmdIdsHdtOutPrintWithBuffer ( IN CHAR8 *Buffer, IN UINTN BufferSize, IN HDTOUT_HEADER *HdtoutHeaderPtr ) { if ((HdtoutHeaderPtr == NULL) || (Buffer == NULL)) { ASSERT (FALSE); return; } while (BufferSize--) { if (HdtoutHeaderPtr->DataIndex >= HdtoutHeaderPtr->BufferSize) { //Flow out current buffer, and clear the index IdsOutPort (HDTOUT_PRINT, (UINT32) (UINTN) &HdtoutHeaderPtr->Data[0], HdtoutHeaderPtr->BufferSize); HdtoutHeaderPtr->DataIndex = 0; } HdtoutHeaderPtr->Data[HdtoutHeaderPtr->DataIndex++] = *(Buffer++); } }
/** * Process HDTOUT breakpoint * * @param[in] Buffer - Point to input buffer * @param[in] BufferSize - Buffer size * @param[in] HdtoutHeaderPtr - Point to Hdtout Header * **/ STATIC VOID AmdIdsHdtOutBreakPoint ( IN CHAR8 *Buffer, IN UINTN BufferSize, IN HDTOUT_HEADER *HdtoutHeaderPtr ) { UINT32 numBp; BREAKPOINT_UNIT *Pbpunit; BOOLEAN isMatched; UINT32 i; Pbpunit = (BREAKPOINT_UNIT *) &HdtoutHeaderPtr->BreakpointList[0]; numBp = HdtoutHeaderPtr->NumBreakpointUnit; for (;;) { if (Pbpunit->AndFlag == IDS_HDTOUT_BP_AND_ON) { isMatched = TRUE; do { isMatched &= AmdIdsHdtOutBreakPointUnit (&Pbpunit, &numBp, HdtoutHeaderPtr, Buffer); } while ((Pbpunit->AndFlag == IDS_HDTOUT_BP_AND_ON) && (isMatched == TRUE) && (numBp > 0)); //Next one is IDS_HDTOUT_BP_AND_OFF if (numBp > 0) { if (isMatched == TRUE) { isMatched &= AmdIdsHdtOutBreakPointUnit (&Pbpunit, &numBp, HdtoutHeaderPtr, Buffer); } else { Pbpunit++; numBp--; } } } else { isMatched = AmdIdsHdtOutBreakPointUnit (&Pbpunit, &numBp, HdtoutHeaderPtr, Buffer); } if ((isMatched == TRUE) || (numBp == 0)) { break; } } //Do action if (isMatched) { // AmdIdsSerialPrint (Buffer, BufferSize, NULL); Pbpunit--; switch (Pbpunit->Action) { case HDTOUT_BP_ACTION_HALT: i = (UINT32) (Pbpunit - ((BREAKPOINT_UNIT *) &HdtoutHeaderPtr->BreakpointList[0])); IdsOutPort (HDTOUT_BREAKPOINT, (UINT32) (UINTN) Buffer, ( i << 16) | (UINT32) BufferSize); break; case HDTOUT_BP_ACTION_PRINTON: if (HdtoutHeaderPtr->PrintCtrl != 1) { HdtoutHeaderPtr->PrintCtrl = 1; if (HdtoutHeaderPtr->OutBufferMode == HDTOUT_BUFFER_MODE_ON) { AmdIdsHdtOutPrintWithBuffer (Buffer, BufferSize, HdtoutHeaderPtr); } else { IdsOutPort (HDTOUT_PRINT, (UINT32) (UINTN) Buffer, (UINT32) BufferSize); } } break; case HDTOUT_BP_ACTION_PRINTOFF: if (HdtoutHeaderPtr->PrintCtrl != 0) { HdtoutHeaderPtr->PrintCtrl = 0; IdsOutPort (HDTOUT_PRINT, (UINT32) (UINTN) Buffer, (UINT32)BufferSize); } break; default: ASSERT (FALSE); } } }
/** * * 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); } } }