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 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 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 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 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 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 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 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 274 DebugPrintLevelEnabled ( 275 IN CONST UINTN ErrorLevel 276 ) 277 { 278 return (BOOLEAN) ((ErrorLevel & PcdGet32(PcdFixedDebugPrintErrorLevel)) != 0); 279 } 280