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