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