OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OcDebugLibProtocol.c
Go to the documentation of this file.
1
16#include <Uefi.h>
17
18#include <Protocol/OcLog.h>
19
20#include <Library/BaseLib.h>
21#include <Library/BaseMemoryLib.h>
22#include <Library/DebugLib.h>
23#include <Library/DebugPrintErrorLevelLib.h>
24#include <Library/MemoryAllocationLib.h>
25#include <Library/PcdLib.h>
26#include <Library/PrintLib.h>
27#include <Library/UefiBootServicesTableLib.h>
28
29#define OC_LOG_BUFFER_SIZE (2 * EFI_PAGE_SIZE)
30
31STATIC UINT8 *mLogBuffer = NULL;
32STATIC UINT8 *mLogWalker = NULL;
33STATIC UINTN mLogCount = 0;
34
35STATIC
38 VOID
39 )
40{
41 EFI_STATUS Status;
42
43 STATIC OC_LOG_PROTOCOL *mInternalOcLog = NULL;
44
45 if (mInternalOcLog == NULL) {
46 Status = gBS->LocateProtocol (
48 NULL,
49 (VOID **)&mInternalOcLog
50 );
51
52 if (EFI_ERROR (Status) || (mInternalOcLog->Revision != OC_LOG_REVISION)) {
53 mInternalOcLog = NULL;
54 }
55 }
56
57 return mInternalOcLog;
58}
59
60STATIC
61VOID
62EFIAPI
64 IN EFI_EVENT Event,
65 IN VOID *Context
66 )
67{
68 UINTN Index;
69 OC_LOG_PROTOCOL *OcLog;
70 CHAR8 *Walker;
71 UINTN ErrorLevel;
72 OC_LOG_OPTIONS CurrLogOpt;
73
74 //
75 // Event arrives. Close it.
76 //
77 gBS->CloseEvent (Event);
78
79 OcLog = InternalGetOcLog ();
80
81 if (OcLog == NULL) {
82 return;
83 }
84
85 //
86 // Print messages without onscreen, as this has been done already.
87 //
88 CurrLogOpt = OcLog->Options;
89 OcLog->Options &= ~OC_LOG_CONSOLE;
90
91 Walker = (CHAR8 *)mLogBuffer;
92 for (Index = 0; Index < mLogCount; ++Index) {
93 //
94 // Set ErrorLevel.
95 //
96 CopyMem (&ErrorLevel, Walker, sizeof (ErrorLevel));
97 Walker += sizeof (ErrorLevel);
98
99 DebugPrint (ErrorLevel, "%a", Walker);
100
101 //
102 // Skip message chars.
103 //
104 while (*Walker != '\0') {
105 ++Walker;
106 }
107
108 //
109 // Matched '\0'. Go to the next message.
110 //
111 ++Walker;
112 }
113
114 //
115 // Restore original value.
116 //
117 OcLog->Options = CurrLogOpt;
118
119 FreePool (mLogBuffer);
120 mLogBuffer = NULL;
121}
122
123STATIC
124VOID
126 IN UINTN ErrorLevel,
127 IN CONST CHAR16 *Buffer
128 )
129{
130 EFI_STATUS Status;
131 EFI_EVENT Event;
132 VOID *Registration;
133
134 if (mLogBuffer == NULL) {
135 mLogBuffer = AllocatePool (OC_LOG_BUFFER_SIZE);
136 if (mLogBuffer == NULL) {
137 return;
138 }
139
141
142 //
143 // Notify when log protocol arrives.
144 //
145 Status = gBS->CreateEvent (
146 EVT_NOTIFY_SIGNAL,
147 TPL_NOTIFY,
149 NULL,
150 &Event
151 );
152
153 if (!EFI_ERROR (Status)) {
154 Status = gBS->RegisterProtocolNotify (
156 Event,
157 &Registration
158 );
159
160 if (EFI_ERROR (Status)) {
161 gBS->CloseEvent (Event);
162 }
163 }
164 }
165
166 //
167 // The size of ErrorLevel and that of Buffer string including null terminator should not overflow.
168 // The current position (mLogWalker) has been moved to the right side for the same purpose.
169 //
170 if ((sizeof (ErrorLevel) + StrLen (Buffer) + 1) <= (UINTN)(mLogBuffer + OC_LOG_BUFFER_SIZE - mLogWalker)) {
171 //
172 // Store ErrorLevel into buffer.
173 //
174 CopyMem (mLogWalker, &ErrorLevel, sizeof (ErrorLevel));
175 mLogWalker += sizeof (ErrorLevel);
176
177 //
178 // Store logs into buffer.
179 //
180 while (*Buffer != CHAR_NULL) {
181 *mLogWalker++ = (UINT8)*Buffer++;
182 }
183
184 *mLogWalker++ = CHAR_NULL;
185
186 //
187 // Increment number of messages.
188 //
189 ++mLogCount;
190 }
191}
192
204VOID
205EFIAPI
207 IN UINTN ErrorLevel,
208 IN CONST CHAR8 *Format,
209 ...
210 )
211{
212 VA_LIST Marker;
213 CHAR16 Buffer[256];
214 OC_LOG_PROTOCOL *OcLog;
215 BOOLEAN IsBufferEarlyLogEnabled;
216 BOOLEAN ShouldPrintConsole;
217
218 ASSERT (Format != NULL);
219
220 OcLog = InternalGetOcLog ();
221 IsBufferEarlyLogEnabled = PcdGetBool (PcdDebugLibProtocolBufferEarlyLog);
222 ShouldPrintConsole = (ErrorLevel & GetDebugPrintErrorLevel ()) != 0;
223
224 VA_START (Marker, Format);
225
226 if (OcLog != NULL) {
227 OcLog->AddEntry (OcLog, ErrorLevel, Format, Marker);
228 } else if (IsBufferEarlyLogEnabled || ShouldPrintConsole) {
229 UnicodeVSPrintAsciiFormat (Buffer, sizeof (Buffer), Format, Marker);
230
231 if (IsBufferEarlyLogEnabled) {
232 OcBufferEarlyLog (ErrorLevel, Buffer);
233 }
234
235 if (ShouldPrintConsole) {
236 gST->ConOut->OutputString (gST->ConOut, Buffer);
237 }
238 }
239
240 VA_END (Marker);
241}
242
266VOID
267EFIAPI
269 IN CONST CHAR8 *FileName,
270 IN UINTN LineNumber,
271 IN CONST CHAR8 *Description
272 )
273{
274 //
275 // Generate the ASSERT() message and log it
276 //
277 DebugPrint (
278 DEBUG_ERROR,
279 "ASSERT [%a] %a(%d): %a\n",
281 FileName,
282 LineNumber,
283 Description
284 );
285
286 //
287 // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings
288 //
289 if ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {
290 CpuBreakpoint ();
291 } else if ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {
292 CpuDeadLoop ();
293 }
294}
295
310VOID *
311EFIAPI
313 OUT VOID *Buffer,
314 IN UINTN Length
315 )
316{
317 //
318 // If Buffer is NULL, then ASSERT().
319 //
320 ASSERT (Buffer != NULL);
321
322 //
323 // SetMem() checks for the the ASSERT() condition on Length and returns Buffer
324 //
325 return SetMem (Buffer, Length, PcdGet8 (PcdDebugClearMemoryValue));
326}
327
338BOOLEAN
339EFIAPI
341 VOID
342 )
343{
344 return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);
345}
346
357BOOLEAN
358EFIAPI
360 VOID
361 )
362{
363 return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);
364}
365
376BOOLEAN
377EFIAPI
379 VOID
380 )
381{
382 return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);
383}
384
395BOOLEAN
396EFIAPI
398 VOID
399 )
400{
401 return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);
402}
403
413BOOLEAN
414EFIAPI
416 IN CONST UINTN ErrorLevel
417 )
418{
419 return (BOOLEAN)((ErrorLevel & PcdGet32 (PcdFixedDebugPrintErrorLevel)) != 0);
420}
421
429VOID
430EFIAPI
432 IN CONST CHAR16 *Format,
433 ...
434 )
435{
436 CHAR16 Buffer[1024];
437 VA_LIST Marker;
438
439 VA_START (Marker, Format);
440 UnicodeVSPrint (Buffer, sizeof (Buffer), Format, Marker);
441 VA_END (Marker);
442
443 //
444 // It is safe to call gST->ConOut->OutputString, because in crtitical areas
445 // AptioMemoryFix is responsible for overriding gBS->AllocatePool with its own
446 // implementation that uses a custom allocator.
447 //
448 if (gST->ConOut) {
449 gST->ConOut->OutputString (gST->ConOut, Buffer);
450 }
451}
UINT64 Length
EFI_SYSTEM_TABLE * gST
EFI_BOOT_SERVICES * gBS
VOID EFIAPI DebugAssert(IN CONST CHAR8 *FileName, IN UINTN LineNumber, IN CONST CHAR8 *Description)
BOOLEAN EFIAPI DebugPrintLevelEnabled(IN CONST UINTN ErrorLevel)
VOID *EFIAPI DebugClearMemory(OUT VOID *Buffer, IN UINTN Length)
#define OC_LOG_BUFFER_SIZE
STATIC VOID OcBufferEarlyLog(IN UINTN ErrorLevel, IN CONST CHAR16 *Buffer)
STATIC VOID EFIAPI LogProtocolArrivedNotify(IN EFI_EVENT Event, IN VOID *Context)
VOID EFIAPI DebugPrint(IN UINTN ErrorLevel, IN CONST CHAR8 *Format,...)
VOID EFIAPI OcPrintScreen(IN CONST CHAR16 *Format,...)
BOOLEAN EFIAPI DebugCodeEnabled(VOID)
STATIC UINTN mLogCount
STATIC UINT8 * mLogBuffer
STATIC OC_LOG_PROTOCOL * InternalGetOcLog(VOID)
STATIC UINT8 * mLogWalker
BOOLEAN EFIAPI DebugClearMemoryEnabled(VOID)
BOOLEAN EFIAPI DebugPrintEnabled(VOID)
BOOLEAN EFIAPI DebugAssertEnabled(VOID)
UINT32 OC_LOG_OPTIONS
Definition OcLog.h:48
EFI_GUID gOcLogProtocolGuid
A global variable storing the GUID of the OC_LOG_PROTOCOL.
#define OC_LOG_REVISION
Definition OcLog.h:24
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
CONST CHAR8 * gEfiCallerBaseName
VOID EFIAPI CpuBreakpoint(VOID)
Definition UserMisc.c:13
#define ASSERT(x)
Definition coder.h:55
OC_LOG_ADD_ENTRY AddEntry
A pointer to the AddEntry function.
Definition OcLog.h:132
OC_LOG_OPTIONS Options
The current options of the installed protocol.
Definition OcLog.h:136