xref: /freebsd/sys/contrib/edk2/Include/Library/DebugLib.h (revision 580fcf642ea2d5a1e60f24947d1c2e97007e44e9)
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