1 /** @file
2 UEFI Debug Lib that sends messages to the Standard Error Device in the EFI System Table.
3
4 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15
16 #include <Uefi.h>
17
18 #include <Library/DebugLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/PrintLib.h>
21 #include <Library/PcdLib.h>
22 #include <Library/BaseLib.h>
23 #include <Library/BaseMemoryLib.h>
24 #include <Library/DebugPrintErrorLevelLib.h>
25
26 //
27 // Define the maximum debug and assert message length that this library supports
28 //
29 #define MAX_DEBUG_MESSAGE_LENGTH 0x100
30
31
32 /**
33 Prints a debug message to the debug output device if the specified error level is enabled.
34
35 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
36 GetDebugPrintErrorLevel (), then print the message specified by Format and the
37 associated variable argument list to the debug output device.
38
39 If Format is NULL, then ASSERT().
40
41 @param ErrorLevel The error level of the debug message.
42 @param Format The format string for the debug message to print.
43 @param ... The variable argument list whose contents are accessed
44 based on the format string specified by Format.
45
46 **/
47 VOID
48 EFIAPI
DebugPrint(IN UINTN ErrorLevel,IN CONST CHAR8 * Format,...)49 DebugPrint (
50 IN UINTN ErrorLevel,
51 IN CONST CHAR8 *Format,
52 ...
53 )
54 {
55 CHAR16 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
56 VA_LIST Marker;
57
58 //
59 // If Format is NULL, then ASSERT().
60 //
61 ASSERT (Format != NULL);
62
63 //
64 // Check driver debug mask value and global mask
65 //
66 if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
67 return;
68 }
69
70 //
71 // Convert the DEBUG() message to a Unicode String
72 //
73 VA_START (Marker, Format);
74 UnicodeVSPrintAsciiFormat (Buffer, MAX_DEBUG_MESSAGE_LENGTH, Format, Marker);
75 VA_END (Marker);
76
77 //
78 // Send the print string to the Standard Error device
79 //
80 if ((gST != NULL) && (gST->StdErr != NULL)) {
81 gST->StdErr->OutputString (gST->StdErr, Buffer);
82 }
83 }
84
85
86 /**
87 Prints an assert message containing a filename, line number, and description.
88 This may be followed by a breakpoint or a dead loop.
89
90 Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
91 to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
92 PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
93 DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
94 CpuDeadLoop() is called. If neither of these bits are set, then this function
95 returns immediately after the message is printed to the debug output device.
96 DebugAssert() must actively prevent recursion. If DebugAssert() is called while
97 processing another DebugAssert(), then DebugAssert() must return immediately.
98
99 If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
100 If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
101
102 @param FileName The pointer to the name of the source file that generated
103 the assert condition.
104 @param LineNumber The line number in the source file that generated the
105 assert condition
106 @param Description The pointer to the description of the assert condition.
107
108 **/
109 VOID
110 EFIAPI
DebugAssert(IN CONST CHAR8 * FileName,IN UINTN LineNumber,IN CONST CHAR8 * Description)111 DebugAssert (
112 IN CONST CHAR8 *FileName,
113 IN UINTN LineNumber,
114 IN CONST CHAR8 *Description
115 )
116 {
117 CHAR16 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
118
119 //
120 // Generate the ASSERT() message in Unicode format
121 //
122 UnicodeSPrintAsciiFormat (
123 Buffer,
124 sizeof (Buffer),
125 "ASSERT [%a] %a(%d): %a\n",
126 gEfiCallerBaseName,
127 FileName,
128 LineNumber,
129 Description
130 );
131
132 //
133 // Send the print string to the Standard Error device
134 //
135 if ((gST != NULL) && (gST->StdErr != NULL)) {
136 gST->StdErr->OutputString (gST->StdErr, Buffer);
137 }
138
139 //
140 // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings
141 //
142 if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {
143 CpuBreakpoint ();
144 } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {
145 CpuDeadLoop ();
146 }
147 }
148
149
150 /**
151 Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.
152
153 This function fills Length bytes of Buffer with the value specified by
154 PcdDebugClearMemoryValue, and returns Buffer.
155
156 If Buffer is NULL, then ASSERT().
157 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
158
159 @param Buffer The pointer to the target buffer to be filled with PcdDebugClearMemoryValue.
160 @param Length The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue.
161
162 @return Buffer The pointer to the target buffer filled with PcdDebugClearMemoryValue.
163
164 **/
165 VOID *
166 EFIAPI
DebugClearMemory(OUT VOID * Buffer,IN UINTN Length)167 DebugClearMemory (
168 OUT VOID *Buffer,
169 IN UINTN Length
170 )
171 {
172 //
173 // If Buffer is NULL, then ASSERT().
174 //
175 ASSERT (Buffer != NULL);
176
177 //
178 // SetMem() checks for the the ASSERT() condition on Length and returns Buffer
179 //
180 return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));
181 }
182
183
184 /**
185 Returns TRUE if ASSERT() macros are enabled.
186
187 This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
188 PcdDebugProperyMask is set. Otherwise FALSE is returned.
189
190 @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
191 @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.
192
193 **/
194 BOOLEAN
195 EFIAPI
DebugAssertEnabled(VOID)196 DebugAssertEnabled (
197 VOID
198 )
199 {
200 return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);
201 }
202
203
204 /**
205 Returns TRUE if DEBUG() macros are enabled.
206
207 This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
208 PcdDebugProperyMask is set. Otherwise FALSE is returned.
209
210 @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
211 @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
212
213 **/
214 BOOLEAN
215 EFIAPI
DebugPrintEnabled(VOID)216 DebugPrintEnabled (
217 VOID
218 )
219 {
220 return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);
221 }
222
223
224 /**
225 Returns TRUE if DEBUG_CODE() macros are enabled.
226
227 This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
228 PcdDebugProperyMask is set. Otherwise FALSE is returned.
229
230 @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
231 @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.
232
233 **/
234 BOOLEAN
235 EFIAPI
DebugCodeEnabled(VOID)236 DebugCodeEnabled (
237 VOID
238 )
239 {
240 return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);
241 }
242
243
244 /**
245 Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.
246
247 This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of
248 PcdDebugProperyMask is set. Otherwise FALSE is returned.
249
250 @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
251 @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.
252
253 **/
254 BOOLEAN
255 EFIAPI
DebugClearMemoryEnabled(VOID)256 DebugClearMemoryEnabled (
257 VOID
258 )
259 {
260 return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);
261 }
262
263 /**
264 Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel.
265
266 This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel.
267
268 @retval TRUE Current ErrorLevel is supported.
269 @retval FALSE Current ErrorLevel is not supported.
270
271 **/
272 BOOLEAN
273 EFIAPI
DebugPrintLevelEnabled(IN CONST UINTN ErrorLevel)274 DebugPrintLevelEnabled (
275 IN CONST UINTN ErrorLevel
276 )
277 {
278 return (BOOLEAN) ((ErrorLevel & PcdGet32(PcdFixedDebugPrintErrorLevel)) != 0);
279 }
280