]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseDebugLibSerialPort/DebugLib.c
MdePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdePkg / Library / BaseDebugLibSerialPort / DebugLib.c
1 /** @file
2 Base Debug library instance base on Serial Port library.
3 It uses PrintLib to send debug messages to serial port device.
4
5 NOTE: If the Serial Port library enables hardware flow control, then a call
6 to DebugPrint() or DebugAssert() may hang if writes to the serial port are
7 being blocked. This may occur if a key(s) are pressed in a terminal emulator
8 used to monitor the DEBUG() and ASSERT() messages.
9
10 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
11 SPDX-License-Identifier: BSD-2-Clause-Patent
12
13 **/
14
15 #include <Base.h>
16 #include <Library/DebugLib.h>
17 #include <Library/BaseLib.h>
18 #include <Library/PrintLib.h>
19 #include <Library/PcdLib.h>
20 #include <Library/BaseMemoryLib.h>
21 #include <Library/SerialPortLib.h>
22 #include <Library/DebugPrintErrorLevelLib.h>
23
24 //
25 // Define the maximum debug and assert message length that this library supports
26 //
27 #define MAX_DEBUG_MESSAGE_LENGTH 0x100
28
29 //
30 // VA_LIST can not initialize to NULL for all compiler, so we use this to
31 // indicate a null VA_LIST
32 //
33 VA_LIST mVaListNull;
34
35 /**
36 The constructor function initialize the Serial Port Library
37
38 @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS.
39
40 **/
41 RETURN_STATUS
42 EFIAPI
43 BaseDebugLibSerialPortConstructor (
44 VOID
45 )
46 {
47 return SerialPortInitialize ();
48 }
49
50 /**
51 Prints a debug message to the debug output device if the specified error level is enabled.
52
53 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
54 GetDebugPrintErrorLevel (), then print the message specified by Format and the
55 associated variable argument list to the debug output device.
56
57 If Format is NULL, then ASSERT().
58
59 @param ErrorLevel The error level of the debug message.
60 @param Format Format string for the debug message to print.
61 @param ... Variable argument list whose contents are accessed
62 based on the format string specified by Format.
63
64 **/
65 VOID
66 EFIAPI
67 DebugPrint (
68 IN UINTN ErrorLevel,
69 IN CONST CHAR8 *Format,
70 ...
71 )
72 {
73 VA_LIST Marker;
74
75 VA_START (Marker, Format);
76 DebugVPrint (ErrorLevel, Format, Marker);
77 VA_END (Marker);
78 }
79
80
81 /**
82 Prints a debug message to the debug output device if the specified
83 error level is enabled base on Null-terminated format string and a
84 VA_LIST argument list or a BASE_LIST argument list.
85
86 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
87 GetDebugPrintErrorLevel (), then print the message specified by Format and
88 the associated variable argument list to the debug output device.
89
90 If Format is NULL, then ASSERT().
91
92 @param ErrorLevel The error level of the debug message.
93 @param Format Format string for the debug message to print.
94 @param VaListMarker VA_LIST marker for the variable argument list.
95 @param BaseListMarker BASE_LIST marker for the variable argument list.
96
97 **/
98 VOID
99 DebugPrintMarker (
100 IN UINTN ErrorLevel,
101 IN CONST CHAR8 *Format,
102 IN VA_LIST VaListMarker,
103 IN BASE_LIST BaseListMarker
104 )
105 {
106 CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
107
108 //
109 // If Format is NULL, then ASSERT().
110 //
111 ASSERT (Format != NULL);
112
113 //
114 // Check driver debug mask value and global mask
115 //
116 if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
117 return;
118 }
119
120 //
121 // Convert the DEBUG() message to an ASCII String
122 //
123 if (BaseListMarker == NULL) {
124 AsciiVSPrint (Buffer, sizeof (Buffer), Format, VaListMarker);
125 } else {
126 AsciiBSPrint (Buffer, sizeof (Buffer), Format, BaseListMarker);
127 }
128
129 //
130 // Send the print string to a Serial Port
131 //
132 SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
133 }
134
135
136 /**
137 Prints a debug message to the debug output device if the specified
138 error level is enabled.
139
140 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
141 GetDebugPrintErrorLevel (), then print the message specified by Format and
142 the associated variable argument list to the debug output device.
143
144 If Format is NULL, then ASSERT().
145
146 @param ErrorLevel The error level of the debug message.
147 @param Format Format string for the debug message to print.
148 @param VaListMarker VA_LIST marker for the variable argument list.
149
150 **/
151 VOID
152 EFIAPI
153 DebugVPrint (
154 IN UINTN ErrorLevel,
155 IN CONST CHAR8 *Format,
156 IN VA_LIST VaListMarker
157 )
158 {
159 DebugPrintMarker (ErrorLevel, Format, VaListMarker, NULL);
160 }
161
162
163 /**
164 Prints a debug message to the debug output device if the specified
165 error level is enabled.
166 This function use BASE_LIST which would provide a more compatible
167 service than VA_LIST.
168
169 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
170 GetDebugPrintErrorLevel (), then print the message specified by Format and
171 the associated variable argument list to the debug output device.
172
173 If Format is NULL, then ASSERT().
174
175 @param ErrorLevel The error level of the debug message.
176 @param Format Format string for the debug message to print.
177 @param BaseListMarker BASE_LIST marker for the variable argument list.
178
179 **/
180 VOID
181 EFIAPI
182 DebugBPrint (
183 IN UINTN ErrorLevel,
184 IN CONST CHAR8 *Format,
185 IN BASE_LIST BaseListMarker
186 )
187 {
188 DebugPrintMarker (ErrorLevel, Format, mVaListNull, BaseListMarker);
189 }
190
191
192 /**
193 Prints an assert message containing a filename, line number, and description.
194 This may be followed by a breakpoint or a dead loop.
195
196 Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
197 to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
198 PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
199 DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
200 CpuDeadLoop() is called. If neither of these bits are set, then this function
201 returns immediately after the message is printed to the debug output device.
202 DebugAssert() must actively prevent recursion. If DebugAssert() is called while
203 processing another DebugAssert(), then DebugAssert() must return immediately.
204
205 If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
206 If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
207
208 @param FileName The pointer to the name of the source file that generated the assert condition.
209 @param LineNumber The line number in the source file that generated the assert condition
210 @param Description The pointer to the description of the assert condition.
211
212 **/
213 VOID
214 EFIAPI
215 DebugAssert (
216 IN CONST CHAR8 *FileName,
217 IN UINTN LineNumber,
218 IN CONST CHAR8 *Description
219 )
220 {
221 CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
222
223 //
224 // Generate the ASSERT() message in Ascii format
225 //
226 AsciiSPrint (Buffer, sizeof (Buffer), "ASSERT [%a] %a(%d): %a\n", gEfiCallerBaseName, FileName, LineNumber, Description);
227
228 //
229 // Send the print string to the Console Output device
230 //
231 SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
232
233 //
234 // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings
235 //
236 if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {
237 CpuBreakpoint ();
238 } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {
239 CpuDeadLoop ();
240 }
241 }
242
243
244 /**
245 Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.
246
247 This function fills Length bytes of Buffer with the value specified by
248 PcdDebugClearMemoryValue, and returns Buffer.
249
250 If Buffer is NULL, then ASSERT().
251 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
252
253 @param Buffer The pointer to the target buffer to be filled with PcdDebugClearMemoryValue.
254 @param Length The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue.
255
256 @return Buffer The pointer to the target buffer filled with PcdDebugClearMemoryValue.
257
258 **/
259 VOID *
260 EFIAPI
261 DebugClearMemory (
262 OUT VOID *Buffer,
263 IN UINTN Length
264 )
265 {
266 //
267 // If Buffer is NULL, then ASSERT().
268 //
269 ASSERT (Buffer != NULL);
270
271 //
272 // SetMem() checks for the the ASSERT() condition on Length and returns Buffer
273 //
274 return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));
275 }
276
277
278 /**
279 Returns TRUE if ASSERT() macros are enabled.
280
281 This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
282 PcdDebugProperyMask is set. Otherwise FALSE is returned.
283
284 @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
285 @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.
286
287 **/
288 BOOLEAN
289 EFIAPI
290 DebugAssertEnabled (
291 VOID
292 )
293 {
294 return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);
295 }
296
297
298 /**
299 Returns TRUE if DEBUG() macros are enabled.
300
301 This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
302 PcdDebugProperyMask is set. Otherwise FALSE is returned.
303
304 @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
305 @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
306
307 **/
308 BOOLEAN
309 EFIAPI
310 DebugPrintEnabled (
311 VOID
312 )
313 {
314 return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);
315 }
316
317
318 /**
319 Returns TRUE if DEBUG_CODE() macros are enabled.
320
321 This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
322 PcdDebugProperyMask is set. Otherwise FALSE is returned.
323
324 @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
325 @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.
326
327 **/
328 BOOLEAN
329 EFIAPI
330 DebugCodeEnabled (
331 VOID
332 )
333 {
334 return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);
335 }
336
337
338 /**
339 Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.
340
341 This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of
342 PcdDebugProperyMask is set. Otherwise FALSE is returned.
343
344 @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
345 @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.
346
347 **/
348 BOOLEAN
349 EFIAPI
350 DebugClearMemoryEnabled (
351 VOID
352 )
353 {
354 return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);
355 }
356
357 /**
358 Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel.
359
360 This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel.
361
362 @retval TRUE Current ErrorLevel is supported.
363 @retval FALSE Current ErrorLevel is not supported.
364
365 **/
366 BOOLEAN
367 EFIAPI
368 DebugPrintLevelEnabled (
369 IN CONST UINTN ErrorLevel
370 )
371 {
372 return (BOOLEAN) ((ErrorLevel & PcdGet32(PcdFixedDebugPrintErrorLevel)) != 0);
373 }
374