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