10d1ba665SWarner Losh /** @file 20d1ba665SWarner Losh Provides services to print debug and assert messages to a debug output device. 30d1ba665SWarner Losh 40d1ba665SWarner Losh The Debug library supports debug print and asserts based on a combination of macros and code. 50d1ba665SWarner Losh The debug library can be turned on and off so that the debug code does not increase the size of an image. 60d1ba665SWarner Losh 70d1ba665SWarner Losh Note that a reserved macro named MDEPKG_NDEBUG is introduced for the intention 80d1ba665SWarner Losh of size reduction when compiler optimization is disabled. If MDEPKG_NDEBUG is 90d1ba665SWarner Losh defined, then debug and assert related macros wrapped by it are the NULL implementations. 100d1ba665SWarner Losh 11*580fcf64SWarner Losh The implementations of the macros used when MDEPKG_NDEBUG is defined rely on the fact that 12*580fcf64SWarner Losh directly unreachable code is pruned, even with compiler optimization disabled (which has 13*580fcf64SWarner Losh been confirmed by generated code size tests on supported compilers). The advantage of 14*580fcf64SWarner Losh implementations which consume their arguments within directly unreachable code is that 15*580fcf64SWarner Losh compilers understand this, and stop warning about variables which would become unused when 16*580fcf64SWarner Losh MDEPKG_NDEBUG is defined if the macros had completely empty definitions. 17*580fcf64SWarner Losh 183245fa21SMitchell Horne Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR> 193245fa21SMitchell Horne SPDX-License-Identifier: BSD-2-Clause-Patent 200d1ba665SWarner Losh 210d1ba665SWarner Losh **/ 220d1ba665SWarner Losh 230d1ba665SWarner Losh #ifndef __DEBUG_LIB_H__ 240d1ba665SWarner Losh #define __DEBUG_LIB_H__ 250d1ba665SWarner Losh 260d1ba665SWarner Losh // 270d1ba665SWarner Losh // Declare bits for PcdDebugPropertyMask 280d1ba665SWarner Losh // 290d1ba665SWarner Losh #define DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED 0x01 300d1ba665SWarner Losh #define DEBUG_PROPERTY_DEBUG_PRINT_ENABLED 0x02 310d1ba665SWarner Losh #define DEBUG_PROPERTY_DEBUG_CODE_ENABLED 0x04 320d1ba665SWarner Losh #define DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED 0x08 330d1ba665SWarner Losh #define DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED 0x10 340d1ba665SWarner Losh #define DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED 0x20 350d1ba665SWarner Losh 360d1ba665SWarner Losh // 370d1ba665SWarner Losh // Declare bits for PcdDebugPrintErrorLevel and the ErrorLevel parameter of DebugPrint() 380d1ba665SWarner Losh // 390d1ba665SWarner Losh #define DEBUG_INIT 0x00000001 // Initialization 400d1ba665SWarner Losh #define DEBUG_WARN 0x00000002 // Warnings 410d1ba665SWarner Losh #define DEBUG_LOAD 0x00000004 // Load events 420d1ba665SWarner Losh #define DEBUG_FS 0x00000008 // EFI File system 430d1ba665SWarner Losh #define DEBUG_POOL 0x00000010 // Alloc & Free (pool) 440d1ba665SWarner Losh #define DEBUG_PAGE 0x00000020 // Alloc & Free (page) 450d1ba665SWarner Losh #define DEBUG_INFO 0x00000040 // Informational debug messages 460d1ba665SWarner Losh #define DEBUG_DISPATCH 0x00000080 // PEI/DXE/SMM Dispatchers 470d1ba665SWarner Losh #define DEBUG_VARIABLE 0x00000100 // Variable 480d1ba665SWarner Losh #define DEBUG_BM 0x00000400 // Boot Manager 490d1ba665SWarner Losh #define DEBUG_BLKIO 0x00001000 // BlkIo Driver 500d1ba665SWarner Losh #define DEBUG_NET 0x00004000 // Network Io Driver 510d1ba665SWarner Losh #define DEBUG_UNDI 0x00010000 // UNDI Driver 520d1ba665SWarner Losh #define DEBUG_LOADFILE 0x00020000 // LoadFile 530d1ba665SWarner Losh #define DEBUG_EVENT 0x00080000 // Event messages 540d1ba665SWarner Losh #define DEBUG_GCD 0x00100000 // Global Coherency Database changes 550d1ba665SWarner Losh #define DEBUG_CACHE 0x00200000 // Memory range cachability changes 560d1ba665SWarner Losh #define DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may 570d1ba665SWarner Losh // significantly impact boot performance 58*580fcf64SWarner Losh #define DEBUG_MANAGEABILITY 0x00800000 // Detailed debug and payload manageability messages 59*580fcf64SWarner Losh // related to modules such as Redfish, IPMI, MCTP etc. 600d1ba665SWarner Losh #define DEBUG_ERROR 0x80000000 // Error 610d1ba665SWarner Losh 620d1ba665SWarner Losh // 630d1ba665SWarner Losh // Aliases of debug message mask bits 640d1ba665SWarner Losh // 650d1ba665SWarner Losh #define EFI_D_INIT DEBUG_INIT 660d1ba665SWarner Losh #define EFI_D_WARN DEBUG_WARN 670d1ba665SWarner Losh #define EFI_D_LOAD DEBUG_LOAD 680d1ba665SWarner Losh #define EFI_D_FS DEBUG_FS 690d1ba665SWarner Losh #define EFI_D_POOL DEBUG_POOL 700d1ba665SWarner Losh #define EFI_D_PAGE DEBUG_PAGE 710d1ba665SWarner Losh #define EFI_D_INFO DEBUG_INFO 720d1ba665SWarner Losh #define EFI_D_DISPATCH DEBUG_DISPATCH 730d1ba665SWarner Losh #define EFI_D_VARIABLE DEBUG_VARIABLE 740d1ba665SWarner Losh #define EFI_D_BM DEBUG_BM 750d1ba665SWarner Losh #define EFI_D_BLKIO DEBUG_BLKIO 760d1ba665SWarner Losh #define EFI_D_NET DEBUG_NET 770d1ba665SWarner Losh #define EFI_D_UNDI DEBUG_UNDI 780d1ba665SWarner Losh #define EFI_D_LOADFILE DEBUG_LOADFILE 790d1ba665SWarner Losh #define EFI_D_EVENT DEBUG_EVENT 800d1ba665SWarner Losh #define EFI_D_VERBOSE DEBUG_VERBOSE 810d1ba665SWarner Losh #define EFI_D_ERROR DEBUG_ERROR 820d1ba665SWarner Losh 83*580fcf64SWarner Losh // 84*580fcf64SWarner Losh // Source file line number. 85*580fcf64SWarner Losh // Default is use the to compiler provided __LINE__ macro value. The __LINE__ 86*580fcf64SWarner Losh // mapping can be overriden by predefining DEBUG_LINE_NUMBER 87*580fcf64SWarner Losh // 88*580fcf64SWarner Losh // Defining DEBUG_LINE_NUMBER to a fixed value is useful when comparing builds 89*580fcf64SWarner Losh // across source code formatting changes that may add/remove lines in a source 90*580fcf64SWarner Losh // file. 91*580fcf64SWarner Losh // 92*580fcf64SWarner Losh #ifdef DEBUG_LINE_NUMBER 93*580fcf64SWarner Losh #else 94*580fcf64SWarner Losh #define DEBUG_LINE_NUMBER __LINE__ 95*580fcf64SWarner Losh #endif 96*580fcf64SWarner Losh 97*580fcf64SWarner Losh /** 98*580fcf64SWarner Losh Macro that converts a Boolean expression to a Null-terminated ASCII string. 99*580fcf64SWarner Losh 100*580fcf64SWarner Losh The default is to use the C pre-processor stringizing operator '#' to add 101*580fcf64SWarner Losh quotes around the C expression. If DEBUG_EXPRESSION_STRING_VALUE is defined 102*580fcf64SWarner Losh then the C expression is converted to the fixed string value. 103*580fcf64SWarner Losh 104*580fcf64SWarner Losh Defining DEBUG_EXPRESSION_STRING_VALUE to a fixed value is useful when 105*580fcf64SWarner Losh comparing builds across source code formatting changes that may make 106*580fcf64SWarner Losh changes to spaces or parenthesis in a Boolean expression. 107*580fcf64SWarner Losh 108*580fcf64SWarner Losh @param Expression Boolean expression. 109*580fcf64SWarner Losh 110*580fcf64SWarner Losh **/ 111*580fcf64SWarner Losh 112*580fcf64SWarner Losh #ifdef DEBUG_EXPRESSION_STRING_VALUE 113*580fcf64SWarner Losh #define DEBUG_EXPRESSION_STRING(Expression) DEBUG_EXPRESSION_STRING_VALUE 114*580fcf64SWarner Losh #else 115*580fcf64SWarner Losh #define DEBUG_EXPRESSION_STRING(Expression) #Expression 116*580fcf64SWarner Losh #endif 117*580fcf64SWarner Losh 1180d1ba665SWarner Losh /** 1190d1ba665SWarner Losh Prints a debug message to the debug output device if the specified error level is enabled. 1200d1ba665SWarner Losh 1210d1ba665SWarner Losh If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function 1220d1ba665SWarner Losh GetDebugPrintErrorLevel (), then print the message specified by Format and the 1230d1ba665SWarner Losh associated variable argument list to the debug output device. 1240d1ba665SWarner Losh 1250d1ba665SWarner Losh If Format is NULL, then ASSERT(). 1260d1ba665SWarner Losh 1270d1ba665SWarner Losh @param ErrorLevel The error level of the debug message. 1280d1ba665SWarner Losh @param Format The format string for the debug message to print. 1290d1ba665SWarner Losh @param ... The variable argument list whose contents are accessed 1300d1ba665SWarner Losh based on the format string specified by Format. 1310d1ba665SWarner Losh 1320d1ba665SWarner Losh **/ 1330d1ba665SWarner Losh VOID 1340d1ba665SWarner Losh EFIAPI 1350d1ba665SWarner Losh DebugPrint ( 1360d1ba665SWarner Losh IN UINTN ErrorLevel, 1370d1ba665SWarner Losh IN CONST CHAR8 *Format, 1380d1ba665SWarner Losh ... 1390d1ba665SWarner Losh ); 1400d1ba665SWarner Losh 1410d1ba665SWarner Losh /** 1423245fa21SMitchell Horne Prints a debug message to the debug output device if the specified 1433245fa21SMitchell Horne error level is enabled. 1443245fa21SMitchell Horne 1453245fa21SMitchell Horne If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function 1463245fa21SMitchell Horne GetDebugPrintErrorLevel (), then print the message specified by Format and 1473245fa21SMitchell Horne the associated variable argument list to the debug output device. 1483245fa21SMitchell Horne 1493245fa21SMitchell Horne If Format is NULL, then ASSERT(). 1503245fa21SMitchell Horne 1513245fa21SMitchell Horne @param ErrorLevel The error level of the debug message. 1523245fa21SMitchell Horne @param Format Format string for the debug message to print. 1533245fa21SMitchell Horne @param VaListMarker VA_LIST marker for the variable argument list. 1543245fa21SMitchell Horne 1553245fa21SMitchell Horne **/ 1563245fa21SMitchell Horne VOID 1573245fa21SMitchell Horne EFIAPI 1583245fa21SMitchell Horne DebugVPrint ( 1593245fa21SMitchell Horne IN UINTN ErrorLevel, 1603245fa21SMitchell Horne IN CONST CHAR8 *Format, 1613245fa21SMitchell Horne IN VA_LIST VaListMarker 1623245fa21SMitchell Horne ); 1633245fa21SMitchell Horne 1643245fa21SMitchell Horne /** 1653245fa21SMitchell Horne Prints a debug message to the debug output device if the specified 1663245fa21SMitchell Horne error level is enabled. 1673245fa21SMitchell Horne This function use BASE_LIST which would provide a more compatible 1683245fa21SMitchell Horne service than VA_LIST. 1693245fa21SMitchell Horne 1703245fa21SMitchell Horne If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function 1713245fa21SMitchell Horne GetDebugPrintErrorLevel (), then print the message specified by Format and 1723245fa21SMitchell Horne the associated variable argument list to the debug output device. 1733245fa21SMitchell Horne 1743245fa21SMitchell Horne If Format is NULL, then ASSERT(). 1753245fa21SMitchell Horne 1763245fa21SMitchell Horne @param ErrorLevel The error level of the debug message. 1773245fa21SMitchell Horne @param Format Format string for the debug message to print. 1783245fa21SMitchell Horne @param BaseListMarker BASE_LIST marker for the variable argument list. 1793245fa21SMitchell Horne 1803245fa21SMitchell Horne **/ 1813245fa21SMitchell Horne VOID 1823245fa21SMitchell Horne EFIAPI 1833245fa21SMitchell Horne DebugBPrint ( 1843245fa21SMitchell Horne IN UINTN ErrorLevel, 1853245fa21SMitchell Horne IN CONST CHAR8 *Format, 1863245fa21SMitchell Horne IN BASE_LIST BaseListMarker 1873245fa21SMitchell Horne ); 1883245fa21SMitchell Horne 1893245fa21SMitchell Horne /** 1900d1ba665SWarner Losh Prints an assert message containing a filename, line number, and description. 1910d1ba665SWarner Losh This may be followed by a breakpoint or a dead loop. 1920d1ba665SWarner Losh 1930d1ba665SWarner Losh Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n" 1940d1ba665SWarner Losh to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of 1950d1ba665SWarner Losh PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if 1960d1ba665SWarner Losh DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then 1970d1ba665SWarner Losh CpuDeadLoop() is called. If neither of these bits are set, then this function 1980d1ba665SWarner Losh returns immediately after the message is printed to the debug output device. 1990d1ba665SWarner Losh DebugAssert() must actively prevent recursion. If DebugAssert() is called while 2000d1ba665SWarner Losh processing another DebugAssert(), then DebugAssert() must return immediately. 2010d1ba665SWarner Losh 2020d1ba665SWarner Losh If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed. 2030d1ba665SWarner Losh If Description is NULL, then a <Description> string of "(NULL) Description" is printed. 2040d1ba665SWarner Losh 2050d1ba665SWarner Losh @param FileName The pointer to the name of the source file that generated the assert condition. 2060d1ba665SWarner Losh @param LineNumber The line number in the source file that generated the assert condition 2070d1ba665SWarner Losh @param Description The pointer to the description of the assert condition. 2080d1ba665SWarner Losh 2090d1ba665SWarner Losh **/ 2100d1ba665SWarner Losh VOID 2110d1ba665SWarner Losh EFIAPI 2120d1ba665SWarner Losh DebugAssert ( 2130d1ba665SWarner Losh IN CONST CHAR8 *FileName, 2140d1ba665SWarner Losh IN UINTN LineNumber, 2150d1ba665SWarner Losh IN CONST CHAR8 *Description 2160d1ba665SWarner Losh ); 2170d1ba665SWarner Losh 2180d1ba665SWarner Losh /** 2190d1ba665SWarner Losh Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer. 2200d1ba665SWarner Losh 2210d1ba665SWarner Losh This function fills Length bytes of Buffer with the value specified by 2220d1ba665SWarner Losh PcdDebugClearMemoryValue, and returns Buffer. 2230d1ba665SWarner Losh 2240d1ba665SWarner Losh If Buffer is NULL, then ASSERT(). 2250d1ba665SWarner Losh If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). 2260d1ba665SWarner Losh 2270d1ba665SWarner Losh @param Buffer The pointer to the target buffer to be filled with PcdDebugClearMemoryValue. 2280d1ba665SWarner Losh @param Length The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. 2290d1ba665SWarner Losh 2300d1ba665SWarner Losh @return Buffer The pointer to the target buffer filled with PcdDebugClearMemoryValue. 2310d1ba665SWarner Losh 2320d1ba665SWarner Losh **/ 2330d1ba665SWarner Losh VOID * 2340d1ba665SWarner Losh EFIAPI 2350d1ba665SWarner Losh DebugClearMemory ( 2360d1ba665SWarner Losh OUT VOID *Buffer, 2370d1ba665SWarner Losh IN UINTN Length 2380d1ba665SWarner Losh ); 2390d1ba665SWarner Losh 2400d1ba665SWarner Losh /** 2410d1ba665SWarner Losh Returns TRUE if ASSERT() macros are enabled. 2420d1ba665SWarner Losh 2430d1ba665SWarner Losh This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of 2440d1ba665SWarner Losh PcdDebugProperyMask is set. Otherwise, FALSE is returned. 2450d1ba665SWarner Losh 2460d1ba665SWarner Losh @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set. 2470d1ba665SWarner Losh @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear. 2480d1ba665SWarner Losh 2490d1ba665SWarner Losh **/ 2500d1ba665SWarner Losh BOOLEAN 2510d1ba665SWarner Losh EFIAPI 2520d1ba665SWarner Losh DebugAssertEnabled ( 2530d1ba665SWarner Losh VOID 2540d1ba665SWarner Losh ); 2550d1ba665SWarner Losh 2560d1ba665SWarner Losh /** 2570d1ba665SWarner Losh Returns TRUE if DEBUG() macros are enabled. 2580d1ba665SWarner Losh 2590d1ba665SWarner Losh This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of 2600d1ba665SWarner Losh PcdDebugProperyMask is set. Otherwise, FALSE is returned. 2610d1ba665SWarner Losh 2620d1ba665SWarner Losh @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set. 2630d1ba665SWarner Losh @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear. 2640d1ba665SWarner Losh 2650d1ba665SWarner Losh **/ 2660d1ba665SWarner Losh BOOLEAN 2670d1ba665SWarner Losh EFIAPI 2680d1ba665SWarner Losh DebugPrintEnabled ( 2690d1ba665SWarner Losh VOID 2700d1ba665SWarner Losh ); 2710d1ba665SWarner Losh 2720d1ba665SWarner Losh /** 2730d1ba665SWarner Losh Returns TRUE if DEBUG_CODE() macros are enabled. 2740d1ba665SWarner Losh 2750d1ba665SWarner Losh This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of 2760d1ba665SWarner Losh PcdDebugProperyMask is set. Otherwise, FALSE is returned. 2770d1ba665SWarner Losh 2780d1ba665SWarner Losh @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set. 2790d1ba665SWarner Losh @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear. 2800d1ba665SWarner Losh 2810d1ba665SWarner Losh **/ 2820d1ba665SWarner Losh BOOLEAN 2830d1ba665SWarner Losh EFIAPI 2840d1ba665SWarner Losh DebugCodeEnabled ( 2850d1ba665SWarner Losh VOID 2860d1ba665SWarner Losh ); 2870d1ba665SWarner Losh 2880d1ba665SWarner Losh /** 2890d1ba665SWarner Losh Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled. 2900d1ba665SWarner Losh 2910d1ba665SWarner Losh This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of 2920d1ba665SWarner Losh PcdDebugProperyMask is set. Otherwise, FALSE is returned. 2930d1ba665SWarner Losh 2940d1ba665SWarner Losh @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set. 2950d1ba665SWarner Losh @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear. 2960d1ba665SWarner Losh 2970d1ba665SWarner Losh **/ 2980d1ba665SWarner Losh BOOLEAN 2990d1ba665SWarner Losh EFIAPI 3000d1ba665SWarner Losh DebugClearMemoryEnabled ( 3010d1ba665SWarner Losh VOID 3020d1ba665SWarner Losh ); 3030d1ba665SWarner Losh 3040d1ba665SWarner Losh /** 3050d1ba665SWarner Losh Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel. 3060d1ba665SWarner Losh 3070d1ba665SWarner Losh This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel. 3080d1ba665SWarner Losh 3090d1ba665SWarner Losh @retval TRUE Current ErrorLevel is supported. 3100d1ba665SWarner Losh @retval FALSE Current ErrorLevel is not supported. 3110d1ba665SWarner Losh 3120d1ba665SWarner Losh **/ 3130d1ba665SWarner Losh BOOLEAN 3140d1ba665SWarner Losh EFIAPI 3150d1ba665SWarner Losh DebugPrintLevelEnabled ( 3160d1ba665SWarner Losh IN CONST UINTN ErrorLevel 3170d1ba665SWarner Losh ); 3180d1ba665SWarner Losh 3190d1ba665SWarner Losh /** 3200d1ba665SWarner Losh Internal worker macro that calls DebugAssert(). 3210d1ba665SWarner Losh 3220d1ba665SWarner Losh This macro calls DebugAssert(), passing in the filename, line number, and an 3230d1ba665SWarner Losh expression that evaluated to FALSE. 3240d1ba665SWarner Losh 3250d1ba665SWarner Losh @param Expression Boolean expression that evaluated to FALSE 3260d1ba665SWarner Losh 3270d1ba665SWarner Losh **/ 328*580fcf64SWarner Losh #if defined (EDKII_UNIT_TEST_FRAMEWORK_ENABLED) 3290d1ba665SWarner Losh 330*580fcf64SWarner Losh /** 331*580fcf64SWarner Losh Unit test library replacement for DebugAssert() in DebugLib. 332*580fcf64SWarner Losh 333*580fcf64SWarner Losh If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed. 334*580fcf64SWarner Losh If Description is NULL, then a <Description> string of "(NULL) Description" is printed. 335*580fcf64SWarner Losh 336*580fcf64SWarner Losh @param FileName The pointer to the name of the source file that generated the assert condition. 337*580fcf64SWarner Losh @param LineNumber The line number in the source file that generated the assert condition 338*580fcf64SWarner Losh @param Description The pointer to the description of the assert condition. 339*580fcf64SWarner Losh 340*580fcf64SWarner Losh **/ 341*580fcf64SWarner Losh VOID 342*580fcf64SWarner Losh EFIAPI 343*580fcf64SWarner Losh UnitTestDebugAssert ( 344*580fcf64SWarner Losh IN CONST CHAR8 *FileName, 345*580fcf64SWarner Losh IN UINTN LineNumber, 346*580fcf64SWarner Losh IN CONST CHAR8 *Description 347*580fcf64SWarner Losh ); 348*580fcf64SWarner Losh 349*580fcf64SWarner Losh #if defined (_ASSERT) 350*580fcf64SWarner Losh #undef _ASSERT 351*580fcf64SWarner Losh #endif 352*580fcf64SWarner Losh #if defined (__FILE_NAME__) 353*580fcf64SWarner Losh #define _ASSERT(Expression) UnitTestDebugAssert (__FILE_NAME__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) 354*580fcf64SWarner Losh #else 355*580fcf64SWarner Losh #define _ASSERT(Expression) UnitTestDebugAssert (__FILE__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) 356*580fcf64SWarner Losh #endif 357*580fcf64SWarner Losh #else 358*580fcf64SWarner Losh #if defined (__FILE_NAME__) 359*580fcf64SWarner Losh #define _ASSERT(Expression) DebugAssert (__FILE_NAME__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) 360*580fcf64SWarner Losh #else 361*580fcf64SWarner Losh #define _ASSERT(Expression) DebugAssert (__FILE__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) 362*580fcf64SWarner Losh #endif 363*580fcf64SWarner Losh #endif 3640d1ba665SWarner Losh 3650d1ba665SWarner Losh /** 3660d1ba665SWarner Losh Internal worker macro that calls DebugPrint(). 3670d1ba665SWarner Losh 3680d1ba665SWarner Losh This macro calls DebugPrint() passing in the debug error level, a format 3690d1ba665SWarner Losh string, and a variable argument list. 3700d1ba665SWarner Losh __VA_ARGS__ is not supported by EBC compiler, Microsoft Visual Studio .NET 2003 3710d1ba665SWarner Losh and Microsoft Windows Server 2003 Driver Development Kit (Microsoft WINDDK) version 3790.1830. 3720d1ba665SWarner Losh 3730d1ba665SWarner Losh @param Expression Expression containing an error level, a format string, 3740d1ba665SWarner Losh and a variable argument list based on the format string. 3750d1ba665SWarner Losh 3760d1ba665SWarner Losh **/ 3770d1ba665SWarner Losh 3780d1ba665SWarner Losh #if !defined (MDE_CPU_EBC) && (!defined (_MSC_VER) || _MSC_VER > 1400) 3790d1ba665SWarner Losh #define _DEBUG_PRINT(PrintLevel, ...) \ 3800d1ba665SWarner Losh do { \ 3810d1ba665SWarner Losh if (DebugPrintLevelEnabled (PrintLevel)) { \ 3820d1ba665SWarner Losh DebugPrint (PrintLevel, ##__VA_ARGS__); \ 3830d1ba665SWarner Losh } \ 3840d1ba665SWarner Losh } while (FALSE) 385*580fcf64SWarner Losh #define _DEBUGLIB_DEBUG(Expression) _DEBUG_PRINT Expression 3860d1ba665SWarner Losh #else 387*580fcf64SWarner Losh #define _DEBUGLIB_DEBUG(Expression) DebugPrint Expression 3880d1ba665SWarner Losh #endif 3890d1ba665SWarner Losh 3900d1ba665SWarner Losh /** 3910d1ba665SWarner Losh Macro that calls DebugAssert() if an expression evaluates to FALSE. 3920d1ba665SWarner Losh 3930d1ba665SWarner Losh If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED 3940d1ba665SWarner Losh bit of PcdDebugProperyMask is set, then this macro evaluates the Boolean 3950d1ba665SWarner Losh expression specified by Expression. If Expression evaluates to FALSE, then 3960d1ba665SWarner Losh DebugAssert() is called passing in the source filename, source line number, 3970d1ba665SWarner Losh and Expression. 3980d1ba665SWarner Losh 3990d1ba665SWarner Losh @param Expression Boolean expression. 4000d1ba665SWarner Losh 4010d1ba665SWarner Losh **/ 4020d1ba665SWarner Losh #if !defined (MDEPKG_NDEBUG) 4030d1ba665SWarner Losh #define ASSERT(Expression) \ 4040d1ba665SWarner Losh do { \ 4050d1ba665SWarner Losh if (DebugAssertEnabled ()) { \ 4060d1ba665SWarner Losh if (!(Expression)) { \ 4070d1ba665SWarner Losh _ASSERT (Expression); \ 4080d1ba665SWarner Losh ANALYZER_UNREACHABLE (); \ 4090d1ba665SWarner Losh } \ 4100d1ba665SWarner Losh } \ 4110d1ba665SWarner Losh } while (FALSE) 4120d1ba665SWarner Losh #else 413*580fcf64SWarner Losh #define ASSERT(Expression) \ 414*580fcf64SWarner Losh do { \ 415*580fcf64SWarner Losh if (FALSE) { \ 416*580fcf64SWarner Losh (VOID) (Expression); \ 417*580fcf64SWarner Losh } \ 418*580fcf64SWarner Losh } while (FALSE) 4190d1ba665SWarner Losh #endif 4200d1ba665SWarner Losh 4210d1ba665SWarner Losh /** 4220d1ba665SWarner Losh Macro that calls DebugPrint(). 4230d1ba665SWarner Losh 4240d1ba665SWarner Losh If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED 4250d1ba665SWarner Losh bit of PcdDebugProperyMask is set, then this macro passes Expression to 4260d1ba665SWarner Losh DebugPrint(). 4270d1ba665SWarner Losh 4280d1ba665SWarner Losh @param Expression Expression containing an error level, a format string, 4290d1ba665SWarner Losh and a variable argument list based on the format string. 4300d1ba665SWarner Losh 4310d1ba665SWarner Losh 4320d1ba665SWarner Losh **/ 4330d1ba665SWarner Losh #if !defined (MDEPKG_NDEBUG) 4340d1ba665SWarner Losh #define DEBUG(Expression) \ 4350d1ba665SWarner Losh do { \ 4360d1ba665SWarner Losh if (DebugPrintEnabled ()) { \ 437*580fcf64SWarner Losh _DEBUGLIB_DEBUG (Expression); \ 4380d1ba665SWarner Losh } \ 4390d1ba665SWarner Losh } while (FALSE) 4400d1ba665SWarner Losh #else 441*580fcf64SWarner Losh #define DEBUG(Expression) \ 442*580fcf64SWarner Losh do { \ 443*580fcf64SWarner Losh if (FALSE) { \ 444*580fcf64SWarner Losh _DEBUGLIB_DEBUG (Expression); \ 445*580fcf64SWarner Losh } \ 446*580fcf64SWarner Losh } while (FALSE) 4470d1ba665SWarner Losh #endif 4480d1ba665SWarner Losh 4490d1ba665SWarner Losh /** 4500d1ba665SWarner Losh Macro that calls DebugAssert() if an EFI_STATUS evaluates to an error code. 4510d1ba665SWarner Losh 4520d1ba665SWarner Losh If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED 4530d1ba665SWarner Losh bit of PcdDebugProperyMask is set, then this macro evaluates the EFI_STATUS 4540d1ba665SWarner Losh value specified by StatusParameter. If StatusParameter is an error code, 4550d1ba665SWarner Losh then DebugAssert() is called passing in the source filename, source line 4560d1ba665SWarner Losh number, and StatusParameter. 4570d1ba665SWarner Losh 4580d1ba665SWarner Losh @param StatusParameter EFI_STATUS value to evaluate. 4590d1ba665SWarner Losh 4600d1ba665SWarner Losh **/ 4610d1ba665SWarner Losh #if !defined (MDEPKG_NDEBUG) 4620d1ba665SWarner Losh #define ASSERT_EFI_ERROR(StatusParameter) \ 4630d1ba665SWarner Losh do { \ 4640d1ba665SWarner Losh if (DebugAssertEnabled ()) { \ 4650d1ba665SWarner Losh if (EFI_ERROR (StatusParameter)) { \ 466*580fcf64SWarner Losh DEBUG ((DEBUG_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", StatusParameter)); \ 4670d1ba665SWarner Losh _ASSERT (!EFI_ERROR (StatusParameter)); \ 4680d1ba665SWarner Losh } \ 4690d1ba665SWarner Losh } \ 4700d1ba665SWarner Losh } while (FALSE) 4710d1ba665SWarner Losh #else 472*580fcf64SWarner Losh #define ASSERT_EFI_ERROR(StatusParameter) \ 473*580fcf64SWarner Losh do { \ 474*580fcf64SWarner Losh if (FALSE) { \ 475*580fcf64SWarner Losh (VOID) (StatusParameter); \ 476*580fcf64SWarner Losh } \ 477*580fcf64SWarner Losh } while (FALSE) 4780d1ba665SWarner Losh #endif 4790d1ba665SWarner Losh 4800d1ba665SWarner Losh /** 4810d1ba665SWarner Losh Macro that calls DebugAssert() if a RETURN_STATUS evaluates to an error code. 4820d1ba665SWarner Losh 4830d1ba665SWarner Losh If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED 4840d1ba665SWarner Losh bit of PcdDebugProperyMask is set, then this macro evaluates the 4850d1ba665SWarner Losh RETURN_STATUS value specified by StatusParameter. If StatusParameter is an 4860d1ba665SWarner Losh error code, then DebugAssert() is called passing in the source filename, 4870d1ba665SWarner Losh source line number, and StatusParameter. 4880d1ba665SWarner Losh 4890d1ba665SWarner Losh @param StatusParameter RETURN_STATUS value to evaluate. 4900d1ba665SWarner Losh 4910d1ba665SWarner Losh **/ 4920d1ba665SWarner Losh #if !defined (MDEPKG_NDEBUG) 4930d1ba665SWarner Losh #define ASSERT_RETURN_ERROR(StatusParameter) \ 4940d1ba665SWarner Losh do { \ 4950d1ba665SWarner Losh if (DebugAssertEnabled ()) { \ 4960d1ba665SWarner Losh if (RETURN_ERROR (StatusParameter)) { \ 4970d1ba665SWarner Losh DEBUG ((DEBUG_ERROR, "\nASSERT_RETURN_ERROR (Status = %r)\n", \ 4980d1ba665SWarner Losh StatusParameter)); \ 4990d1ba665SWarner Losh _ASSERT (!RETURN_ERROR (StatusParameter)); \ 5000d1ba665SWarner Losh } \ 5010d1ba665SWarner Losh } \ 5020d1ba665SWarner Losh } while (FALSE) 5030d1ba665SWarner Losh #else 504*580fcf64SWarner Losh #define ASSERT_RETURN_ERROR(StatusParameter) \ 505*580fcf64SWarner Losh do { \ 506*580fcf64SWarner Losh if (FALSE) { \ 507*580fcf64SWarner Losh (VOID) (StatusParameter); \ 508*580fcf64SWarner Losh } \ 509*580fcf64SWarner Losh } while (FALSE) 5100d1ba665SWarner Losh #endif 5110d1ba665SWarner Losh 5120d1ba665SWarner Losh /** 5130d1ba665SWarner Losh Macro that calls DebugAssert() if a protocol is already installed in the 5140d1ba665SWarner Losh handle database. 5150d1ba665SWarner Losh 5160d1ba665SWarner Losh If MDEPKG_NDEBUG is defined or the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit 5170d1ba665SWarner Losh of PcdDebugProperyMask is clear, then return. 5180d1ba665SWarner Losh 5190d1ba665SWarner Losh If Handle is NULL, then a check is made to see if the protocol specified by Guid 5200d1ba665SWarner Losh is present on any handle in the handle database. If Handle is not NULL, then 5210d1ba665SWarner Losh a check is made to see if the protocol specified by Guid is present on the 5220d1ba665SWarner Losh handle specified by Handle. If the check finds the protocol, then DebugAssert() 5230d1ba665SWarner Losh is called passing in the source filename, source line number, and Guid. 5240d1ba665SWarner Losh 5250d1ba665SWarner Losh If Guid is NULL, then ASSERT(). 5260d1ba665SWarner Losh 5270d1ba665SWarner Losh @param Handle The handle to check for the protocol. This is an optional 5280d1ba665SWarner Losh parameter that may be NULL. If it is NULL, then the entire 5290d1ba665SWarner Losh handle database is searched. 5300d1ba665SWarner Losh 5310d1ba665SWarner Losh @param Guid The pointer to a protocol GUID. 5320d1ba665SWarner Losh 5330d1ba665SWarner Losh **/ 5340d1ba665SWarner Losh #if !defined (MDEPKG_NDEBUG) 5350d1ba665SWarner Losh #define ASSERT_PROTOCOL_ALREADY_INSTALLED(Handle, Guid) \ 5360d1ba665SWarner Losh do { \ 5370d1ba665SWarner Losh if (DebugAssertEnabled ()) { \ 5380d1ba665SWarner Losh VOID *Instance; \ 5390d1ba665SWarner Losh ASSERT (Guid != NULL); \ 5400d1ba665SWarner Losh if (Handle == NULL) { \ 5410d1ba665SWarner Losh if (!EFI_ERROR (gBS->LocateProtocol ((EFI_GUID *)Guid, NULL, &Instance))) { \ 5420d1ba665SWarner Losh _ASSERT (Guid already installed in database); \ 5430d1ba665SWarner Losh } \ 5440d1ba665SWarner Losh } else { \ 5450d1ba665SWarner Losh if (!EFI_ERROR (gBS->HandleProtocol (Handle, (EFI_GUID *)Guid, &Instance))) { \ 5460d1ba665SWarner Losh _ASSERT (Guid already installed on Handle); \ 5470d1ba665SWarner Losh } \ 5480d1ba665SWarner Losh } \ 5490d1ba665SWarner Losh } \ 5500d1ba665SWarner Losh } while (FALSE) 5510d1ba665SWarner Losh #else 5520d1ba665SWarner Losh #define ASSERT_PROTOCOL_ALREADY_INSTALLED(Handle, Guid) 5530d1ba665SWarner Losh #endif 5540d1ba665SWarner Losh 5550d1ba665SWarner Losh /** 5560d1ba665SWarner Losh Macro that marks the beginning of debug source code. 5570d1ba665SWarner Losh 5580d1ba665SWarner Losh If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set, 5590d1ba665SWarner Losh then this macro marks the beginning of source code that is included in a module. 5600d1ba665SWarner Losh Otherwise, the source lines between DEBUG_CODE_BEGIN() and DEBUG_CODE_END() 5610d1ba665SWarner Losh are not included in a module. 5620d1ba665SWarner Losh 5630d1ba665SWarner Losh **/ 564*580fcf64SWarner Losh #define DEBUG_CODE_BEGIN() \ 565*580fcf64SWarner Losh do { \ 566*580fcf64SWarner Losh if (DebugCodeEnabled ()) { \ 567*580fcf64SWarner Losh do { } while (FALSE) 5680d1ba665SWarner Losh 5690d1ba665SWarner Losh /** 5700d1ba665SWarner Losh The macro that marks the end of debug source code. 5710d1ba665SWarner Losh 5720d1ba665SWarner Losh If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set, 5730d1ba665SWarner Losh then this macro marks the end of source code that is included in a module. 5740d1ba665SWarner Losh Otherwise, the source lines between DEBUG_CODE_BEGIN() and DEBUG_CODE_END() 5750d1ba665SWarner Losh are not included in a module. 5760d1ba665SWarner Losh 5770d1ba665SWarner Losh **/ 578*580fcf64SWarner Losh #define DEBUG_CODE_END() \ 579*580fcf64SWarner Losh } \ 580*580fcf64SWarner Losh } while (FALSE) 5810d1ba665SWarner Losh 5820d1ba665SWarner Losh /** 5830d1ba665SWarner Losh The macro that declares a section of debug source code. 5840d1ba665SWarner Losh 5850d1ba665SWarner Losh If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set, 5860d1ba665SWarner Losh then the source code specified by Expression is included in a module. 5870d1ba665SWarner Losh Otherwise, the source specified by Expression is not included in a module. 5880d1ba665SWarner Losh 5890d1ba665SWarner Losh **/ 5900d1ba665SWarner Losh #define DEBUG_CODE(Expression) \ 5910d1ba665SWarner Losh DEBUG_CODE_BEGIN (); \ 5920d1ba665SWarner Losh Expression \ 5930d1ba665SWarner Losh DEBUG_CODE_END () 5940d1ba665SWarner Losh 5950d1ba665SWarner Losh /** 5960d1ba665SWarner Losh The macro that calls DebugClearMemory() to clear a buffer to a default value. 5970d1ba665SWarner Losh 5980d1ba665SWarner Losh If the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set, 5990d1ba665SWarner Losh then this macro calls DebugClearMemory() passing in Address and Length. 6000d1ba665SWarner Losh 6010d1ba665SWarner Losh @param Address The pointer to a buffer. 6020d1ba665SWarner Losh @param Length The number of bytes in the buffer to set. 6030d1ba665SWarner Losh 6040d1ba665SWarner Losh **/ 6050d1ba665SWarner Losh #define DEBUG_CLEAR_MEMORY(Address, Length) \ 6060d1ba665SWarner Losh do { \ 6070d1ba665SWarner Losh if (DebugClearMemoryEnabled ()) { \ 6080d1ba665SWarner Losh DebugClearMemory (Address, Length); \ 6090d1ba665SWarner Losh } \ 6100d1ba665SWarner Losh } while (FALSE) 6110d1ba665SWarner Losh 6120d1ba665SWarner Losh /** 6130d1ba665SWarner Losh Macro that calls DebugAssert() if the containing record does not have a 6140d1ba665SWarner Losh matching signature. If the signatures matches, then a pointer to the data 6150d1ba665SWarner Losh structure that contains a specified field of that data structure is returned. 6160d1ba665SWarner Losh This is a lightweight method hide information by placing a public data 6170d1ba665SWarner Losh structure inside a larger private data structure and using a pointer to the 6180d1ba665SWarner Losh public data structure to retrieve a pointer to the private data structure. 6190d1ba665SWarner Losh 6200d1ba665SWarner Losh If MDEPKG_NDEBUG is defined or the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit 6210d1ba665SWarner Losh of PcdDebugProperyMask is clear, then this macro computes the offset, in bytes, 6220d1ba665SWarner Losh of the field specified by Field from the beginning of the data structure specified 623*580fcf64SWarner Losh by TYPE. This offset is subtracted from Record, and is used to compute a pointer 624*580fcf64SWarner Losh to a data structure of the type specified by TYPE. The Signature field of the 625*580fcf64SWarner Losh data structure specified by TYPE is compared to TestSignature. If the signatures 626*580fcf64SWarner Losh match, then a pointer to the pointer to a data structure of the type specified by 627*580fcf64SWarner Losh TYPE is returned. If the signatures do not match, then NULL is returned to 628*580fcf64SWarner Losh signify that the passed in data structure is invalid. 6290d1ba665SWarner Losh 6300d1ba665SWarner Losh If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit 6310d1ba665SWarner Losh of PcdDebugProperyMask is set, then this macro computes the offset, in bytes, 6320d1ba665SWarner Losh of field specified by Field from the beginning of the data structure specified 6330d1ba665SWarner Losh by TYPE. This offset is subtracted from Record, and is used to compute a pointer 6340d1ba665SWarner Losh to a data structure of the type specified by TYPE. The Signature field of the 6350d1ba665SWarner Losh data structure specified by TYPE is compared to TestSignature. If the signatures 6360d1ba665SWarner Losh match, then a pointer to the pointer to a data structure of the type specified by 6370d1ba665SWarner Losh TYPE is returned. If the signatures do not match, then DebugAssert() is called 6380d1ba665SWarner Losh with a description of "CR has a bad signature" and Record is returned. 6390d1ba665SWarner Losh 6400d1ba665SWarner Losh If the data type specified by TYPE does not contain the field specified by Field, 6410d1ba665SWarner Losh then the module will not compile. 6420d1ba665SWarner Losh 6430d1ba665SWarner Losh If TYPE does not contain a field called Signature, then the module will not 6440d1ba665SWarner Losh compile. 6450d1ba665SWarner Losh 6460d1ba665SWarner Losh @param Record The pointer to the field specified by Field within a data 6470d1ba665SWarner Losh structure of type TYPE. 6480d1ba665SWarner Losh 6490d1ba665SWarner Losh @param TYPE The name of the data structure type to return This 6500d1ba665SWarner Losh data structure must contain the field specified by Field. 6510d1ba665SWarner Losh 6520d1ba665SWarner Losh @param Field The name of the field in the data structure specified 6530d1ba665SWarner Losh by TYPE to which Record points. 6540d1ba665SWarner Losh 6550d1ba665SWarner Losh @param TestSignature The 32-bit signature value to match. 6560d1ba665SWarner Losh 6570d1ba665SWarner Losh **/ 6580d1ba665SWarner Losh #if !defined (MDEPKG_NDEBUG) 6590d1ba665SWarner Losh #define CR(Record, TYPE, Field, TestSignature) \ 6600d1ba665SWarner Losh (DebugAssertEnabled () && (BASE_CR (Record, TYPE, Field)->Signature != TestSignature)) ? \ 6610d1ba665SWarner Losh (TYPE *) (_ASSERT (CR has Bad Signature), Record) : \ 662*580fcf64SWarner Losh (BASE_CR (Record, TYPE, Field)->Signature != TestSignature) ? \ 663*580fcf64SWarner Losh NULL : \ 6640d1ba665SWarner Losh BASE_CR (Record, TYPE, Field) 6650d1ba665SWarner Losh #else 6660d1ba665SWarner Losh #define CR(Record, TYPE, Field, TestSignature) \ 667*580fcf64SWarner Losh (BASE_CR (Record, TYPE, Field)->Signature != TestSignature) ? \ 668*580fcf64SWarner Losh NULL : \ 6690d1ba665SWarner Losh BASE_CR (Record, TYPE, Field) 6700d1ba665SWarner Losh #endif 6710d1ba665SWarner Losh 6720d1ba665SWarner Losh #endif 673