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