OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OcLog.c
Go to the documentation of this file.
1
15#include <Uefi.h>
16
17#include <Guid/OcVariable.h>
18
19#include <Protocol/OcLog.h>
20
21#include <Library/BaseLib.h>
22#include <Library/DebugLib.h>
23#include <Library/BaseMemoryLib.h>
24#include <Library/MemoryAllocationLib.h>
25#include <Library/PcdLib.h>
26#include <Library/PrintLib.h>
29#include <Library/OcFileLib.h>
30#include <Library/OcMiscLib.h>
31#include <Library/OcStringLib.h>
32#include <Library/OcTimerLib.h>
34#include <Library/SerialPortLib.h>
35#include <Library/UefiLib.h>
36#include <Library/UefiBootServicesTableLib.h>
37#include <Library/UefiRuntimeServicesTableLib.h>
38
39#include "OcLogInternal.h"
40
41STATIC
42CHAR8 *
44 IN OC_LOG_PROTOCOL *This
45 )
46{
47 OC_LOG_PRIVATE_DATA *Private = NULL;
48
49 UINT64 dTStartSec = 0;
50 UINT64 dTStartMs = 0;
51 UINT64 dTLastSec = 0;
52 UINT64 dTLastMs = 0;
53 UINT64 CurrentTsc = 0;
54
55 if (This == NULL) {
56 return NULL;
57 }
58
60
61 //
62 // Calibrate TSC for timings.
63 //
64
65 if (Private->TscFrequency == 0) {
66 Private->TscFrequency = OcGetTSCFrequency ();
67
68 if (Private->TscFrequency != 0) {
69 CurrentTsc = AsmReadTsc ();
70
71 Private->TscStart = CurrentTsc;
72 Private->TscLast = CurrentTsc;
73 }
74 }
75
76 if (Private->TscFrequency > 0) {
77 CurrentTsc = AsmReadTsc ();
78
79 dTStartMs = DivU64x64Remainder (MultU64x32 (CurrentTsc - Private->TscStart, 1000), Private->TscFrequency, NULL);
80 dTStartSec = DivU64x64Remainder (dTStartMs, 1000, &dTStartMs);
81 dTLastMs = DivU64x64Remainder (MultU64x32 (CurrentTsc - Private->TscLast, 1000), Private->TscFrequency, NULL);
82 dTLastSec = DivU64x64Remainder (dTLastMs, 1000, &dTLastMs);
83
84 Private->TscLast = CurrentTsc;
85 }
86
87 AsciiSPrint (
88 Private->TimingTxt,
90 "%02d:%03d %02d:%03d ",
91 dTStartSec,
92 dTStartMs,
93 dTLastSec,
94 dTLastMs
95 );
96
97 return Private->TimingTxt;
98}
99
100STATIC
101CHAR16 *
103 IN CONST CHAR16 *LogPrefixPath
104 )
105{
106 EFI_STATUS Status;
107 EFI_TIME Date;
108 CHAR16 *LogPath;
109 UINTN Size;
110
111 if (LogPrefixPath == NULL) {
112 return NULL;
113 }
114
115 Status = gRT->GetTime (&Date, NULL);
116 if (EFI_ERROR (Status)) {
117 ZeroMem (&Date, sizeof (Date));
118 }
119
120 Size = StrSize (LogPrefixPath) + L_STR_SIZE (L"-0000-00-00-000000.txt");
121
122 LogPath = AllocatePool (Size);
123 if (LogPath == NULL) {
124 return NULL;
125 }
126
127 UnicodeSPrint (
128 LogPath,
129 Size,
130 L"%s-%04u-%02u-%02u-%02u%02u%02u.txt",
131 LogPrefixPath,
132 (UINT32)Date.Year,
133 (UINT32)Date.Month,
134 (UINT32)Date.Day,
135 (UINT32)Date.Hour,
136 (UINT32)Date.Minute,
137 (UINT32)Date.Second
138 );
139
140 return LogPath;
141}
142
143STATIC
144EFI_STATUS
146 IN CONST CHAR8 *FormattedString,
147 OUT CHAR8 *Prefix
148 )
149{
150 UINTN Pos;
151 CHAR8 Char;
152
153 ASSERT (FormattedString != NULL);
154 ASSERT (Prefix != NULL);
155
156 Pos = 0;
157 while (TRUE) {
158 Char = FormattedString[Pos];
159
160 //
161 // If we reached end of string, then ':' was not found.
162 //
163 if (Char == '\0') {
164 return EFI_NOT_FOUND;
165 }
166
167 //
168 // Match the first occurrence of colon.
169 //
170 if (Char == ':') {
171 //
172 // If log string starts with colon, it must be illegal.
173 //
174 if (Pos == 0) {
175 return EFI_NOT_FOUND;
176 }
177
178 break;
179 }
180
181 //
182 // If size of prefix would exceed OC_LOG_PREFIX_CHAR_MAX, then not found.
183 //
185 return EFI_NOT_FOUND;
186 }
187
188 //
189 // Except for colon, a valid prefix must be either 0-9, or uppercase letter.
190 //
191 if (!(IsAsciiNumber (Char) || ((Char >= 'A') && (Char <= 'Z')))) {
192 return EFI_NOT_FOUND;
193 }
194
195 ++Pos;
196 }
197
198 CopyMem (Prefix, FormattedString, Pos);
199 Prefix[Pos] = '\0';
200 return EFI_SUCCESS;
201}
202
203STATIC
204BOOLEAN
206 IN CONST CHAR8 *FormattedString,
207 IN CONST OC_FLEX_ARRAY *FlexFilters OPTIONAL,
208 IN BOOLEAN BlacklistFiltering
209 )
210{
211 UINTN Index;
212 CHAR8 Prefix[OC_LOG_PREFIX_CHAR_MAX + 1];
213 EFI_STATUS Status;
214 CHAR8 **Value;
215
216 ASSERT (FormattedString != NULL);
217
218 //
219 // Do not filter without filters.
220 //
221 if (FlexFilters == NULL) {
222 return FALSE;
223 }
224
225 Status = GetLogPrefix (FormattedString, Prefix);
226 if (EFI_ERROR (Status)) {
227 AsciiStrCpyS (Prefix, ARRAY_SIZE (Prefix), "?");
228 }
229
230 for (Index = 0; Index < FlexFilters->Count; ++Index) {
231 Value = (CHAR8 **)OcFlexArrayItemAt (FlexFilters, Index);
232 ASSERT (Value != NULL);
233
234 if (AsciiStrCmp (Prefix, *Value) == 0) {
235 //
236 // Upon matching, return TRUE (i.e. not to print logs) if blacklisted.
237 //
238 return BlacklistFiltering;
239 }
240 }
241
242 //
243 // Otherwise return default, depending on positive or negative filtering.
244 //
245 return !BlacklistFiltering;
246}
247
248STATIC
249EFI_STATUS
251 IN OC_LOG_PRIVATE_DATA *Private,
252 IN OC_LOG_PROTOCOL *OcLog,
253 IN UINTN ErrorLevel,
254 IN CONST OC_FLEX_ARRAY *FlexFilters OPTIONAL,
255 IN BOOLEAN BlacklistFiltering,
256 IN CONST CHAR8 *FormatString,
257 IN VA_LIST Marker
258 )
259{
260 EFI_STATUS Status;
261 UINT32 Attributes;
262 UINT32 TimingLength;
263 UINT32 LineLength;
265 UINT32 KeySize;
266 UINT32 DataSize;
267 UINT32 TotalSize;
268 UINTN WriteSize;
269 UINTN WrittenSize;
270
271 AsciiVSPrint (
272 Private->LineBuffer,
273 sizeof (Private->LineBuffer),
274 FormatString,
275 Marker
276 );
277
278 //
279 // Filter log after formatting string. Always log at WARN and ERROR level.
280 //
281 if ( ((ErrorLevel & (DEBUG_WARN | DEBUG_ERROR)) == 0)
282 && IsPrefixFiltered (Private->LineBuffer, Private->FlexFilters, Private->BlacklistFiltering))
283 {
284 return EFI_SUCCESS;
285 }
286
287 //
288 // Add Entry.
289 //
290
291 Status = EFI_SUCCESS;
292
293 if (*Private->LineBuffer != '\0') {
294 GetTiming (OcLog);
295
296 //
297 // Send the string to the console output device.
298 //
299 if (((OcLog->Options & OC_LOG_CONSOLE) != 0) && ((OcLog->DisplayLevel & ErrorLevel) != 0)) {
300 UnicodeSPrint (
301 Private->UnicodeLineBuffer,
302 sizeof (Private->UnicodeLineBuffer),
303 L"%a",
304 Private->LineBuffer
305 );
306 gST->ConOut->OutputString (gST->ConOut, Private->UnicodeLineBuffer);
307
308 if (OcLog->DisplayDelay > 0) {
309 gBS->Stall (OcLog->DisplayDelay);
310 }
311 }
312
313 TimingLength = (UINT32)AsciiStrLen (Private->TimingTxt);
314 LineLength = (UINT32)AsciiStrLen (Private->LineBuffer);
315
316 //
317 // Write to serial port.
318 //
319 if ((OcLog->Options & OC_LOG_SERIAL) != 0) {
320 //
321 // No return value check - SerialPortWrite either stalls or falsely return all bytes written if no serial available.
322 //
323 SerialPortWrite ((UINT8 *)Private->TimingTxt, TimingLength);
324 SerialPortWrite ((UINT8 *)Private->LineBuffer, LineLength);
325 }
326
327 //
328 // Write to DataHub.
329 //
330 if ((OcLog->Options & OC_LOG_DATA_HUB) != 0) {
331 if (Private->DataHub == NULL) {
332 gBS->LocateProtocol (
334 NULL,
335 (VOID **)&Private->DataHub
336 );
337 }
338
339 if (Private->DataHub != NULL) {
340 KeySize = (L_STR_LEN (OC_LOG_VARIABLE_NAME) + 6) * sizeof (CHAR16);
341 DataSize = TimingLength + LineLength + 1;
342 TotalSize = KeySize + DataSize + sizeof (*Entry);
343
344 Entry = AllocatePool (TotalSize);
345
346 if (Entry != NULL) {
347 ZeroMem (Entry, sizeof (*Entry));
348 Entry->KeySize = KeySize;
349 Entry->ValueSize = DataSize;
350
351 UnicodeSPrint (
352 (CHAR16 *)&Entry->Data[0],
353 Entry->KeySize,
354 L"%s%05u",
356 Private->LogCounter++
357 );
358
359 CopyMem (
360 &Entry->Data[Entry->KeySize],
361 Private->TimingTxt,
362 TimingLength
363 );
364
365 CopyMem (
366 &Entry->Data[Entry->KeySize + TimingLength],
367 Private->LineBuffer,
368 LineLength + 1
369 );
370
371 Private->DataHub->LogData (
372 Private->DataHub,
376 Entry,
377 TotalSize
378 );
379
380 FreePool (Entry);
381 }
382 }
383 }
384
385 //
386 // Write to internal buffer.
387 //
388 Status = AsciiStrCatS (Private->AsciiBuffer, Private->AsciiBufferSize, Private->TimingTxt);
389 if (!EFI_ERROR (Status)) {
390 Private->AsciiBufferWrittenOffset += AsciiStrLen (Private->TimingTxt);
391 Status = AsciiStrCatS (Private->AsciiBuffer, Private->AsciiBufferSize, Private->LineBuffer);
392 if (!EFI_ERROR (Status)) {
393 Private->AsciiBufferWrittenOffset += AsciiStrLen (Private->LineBuffer);
394 }
395 }
396
397 //
398 // Write to a file.
399 //
400 if (((OcLog->Options & OC_LOG_FILE) != 0) && (OcLog->FileSystem != NULL)) {
401 //
402 // Log lines may arrive when CurrentTpl > TPL_CALLBACK, we must batch them
403 // and emit them when we can, in both log methods.
404 //
405 if (EfiGetCurrentTpl () <= TPL_CALLBACK) {
406 if (OcLog->UnsafeLogFile != NULL) {
407 //
408 // For non-broken FAT32 driver this is fine. For driver with broken write
409 // support (e.g. Aptio IV) this can result in corrupt file or unusable fs.
410 //
411 ASSERT (Private->AsciiBufferWrittenOffset >= Private->AsciiBufferFlushedOffset);
412 WriteSize = Private->AsciiBufferWrittenOffset - Private->AsciiBufferFlushedOffset;
413 WrittenSize = WriteSize;
414 OcLog->UnsafeLogFile->Write (OcLog->UnsafeLogFile, &WrittenSize, &Private->AsciiBuffer[Private->AsciiBufferFlushedOffset]);
415 OcLog->UnsafeLogFile->Flush (OcLog->UnsafeLogFile);
416 Private->AsciiBufferFlushedOffset += WrittenSize;
417 if (WriteSize != WrittenSize) {
418 DEBUG ((
419 DEBUG_VERBOSE,
420 "OCL: Log write truncated %u to %u\n",
421 WriteSize,
422 WrittenSize
423 ));
424 }
425 } else {
426 //
427 // Always overwriting file completely is most reliable.
428 // It is slow, but fixed size write is more reliable with broken FAT32 driver.
429 //
431 OcLog->FileSystem,
432 OcLog->FilePath,
433 Private->AsciiBuffer,
434 (UINT32)Private->AsciiBufferSize
435 );
436 }
437 }
438 }
439
440 //
441 // Write to a variable.
442 //
443 if ((ErrorLevel != DEBUG_BULK_INFO) && ((OcLog->Options & (OC_LOG_VARIABLE | OC_LOG_NONVOLATILE)) != 0)) {
444 //
445 // Do not log timing information to NVRAM, it is already large.
446 // This check is here, because Microsoft is retarded and asserts.
447 //
448 if (Private->NvramBufferSize - AsciiStrSize (Private->NvramBuffer) >= AsciiStrLen (Private->LineBuffer)) {
449 Status = AsciiStrCatS (Private->NvramBuffer, Private->NvramBufferSize, Private->LineBuffer);
450 } else {
451 Status = EFI_BUFFER_TOO_SMALL;
452 }
453
454 if (!EFI_ERROR (Status)) {
455 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
456 if ((OcLog->Options & OC_LOG_NONVOLATILE) != 0) {
457 Attributes |= EFI_VARIABLE_NON_VOLATILE;
458 }
459
460 //
461 // Do not use OcSetSystemVariable() as persistence is configured by the
462 // user.
463 //
464 Status = gRT->SetVariable (
467 Attributes,
468 AsciiStrLen (Private->NvramBuffer),
469 Private->NvramBuffer
470 );
471
472 if (EFI_ERROR (Status)) {
473 //
474 // On APTIO V this may not even get printed. Regardless of volatile or not
475 // it will firstly start discarding NVRAM data silently, and then will borks
476 // NVRAM support completely till reboot. Let's stop on first error at least.
477 //
478 gST->ConOut->OutputString (gST->ConOut, L"NVRAM is full, cannot log!\r\n");
479 gBS->Stall (SECONDS_TO_MICROSECONDS (1));
480 OcLog->Options &= ~(OC_LOG_VARIABLE | OC_LOG_NONVOLATILE);
481 }
482 } else {
483 gST->ConOut->OutputString (gST->ConOut, L"NVRAM log size exceeded, cannot log!\r\n");
484 gBS->Stall (SECONDS_TO_MICROSECONDS (1));
485 OcLog->Options &= ~(OC_LOG_VARIABLE | OC_LOG_NONVOLATILE);
486 }
487 }
488 }
489
490 return Status;
491}
492
493EFI_STATUS
494EFIAPI
496 IN OC_LOG_PROTOCOL *OcLog,
497 IN UINTN ErrorLevel,
498 IN CONST CHAR8 *FormatString,
499 IN VA_LIST Marker
500 )
501{
502 EFI_STATUS Status;
503 OC_LOG_PRIVATE_DATA *Private;
504
505 ASSERT (OcLog != NULL);
506 ASSERT (FormatString != NULL);
507
508 Private = OC_LOG_PRIVATE_DATA_FROM_OC_LOG_THIS (OcLog);
509
510 if ((OcLog->Options & OC_LOG_ENABLE) == 0) {
511 //
512 // Silently ignore when disabled.
513 //
514 return EFI_SUCCESS;
515 }
516
517 Status = InternalLogAddEntry (Private, OcLog, ErrorLevel, Private->FlexFilters, Private->BlacklistFiltering, FormatString, Marker);
518
519 if ( ((ErrorLevel & OcLog->HaltLevel) != 0)
520 && (AsciiStrnCmp (FormatString, "\nASSERT_RETURN_ERROR", L_STR_LEN ("\nASSERT_RETURN_ERROR")) != 0)
521 && (AsciiStrnCmp (FormatString, "\nASSERT_EFI_ERROR", L_STR_LEN ("\nASSERT_EFI_ERROR")) != 0))
522 {
523 gST->ConOut->OutputString (gST->ConOut, L"Halting on critical error\r\n");
524 gBS->Stall (SECONDS_TO_MICROSECONDS (1));
525 CpuDeadLoop ();
526 }
527
528 return Status;
529}
530
531EFI_STATUS
532EFIAPI
534 IN OC_LOG_PROTOCOL *This,
535 OUT CHAR8 **OcLogBuffer
536 )
537{
538 EFI_STATUS Status;
539
540 OC_LOG_PRIVATE_DATA *Private;
541
542 Status = EFI_INVALID_PARAMETER;
543
544 if (OcLogBuffer != NULL) {
546 *OcLogBuffer = Private->AsciiBuffer;
547
548 Status = EFI_SUCCESS;
549 }
550
551 return Status;
552}
553
554EFI_STATUS
555EFIAPI
557 IN OC_LOG_PROTOCOL *This,
558 IN UINT32 NonVolatile OPTIONAL,
559 IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL
560 )
561{
562 return EFI_NOT_FOUND;
563}
564
565EFI_STATUS
566EFIAPI
568 IN OC_LOG_PROTOCOL *This
569 )
570{
571 return EFI_SUCCESS;
572}
573
576 VOID
577 )
578{
579 EFI_STATUS Status;
580
581 STATIC OC_LOG_PROTOCOL *mInternalOcLog = NULL;
582
583 if (mInternalOcLog == NULL) {
584 Status = gBS->LocateProtocol (
586 NULL,
587 (VOID **)&mInternalOcLog
588 );
589
590 if (EFI_ERROR (Status) || (mInternalOcLog->Revision != OC_LOG_REVISION)) {
591 mInternalOcLog = NULL;
592 }
593 }
594
595 return mInternalOcLog;
596}
597
598EFI_STATUS
600 IN OC_LOG_OPTIONS Options,
601 IN CONST CHAR8 *LogModules,
602 IN UINT32 DisplayDelay,
603 IN UINTN DisplayLevel,
604 IN UINTN HaltLevel,
605 IN CONST CHAR16 *LogPrefixPath OPTIONAL,
606 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *LogFileSystem OPTIONAL
607 )
608{
609 EFI_STATUS Status;
610
611 OC_LOG_PROTOCOL *OcLog;
612 OC_LOG_PRIVATE_DATA *Private;
613 EFI_HANDLE Handle;
614 EFI_FILE_PROTOCOL *LogRoot;
615 CHAR16 *LogPath;
616 EFI_FILE_PROTOCOL *UnsafeLogFile;
617
618 ASSERT (LogModules != NULL);
619
620 if ((Options & (OC_LOG_FILE | OC_LOG_ENABLE)) == (OC_LOG_FILE | OC_LOG_ENABLE)) {
621 LogRoot = NULL;
622 LogPath = GetLogPath (LogPrefixPath);
623 UnsafeLogFile = NULL;
624
625 if (LogPath != NULL) {
626 if (LogFileSystem != NULL) {
627 Status = LogFileSystem->OpenVolume (LogFileSystem, &LogRoot);
628 if (EFI_ERROR (Status)) {
629 LogRoot = NULL;
630 } else if (!OcIsWritableFileSystem (LogRoot)) {
631 LogRoot->Close (LogRoot);
632 LogRoot = NULL;
633 }
634 }
635
636 if (LogRoot == NULL) {
637 Status = OcFindWritableFileSystem (&LogRoot);
638 if (EFI_ERROR (Status)) {
639 DEBUG ((DEBUG_ERROR, "OCL: There is no place to write log file to - %r\n", Status));
640 LogRoot = NULL;
641 }
642 }
643
644 if ((LogRoot != NULL) && ((Options & OC_LOG_UNSAFE) != 0)) {
645 Status = OcSafeFileOpen (
646 LogRoot,
647 &UnsafeLogFile,
648 LogPath,
649 EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE,
650 0
651 );
652 if (EFI_ERROR (Status)) {
653 DEBUG ((DEBUG_ERROR, "OCL: Failure opening log file - %r\n", Status));
654 UnsafeLogFile = NULL;
655 LogRoot->Close (LogRoot);
656 LogRoot = NULL;
657 }
658 }
659
660 if (LogRoot == NULL) {
661 FreePool (LogPath);
662 LogPath = NULL;
663 }
664 }
665 } else {
666 LogRoot = NULL;
667 LogPath = NULL;
668 UnsafeLogFile = NULL;
669 }
670
671 //
672 // Check if protocol already exists.
673 //
674
675 OcLog = InternalGetOcLog ();
676
677 if (OcLog != NULL) {
678 //
679 // Set desired options in existing protocol.
680 //
681
682 if (OcLog->FileSystem != NULL) {
683 OcLog->FileSystem->Close (OcLog->FileSystem);
684 }
685
686 if (OcLog->UnsafeLogFile != NULL) {
687 OcLog->UnsafeLogFile->Close (OcLog->UnsafeLogFile);
688 }
689
690 if (OcLog->FilePath != NULL) {
691 FreePool (OcLog->FilePath);
692 }
693
694 OcLog->Options = Options;
695 OcLog->DisplayDelay = DisplayDelay;
696 OcLog->DisplayLevel = DisplayLevel;
697 OcLog->HaltLevel = HaltLevel;
698 OcLog->FileSystem = LogRoot;
699 OcLog->FilePath = LogPath;
700 OcLog->UnsafeLogFile = UnsafeLogFile;
701
702 Status = EFI_SUCCESS;
703 } else {
704 Private = AllocateZeroPool (sizeof (*Private));
705 Status = EFI_OUT_OF_RESOURCES;
706
707 if (Private != NULL) {
711 Private->OcLog.Revision = OC_LOG_REVISION;
712 Private->OcLog.AddEntry = OcLogAddEntry;
713 Private->OcLog.GetLog = OcLogGetLog;
714 Private->OcLog.SaveLog = OcLogSaveLog;
716 Private->OcLog.Options = Options;
717 Private->OcLog.DisplayDelay = DisplayDelay;
718 Private->OcLog.DisplayLevel = DisplayLevel;
719 Private->OcLog.HaltLevel = HaltLevel;
720 Private->OcLog.FileSystem = LogRoot;
721 Private->OcLog.FilePath = LogPath;
722 Private->OcLog.UnsafeLogFile = UnsafeLogFile;
723
724 //
725 // Write filters into Private.
726 //
727 Private->FlexFilters = NULL;
728 Private->BlacklistFiltering = FALSE;
729 if ((*LogModules != '*') && (*LogModules != '\0')) {
730 //
731 // Default to positive filtering without symbol.
732 //
733 if (*LogModules == '+') {
734 ++LogModules;
735 } else if (*LogModules == '-') {
736 Private->BlacklistFiltering = TRUE;
737 ++LogModules;
738 }
739
740 Private->FlexFilters = OcStringSplit (LogModules, L',', OcStringFormatAscii);
741 }
742
743 Handle = NULL;
744 Status = gBS->InstallProtocolInterface (
745 &Handle,
747 EFI_NATIVE_INTERFACE,
748 &Private->OcLog
749 );
750
751 if (!EFI_ERROR (Status)) {
752 OcLog = &Private->OcLog;
753 } else {
754 FreePool (Private);
755 }
756 }
757 }
758
759 if (LogRoot != NULL) {
760 if (!EFI_ERROR (Status)) {
761 if ( ((Options & OC_LOG_UNSAFE) == 0)
762 && (OC_LOG_PRIVATE_DATA_FROM_OC_LOG_THIS (OcLog)->AsciiBufferSize > 0)
763 )
764 {
766 LogRoot,
767 LogPath,
768 OC_LOG_PRIVATE_DATA_FROM_OC_LOG_THIS (OcLog)->AsciiBuffer,
769 (UINT32)OC_LOG_PRIVATE_DATA_FROM_OC_LOG_THIS (OcLog)->AsciiBufferSize
770 );
771 }
772 } else {
773 if (UnsafeLogFile != NULL) {
774 UnsafeLogFile->Close (UnsafeLogFile);
775 }
776
777 LogRoot->Close (LogRoot);
778 FreePool (LogPath);
779 }
780 }
781
782 return Status;
783}
EFI_GUID gApplePlatformProducerNameGuid
#define ARRAY_SIZE(Array)
Definition AppleMacEfi.h:34
EFI_GUID gEfiMiscSubClassGuid
#define EFI_DATA_RECORD_CLASS_DATA
Definition DataHub.h:64
EFI_GUID gEfiDataHubProtocolGuid
DMG_FILEPATH_DEVICE_PATH FilePath
DMG_SIZE_DEVICE_PATH Size
EFI_SYSTEM_TABLE * gST
EFI_BOOT_SERVICES * gBS
UINT64 OcGetTSCFrequency(VOID)
#define OC_LOG_BUFFER_SIZE
#define DEBUG_BULK_INFO
BOOLEAN OcIsWritableFileSystem(IN EFI_FILE_PROTOCOL *Fs)
EFI_STATUS OcSetFileData(IN EFI_FILE_PROTOCOL *WritableFs OPTIONAL, IN CONST CHAR16 *FileName, IN CONST VOID *Buffer, IN UINT32 Size)
EFI_STATUS OcSafeFileOpen(IN CONST EFI_FILE_PROTOCOL *Directory, OUT EFI_FILE_PROTOCOL **NewHandle, IN CONST CHAR16 *FileName, IN CONST UINT64 OpenMode, IN CONST UINT64 Attributes)
Definition OpenFile.c:29
EFI_STATUS OcFindWritableFileSystem(IN OUT EFI_FILE_PROTOCOL **WritableFs)
VOID * OcFlexArrayItemAt(IN CONST OC_FLEX_ARRAY *FlexArray, IN CONST UINTN Index)
Definition FlexArray.c:189
OC_FLEX_ARRAY * OcStringSplit(IN CONST VOID *String, IN CONST CHAR16 Delim, IN CONST OC_STRING_FORMAT StringFormat)
Definition FlexString.c:15
STATIC CHAR16 * GetLogPath(IN CONST CHAR16 *LogPrefixPath)
Definition OcLog.c:102
OC_LOG_PROTOCOL * InternalGetOcLog(VOID)
Definition OcLog.c:575
EFI_STATUS EFIAPI OcLogResetTimers(IN OC_LOG_PROTOCOL *This)
Definition OcLog.c:567
STATIC BOOLEAN IsPrefixFiltered(IN CONST CHAR8 *FormattedString, IN CONST OC_FLEX_ARRAY *FlexFilters OPTIONAL, IN BOOLEAN BlacklistFiltering)
Definition OcLog.c:205
EFI_STATUS EFIAPI OcLogAddEntry(IN OC_LOG_PROTOCOL *OcLog, IN UINTN ErrorLevel, IN CONST CHAR8 *FormatString, IN VA_LIST Marker)
Definition OcLog.c:495
STATIC EFI_STATUS InternalLogAddEntry(IN OC_LOG_PRIVATE_DATA *Private, IN OC_LOG_PROTOCOL *OcLog, IN UINTN ErrorLevel, IN CONST OC_FLEX_ARRAY *FlexFilters OPTIONAL, IN BOOLEAN BlacklistFiltering, IN CONST CHAR8 *FormatString, IN VA_LIST Marker)
Definition OcLog.c:250
EFI_STATUS EFIAPI OcLogSaveLog(IN OC_LOG_PROTOCOL *This, IN UINT32 NonVolatile OPTIONAL, IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL)
Definition OcLog.c:556
STATIC CHAR8 * GetTiming(IN OC_LOG_PROTOCOL *This)
Definition OcLog.c:43
STATIC EFI_STATUS GetLogPrefix(IN CONST CHAR8 *FormattedString, OUT CHAR8 *Prefix)
Definition OcLog.c:145
EFI_STATUS OcConfigureLogProtocol(IN OC_LOG_OPTIONS Options, IN CONST CHAR8 *LogModules, IN UINT32 DisplayDelay, IN UINTN DisplayLevel, IN UINTN HaltLevel, IN CONST CHAR16 *LogPrefixPath OPTIONAL, IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *LogFileSystem OPTIONAL)
Definition OcLog.c:599
EFI_STATUS EFIAPI OcLogGetLog(IN OC_LOG_PROTOCOL *This, OUT CHAR8 **OcLogBuffer)
Definition OcLog.c:533
#define OC_LOG_FILE
Definition OcLog.h:35
#define OC_LOG_UNSAFE
Definition OcLog.h:36
#define OC_LOG_SERIAL
Definition OcLog.h:32
UINT32 OC_LOG_OPTIONS
Definition OcLog.h:48
#define OC_LOG_VARIABLE
Definition OcLog.h:33
#define OC_LOG_CONSOLE
Definition OcLog.h:30
#define OC_LOG_DATA_HUB
Definition OcLog.h:31
EFI_GUID gOcLogProtocolGuid
A global variable storing the GUID of the OC_LOG_PROTOCOL.
#define OC_LOG_NONVOLATILE
Definition OcLog.h:34
#define OC_LOG_PREFIX_CHAR_MAX
Definition OcLog.h:46
#define OC_LOG_ENABLE
Definition OcLog.h:29
#define OC_LOG_REVISION
Definition OcLog.h:24
#define OC_LOG_TIMING_BUFFER_SIZE
#define OC_LOG_NVRAM_BUFFER_SIZE
#define OC_LOG_PRIVATE_DATA_FROM_OC_LOG_THIS(a)
#define OC_LOG_PRIVATE_DATA_SIGNATURE
#define SECONDS_TO_MICROSECONDS(x)
Definition OcMiscLib.h:30
BOOLEAN IsAsciiNumber(IN CHAR8 Char)
Definition OcAsciiLib.c:78
#define L_STR_LEN(String)
Definition OcStringLib.h:26
#define L_STR_SIZE(String)
Definition OcStringLib.h:35
@ OcStringFormatAscii
Definition OcStringLib.h:50
APPLE_EVENT_HANDLE Handle
Definition OcTypingLib.h:45
#define OC_LOG_VARIABLE_NAME
Definition OcVariable.h:21
EFI_GUID gOcVendorVariableGuid
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_RUNTIME_SERVICES * gRT
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition UserMath.c:96
UINT64 EFIAPI DivU64x64Remainder(IN UINT64 Dividend, IN UINT64 Divisor, OUT UINT64 *Remainder OPTIONAL)
Definition UserMath.c:59
UINT64 EFIAPI AsmReadTsc(VOID)
Definition UserMisc.c:232
#define ASSERT(x)
Definition coder.h:55
ush Pos
Definition deflate.h:92
CHAR8 TimingTxt[OC_LOG_TIMING_BUFFER_SIZE]
CHAR8 AsciiBuffer[OC_LOG_BUFFER_SIZE]
OC_LOG_PROTOCOL OcLog
OC_FLEX_ARRAY * FlexFilters
OC_LOG_ADD_ENTRY AddEntry
A pointer to the AddEntry function.
Definition OcLog.h:132
UINTN DisplayLevel
The error level visible onscreen.
Definition OcLog.h:138
EFI_FILE_PROTOCOL * UnsafeLogFile
Log file, owned. Unsafe logging only.
Definition OcLog.h:142
UINT32 Revision
The revision of the installed protocol.
Definition OcLog.h:130
CHAR16 * FilePath
Log file path.
Definition OcLog.h:141
OC_LOG_RESET_TIMERS ResetTimers
A pointer to the ResetTimers function.
Definition OcLog.h:135
OC_LOG_SAVE_LOG SaveLog
A pointer to the SaveLog function.
Definition OcLog.h:134
OC_LOG_GET_LOG GetLog
A pointer to the GetLog function.
Definition OcLog.h:133
UINTN HaltLevel
The error level causing CPU dead loop.
Definition OcLog.h:139
UINT32 DisplayDelay
The delay after visible onscreen message in microseconds.
Definition OcLog.h:137
EFI_FILE_PROTOCOL * FileSystem
Log file system root, not owned.
Definition OcLog.h:140
OC_LOG_OPTIONS Options
The current options of the installed protocol.
Definition OcLog.h:136