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
SerialStatusCodeReportWorker(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)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