• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3   Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
4   This program and the accompanying materials
5   are licensed and made available under the terms and conditions of the BSD License
6   which accompanies this distribution.  The full text of the license may be found at
7   http://opensource.org/licenses/bsd-license.php.
8 
9   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 
12 **/
13 
14 #include <Base.h>
15 #include <Library/DebugLib.h>
16 #include <Library/BaseLib.h>
17 #include <Library/PrintLib.h>
18 #include <Library/PcdLib.h>
19 #include <Library/BaseMemoryLib.h>
20 #include <Library/SerialPortLib.h>
21 #include <Library/DebugDeviceLib.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 CONST CHAR8  *mHexTable = "0123456789ABCDEF";
30 
31 /**
32   Get stack frame pointer of function call.
33 
34   @return StackFramePointer  stack frame pointer of function call.
35 **/
36 UINT32 *
37 EFIAPI
38 GetStackFramePointer (
39   VOID
40   );
41 
42 
43 /**
44   Prints a debug message to the debug output device if the specified error level is enabled.
45 
46   If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
47   GetDebugPrintErrorLevel (), then print the message specified by Format and the
48   associated variable argument list to the debug output device.
49 
50   If Format is NULL, then ASSERT().
51 
52   @param  ErrorLevel  The error level of the debug message.
53   @param  Format      Format string for the debug message to print.
54   @param  ...         Variable argument list whose contents are accessed
55                       based on the format string specified by Format.
56 
57 **/
58 VOID
59 EFIAPI
DebugPrint(IN UINTN ErrorLevel,IN CONST CHAR8 * Format,...)60 DebugPrint (
61   IN  UINTN        ErrorLevel,
62   IN  CONST CHAR8  *Format,
63   ...
64   )
65 {
66   CHAR8    Buffer[MAX_DEBUG_MESSAGE_LENGTH];
67   VA_LIST  Marker;
68 
69   //
70   // If Format is NULL, then ASSERT().
71   //
72   if (!GetDebugPrintDeviceEnable ()) {
73     return;
74   }
75 
76   //
77   // Check driver debug mask value and global mask
78   //
79   if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
80     return;
81   }
82 
83   //
84   // If Format is NULL, then ASSERT().
85   //
86   ASSERT (Format != NULL);
87 
88   //
89   // Convert the DEBUG() message to an ASCII String
90   //
91   VA_START (Marker, Format);
92   AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);
93   VA_END (Marker);
94 
95   //
96   // Send the print string to a Serial Port
97   //
98   SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
99 }
100 
101 /**
102   Convert an UINT32 value into HEX string sepcified by Buffer.
103 
104   @param  Value   The HEX value to convert to string
105   @param  Buffer  The pointer to the target buffer to be filled with HEX string
106 
107 **/
108 VOID
FillHex(UINT32 Value,CHAR8 * Buffer)109 FillHex (
110   UINT32   Value,
111   CHAR8   *Buffer
112   )
113 {
114   INTN  Idx;
115   for (Idx = 7; Idx >= 0; Idx--) {
116     Buffer[Idx] = mHexTable[Value & 0x0F];
117     Value >>= 4;
118   }
119 }
120 
121 /**
122   Prints an assert message containing a filename, line number, and description.
123   This may be followed by a breakpoint or a dead loop.
124 
125   Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
126   to the debug output device.  If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
127   PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
128   DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
129   CpuDeadLoop() is called.  If neither of these bits are set, then this function
130   returns immediately after the message is printed to the debug output device.
131   DebugAssert() must actively prevent recursion.  If DebugAssert() is called while
132   processing another DebugAssert(), then DebugAssert() must return immediately.
133 
134   If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
135   If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
136 
137 **/
138 VOID
DebugAssertInternal(VOID)139 DebugAssertInternal (
140   VOID
141   )
142 {
143   CHAR8     Buffer[MAX_DEBUG_MESSAGE_LENGTH];
144   UINT32   *Frame;
145 
146   Frame = (UINT32 *)GetStackFramePointer ();
147 
148   //
149   // Generate the ASSERT() message in Ascii format
150   //
151   AsciiStrnCpyS (
152     Buffer,
153     sizeof(Buffer) / sizeof(CHAR8),
154     "-> EBP:0x00000000  EIP:0x00000000\n",
155     sizeof(Buffer) / sizeof(CHAR8) - 1
156     );
157   SerialPortWrite ((UINT8 *)"ASSERT DUMP:\n", 13);
158   while (Frame != NULL) {
159     FillHex ((UINT32)Frame, Buffer + 9);
160     FillHex (Frame[1], Buffer + 9 + 8 + 8);
161     SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
162     if ((Frame[0] > (UINT32)Frame) && (Frame[0] < (UINT32)Frame + 0x00100000)) {
163       Frame = (UINT32 *)Frame[0];
164     } else {
165       Frame = NULL;
166     }
167   }
168 
169   //
170   // Dead loop
171   //
172   CpuDeadLoop ();
173 }
174 
175 /**
176   Prints an assert message containing a filename, line number, and description.
177   This may be followed by a breakpoint or a dead loop.
178 
179   Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
180   to the debug output device.  If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
181   PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
182   DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
183   CpuDeadLoop() is called.  If neither of these bits are set, then this function
184   returns immediately after the message is printed to the debug output device.
185   DebugAssert() must actively prevent recursion.  If DebugAssert() is called while
186   processing another DebugAssert(), then DebugAssert() must return immediately.
187 
188   If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
189   If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
190 
191   @param  FileName     The pointer to the name of the source file that generated the assert condition.
192   @param  LineNumber   The line number in the source file that generated the assert condition
193   @param  Description  The pointer to the description of the assert condition.
194 
195 **/
196 VOID
197 EFIAPI
DebugAssert(IN CONST CHAR8 * FileName,IN UINTN LineNumber,IN CONST CHAR8 * Description)198 DebugAssert (
199   IN CONST CHAR8  *FileName,
200   IN UINTN        LineNumber,
201   IN CONST CHAR8  *Description
202   )
203 {
204   DebugAssertInternal ();
205 }
206 
207 
208 /**
209   Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.
210 
211   This function fills Length bytes of Buffer with the value specified by
212   PcdDebugClearMemoryValue, and returns Buffer.
213 
214   If Buffer is NULL, then ASSERT().
215   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
216 
217   @param   Buffer  The pointer to the target buffer to be filled with PcdDebugClearMemoryValue.
218   @param   Length  The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue.
219 
220   @return  Buffer  The pointer to the target buffer filled with PcdDebugClearMemoryValue.
221 
222 **/
223 VOID *
224 EFIAPI
DebugClearMemory(OUT VOID * Buffer,IN UINTN Length)225 DebugClearMemory (
226   OUT VOID  *Buffer,
227   IN UINTN  Length
228   )
229 {
230   return Buffer;
231 }
232 
233 
234 /**
235   Returns TRUE if ASSERT() macros are enabled.
236 
237   This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
238   PcdDebugProperyMask is set.  Otherwise FALSE is returned.
239 
240   @retval  TRUE    The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
241   @retval  FALSE   The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.
242 
243 **/
244 BOOLEAN
245 EFIAPI
DebugAssertEnabled(VOID)246 DebugAssertEnabled (
247   VOID
248   )
249 {
250   return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);
251 }
252 
253 
254 /**
255   Returns TRUE if DEBUG() macros are enabled.
256 
257   This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
258   PcdDebugProperyMask is set.  Otherwise FALSE is returned.
259 
260   @retval  TRUE    The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
261   @retval  FALSE   The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
262 
263 **/
264 BOOLEAN
265 EFIAPI
DebugPrintEnabled(VOID)266 DebugPrintEnabled (
267   VOID
268   )
269 {
270   return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);
271 }
272 
273 /**
274   Returns TRUE if DEBUG_CODE() macros are enabled.
275 
276   This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
277   PcdDebugProperyMask is set.  Otherwise FALSE is returned.
278 
279   @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
280   @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.
281 
282 **/
283 BOOLEAN
284 EFIAPI
DebugCodeEnabled(VOID)285 DebugCodeEnabled (
286   VOID
287   )
288 {
289   return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);
290 }
291 
292 
293 /**
294   Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.
295 
296   This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of
297   PcdDebugProperyMask is set.  Otherwise FALSE is returned.
298 
299   @retval  TRUE    The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
300   @retval  FALSE   The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.
301 
302 **/
303 BOOLEAN
304 EFIAPI
DebugClearMemoryEnabled(VOID)305 DebugClearMemoryEnabled (
306   VOID
307   )
308 {
309   return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);
310 }
311 
312 /**
313   Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel.
314 
315   This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel.
316 
317   @retval  TRUE    Current ErrorLevel is supported.
318   @retval  FALSE   Current ErrorLevel is not supported.
319 
320 **/
321 BOOLEAN
322 EFIAPI
DebugPrintLevelEnabled(IN CONST UINTN ErrorLevel)323 DebugPrintLevelEnabled (
324   IN  CONST UINTN        ErrorLevel
325   )
326 {
327   return (BOOLEAN) ((ErrorLevel & PcdGet32(PcdFixedDebugPrintErrorLevel)) != 0);
328 }
329