]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLib.c
MdePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdePkg / Library / UefiDebugLibDebugPortProtocol / DebugLib.c
1 /** @file
2 UEFI Debug Library that sends messages to EFI_DEBUGPORT_PROTOCOL.Write.
3
4 Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <Uefi.h>
10
11 #include <Library/DebugLib.h>
12 #include <Library/UefiBootServicesTableLib.h>
13 #include <Library/PrintLib.h>
14 #include <Library/PcdLib.h>
15 #include <Library/BaseLib.h>
16 #include <Library/BaseMemoryLib.h>
17 #include <Library/DebugPrintErrorLevelLib.h>
18
19 #include <Protocol/DebugPort.h>
20
21 //
22 // Define the maximum debug and assert message length that this library supports
23 //
24 #define MAX_DEBUG_MESSAGE_LENGTH 0x100
25
26 //
27 // Define the timeout for EFI_DEBUGPORT_PROTOCOL.Write
28 //
29 #define WRITE_TIMEOUT 1000
30
31
32 EFI_DEBUGPORT_PROTOCOL *mDebugPort = NULL;
33
34 //
35 // VA_LIST can not initialize to NULL for all compiler, so we use this to
36 // indicate a null VA_LIST
37 //
38 VA_LIST mVaListNull;
39
40 /**
41 Send message to DebugPort Protocol.
42
43 If mDebugPort is NULL, i.e. EFI_DEBUGPORT_PROTOCOL is not located,
44 EFI_DEBUGPORT_PROTOCOL is located first.
45 Then, Buffer is sent via EFI_DEBUGPORT_PROTOCOL.Write.
46
47 @param Buffer The message to be sent.
48 @param BufferLength The byte length of Buffer.
49 **/
50 VOID
51 UefiDebugLibDebugPortProtocolWrite (
52 IN CONST CHAR8 *Buffer,
53 IN UINTN BufferLength
54 )
55 {
56 UINTN Length;
57 EFI_STATUS Status;
58
59 //
60 // If mDebugPort is NULL, initialize first.
61 //
62 if (mDebugPort == NULL) {
63 Status = gBS->LocateProtocol (&gEfiDebugPortProtocolGuid, NULL, (VOID **)&mDebugPort);
64 if (EFI_ERROR (Status)) {
65 return;
66 }
67
68 mDebugPort->Reset (mDebugPort);
69 }
70
71 //
72 // EFI_DEBUGPORT_PROTOCOL.Write is called until all message is sent.
73 //
74 while (BufferLength > 0) {
75 Length = BufferLength;
76
77 Status = mDebugPort->Write (mDebugPort, WRITE_TIMEOUT, &Length, (VOID *) Buffer);
78 if (EFI_ERROR (Status) || BufferLength < Length) {
79 break;
80 }
81
82 Buffer += Length;
83 BufferLength -= Length;
84 }
85 }
86
87 /**
88 Prints a debug message to the debug output device if the specified error level is enabled.
89
90 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
91 GetDebugPrintErrorLevel (), then print the message specified by Format and the
92 associated variable argument list to the debug output device.
93
94 If Format is NULL, then ASSERT().
95
96 @param ErrorLevel The error level of the debug message.
97 @param Format Format string for the debug message to print.
98 @param ... A variable argument list whose contents are accessed
99 based on the format string specified by Format.
100
101 **/
102 VOID
103 EFIAPI
104 DebugPrint (
105 IN UINTN ErrorLevel,
106 IN CONST CHAR8 *Format,
107 ...
108 )
109 {
110 VA_LIST Marker;
111
112 VA_START (Marker, Format);
113 DebugVPrint (ErrorLevel, Format, Marker);
114 VA_END (Marker);
115 }
116
117
118 /**
119 Prints a debug message to the debug output device if the specified
120 error level is enabled base on Null-terminated format string and a
121 VA_LIST argument list or a BASE_LIST argument list.
122
123 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
124 GetDebugPrintErrorLevel (), then print the message specified by Format and
125 the associated variable argument list to the debug output device.
126
127 If Format is NULL, then ASSERT().
128
129 @param ErrorLevel The error level of the debug message.
130 @param Format Format string for the debug message to print.
131 @param VaListMarker VA_LIST marker for the variable argument list.
132 @param BaseListMarker BASE_LIST marker for the variable argument list.
133
134 **/
135 VOID
136 DebugPrintMarker (
137 IN UINTN ErrorLevel,
138 IN CONST CHAR8 *Format,
139 IN VA_LIST VaListMarker,
140 IN BASE_LIST BaseListMarker
141 )
142 {
143 CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
144
145 //
146 // If Format is NULL, then ASSERT().
147 //
148 ASSERT (Format != NULL);
149
150 //
151 // Check driver debug mask value and global mask
152 //
153 if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
154 return;
155 }
156
157 //
158 // Convert the DEBUG() message to an ASCII String
159 //
160 if (BaseListMarker == NULL) {
161 AsciiVSPrint (Buffer, sizeof (Buffer), Format, VaListMarker);
162 } else {
163 AsciiBSPrint (Buffer, sizeof (Buffer), Format, BaseListMarker);
164 }
165
166 //
167 // Send the print string to EFI_DEBUGPORT_PROTOCOL.Write.
168 //
169 UefiDebugLibDebugPortProtocolWrite (Buffer, AsciiStrLen (Buffer));
170 }
171
172
173 /**
174 Prints a debug message to the debug output device if the specified
175 error level is enabled.
176
177 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
178 GetDebugPrintErrorLevel (), then print the message specified by Format and
179 the associated variable argument list to the debug output device.
180
181 If Format is NULL, then ASSERT().
182
183 @param ErrorLevel The error level of the debug message.
184 @param Format Format string for the debug message to print.
185 @param VaListMarker VA_LIST marker for the variable argument list.
186
187 **/
188 VOID
189 EFIAPI
190 DebugVPrint (
191 IN UINTN ErrorLevel,
192 IN CONST CHAR8 *Format,
193 IN VA_LIST VaListMarker
194 )
195 {
196 DebugPrintMarker (ErrorLevel, Format, VaListMarker, NULL);
197 }
198
199
200 /**
201 Prints a debug message to the debug output device if the specified
202 error level is enabled.
203 This function use BASE_LIST which would provide a more compatible
204 service than VA_LIST.
205
206 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
207 GetDebugPrintErrorLevel (), then print the message specified by Format and
208 the associated variable argument list to the debug output device.
209
210 If Format is NULL, then ASSERT().
211
212 @param ErrorLevel The error level of the debug message.
213 @param Format Format string for the debug message to print.
214 @param BaseListMarker BASE_LIST marker for the variable argument list.
215
216 **/
217 VOID
218 EFIAPI
219 DebugBPrint (
220 IN UINTN ErrorLevel,
221 IN CONST CHAR8 *Format,
222 IN BASE_LIST BaseListMarker
223 )
224 {
225 DebugPrintMarker (ErrorLevel, Format, mVaListNull, BaseListMarker);
226 }
227
228
229 /**
230 Prints an assert message containing a filename, line number, and description.
231 This may be followed by a breakpoint or a dead loop.
232
233 Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
234 to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
235 PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
236 DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
237 CpuDeadLoop() is called. If neither of these bits are set, then this function
238 returns immediately after the message is printed to the debug output device.
239 DebugAssert() must actively prevent recursion. If DebugAssert() is called while
240 processing another DebugAssert(), then DebugAssert() must return immediately.
241
242 If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
243 If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
244
245 @param FileName The pointer to the name of the source file that generated
246 the assert condition.
247 @param LineNumber The line number in the source file that generated the
248 assert condition
249 @param Description The pointer to the description of the assert condition.
250
251 **/
252 VOID
253 EFIAPI
254 DebugAssert (
255 IN CONST CHAR8 *FileName,
256 IN UINTN LineNumber,
257 IN CONST CHAR8 *Description
258 )
259 {
260 CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
261
262 //
263 // Generate the ASSERT() message in ASCII format
264 //
265 AsciiSPrint (
266 Buffer,
267 sizeof (Buffer),
268 "ASSERT [%a] %a(%d): %a\n",
269 gEfiCallerBaseName,
270 FileName,
271 LineNumber,
272 Description
273 );
274
275 //
276 // Send the print string to EFI_DEBUGPORT_PROTOCOL.Write.
277 //
278 UefiDebugLibDebugPortProtocolWrite (Buffer, AsciiStrLen (Buffer));
279
280 //
281 // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings
282 //
283 if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {
284 CpuBreakpoint ();
285 } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {
286 CpuDeadLoop ();
287 }
288 }
289
290
291 /**
292 Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.
293
294 This function fills Length bytes of Buffer with the value specified by
295 PcdDebugClearMemoryValue, and returns Buffer.
296
297 If Buffer is NULL, then ASSERT().
298 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
299
300 @param Buffer The pointer to the target buffer to be filled with PcdDebugClearMemoryValue.
301 @param Length The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue.
302
303 @return Buffer The pointer to the target buffer filled with PcdDebugClearMemoryValue.
304
305 **/
306 VOID *
307 EFIAPI
308 DebugClearMemory (
309 OUT VOID *Buffer,
310 IN UINTN Length
311 )
312 {
313 //
314 // If Buffer is NULL, then ASSERT().
315 //
316 ASSERT (Buffer != NULL);
317
318 //
319 // SetMem() checks for the the ASSERT() condition on Length and returns Buffer
320 //
321 return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));
322 }
323
324
325 /**
326 Returns TRUE if ASSERT() macros are enabled.
327
328 This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
329 PcdDebugProperyMask is set. Otherwise FALSE is returned.
330
331 @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
332 @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.
333
334 **/
335 BOOLEAN
336 EFIAPI
337 DebugAssertEnabled (
338 VOID
339 )
340 {
341 return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);
342 }
343
344
345 /**
346 Returns TRUE if DEBUG() macros are enabled.
347
348 This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
349 PcdDebugProperyMask is set. Otherwise FALSE is returned.
350
351 @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
352 @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
353
354 **/
355 BOOLEAN
356 EFIAPI
357 DebugPrintEnabled (
358 VOID
359 )
360 {
361 return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);
362 }
363
364
365 /**
366 Returns TRUE if DEBUG_CODE() macros are enabled.
367
368 This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
369 PcdDebugProperyMask is set. Otherwise FALSE is returned.
370
371 @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
372 @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.
373
374 **/
375 BOOLEAN
376 EFIAPI
377 DebugCodeEnabled (
378 VOID
379 )
380 {
381 return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);
382 }
383
384
385 /**
386 Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.
387
388 This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of
389 PcdDebugProperyMask is set. Otherwise FALSE is returned.
390
391 @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
392 @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.
393
394 **/
395 BOOLEAN
396 EFIAPI
397 DebugClearMemoryEnabled (
398 VOID
399 )
400 {
401 return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);
402 }
403
404 /**
405 Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel.
406
407 This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel.
408
409 @retval TRUE Current ErrorLevel is supported.
410 @retval FALSE Current ErrorLevel is not supported.
411
412 **/
413 BOOLEAN
414 EFIAPI
415 DebugPrintLevelEnabled (
416 IN CONST UINTN ErrorLevel
417 )
418 {
419 return (BOOLEAN) ((ErrorLevel & PcdGet32(PcdFixedDebugPrintErrorLevel)) != 0);
420 }
421