serialstatuscode.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 886 行 · 第 1/4 页

C
886
字号
Arguments:

  OutputString - Ascii string to print to serial port.

Returns:

  None

--*/
{
  EFI_STATUS  Status;

  Status = EFI_SUCCESS;

  for ( ; *OutputString != 0; OutputString++) {
    DebugSerialWrite (*OutputString);
  }
}

EFI_STATUS
EFIAPI 
SerialReportStatusCode (
  IN EFI_STATUS_CODE_TYPE     CodeType,
  IN EFI_STATUS_CODE_VALUE    Value,
  IN UINT32                   Instance,
  IN EFI_GUID                 *CallerId,
  IN EFI_STATUS_CODE_DATA     *Data OPTIONAL
  )
/*++

Routine Description:

  Provide a serial port print

Arguments:

  PeiServices - General purpose services available to every PEIM.
    
Returns:

  Status -  EFI_SUCCESS if the interface could be successfully
            installed

--*/
{
  CHAR8                   Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
  UINT32                  LineNumber;
  CHAR8                   *Filename;
  CHAR8                   *Description;
  CHAR8                   *Format;
  VA_LIST                 Marker;
  UINT32                  ErrorLevel;
  UINTN                   CharCount;

  Buffer[0] = '\0';

  if (ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
    //
    // Processes PEI_ASSERT ()
    //
    ASPrint (
      Buffer,
      EFI_STATUS_CODE_DATA_MAX_SIZE,
      "\nPEI_ASSERT!: %a (%d): %a\n",
      Filename,
      LineNumber,
      Description
      );

  } else if (ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
    //
    // Process PEI_DEBUG () macro to Serial
    //
    AvSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker);

  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) { 
    //
    // Process Errors
    //
    CharCount = ASPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, "ERROR: C%x:V%x I%x", CodeType, Value, Instance);
    //
    // Make sure we don't try to print values that weren't intended to be printed, especially NULL GUID pointers.
    //
    if (CallerId) {
      CharCount += ASPrint (&Buffer[CharCount - 1], (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof(Buffer[0]) * CharCount)), " %g", CallerId);
    }
    if (Data) {
      CharCount += ASPrint (&Buffer[CharCount - 1], (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof(Buffer[0]) * CharCount)), " %x", Data);
    }
    CharCount += ASPrint (&Buffer[CharCount - 1], (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof(Buffer[0]) * CharCount)), "\n");

  }

  if (Buffer[0] != '\0') {
    //
    // Callout to platform Lib function to do print.
    //
    DebugSerialPrint (Buffer);
  }

  //
  // Debug code to display human readable code information.
  //
    {
      CHAR8       *SeverityToken;
      CHAR8       *SubClassToken;
      CHAR8       *OperationToken;

      if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) { 
        //
        // Get the severity token
        //
        MatchString (
          mSeverityToken,
          (CodeType & EFI_STATUS_CODE_SEVERITY_MASK),
          &SeverityToken
          );
    
        //
        // Get the Class/SubClass token
        //
        MatchString (
          mClassSubClassToken,
          (Value & (EFI_STATUS_CODE_CLASS_MASK | EFI_STATUS_CODE_SUBCLASS_MASK)),
          &SubClassToken
          );
    
        //
        // Get the operation token
        //
        MatchString (
          mOperationToken,
          (Value & (EFI_STATUS_CODE_CLASS_MASK | EFI_STATUS_CODE_SUBCLASS_MASK | EFI_STATUS_CODE_OPERATION_MASK)),
          &OperationToken
          );
    
        //
        // Concatenate the instance
        //
        ASPrint (
          Buffer,
          EFI_STATUS_CODE_DATA_MAX_SIZE,
          "%a:%a:%a:%d\n",
          SeverityToken,
          SubClassToken,
          OperationToken,
          Instance
          );

        DebugSerialPrint (Buffer);
      }
    }

  return EFI_SUCCESS;
}


VOID
InstallSerialStatusCode (
  IN EFI_REPORT_STATUS_CODE    *ReportStatusCode
  )
/*++

Routine Description:

  Initialize Serial Port

    The Baud Rate Divisor registers are programmed and the LCR 
    is used to configure the communications format. Hard coded
    UART config comes from globals in DebugSerialPlatform lib.

Arguments: 

  None

Returns: 

  None

--*/
{
  UINTN           Divisor;
  UINT8           OutputData;
  UINT8           Data;

  //
  // Some init is done by the platform status code initialization.
  //
  
  //
  // Map 5..8 to 0..3
  //
  Data = (UINT8) (gData - (UINT8)5);

  //
  // Calculate divisor for baud generator
  //
  Divisor = 115200 / gBps; 
  
  //
  // Set communications format
  //
  OutputData = (UINT8)((DLAB << 7) | ((gBreakSet << 6) | ((gParity << 3) | ((gStop << 2) | Data))));
  CpuIoWrite8 (gComBase + LCR_OFFSET, OutputData);

  //
  // Configure baud rate
  //
  CpuIoWrite8 (gComBase + BAUD_HIGH_OFFSET, (UINT8)(Divisor >> 8));
  CpuIoWrite8 (gComBase + BAUD_LOW_OFFSET, (UINT8)(Divisor & 0xff));

  //
  // Switch back to bank 0
  //
  OutputData = (UINT8)((~DLAB<<7)|((gBreakSet<<6)|((gParity<<3)|((gStop<<2)| Data))));
  CpuIoWrite8 (gComBase + LCR_OFFSET, OutputData);

  *ReportStatusCode = SerialReportStatusCode;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?