• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   OEM hook status code library functions with no library constructor/destructor
3 
4   Copyright (c) 2006 - 2013, 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   Module Name:  Nt32OemHookStatusCodeLib.c
14 
15 **/
16 
17 //
18 // The package level header files this module uses
19 //
20 #include <WinNtDxe.h>
21 
22 //
23 // The protocols, PPI and GUID defintions for this module
24 //
25 #include <Protocol/WinNtThunk.h>
26 #include <Guid/StatusCodeDataTypeId.h>
27 #include <Guid/StatusCodeDataTypeDebug.h>
28 //
29 // The Library classes this module consumes
30 //
31 #include <Library/OemHookStatusCodeLib.h>
32 #include <Library/DebugLib.h>
33 #include <Library/HobLib.h>
34 #include <Library/PrintLib.h>
35 #include <Library/BaseMemoryLib.h>
36 #include <Library/ReportStatusCodeLib.h>
37 
38 //
39 // Cache of WinNtThunk protocol
40 //
41 EFI_WIN_NT_THUNK_PROTOCOL   *mWinNt;
42 
43 //
44 // Cache of standard output handle .
45 //
46 HANDLE                      mStdOut;
47 
48 /**
49 
50   Initialize OEM status code device .
51 
52   @return    Always return EFI_SUCCESS.
53 
54 **/
55 EFI_STATUS
56 EFIAPI
OemHookStatusCodeInitialize(VOID)57 OemHookStatusCodeInitialize (
58   VOID
59   )
60 {
61   EFI_HOB_GUID_TYPE   *GuidHob;
62 
63   //
64   // Retrieve WinNtThunkProtocol from GUID'ed HOB
65   //
66   GuidHob = GetFirstGuidHob (&gEfiWinNtThunkProtocolGuid);
67   ASSERT (GuidHob != NULL);
68   mWinNt = (EFI_WIN_NT_THUNK_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob)));
69   ASSERT (mWinNt != NULL);
70 
71   //
72   // Cache standard output handle.
73   //
74   mStdOut = mWinNt->GetStdHandle (STD_OUTPUT_HANDLE);
75 
76   return EFI_SUCCESS;
77 }
78 
79 /**
80   Report status code to OEM device.
81 
82   @param  CodeType      Indicates the type of status code being reported.  Type EFI_STATUS_CODE_TYPE is defined in "Related Definitions" below.
83 
84   @param  Value         Describes the current status of a hardware or software entity.
85                         This included information about the class and subclass that is used to classify the entity
86                         as well as an operation.  For progress codes, the operation is the current activity.
87                         For error codes, it is the exception.  For debug codes, it is not defined at this time.
88                         Type EFI_STATUS_CODE_VALUE is defined in "Related Definitions" below.
89                         Specific values are discussed in the Intel? Platform Innovation Framework for EFI Status Code Specification.
90 
91   @param  Instance      The enumeration of a hardware or software entity within the system.
92                         A system may contain multiple entities that match a class/subclass pairing.
93                         The instance differentiates between them.  An instance of 0 indicates that instance information is unavailable,
94                         not meaningful, or not relevant.  Valid instance numbers start with 1.
95 
96 
97   @param  CallerId      This optional parameter may be used to identify the caller.
98                         This parameter allows the status code driver to apply different rules to different callers.
99                         Type EFI_GUID is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
100 
101 
102   @param  Data          This optional parameter may be used to pass additional data
103 
104   @return               The function always return EFI_SUCCESS.
105 
106 **/
107 EFI_STATUS
108 EFIAPI
OemHookStatusCodeReport(IN EFI_STATUS_CODE_TYPE CodeType,IN EFI_STATUS_CODE_VALUE Value,IN UINT32 Instance,IN EFI_GUID * CallerId,OPTIONAL IN EFI_STATUS_CODE_DATA * Data OPTIONAL)109 OemHookStatusCodeReport (
110   IN EFI_STATUS_CODE_TYPE     CodeType,
111   IN EFI_STATUS_CODE_VALUE    Value,
112   IN UINT32                   Instance,
113   IN EFI_GUID                 *CallerId, OPTIONAL
114   IN EFI_STATUS_CODE_DATA     *Data      OPTIONAL
115   )
116 {
117   CHAR8           *Filename;
118   CHAR8           *Description;
119   CHAR8           *Format;
120   CHAR8           Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
121   UINT32          ErrorLevel;
122   UINT32          LineNumber;
123   UINTN           CharCount;
124   BASE_LIST       Marker;
125 
126   Buffer[0] = '\0';
127 
128   if (Data != NULL &&
129       ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
130     //
131     // Print ASSERT() information into output buffer.
132     //
133     CharCount = AsciiSPrint (
134                   Buffer,
135                   sizeof (Buffer),
136                   "\n\rASSERT!: %a (%d): %a\n\r",
137                   Filename,
138                   LineNumber,
139                   Description
140                   );
141 
142     //
143     // Callout to standard output.
144     //
145     mWinNt->WriteFile (
146               mStdOut,
147               Buffer,
148               (DWORD)CharCount,
149               (LPDWORD)&CharCount,
150               NULL
151               );
152 
153     return EFI_SUCCESS;
154 
155   } else if (Data != NULL &&
156              ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
157     //
158     // Print DEBUG() information into output buffer.
159     //
160     CharCount = AsciiBSPrint (
161                   Buffer,
162                   sizeof (Buffer),
163                   Format,
164                   Marker
165                   );
166   } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
167     //
168     // Print ERROR information into output buffer.
169     //
170     CharCount = AsciiSPrint (
171                   Buffer,
172                   sizeof (Buffer),
173                   "ERROR: C%x:V%x I%x",
174                   CodeType,
175                   Value,
176                   Instance
177                   );
178 
179     //
180     // Make sure we don't try to print values that weren't intended to be printed, especially NULL GUID pointers.
181     //
182 
183     if (CallerId != NULL) {
184       CharCount += AsciiSPrint (
185                      &Buffer[CharCount - 1],
186                      (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
187                      " %g",
188                      CallerId
189                      );
190     }
191 
192     if (Data != NULL) {
193       CharCount += AsciiSPrint (
194                      &Buffer[CharCount - 1],
195                      (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
196                      " %p",
197                      Data
198                      );
199     }
200 
201     CharCount += AsciiSPrint (
202                    &Buffer[CharCount - 1],
203                    (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
204                    "\n\r"
205                    );
206   } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
207     CharCount = AsciiSPrint (
208                   Buffer,
209                   sizeof (Buffer),
210                   "PROGRESS CODE: V%x I%x\n\r",
211                   Value,
212                   Instance
213                   );
214   } else {
215     CharCount = AsciiSPrint (
216                   Buffer,
217                   sizeof (Buffer),
218                   "Undefined: C%x:V%x I%x\n\r",
219                   CodeType,
220                   Value,
221                   Instance
222                   );
223   }
224 
225   //
226   // Callout to standard output.
227   //
228   mWinNt->WriteFile (
229             mStdOut,
230             Buffer,
231             (DWORD)CharCount,
232             (LPDWORD)&CharCount,
233             NULL
234             );
235 
236   return EFI_SUCCESS;
237 }
238 
239