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