]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/ReportStatusCode.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / EfiCommonLib / ReportStatusCode.c
1 /*++
2
3 Copyright (c) 2004, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 ReportStatusCode.c
15
16 Abstract:
17
18 Worker functions for ReportStatusCode
19
20 --*/
21
22 #include "TianoCommon.h"
23 #include "EfiCommonLib.h"
24 #include EFI_GUID_DEFINITION (StatusCodeCallerId)
25 #include EFI_GUID_DEFINITION (StatusCodeDataTypeId)
26
27
28 VOID *
29 EfiConstructStatusCodeData (
30 IN UINT16 DataSize,
31 IN EFI_GUID *TypeGuid,
32 IN OUT EFI_STATUS_CODE_DATA *Data
33 )
34 /*++
35
36 Routine Description:
37
38 Construct stanader header for optional data passed into ReportStatusCode
39
40 Arguments:
41
42 DataSize - Size of optional data. Does not include EFI_STATUS_CODE_DATA header
43 TypeGuid - GUID to place in EFI_STATUS_CODE_DATA
44 Data - Buffer to use.
45
46 Returns:
47
48 Return pointer to Data buffer pointing past the end of EFI_STATUS_CODE_DATA
49
50 --*/
51 {
52 Data->HeaderSize = sizeof (EFI_STATUS_CODE_DATA);
53 Data->Size = (UINT16)(DataSize - sizeof (EFI_STATUS_CODE_DATA));
54 EfiCommonLibCopyMem (&Data->Type, TypeGuid, sizeof (EFI_GUID));
55
56 return (VOID *)(Data + 1);
57 }
58
59 EFI_STATUS
60 EfiDebugVPrintWorker (
61 IN UINTN ErrorLevel,
62 IN CHAR8 *Format,
63 IN VA_LIST Marker,
64 IN UINTN BufferSize,
65 IN OUT VOID *Buffer
66 )
67 /*++
68
69 Routine Description:
70
71 Worker function for DEBUG(). If Error Logging hub is loaded log ASSERT
72 information. If Error Logging hub is not loaded do nothing.
73
74 The Format string might be truncated to fit into the status code struture
75 which has the max size of EFI_STATUS_CODE_DATA_MAX_SIZE.
76
77 We use UINT64 buffers due to IPF alignment concerns.
78
79 Arguments:
80
81 ErrorLevel - If error level is set do the debug print.
82
83 Format - String to use for the print, followed by Print arguments.
84
85 Marker - VarArgs
86
87 BufferSize - Size of Buffer.
88
89 Buffer - Caller allocated buffer, contains ReportStatusCode extended data
90
91 Returns:
92
93 Status code
94
95 EFI_SUCCESS - Successfully printed
96
97 --*/
98 {
99 UINTN Index;
100 UINTN FormatStrLen;
101 UINTN RemainingStrLen;
102 UINT64 *Ptr;
103 EFI_DEBUG_INFO *EfiDebug;
104
105
106 //
107 // Build the type specific EFI_STATUS_CODE_DATA in order
108 //
109
110 //
111 // Fill in EFI_STATUS_CODE_DATA to Buffer.
112 //
113 EfiDebug = (EFI_DEBUG_INFO *)EfiConstructStatusCodeData (
114 (UINT16)BufferSize,
115 &gEfiStatusCodeDataTypeDebugGuid,
116 Buffer
117 );
118
119 //
120 // Then EFI_DEBUG_INFO
121 //
122 EfiDebug->ErrorLevel = (UINT32)ErrorLevel;
123
124 //
125 // 12 * sizeof (UINT64) byte mini Var Arg stack.
126 // That is followed by the format string.
127 //
128 for (Index = 0, Ptr = (UINT64 *)(EfiDebug + 1); Index < 12; Index++, Ptr++) {
129 *Ptr = VA_ARG (Marker, UINT64);
130 }
131
132 //
133 // Place Ascii Format string at the end
134 // Truncate it to fit into the status code structure
135 //
136 FormatStrLen = EfiAsciiStrLen (Format);
137 RemainingStrLen = EFI_STATUS_CODE_DATA_MAX_SIZE
138 - sizeof (EFI_STATUS_CODE_DATA)
139 - sizeof (EFI_DEBUG_INFO)
140 - 12 * sizeof (UINT64) - 1;
141 if (FormatStrLen > RemainingStrLen) {
142 FormatStrLen = RemainingStrLen;
143 }
144 EfiCommonLibCopyMem (Ptr, Format, FormatStrLen);
145 *((CHAR8 *) Ptr + FormatStrLen) = '\0';
146
147 return EFI_SUCCESS;
148 }
149
150
151
152 EFI_STATUS
153 EfiDebugAssertWorker (
154 IN CHAR8 *Filename,
155 IN INTN LineNumber,
156 IN CHAR8 *Description,
157 IN UINTN BufferSize,
158 IN OUT VOID *Buffer
159 )
160 /*++
161
162 Routine Description:
163
164 Worker function for ASSERT (). If Error Logging hub is loaded log ASSERT
165 information. If Error Logging hub is not loaded DEADLOOP ().
166
167 We use UINT64 buffers due to IPF alignment concerns.
168
169 Arguments:
170
171 Filename - File name of failing routine.
172
173 LineNumber - Line number of failing ASSERT().
174
175 Description - Description, usually the assertion,
176
177 BufferSize - Size of Buffer.
178
179 Buffer - Caller allocated buffer, contains ReportStatusCode extendecd data
180
181 Returns:
182
183 Status code
184
185 EFI_BUFFER_TOO_SMALL - Buffer not large enough
186
187 EFI_SUCCESS - Function successfully done.
188
189 --*/
190 {
191 EFI_DEBUG_ASSERT_DATA *AssertData;
192 UINTN TotalSize;
193 CHAR8 *EndOfStr;
194
195 //
196 // Make sure it will all fit in the passed in buffer
197 //
198 TotalSize = sizeof (EFI_STATUS_CODE_DATA) + sizeof (EFI_DEBUG_ASSERT_DATA);
199 TotalSize += EfiAsciiStrLen (Filename) + EfiAsciiStrLen (Description);
200 if (TotalSize > BufferSize) {
201 return EFI_BUFFER_TOO_SMALL;
202 }
203
204 //
205 // Fill in EFI_STATUS_CODE_DATA
206 //
207 AssertData = (EFI_DEBUG_ASSERT_DATA *)
208 EfiConstructStatusCodeData (
209 (UINT16)(TotalSize - sizeof (EFI_STATUS_CODE_DATA)),
210 &gEfiStatusCodeDataTypeAssertGuid,
211 Buffer
212 );
213
214 //
215 // Fill in EFI_DEBUG_ASSERT_DATA
216 //
217 AssertData->LineNumber = (UINT32)LineNumber;
218
219 //
220 // Copy Ascii FileName including NULL.
221 //
222 EndOfStr = EfiAsciiStrCpy ((CHAR8 *)(AssertData + 1), Filename);
223
224 //
225 // Copy Ascii Description
226 //
227 EfiAsciiStrCpy (EndOfStr, Description);
228 return EFI_SUCCESS;
229 }
230
231
232
233 BOOLEAN
234 ReportStatusCodeExtractAssertInfo (
235 IN EFI_STATUS_CODE_TYPE CodeType,
236 IN EFI_STATUS_CODE_VALUE Value,
237 IN EFI_STATUS_CODE_DATA *Data,
238 OUT CHAR8 **Filename,
239 OUT CHAR8 **Description,
240 OUT UINT32 *LineNumber
241 )
242 /*++
243
244 Routine Description:
245
246 Extract assert information from status code data.
247
248 Arguments:
249
250 CodeType - Code type
251 Value - Code value
252 Data - Optional data associated with this status code.
253 Filename - Filename extracted from Data
254 Description - Description extracted from Data
255 LineNumber - Line number extracted from Data
256
257 Returns:
258
259 TRUE - Successfully extracted
260
261 FALSE - Extraction failed
262
263 --*/
264 {
265 EFI_DEBUG_ASSERT_DATA *AssertData;
266
267 if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&
268 ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED)) {
269 //
270 // Assume if we have an uncontained unrecoverable error that the data hub
271 // may not work. So we will print out data here. If we had an IPMI controller,
272 // or error log we could wack the hardware here.
273 //
274 if ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE && (Data != NULL)) {
275 //
276 // ASSERT (Expresion) -
277 // ExtendedData == FileName
278 // Instance == Line Nuber
279 // NULL == String of Expresion
280 //
281 AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);
282 *Filename = (CHAR8 *)(AssertData + 1);
283 *Description = *Filename + EfiAsciiStrLen (*Filename) + 1;
284 *LineNumber = AssertData->LineNumber;
285 return TRUE;
286 }
287 }
288 return FALSE;
289 }
290
291
292 BOOLEAN
293 ReportStatusCodeExtractDebugInfo (
294 IN EFI_STATUS_CODE_DATA *Data,
295 OUT UINT32 *ErrorLevel,
296 OUT VA_LIST *Marker,
297 OUT CHAR8 **Format
298 )
299 /*++
300
301 Routine Description:
302
303 Extract debug information from status code data.
304
305 Arguments:
306
307 Data - Optional data associated with status code.
308 ErrorLevel - Error level extracted from Data
309 Marker - VA_LIST extracted from Data
310 Format - Format string extracted from Data
311
312 Returns:
313
314 TRUE - Successfully extracted
315
316 FALSE - Extraction failed
317
318 --*/
319 {
320 EFI_DEBUG_INFO *DebugInfo;
321
322 if ((Data == NULL) || (!EfiCompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid))) {
323 return FALSE;
324 }
325
326 DebugInfo = (EFI_DEBUG_INFO *)(Data + 1);
327
328 *ErrorLevel = DebugInfo->ErrorLevel;
329
330 //
331 // The first 12 * UINTN bytes of the string are really an
332 // arguement stack to support varargs on the Format string.
333 //
334 *Marker = (VA_LIST) (DebugInfo + 1);
335 *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12);
336
337 return TRUE;
338 }