1 /** @file
2   Provides services to print debug and assert messages to a debug output device.
3 
4   The Debug library supports debug print and asserts based on a combination of macros and code.
5   The debug library can be turned on and off so that the debug code does not increase the size of an image.
6 
7   Note that a reserved macro named MDEPKG_NDEBUG is introduced for the intention
8   of size reduction when compiler optimization is disabled. If MDEPKG_NDEBUG is
9   defined, then debug and assert related macros wrapped by it are the NULL implementations.
10 
11 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
12 This program and the accompanying materials are licensed and made available under
13 the terms and conditions of the BSD License that accompanies this distribution.
14 The full text of the license may be found at
15 http://opensource.org/licenses/bsd-license.php.
16 
17 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 
20 **/
21 
22 #ifndef __DEBUG_LIB_H__
23 #define __DEBUG_LIB_H__
24 
25 //
26 // Declare bits for PcdDebugPropertyMask
27 //
28 #define DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED       0x01
29 #define DEBUG_PROPERTY_DEBUG_PRINT_ENABLED        0x02
30 #define DEBUG_PROPERTY_DEBUG_CODE_ENABLED         0x04
31 #define DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED       0x08
32 #define DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED  0x10
33 #define DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED    0x20
34 
35 //
36 // Declare bits for PcdDebugPrintErrorLevel and the ErrorLevel parameter of DebugPrint()
37 //
38 #define DEBUG_INIT      0x00000001  // Initialization
39 #define DEBUG_WARN      0x00000002  // Warnings
40 #define DEBUG_LOAD      0x00000004  // Load events
41 #define DEBUG_FS        0x00000008  // EFI File system
42 #define DEBUG_POOL      0x00000010  // Alloc & Free's
43 #define DEBUG_PAGE      0x00000020  // Alloc & Free's
44 #define DEBUG_INFO      0x00000040  // Informational debug messages
45 #define DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
46 #define DEBUG_VARIABLE  0x00000100  // Variable
47 #define DEBUG_BM        0x00000400  // Boot Manager
48 #define DEBUG_BLKIO     0x00001000  // BlkIo Driver
49 #define DEBUG_NET       0x00004000  // SNI Driver
50 #define DEBUG_UNDI      0x00010000  // UNDI Driver
51 #define DEBUG_LOADFILE  0x00020000  // UNDI Driver
52 #define DEBUG_EVENT     0x00080000  // Event messages
53 #define DEBUG_GCD       0x00100000  // Global Coherency Database changes
54 #define DEBUG_CACHE     0x00200000  // Memory range cachability changes
55 #define DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may significantly impact boot performance
56 #define DEBUG_ERROR     0x80000000  // Error
57 
58 //
59 // Aliases of debug message mask bits
60 //
61 #define EFI_D_INIT      DEBUG_INIT
62 #define EFI_D_WARN      DEBUG_WARN
63 #define EFI_D_LOAD      DEBUG_LOAD
64 #define EFI_D_FS        DEBUG_FS
65 #define EFI_D_POOL      DEBUG_POOL
66 #define EFI_D_PAGE      DEBUG_PAGE
67 #define EFI_D_INFO      DEBUG_INFO
68 #define EFI_D_DISPATCH  DEBUG_DISPATCH
69 #define EFI_D_VARIABLE  DEBUG_VARIABLE
70 #define EFI_D_BM        DEBUG_BM
71 #define EFI_D_BLKIO     DEBUG_BLKIO
72 #define EFI_D_NET       DEBUG_NET
73 #define EFI_D_UNDI      DEBUG_UNDI
74 #define EFI_D_LOADFILE  DEBUG_LOADFILE
75 #define EFI_D_EVENT     DEBUG_EVENT
76 #define EFI_D_VERBOSE   DEBUG_VERBOSE
77 #define EFI_D_ERROR     DEBUG_ERROR
78 
79 /**
80   Prints a debug message to the debug output device if the specified error level is enabled.
81 
82   If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
83   GetDebugPrintErrorLevel (), then print the message specified by Format and the
84   associated variable argument list to the debug output device.
85 
86   If Format is NULL, then ASSERT().
87 
88   @param  ErrorLevel  The error level of the debug message.
89   @param  Format      The format string for the debug message to print.
90   @param  ...         The variable argument list whose contents are accessed
91                       based on the format string specified by Format.
92 
93 **/
94 VOID
95 EFIAPI
96 DebugPrint (
97   IN  UINTN        ErrorLevel,
98   IN  CONST CHAR8  *Format,
99   ...
100   );
101 
102 
103 /**
104   Prints an assert message containing a filename, line number, and description.
105   This may be followed by a breakpoint or a dead loop.
106 
107   Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
108   to the debug output device.  If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
109   PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
110   DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
111   CpuDeadLoop() is called.  If neither of these bits are set, then this function
112   returns immediately after the message is printed to the debug output device.
113   DebugAssert() must actively prevent recursion.  If DebugAssert() is called while
114   processing another DebugAssert(), then DebugAssert() must return immediately.
115 
116   If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
117   If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
118 
119   @param  FileName     The pointer to the name of the source file that generated the assert condition.
120   @param  LineNumber   The line number in the source file that generated the assert condition
121   @param  Description  The pointer to the description of the assert condition.
122 
123 **/
124 VOID
125 EFIAPI
126 DebugAssert (
127   IN CONST CHAR8  *FileName,
128   IN UINTN        LineNumber,
129   IN CONST CHAR8  *Description
130   );
131 
132 
133 /**
134   Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.
135 
136   This function fills Length bytes of Buffer with the value specified by
137   PcdDebugClearMemoryValue, and returns Buffer.
138 
139   If Buffer is NULL, then ASSERT().
140   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
141 
142   @param   Buffer  The pointer to the target buffer to be filled with PcdDebugClearMemoryValue.
143   @param   Length  The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue.
144 
145   @return  Buffer  The pointer to the target buffer filled with PcdDebugClearMemoryValue.
146 
147 **/
148 VOID *
149 EFIAPI
150 DebugClearMemory (
151   OUT VOID  *Buffer,
152   IN UINTN  Length
153   );
154 
155 
156 /**
157   Returns TRUE if ASSERT() macros are enabled.
158 
159   This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
160   PcdDebugProperyMask is set.  Otherwise, FALSE is returned.
161 
162   @retval  TRUE    The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
163   @retval  FALSE   The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.
164 
165 **/
166 BOOLEAN
167 EFIAPI
168 DebugAssertEnabled (
169   VOID
170   );
171 
172 
173 /**
174   Returns TRUE if DEBUG() macros are enabled.
175 
176   This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
177   PcdDebugProperyMask is set.  Otherwise, FALSE is returned.
178 
179   @retval  TRUE    The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
180   @retval  FALSE   The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
181 
182 **/
183 BOOLEAN
184 EFIAPI
185 DebugPrintEnabled (
186   VOID
187   );
188 
189 
190 /**
191   Returns TRUE if DEBUG_CODE() macros are enabled.
192 
193   This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
194   PcdDebugProperyMask is set.  Otherwise, FALSE is returned.
195 
196   @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
197   @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.
198 
199 **/
200 BOOLEAN
201 EFIAPI
202 DebugCodeEnabled (
203   VOID
204   );
205 
206 
207 /**
208   Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.
209 
210   This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of
211   PcdDebugProperyMask is set.  Otherwise, FALSE is returned.
212 
213   @retval  TRUE    The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
214   @retval  FALSE   The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.
215 
216 **/
217 BOOLEAN
218 EFIAPI
219 DebugClearMemoryEnabled (
220   VOID
221   );
222 
223 /**
224   Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel.
225 
226   This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel.
227 
228   @retval  TRUE    Current ErrorLevel is supported.
229   @retval  FALSE   Current ErrorLevel is not supported.
230 
231 **/
232 BOOLEAN
233 EFIAPI
234 DebugPrintLevelEnabled (
235   IN  CONST UINTN        ErrorLevel
236   );
237 
238 /**
239   Internal worker macro that calls DebugAssert().
240 
241   This macro calls DebugAssert(), passing in the filename, line number, and an
242   expression that evaluated to FALSE.
243 
244   @param  Expression  Boolean expression that evaluated to FALSE
245 
246 **/
247 #define _ASSERT(Expression)  DebugAssert (__FILE__, __LINE__, #Expression)
248 
249 
250 /**
251   Internal worker macro that calls DebugPrint().
252 
253   This macro calls DebugPrint() passing in the debug error level, a format
254   string, and a variable argument list.
255   __VA_ARGS__ is not supported by EBC compiler, Microsoft Visual Studio .NET 2003
256   and Microsoft Windows Server 2003 Driver Development Kit (Microsoft WINDDK) version 3790.1830.
257 
258   @param  Expression  Expression containing an error level, a format string,
259                       and a variable argument list based on the format string.
260 
261 **/
262 
263 #if !defined(MDE_CPU_EBC) && (!defined (_MSC_VER) || _MSC_VER > 1400)
264   #define _DEBUG_PRINT(PrintLevel, ...)              \
265     do {                                             \
266       if (DebugPrintLevelEnabled (PrintLevel)) {     \
267         DebugPrint (PrintLevel, ##__VA_ARGS__);      \
268       }                                              \
269     } while (FALSE)
270   #define _DEBUG(Expression)   _DEBUG_PRINT Expression
271 #else
272 #define _DEBUG(Expression)   DebugPrint Expression
273 #endif
274 
275 /**
276   Macro that calls DebugAssert() if an expression evaluates to FALSE.
277 
278   If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED
279   bit of PcdDebugProperyMask is set, then this macro evaluates the Boolean
280   expression specified by Expression.  If Expression evaluates to FALSE, then
281   DebugAssert() is called passing in the source filename, source line number,
282   and Expression.
283 
284   @param  Expression  Boolean expression.
285 
286 **/
287 #if !defined(MDEPKG_NDEBUG)
288   #define ASSERT(Expression)        \
289     do {                            \
290       if (DebugAssertEnabled ()) {  \
291         if (!(Expression)) {        \
292           _ASSERT (Expression);     \
293         }                           \
294       }                             \
295     } while (FALSE)
296 #else
297   #define ASSERT(Expression)
298 #endif
299 
300 /**
301   Macro that calls DebugPrint().
302 
303   If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED
304   bit of PcdDebugProperyMask is set, then this macro passes Expression to
305   DebugPrint().
306 
307   @param  Expression  Expression containing an error level, a format string,
308                       and a variable argument list based on the format string.
309 
310 
311 **/
312 #if !defined(MDEPKG_NDEBUG)
313   #define DEBUG(Expression)        \
314     do {                           \
315       if (DebugPrintEnabled ()) {  \
316         _DEBUG (Expression);       \
317       }                            \
318     } while (FALSE)
319 #else
320   #define DEBUG(Expression)
321 #endif
322 
323 /**
324   Macro that calls DebugAssert() if an EFI_STATUS evaluates to an error code.
325 
326   If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED
327   bit of PcdDebugProperyMask is set, then this macro evaluates the EFI_STATUS
328   value specified by StatusParameter.  If StatusParameter is an error code,
329   then DebugAssert() is called passing in the source filename, source line
330   number, and StatusParameter.
331 
332   @param  StatusParameter  EFI_STATUS value to evaluate.
333 
334 **/
335 #if !defined(MDEPKG_NDEBUG)
336   #define ASSERT_EFI_ERROR(StatusParameter)                                              \
337     do {                                                                                 \
338       if (DebugAssertEnabled ()) {                                                       \
339         if (EFI_ERROR (StatusParameter)) {                                               \
340           DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", StatusParameter));  \
341           _ASSERT (!EFI_ERROR (StatusParameter));                                        \
342         }                                                                                \
343       }                                                                                  \
344     } while (FALSE)
345 #else
346   #define ASSERT_EFI_ERROR(StatusParameter)
347 #endif
348 
349 /**
350   Macro that calls DebugAssert() if a protocol is already installed in the
351   handle database.
352 
353   If MDEPKG_NDEBUG is defined or the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit
354   of PcdDebugProperyMask is clear, then return.
355 
356   If Handle is NULL, then a check is made to see if the protocol specified by Guid
357   is present on any handle in the handle database.  If Handle is not NULL, then
358   a check is made to see if the protocol specified by Guid is present on the
359   handle specified by Handle.  If the check finds the protocol, then DebugAssert()
360   is called passing in the source filename, source line number, and Guid.
361 
362   If Guid is NULL, then ASSERT().
363 
364   @param  Handle  The handle to check for the protocol.  This is an optional
365                   parameter that may be NULL.  If it is NULL, then the entire
366                   handle database is searched.
367 
368   @param  Guid    The pointer to a protocol GUID.
369 
370 **/
371 #if !defined(MDEPKG_NDEBUG)
372   #define ASSERT_PROTOCOL_ALREADY_INSTALLED(Handle, Guid)                               \
373     do {                                                                                \
374       if (DebugAssertEnabled ()) {                                                      \
375         VOID  *Instance;                                                                \
376         ASSERT (Guid != NULL);                                                          \
377         if (Handle == NULL) {                                                           \
378           if (!EFI_ERROR (gBS->LocateProtocol ((EFI_GUID *)Guid, NULL, &Instance))) {   \
379             _ASSERT (Guid already installed in database);                               \
380           }                                                                             \
381         } else {                                                                        \
382           if (!EFI_ERROR (gBS->HandleProtocol (Handle, (EFI_GUID *)Guid, &Instance))) { \
383             _ASSERT (Guid already installed on Handle);                                 \
384           }                                                                             \
385         }                                                                               \
386       }                                                                                 \
387     } while (FALSE)
388 #else
389   #define ASSERT_PROTOCOL_ALREADY_INSTALLED(Handle, Guid)
390 #endif
391 
392 /**
393   Macro that marks the beginning of debug source code.
394 
395   If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set,
396   then this macro marks the beginning of source code that is included in a module.
397   Otherwise, the source lines between DEBUG_CODE_BEGIN() and DEBUG_CODE_END()
398   are not included in a module.
399 
400 **/
401 #define DEBUG_CODE_BEGIN()  do { if (DebugCodeEnabled ()) { UINT8  __DebugCodeLocal
402 
403 
404 /**
405   The macro that marks the end of debug source code.
406 
407   If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set,
408   then this macro marks the end of source code that is included in a module.
409   Otherwise, the source lines between DEBUG_CODE_BEGIN() and DEBUG_CODE_END()
410   are not included in a module.
411 
412 **/
413 #define DEBUG_CODE_END()    __DebugCodeLocal = 0; __DebugCodeLocal++; } } while (FALSE)
414 
415 
416 /**
417   The macro that declares a section of debug source code.
418 
419   If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set,
420   then the source code specified by Expression is included in a module.
421   Otherwise, the source specified by Expression is not included in a module.
422 
423 **/
424 #define DEBUG_CODE(Expression)  \
425   DEBUG_CODE_BEGIN ();          \
426   Expression                    \
427   DEBUG_CODE_END ()
428 
429 
430 /**
431   The macro that calls DebugClearMemory() to clear a buffer to a default value.
432 
433   If the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set,
434   then this macro calls DebugClearMemory() passing in Address and Length.
435 
436   @param  Address  The pointer to a buffer.
437   @param  Length   The number of bytes in the buffer to set.
438 
439 **/
440 #define DEBUG_CLEAR_MEMORY(Address, Length)  \
441   do {                                       \
442     if (DebugClearMemoryEnabled ()) {        \
443       DebugClearMemory (Address, Length);    \
444     }                                        \
445   } while (FALSE)
446 
447 
448 /**
449   Macro that calls DebugAssert() if the containing record does not have a
450   matching signature.  If the signatures matches, then a pointer to the data
451   structure that contains a specified field of that data structure is returned.
452   This is a lightweight method hide information by placing a public data
453   structure inside a larger private data structure and using a pointer to the
454   public data structure to retrieve a pointer to the private data structure.
455 
456   If MDEPKG_NDEBUG is defined or the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit
457   of PcdDebugProperyMask is clear, then this macro computes the offset, in bytes,
458   of the field specified by Field from the beginning of the data structure specified
459   by TYPE.  This offset is subtracted from Record, and is used to return a pointer
460   to a data structure of the type specified by TYPE.
461 
462   If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit
463   of PcdDebugProperyMask is set, then this macro computes the offset, in bytes,
464   of field specified by Field from the beginning of the data structure specified
465   by TYPE.  This offset is subtracted from Record, and is used to compute a pointer
466   to a data structure of the type specified by TYPE.  The Signature field of the
467   data structure specified by TYPE is compared to TestSignature.  If the signatures
468   match, then a pointer to the pointer to a data structure of the type specified by
469   TYPE is returned.  If the signatures do not match, then DebugAssert() is called
470   with a description of "CR has a bad signature" and Record is returned.
471 
472   If the data type specified by TYPE does not contain the field specified by Field,
473   then the module will not compile.
474 
475   If TYPE does not contain a field called Signature, then the module will not
476   compile.
477 
478   @param  Record         The pointer to the field specified by Field within a data
479                          structure of type TYPE.
480 
481   @param  TYPE           The name of the data structure type to return  This
482                          data structure must contain the field specified by Field.
483 
484   @param  Field          The name of the field in the data structure specified
485                          by TYPE to which Record points.
486 
487   @param  TestSignature  The 32-bit signature value to match.
488 
489 **/
490 #if !defined(MDEPKG_NDEBUG)
491   #define CR(Record, TYPE, Field, TestSignature)                                              \
492     (DebugAssertEnabled () && (BASE_CR (Record, TYPE, Field)->Signature != TestSignature)) ?  \
493     (TYPE *) (_ASSERT (CR has Bad Signature), Record) :                                       \
494     BASE_CR (Record, TYPE, Field)
495 #else
496   #define CR(Record, TYPE, Field, TestSignature)                                              \
497     BASE_CR (Record, TYPE, Field)
498 #endif
499 
500 #endif
501