Home | History | Annotate | Download | only in Library
      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