Home | History | Annotate | Download | only in RuntimeDxe
      1 /** @file
      2   Serial I/O status code reporting worker.
      3 
      4   Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "StatusCodeRuntimeDxe.h"
     16 
     17 /**
     18   Convert status code value and extended data to readable ASCII string, send string to serial I/O device.
     19 
     20   @param  CodeType         Indicates the type of status code being reported.
     21   @param  Value            Describes the current status of a hardware or software entity.
     22                            This included information about the class and subclass that is used to
     23                            classify the entity as well as an operation.
     24   @param  Instance         The enumeration of a hardware or software entity within
     25                            the system. Valid instance numbers start with 1.
     26   @param  CallerId         This optional parameter may be used to identify the caller.
     27                            This parameter allows the status code driver to apply different rules to
     28                            different callers.
     29   @param  Data             This optional parameter may be used to pass additional data.
     30 
     31   @retval EFI_SUCCESS      Status code reported to serial I/O successfully.
     32   @retval EFI_DEVICE_ERROR EFI serial device cannot work after ExitBootService() is called.
     33   @retval EFI_DEVICE_ERROR EFI serial device cannot work with TPL higher than TPL_CALLBACK.
     34 
     35 **/
     36 EFI_STATUS
     37 SerialStatusCodeReportWorker (
     38   IN EFI_STATUS_CODE_TYPE     CodeType,
     39   IN EFI_STATUS_CODE_VALUE    Value,
     40   IN UINT32                   Instance,
     41   IN EFI_GUID                 *CallerId,
     42   IN EFI_STATUS_CODE_DATA     *Data OPTIONAL
     43   )
     44 {
     45   CHAR8           *Filename;
     46   CHAR8           *Description;
     47   CHAR8           *Format;
     48   CHAR8           Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
     49   UINT32          ErrorLevel;
     50   UINT32          LineNumber;
     51   UINTN           CharCount;
     52   BASE_LIST       Marker;
     53 
     54   Buffer[0] = '\0';
     55 
     56   if (Data != NULL &&
     57       ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
     58     //
     59     // Print ASSERT() information into output buffer.
     60     //
     61     CharCount = AsciiSPrint (
     62                   Buffer,
     63                   sizeof (Buffer),
     64                   "\n\rDXE_ASSERT!: %a (%d): %a\n\r",
     65                   Filename,
     66                   LineNumber,
     67                   Description
     68                   );
     69   } else if (Data != NULL &&
     70              ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
     71     //
     72     // Print DEBUG() information into output buffer.
     73     //
     74     CharCount = AsciiBSPrint (
     75                   Buffer,
     76                   sizeof (Buffer),
     77                   Format,
     78                   Marker
     79                   );
     80   } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
     81     //
     82     // Print ERROR information into output buffer.
     83     //
     84     CharCount = AsciiSPrint (
     85                   Buffer,
     86                   sizeof (Buffer),
     87                   "ERROR: C%08x:V%08x I%x",
     88                   CodeType,
     89                   Value,
     90                   Instance
     91                   );
     92 
     93     if (CallerId != NULL) {
     94       CharCount += AsciiSPrint (
     95                      &Buffer[CharCount],
     96                      (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
     97                      " %g",
     98                      CallerId
     99                      );
    100     }
    101 
    102     if (Data != NULL) {
    103       CharCount += AsciiSPrint (
    104                      &Buffer[CharCount],
    105                      (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
    106                      " %x",
    107                      Data
    108                      );
    109     }
    110 
    111     CharCount += AsciiSPrint (
    112                    &Buffer[CharCount],
    113                    (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
    114                    "\n\r"
    115                    );
    116   } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
    117     //
    118     // Print PROGRESS information into output buffer.
    119     //
    120     CharCount = AsciiSPrint (
    121                   Buffer,
    122                   sizeof (Buffer),
    123                   "PROGRESS CODE: V%08x I%x\n\r",
    124                   Value,
    125                   Instance
    126                   );
    127   } else if (Data != NULL &&
    128              CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeStringGuid) &&
    129              ((EFI_STATUS_CODE_STRING_DATA *) Data)->StringType == EfiStringAscii) {
    130     //
    131     // EFI_STATUS_CODE_STRING_DATA
    132     //
    133     CharCount = AsciiSPrint (
    134                   Buffer,
    135                   sizeof (Buffer),
    136                   "%a\n\r",
    137                   ((EFI_STATUS_CODE_STRING_DATA *) Data)->String.Ascii
    138                   );
    139   } else {
    140     //
    141     // Code type is not defined.
    142     //
    143     CharCount = AsciiSPrint (
    144                   Buffer,
    145                   sizeof (Buffer),
    146                   "Undefined: C%08x:V%08x I%x\n\r",
    147                   CodeType,
    148                   Value,
    149                   Instance
    150                   );
    151   }
    152 
    153   //
    154   // Call SerialPort Lib function to do print.
    155   //
    156   SerialPortWrite ((UINT8 *) Buffer, CharCount);
    157 
    158   return EFI_SUCCESS;
    159 }
    160 
    161