Home | History | Annotate | Download | only in Smm
      1 /** @file
      2   Serial I/O status code reporting worker.
      3 
      4   Copyright (c) 2009 - 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 "StatusCodeHandlerSmm.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 EFIAPI
     38 SerialStatusCodeReportWorker (
     39   IN EFI_STATUS_CODE_TYPE     CodeType,
     40   IN EFI_STATUS_CODE_VALUE    Value,
     41   IN UINT32                   Instance,
     42   IN EFI_GUID                 *CallerId,
     43   IN EFI_STATUS_CODE_DATA     *Data OPTIONAL
     44   )
     45 {
     46   CHAR8           *Filename;
     47   CHAR8           *Description;
     48   CHAR8           *Format;
     49   CHAR8           Buffer[MAX_DEBUG_MESSAGE_LENGTH];
     50   UINT32          ErrorLevel;
     51   UINT32          LineNumber;
     52   UINTN           CharCount;
     53   BASE_LIST       Marker;
     54 
     55   Buffer[0] = '\0';
     56 
     57   if (Data != NULL &&
     58       ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
     59     //
     60     // Print ASSERT() information into output buffer.
     61     //
     62     CharCount = AsciiSPrint (
     63                   Buffer,
     64                   sizeof (Buffer),
     65                   "\n\rDXE_ASSERT!: %a (%d): %a\n\r",
     66                   Filename,
     67                   LineNumber,
     68                   Description
     69                   );
     70   } else if (Data != NULL &&
     71              ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
     72     //
     73     // Print DEBUG() information into output buffer.
     74     //
     75     CharCount = AsciiBSPrint (
     76                   Buffer,
     77                   sizeof (Buffer),
     78                   Format,
     79                   Marker
     80                   );
     81   } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
     82     //
     83     // Print ERROR information into output buffer.
     84     //
     85     CharCount = AsciiSPrint (
     86                   Buffer,
     87                   sizeof (Buffer),
     88                   "ERROR: C%08x:V%08x I%x",
     89                   CodeType,
     90                   Value,
     91                   Instance
     92                   );
     93     ASSERT (CharCount > 0);
     94 
     95     if (CallerId != NULL) {
     96       CharCount += AsciiSPrint (
     97                      &Buffer[CharCount],
     98                      (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
     99                      " %g",
    100                      CallerId
    101                      );
    102     }
    103 
    104     if (Data != NULL) {
    105       CharCount += AsciiSPrint (
    106                      &Buffer[CharCount],
    107                      (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
    108                      " %x",
    109                      Data
    110                      );
    111     }
    112 
    113     CharCount += AsciiSPrint (
    114                    &Buffer[CharCount],
    115                    (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
    116                    "\n\r"
    117                    );
    118   } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
    119     //
    120     // Print PROGRESS information into output buffer.
    121     //
    122     CharCount = AsciiSPrint (
    123                   Buffer,
    124                   sizeof (Buffer),
    125                   "PROGRESS CODE: V%08x I%x\n\r",
    126                   Value,
    127                   Instance
    128                   );
    129   } else if (Data != NULL &&
    130              CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeStringGuid) &&
    131              ((EFI_STATUS_CODE_STRING_DATA *) Data)->StringType == EfiStringAscii) {
    132     //
    133     // EFI_STATUS_CODE_STRING_DATA
    134     //
    135     CharCount = AsciiSPrint (
    136                   Buffer,
    137                   sizeof (Buffer),
    138                   "%a\n\r",
    139                   ((EFI_STATUS_CODE_STRING_DATA *) Data)->String.Ascii
    140                   );
    141   } else {
    142     //
    143     // Code type is not defined.
    144     //
    145     CharCount = AsciiSPrint (
    146                   Buffer,
    147                   sizeof (Buffer),
    148                   "Undefined: C%08x:V%08x I%x\n\r",
    149                   CodeType,
    150                   Value,
    151                   Instance
    152                   );
    153   }
    154 
    155   //
    156   // Call SerialPort Lib function to do print.
    157   //
    158   SerialPortWrite ((UINT8 *) Buffer, CharCount);
    159 
    160   return EFI_SUCCESS;
    161 }
    162 
    163