OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
ValidateUefi.c
Go to the documentation of this file.
1
16#include "NvramKeyInfo.h"
17#include "ocvalidate.h"
18#include "OcValidateLib.h"
19
20#include <Library/BaseLib.h>
22
31STATIC
32BOOLEAN
34 IN CONST VOID *PrimaryDriver,
35 IN CONST VOID *SecondaryDriver
36 )
37{
38 CONST OC_UEFI_DRIVER_ENTRY *UefiPrimaryDriver;
39 CONST OC_UEFI_DRIVER_ENTRY *UefiSecondaryDriver;
40 CONST CHAR8 *UefiDriverPrimaryString;
41 CONST CHAR8 *UefiDriverSecondaryString;
42
43 UefiPrimaryDriver = *(CONST OC_UEFI_DRIVER_ENTRY **)PrimaryDriver;
44 UefiSecondaryDriver = *(CONST OC_UEFI_DRIVER_ENTRY **)SecondaryDriver;
45 UefiDriverPrimaryString = OC_BLOB_GET (&UefiPrimaryDriver->Path);
46 UefiDriverSecondaryString = OC_BLOB_GET (&UefiSecondaryDriver->Path);
47
48 return StringIsDuplicated ("UEFI->Drivers", UefiDriverPrimaryString, UefiDriverSecondaryString);
49}
50
60STATIC
61BOOLEAN
63 IN CONST VOID *PrimaryEntry,
64 IN CONST VOID *SecondaryEntry
65 )
66{
67 CONST OC_UEFI_RSVD_ENTRY *UefiReservedMemoryPrimaryEntry;
68 CONST OC_UEFI_RSVD_ENTRY *UefiReservedMemorySecondaryEntry;
69 UINT64 UefiReservedMemoryPrimaryAddress;
70 UINT64 UefiReservedMemoryPrimarySize;
71 UINT64 UefiReservedMemorySecondaryAddress;
72 UINT64 UefiReservedMemorySecondarySize;
73
74 UefiReservedMemoryPrimaryEntry = *(CONST OC_UEFI_RSVD_ENTRY **)PrimaryEntry;
75 UefiReservedMemorySecondaryEntry = *(CONST OC_UEFI_RSVD_ENTRY **)SecondaryEntry;
76 UefiReservedMemoryPrimaryAddress = UefiReservedMemoryPrimaryEntry->Address;
77 UefiReservedMemoryPrimarySize = UefiReservedMemoryPrimaryEntry->Size;
78 UefiReservedMemorySecondaryAddress = UefiReservedMemorySecondaryEntry->Address;
79 UefiReservedMemorySecondarySize = UefiReservedMemorySecondaryEntry->Size;
80
81 if (!UefiReservedMemoryPrimaryEntry->Enabled || !UefiReservedMemorySecondaryEntry->Enabled) {
82 return FALSE;
83 }
84
85 if ( (UefiReservedMemoryPrimaryAddress < UefiReservedMemorySecondaryAddress + UefiReservedMemorySecondarySize)
86 && (UefiReservedMemorySecondaryAddress < UefiReservedMemoryPrimaryAddress + UefiReservedMemoryPrimarySize))
87 {
88 DEBUG ((DEBUG_WARN, "UEFI->ReservedMemory: Entries have overlapped Address and Size "));
89 return TRUE;
90 }
91
92 return FALSE;
93}
94
95STATIC
96BOOLEAN
98 IN CONST CHAR8 *Type
99 )
100{
101 UINTN Index;
102 STATIC CONST CHAR8 *AllowedType[] = {
103 "Reserved", "LoaderCode", "LoaderData", "BootServiceCode", "BootServiceData",
104 "RuntimeCode", "RuntimeData", "Available", "Persistent", "UnusableMemory",
105 "ACPIReclaimMemory", "ACPIMemoryNVS", "MemoryMappedIO", "MemoryMappedIOPortSpace", "PalCode"
106 };
107
108 for (Index = 0; Index < ARRAY_SIZE (AllowedType); ++Index) {
109 if (AsciiStrCmp (Type, AllowedType[Index]) == 0) {
110 return TRUE;
111 }
112 }
113
114 return FALSE;
115}
116
117STATIC
118UINT32
120 IN OC_GLOBAL_CONFIG *Config
121 )
122{
123 UINT32 ErrorCount;
124 BOOLEAN IsEnableJumpstartEnabled;
125 UINT32 ScanPolicy;
126
127 ErrorCount = 0;
128
129 //
130 // If FS restrictions is enabled but APFS FS scanning is disabled, it is an error.
131 //
132 IsEnableJumpstartEnabled = Config->Uefi.Apfs.EnableJumpstart;
133 ScanPolicy = Config->Misc.Security.ScanPolicy;
134 if ( IsEnableJumpstartEnabled
135 && ((ScanPolicy & OC_SCAN_FILE_SYSTEM_LOCK) != 0)
136 && ((ScanPolicy & OC_SCAN_ALLOW_FS_APFS) == 0))
137 {
138 DEBUG ((DEBUG_WARN, "UEFI->APFS->EnableJumpstart is enabled, but Misc->Security->ScanPolicy does not allow APFS scanning!\n"));
139 ++ErrorCount;
140 }
141
142 return ErrorCount;
143}
144
145STATIC
146UINT32
148 IN OC_GLOBAL_CONFIG *Config
149 )
150{
151 UINT32 ErrorCount;
152 CONST CHAR8 *AppleEvent;
153
154 ErrorCount = 0;
155
156 AppleEvent = OC_BLOB_GET (&Config->Uefi.AppleInput.AppleEvent);
157 if ( (AsciiStrCmp (AppleEvent, "Auto") != 0)
158 && (AsciiStrCmp (AppleEvent, "Builtin") != 0)
159 && (AsciiStrCmp (AppleEvent, "OEM") != 0))
160 {
161 DEBUG ((DEBUG_WARN, "UEFI->AppleInput->AppleEvent is illegal (Can only be Auto, Builtin, OEM)!\n"));
162 ++ErrorCount;
163 }
164
165 if (Config->Uefi.Input.KeySupport && Config->Uefi.AppleInput.CustomDelays) {
166 if ( (Config->Uefi.AppleInput.KeyInitialDelay != 0)
167 && (Config->Uefi.AppleInput.KeyInitialDelay < Config->Uefi.Input.KeyForgetThreshold))
168 {
169 DEBUG ((DEBUG_WARN, "KeyInitialDelay is enabled in KeySupport mode, is non-zero and is less than the KeyForgetThreshold value (will result in uncontrolled key repeats)!\n"));
170 ++ErrorCount;
171 }
172
173 if (Config->Uefi.AppleInput.KeySubsequentDelay < Config->Uefi.Input.KeyForgetThreshold) {
174 DEBUG ((DEBUG_WARN, "KeySubsequentDelay is enabled in KeySupport mode and is less than the KeyForgetThreshold value (will result in uncontrolled key repeats)!\n"));
175 ++ErrorCount;
176 }
177 }
178
179 return ErrorCount;
180}
181
182STATIC
183UINT32
185 INT8 Gain,
186 CHAR8 *GainName,
187 INT8 GainAbove, OPTIONAL
188 CHAR8 *GainAboveName OPTIONAL
189 )
190{
191 UINT32 ErrorCount;
192
193 ErrorCount = 0;
194
195 //
196 // Cannot check these as they are already truncated to INT8 before we can validate them.
197 // TODO: (?) Add check during DEBUG parsing that specified values fit into what they will be cast to.
198 //
199 #if 0
200 if (Gain < -128) {
201 DEBUG ((DEBUG_WARN, "UEFI->Audio->%a must be greater than or equal to -128!\n", GainName));
202 ++ErrorCount;
203 } else if (Gain > 127) {
204 DEBUG ((DEBUG_WARN, "UEFI->Audio->%a must be less than or equal to 127!\n", GainName));
205 ++ErrorCount;
206 }
207
208 #endif
209
210 if ((GainAboveName != NULL) && (Gain > GainAbove)) {
211 DEBUG ((DEBUG_WARN, "UEFI->Audio->%a must be less than or equal to UEFI->Audio->%a!\n", GainName, GainAboveName));
212 ++ErrorCount;
213 }
214
215 return ErrorCount;
216}
217
218STATIC
219UINT32
221 IN OC_GLOBAL_CONFIG *Config
222 )
223{
224 UINT32 ErrorCount;
225 BOOLEAN IsAudioSupportEnabled;
226 UINT64 AudioOutMask;
227 CONST CHAR8 *AsciiAudioDevicePath;
228 CONST CHAR8 *AsciiPlayChime;
229
230 ErrorCount = 0;
231
232 IsAudioSupportEnabled = Config->Uefi.Audio.AudioSupport;
233 AudioOutMask = Config->Uefi.Audio.AudioOutMask;
234 AsciiAudioDevicePath = OC_BLOB_GET (&Config->Uefi.Audio.AudioDevice);
235 AsciiPlayChime = OC_BLOB_GET (&Config->Uefi.Audio.PlayChime);
236 if (IsAudioSupportEnabled) {
237 if (AudioOutMask == 0) {
238 DEBUG ((DEBUG_WARN, "UEFI->Audio->AudioOutMask is zero when AudioSupport is enabled, no sound will play!\n"));
239 ++ErrorCount;
240 }
241
242 ErrorCount += CheckUefiGain (
243 Config->Uefi.Audio.MaximumGain,
244 "MaximumGain",
245 0,
246 NULL
247 );
248
249 // No operational reason for MinimumAssistGain <= MaximumGain, but is safer to ensure non-deafening sound levels.
250 ErrorCount += CheckUefiGain (
251 Config->Uefi.Audio.MinimumAssistGain,
252 "MinimumAssistGain",
253 Config->Uefi.Audio.MaximumGain,
254 "MaximumGain"
255 );
256
257 ErrorCount += CheckUefiGain (
258 Config->Uefi.Audio.MinimumAudibleGain,
259 "MinimumAudibleGain",
260 Config->Uefi.Audio.MinimumAssistGain,
261 "MinimumAssistGain"
262 );
263
264 ErrorCount += CheckUefiGain (
265 Config->Uefi.Audio.MinimumAudibleGain,
266 "MinimumAudibleGain",
267 Config->Uefi.Audio.MaximumGain,
268 "MaximumGain"
269 );
270
271 if (!AsciiDevicePathIsLegal (AsciiAudioDevicePath)) {
272 DEBUG ((DEBUG_WARN, "UEFI->Audio->AudioDevice is borked! Please check the information above!\n"));
273 ++ErrorCount;
274 }
275
276 if (AsciiPlayChime[0] == '\0') {
277 DEBUG ((DEBUG_WARN, "UEFI->Audio->PlayChime cannot be empty when AudioSupport is enabled!\n"));
278 ++ErrorCount;
279 } else if ( (AsciiStrCmp (AsciiPlayChime, "Auto") != 0)
280 && (AsciiStrCmp (AsciiPlayChime, "Enabled") != 0)
281 && (AsciiStrCmp (AsciiPlayChime, "Disabled") != 0))
282 {
283 DEBUG ((DEBUG_WARN, "UEFI->Audio->PlayChime is borked (Can only be Auto, Enabled, or Disabled)!\n"));
284 ++ErrorCount;
285 }
286 }
287
288 return ErrorCount;
289}
290
291STATIC
292UINT32
294 IN OC_GLOBAL_CONFIG *Config
295 )
296{
297 UINT32 ErrorCount;
298 UINT32 Index;
299 OC_UEFI_DRIVER_ENTRY *DriverEntry;
300 CONST CHAR8 *Comment;
301 CONST CHAR8 *Driver;
302 UINTN DriverSumSize;
303 BOOLEAN HasOpenRuntimeEfiDriver;
304 BOOLEAN IsOpenRuntimeLoadEarly;
305 UINT32 IndexOpenRuntimeEfiDriver;
306 BOOLEAN HasOpenUsbKbDxeEfiDriver;
307 UINT32 IndexOpenUsbKbDxeEfiDriver;
308 BOOLEAN HasPs2KeyboardDxeEfiDriver;
309 BOOLEAN IndexPs2KeyboardDxeEfiDriver;
310 BOOLEAN HasHfsEfiDriver;
311 UINT32 IndexHfsEfiDriver;
312 BOOLEAN HasAudioDxeEfiDriver;
313 UINT32 IndexAudioDxeEfiDriver;
314 BOOLEAN IsRequestBootVarRoutingEnabled;
315 BOOLEAN IsKeySupportEnabled;
316 BOOLEAN IsConnectDriversEnabled;
317 BOOLEAN HasOpenVariableRuntimeDxeEfiDriver;
318 UINT32 IndexOpenVariableRuntimeDxeEfiDriver;
319 BOOLEAN HasFirmwareSettingsEntryEfiDriver;
320
321 ErrorCount = 0;
322
323 HasOpenRuntimeEfiDriver = FALSE;
324 IndexOpenRuntimeEfiDriver = 0;
325 HasOpenUsbKbDxeEfiDriver = FALSE;
326 IndexOpenUsbKbDxeEfiDriver = 0;
327 HasPs2KeyboardDxeEfiDriver = FALSE;
328 IndexPs2KeyboardDxeEfiDriver = 0;
329 HasHfsEfiDriver = FALSE;
330 IndexHfsEfiDriver = 0;
331 HasAudioDxeEfiDriver = FALSE;
332 IndexAudioDxeEfiDriver = 0;
333 HasOpenVariableRuntimeDxeEfiDriver = FALSE;
334 IndexOpenVariableRuntimeDxeEfiDriver = 0;
335 IsOpenRuntimeLoadEarly = FALSE;
336 HasFirmwareSettingsEntryEfiDriver = FALSE;
337 for (Index = 0; Index < Config->Uefi.Drivers.Count; ++Index) {
338 DriverEntry = Config->Uefi.Drivers.Values[Index];
339 Comment = OC_BLOB_GET (&DriverEntry->Comment);
340 Driver = OC_BLOB_GET (&DriverEntry->Path);
341
342 //
343 // Check the length of path relative to OC directory.
344 //
345 DriverSumSize = L_STR_LEN (OPEN_CORE_UEFI_DRIVER_PATH) + AsciiStrSize (Driver);
346 if (DriverSumSize > OC_STORAGE_SAFE_PATH_MAX) {
347 DEBUG ((
348 DEBUG_WARN,
349 "UEFI->Drivers[%u] (length %u) is too long (should not exceed %u)!\n",
350 Index,
351 AsciiStrLen (Driver),
353 ));
354 ++ErrorCount;
355 }
356
357 //
358 // Sanitise strings.
359 //
360 if (!AsciiCommentIsLegal (Comment)) {
361 DEBUG ((DEBUG_WARN, "UEFI->Drivers[%u]->Comment contains illegal character!\n", Index));
362 ++ErrorCount;
363 }
364
365 if (!AsciiUefiDriverIsLegal (Driver, Index)) {
366 ++ErrorCount;
367 continue;
368 }
369
370 if (!DriverEntry->Enabled) {
371 continue;
372 }
373
374 if (AsciiStrCmp (Driver, "OpenVariableRuntimeDxe.efi") == 0) {
375 HasOpenVariableRuntimeDxeEfiDriver = TRUE;
376 IndexOpenVariableRuntimeDxeEfiDriver = Index;
377
378 if (!DriverEntry->LoadEarly) {
379 DEBUG ((DEBUG_WARN, "OpenVariableRuntimeDxe at UEFI->Drivers[%u] must have LoadEarly set to TRUE!\n", Index));
380 ++ErrorCount;
381 }
382 }
383
384 //
385 // For all drivers but OpenVariableRuntimeDxe.efi and OpenRuntime.efi, LoadEarly must be FALSE.
386 //
387 if ((AsciiStrCmp (Driver, "OpenVariableRuntimeDxe.efi") != 0) && (AsciiStrCmp (Driver, "OpenRuntime.efi") != 0) && DriverEntry->LoadEarly) {
388 DEBUG ((DEBUG_WARN, "%a at UEFI->Drivers[%u] must have LoadEarly set to FALSE!\n", Driver, Index));
389 ++ErrorCount;
390 }
391
392 if (AsciiStrCmp (Driver, "OpenRuntime.efi") == 0) {
393 HasOpenRuntimeEfiDriver = TRUE;
394 IndexOpenRuntimeEfiDriver = Index;
395 IsOpenRuntimeLoadEarly = DriverEntry->LoadEarly;
396 }
397
398 if (AsciiStrCmp (Driver, "OpenUsbKbDxe.efi") == 0) {
399 HasOpenUsbKbDxeEfiDriver = TRUE;
400 IndexOpenUsbKbDxeEfiDriver = Index;
401 }
402
403 if (AsciiStrCmp (Driver, "Ps2KeyboardDxe.efi") == 0) {
404 HasPs2KeyboardDxeEfiDriver = TRUE;
405 IndexPs2KeyboardDxeEfiDriver = Index;
406 }
407
408 //
409 // There are several HFS Plus drivers, including HfsPlus, VboxHfs, etc.
410 // Here only "hfs" (case-insensitive) is matched.
411 //
412 if (OcAsciiStriStr (Driver, "hfs") != NULL) {
413 HasHfsEfiDriver = TRUE;
414 IndexHfsEfiDriver = Index;
415 }
416
417 if (AsciiStrCmp (Driver, "AudioDxe.efi") == 0) {
418 HasAudioDxeEfiDriver = TRUE;
419 IndexAudioDxeEfiDriver = Index;
420 }
421
422 if (AsciiStrCmp (Driver, "FirmwareSettingsEntry.efi") == 0) {
423 HasFirmwareSettingsEntryEfiDriver = TRUE;
424 }
425 }
426
427 //
428 // Check duplicated Drivers.
429 //
430 ErrorCount += FindArrayDuplication (
431 Config->Uefi.Drivers.Values,
432 Config->Uefi.Drivers.Count,
433 sizeof (Config->Uefi.Drivers.Values[0]),
435 );
436
437 if (HasOpenRuntimeEfiDriver) {
438 if (HasOpenVariableRuntimeDxeEfiDriver) {
439 if (!IsOpenRuntimeLoadEarly) {
440 DEBUG ((
441 DEBUG_WARN,
442 "OpenRuntime.efi at UEFI->Drivers[%u] should have its LoadEarly set to TRUE when OpenVariableRuntimeDxe.efi at UEFI->Drivers[%u] is in use!\n",
443 IndexOpenRuntimeEfiDriver,
444 IndexOpenVariableRuntimeDxeEfiDriver
445 ));
446 ++ErrorCount;
447 }
448
449 if (IndexOpenVariableRuntimeDxeEfiDriver >= IndexOpenRuntimeEfiDriver) {
450 DEBUG ((
451 DEBUG_WARN,
452 "OpenRuntime.efi (currently at UEFI->Drivers[%u]) should be placed after OpenVariableRuntimeDxe.efi (currently at UEFI->Drivers[%u])!\n",
453 IndexOpenRuntimeEfiDriver,
454 IndexOpenVariableRuntimeDxeEfiDriver
455 ));
456 ++ErrorCount;
457 }
458 } else {
459 if (IsOpenRuntimeLoadEarly) {
460 DEBUG ((
461 DEBUG_WARN,
462 "OpenRuntime.efi at UEFI->Drivers[%u] should have its LoadEarly set to FALSE unless OpenVariableRuntimeDxe.efi is in use!\n",
463 IndexOpenRuntimeEfiDriver
464 ));
465 ++ErrorCount;
466 }
467 }
468 }
469
470 if (HasFirmwareSettingsEntryEfiDriver && HasOpenVariableRuntimeDxeEfiDriver) {
471 DEBUG ((DEBUG_WARN, "OpenVariableRuntimeDxe.efi is incompatible with FirmwareSettingsEntry.efi!\n"));
472 ++ErrorCount;
473 }
474
475 IsRequestBootVarRoutingEnabled = Config->Uefi.Quirks.RequestBootVarRouting;
476 if (IsRequestBootVarRoutingEnabled) {
477 if (!HasOpenRuntimeEfiDriver) {
478 DEBUG ((DEBUG_WARN, "UEFI->Quirks->RequestBootVarRouting is enabled, but OpenRuntime.efi is not loaded at UEFI->Drivers!\n"));
479 ++ErrorCount;
480 }
481 }
482
483 IsKeySupportEnabled = Config->Uefi.Input.KeySupport;
484 if (IsKeySupportEnabled) {
485 if (HasOpenUsbKbDxeEfiDriver) {
486 DEBUG ((DEBUG_WARN, "OpenUsbKbDxe.efi at UEFI->Drivers[%u] should NEVER be used together with UEFI->Input->KeySupport!\n", IndexOpenUsbKbDxeEfiDriver));
487 ++ErrorCount;
488 }
489 } else {
490 if (HasPs2KeyboardDxeEfiDriver) {
491 DEBUG ((DEBUG_WARN, "UEFI->Input->KeySupport should be enabled when Ps2KeyboardDxe.efi is in use!\n"));
492 ++ErrorCount;
493 }
494 }
495
496 if (HasOpenUsbKbDxeEfiDriver && HasPs2KeyboardDxeEfiDriver) {
497 DEBUG ((
498 DEBUG_WARN,
499 "OpenUsbKbDxe.efi at UEFI->Drivers[%u], and Ps2KeyboardDxe.efi at UEFI->Drivers[%u], should NEVER co-exist!\n",
500 IndexOpenUsbKbDxeEfiDriver,
501 IndexPs2KeyboardDxeEfiDriver
502 ));
503 ++ErrorCount;
504 }
505
506 IsConnectDriversEnabled = Config->Uefi.ConnectDrivers;
507 if (!IsConnectDriversEnabled) {
508 if (HasHfsEfiDriver) {
509 DEBUG ((DEBUG_WARN, "HFS+ filesystem driver is loaded at UEFI->Drivers[%u], but UEFI->ConnectDrivers is not enabled!\n", IndexHfsEfiDriver));
510 ++ErrorCount;
511 }
512
513 if (HasAudioDxeEfiDriver) {
514 DEBUG ((DEBUG_WARN, "AudioDevice.efi is loaded at UEFI->Drivers[%u], but UEFI->ConnectDrivers is not enabled!\n", IndexAudioDxeEfiDriver));
515 ++ErrorCount;
516 }
517 }
518
519 return ErrorCount;
520}
521
522STATIC
523UINT32
525 IN OC_GLOBAL_CONFIG *Config
526 )
527{
528 UINT32 ErrorCount;
529 BOOLEAN IsPointerSupportEnabled;
530 CONST CHAR8 *PointerSupportMode;
531 CONST CHAR8 *KeySupportMode;
532
533 ErrorCount = 0;
534
535 IsPointerSupportEnabled = Config->Uefi.Input.PointerSupport;
536 PointerSupportMode = OC_BLOB_GET (&Config->Uefi.Input.PointerSupportMode);
537 if (IsPointerSupportEnabled && (AsciiStrCmp (PointerSupportMode, "ASUS") != 0)) {
538 DEBUG ((DEBUG_WARN, "UEFI->Input->PointerSupport is enabled, but PointerSupportMode is not ASUS!\n"));
539 ++ErrorCount;
540 }
541
542 KeySupportMode = OC_BLOB_GET (&Config->Uefi.Input.KeySupportMode);
543 if ( (AsciiStrCmp (KeySupportMode, "Auto") != 0)
544 && (AsciiStrCmp (KeySupportMode, "V1") != 0)
545 && (AsciiStrCmp (KeySupportMode, "V2") != 0)
546 && (AsciiStrCmp (KeySupportMode, "AMI") != 0))
547 {
548 DEBUG ((DEBUG_WARN, "UEFI->Input->KeySupportMode is illegal (Can only be Auto, V1, V2, AMI)!\n"));
549 ++ErrorCount;
550 }
551
552 return ErrorCount;
553}
554
555STATIC
556UINT32
558 IN OC_GLOBAL_CONFIG *Config
559 )
560{
561 UINT32 ErrorCount;
562 CONST CHAR8 *InitialMode;
563 CONST CHAR8 *TextRenderer;
564 CONST CHAR8 *GopPassThrough;
565 BOOLEAN IsTextRendererSystem;
566 BOOLEAN IsClearScreenOnModeSwitchEnabled;
567 BOOLEAN IsIgnoreTextInGraphicsEnabled;
568 BOOLEAN IsReplaceTabWithSpaceEnabled;
569 BOOLEAN IsSanitiseClearScreenEnabled;
570 CONST CHAR8 *ConsoleFont;
571 CONST CHAR8 *ConsoleMode;
572 CONST CHAR8 *Resolution;
573 UINT32 UserWidth;
574 UINT32 UserHeight;
575 UINT32 UserBpp;
576 BOOLEAN UserSetMax;
577 INT8 UIScale;
578 BOOLEAN HasUefiOutputUIScale;
579
580 ErrorCount = 0;
581 IsTextRendererSystem = FALSE;
582 HasUefiOutputUIScale = FALSE;
583
584 //
585 // Sanitise strings.
586 //
587 InitialMode = OC_BLOB_GET (&Config->Uefi.Output.InitialMode);
588 if ( (AsciiStrCmp (InitialMode, "Auto") != 0)
589 && (AsciiStrCmp (InitialMode, "Text") != 0)
590 && (AsciiStrCmp (InitialMode, "Graphics") != 0))
591 {
592 DEBUG ((DEBUG_WARN, "UEFI->Output->InitialMode is illegal (Can only be Auto, Text, or Graphics)!\n"));
593 ++ErrorCount;
594 }
595
596 TextRenderer = OC_BLOB_GET (&Config->Uefi.Output.TextRenderer);
597 if ( (AsciiStrCmp (TextRenderer, "BuiltinGraphics") != 0)
598 && (AsciiStrCmp (TextRenderer, "BuiltinText") != 0)
599 && (AsciiStrCmp (TextRenderer, "SystemGraphics") != 0)
600 && (AsciiStrCmp (TextRenderer, "SystemText") != 0)
601 && (AsciiStrCmp (TextRenderer, "SystemGeneric") != 0))
602 {
603 DEBUG ((DEBUG_WARN, "UEFI->Output->TextRenderer is illegal (Can only be BuiltinGraphics, BuiltinText, SystemGraphics, SystemText, or SystemGeneric)!\n"));
604 ++ErrorCount;
605 } else if (AsciiStrnCmp (TextRenderer, "System", L_STR_LEN ("System")) == 0) {
606 //
607 // Check whether TextRenderer has System prefix.
608 //
609 IsTextRendererSystem = TRUE;
610 }
611
612 if (IsTextRendererSystem) {
613 ConsoleFont = OC_BLOB_GET (&Config->Uefi.Output.ConsoleFont);
614 if (ConsoleFont[0] != '\0') {
615 DEBUG ((DEBUG_WARN, "UEFI->Output->ConsoleFont is specified on non-Builtin TextRenderer (currently %a)!\n", TextRenderer));
616 ++ErrorCount;
617 }
618 } else {
619 IsClearScreenOnModeSwitchEnabled = Config->Uefi.Output.ClearScreenOnModeSwitch;
620 if (IsClearScreenOnModeSwitchEnabled) {
621 DEBUG ((DEBUG_WARN, "UEFI->Output->ClearScreenOnModeSwitch is enabled on non-System TextRenderer (currently %a)!\n", TextRenderer));
622 ++ErrorCount;
623 }
624
625 IsIgnoreTextInGraphicsEnabled = Config->Uefi.Output.IgnoreTextInGraphics;
626 if (IsIgnoreTextInGraphicsEnabled) {
627 DEBUG ((DEBUG_WARN, "UEFI->Output->IgnoreTextInGraphics is enabled on non-System TextRenderer (currently %a)!\n", TextRenderer));
628 ++ErrorCount;
629 }
630
631 IsReplaceTabWithSpaceEnabled = Config->Uefi.Output.ReplaceTabWithSpace;
632 if (IsReplaceTabWithSpaceEnabled) {
633 DEBUG ((DEBUG_WARN, "UEFI->Output->ReplaceTabWithSpace is enabled on non-System TextRenderer (currently %a)!\n", TextRenderer));
634 ++ErrorCount;
635 }
636
637 IsSanitiseClearScreenEnabled = Config->Uefi.Output.SanitiseClearScreen;
638 if (IsSanitiseClearScreenEnabled) {
639 DEBUG ((DEBUG_WARN, "UEFI->Output->SanitiseClearScreen is enabled on non-System TextRenderer (currently %a)!\n", TextRenderer));
640 ++ErrorCount;
641 }
642 }
643
644 GopPassThrough = OC_BLOB_GET (&Config->Uefi.Output.GopPassThrough);
645 if ( (AsciiStrCmp (GopPassThrough, "Enabled") != 0)
646 && (AsciiStrCmp (GopPassThrough, "Disabled") != 0)
647 && (AsciiStrCmp (GopPassThrough, "Apple") != 0))
648 {
649 DEBUG ((DEBUG_WARN, "UEFI->Output->GopPassThrough is illegal (Can only be Enabled, Disabled, Apple)!\n"));
650 ++ErrorCount;
651 }
652
653 //
654 // Parse Output->ConsoleMode by calling OpenCore libraries.
655 //
656 ConsoleMode = OC_BLOB_GET (&Config->Uefi.Output.ConsoleMode);
658 ConsoleMode,
659 &UserWidth,
660 &UserHeight,
661 &UserSetMax
662 );
663 if ( (ConsoleMode[0] != '\0')
664 && !UserSetMax)
665 {
666 if ((UserWidth == 0) || (UserHeight == 0)) {
667 DEBUG ((DEBUG_WARN, "UEFI->Output->ConsoleMode is borked, please check documentation!\n"));
668 ++ErrorCount;
669 } else if ((UserWidth < 80) || (UserHeight < 25)) {
670 DEBUG ((DEBUG_WARN, "UEFI->Output->ConsoleMode is below minumum supported console text resolution of 80x25, please fix!\n"));
671 ++ErrorCount;
672 }
673 }
674
675 //
676 // Parse Output->Resolution by calling OpenCore libraries.
677 //
678 Resolution = OC_BLOB_GET (&Config->Uefi.Output.Resolution);
680 Resolution,
681 &UserWidth,
682 &UserHeight,
683 &UserBpp,
684 &UserSetMax
685 );
686 if ( (Resolution[0] != '\0')
687 && !UserSetMax
688 && ((UserWidth == 0) || (UserHeight == 0)))
689 {
690 DEBUG ((DEBUG_WARN, "UEFI->Output->Resolution is borked, please check documentation!\n"));
691 ++ErrorCount;
692 }
693
694 UIScale = Config->Uefi.Output.UIScale;
695 if ((UIScale < -1) || (UIScale > 2)) {
696 DEBUG ((DEBUG_WARN, "UEFI->Output->UIScale is borked (Can only be between -1 and 2)!\n"));
697 ++ErrorCount;
698 } else if (UIScale != -1) {
699 HasUefiOutputUIScale = TRUE;
700 }
701
702 if (HasUefiOutputUIScale && mHasNvramUIScale) {
703 DEBUG ((DEBUG_WARN, "UIScale is set under both NVRAM and UEFI->Output!\n"));
704 ++ErrorCount;
705 }
706
707 return ErrorCount;
708}
709
710//
711// FIXME: Just in case this can be of use...
712//
713STATIC
714UINT32
716 IN OC_GLOBAL_CONFIG *Config
717 )
718{
719 UINT32 ErrorCount;
720 INT8 ResizeGpuBars;
721
722 ErrorCount = 0;
723 ResizeGpuBars = Config->Uefi.Quirks.ResizeGpuBars;
724
725 if ((ResizeGpuBars < -1) || (ResizeGpuBars > 19)) {
726 DEBUG ((DEBUG_WARN, "UEFI->Quirks->ResizeGpuBars is borked (Can only be between -1 and 19)!\n"));
727 ++ErrorCount;
728 }
729
730 return ErrorCount;
731}
732
733STATIC
734UINT32
736 IN OC_GLOBAL_CONFIG *Config
737 )
738{
739 UINT32 ErrorCount;
740 UINT32 Index;
741 CONST CHAR8 *AsciiReservedMemoryType;
742 UINT64 ReservedMemoryAddress;
743 UINT64 ReservedMemorySize;
744
745 ErrorCount = 0;
746
747 //
748 // Validate ReservedMemory[N].
749 //
750 for (Index = 0; Index < Config->Uefi.ReservedMemory.Count; ++Index) {
751 AsciiReservedMemoryType = OC_BLOB_GET (&Config->Uefi.ReservedMemory.Values[Index]->Type);
752 ReservedMemoryAddress = Config->Uefi.ReservedMemory.Values[Index]->Address;
753 ReservedMemorySize = Config->Uefi.ReservedMemory.Values[Index]->Size;
754
755 if (!ValidateReservedMemoryType (AsciiReservedMemoryType)) {
756 DEBUG ((DEBUG_WARN, "UEFI->ReservedMemory[%u]->Type is borked!\n", Index));
757 ++ErrorCount;
758 }
759
760 if (ReservedMemoryAddress % EFI_PAGE_SIZE != 0) {
761 DEBUG ((DEBUG_WARN, "UEFI->ReservedMemory[%u]->Address (%Lu) cannot be divided by page size!\n", Index, ReservedMemoryAddress));
762 ++ErrorCount;
763 }
764
765 if (ReservedMemorySize == 0ULL) {
766 DEBUG ((DEBUG_WARN, "UEFI->ReservedMemory[%u]->Size cannot be zero!\n", Index));
767 ++ErrorCount;
768 } else if (ReservedMemorySize % EFI_PAGE_SIZE != 0) {
769 DEBUG ((DEBUG_WARN, "UEFI->ReservedMemory[%u]->Size (%Lu) cannot be divided by page size!\n", Index, ReservedMemorySize));
770 ++ErrorCount;
771 }
772 }
773
774 //
775 // Now overlapping check amongst Address and Size.
776 //
777 ErrorCount += FindArrayDuplication (
778 Config->Uefi.ReservedMemory.Values,
779 Config->Uefi.ReservedMemory.Count,
780 sizeof (Config->Uefi.ReservedMemory.Values[0]),
782 );
783
784 return ErrorCount;
785}
786
787UINT32
789 IN OC_GLOBAL_CONFIG *Config
790 )
791{
792 UINT32 ErrorCount;
793 UINTN Index;
794 STATIC CONFIG_CHECK UefiCheckers[] = {
803 };
804
805 DEBUG ((DEBUG_VERBOSE, "config loaded into %a!\n", __func__));
806
807 ErrorCount = 0;
808
809 for (Index = 0; Index < ARRAY_SIZE (UefiCheckers); ++Index) {
810 ErrorCount += UefiCheckers[Index](Config);
811 }
812
813 return ReportError (__func__, ErrorCount);
814}
#define ARRAY_SIZE(Array)
Definition AppleMacEfi.h:34
BOOLEAN mHasNvramUIScale
#define OC_SCAN_FILE_SYSTEM_LOCK
#define OC_SCAN_ALLOW_FS_APFS
VOID OcParseScreenResolution(IN CONST CHAR8 *String, OUT UINT32 *Width, OUT UINT32 *Height, OUT UINT32 *Bpp, OUT BOOLEAN *Max)
VOID OcParseConsoleMode(IN CONST CHAR8 *String, OUT UINT32 *Width, OUT UINT32 *Height, OUT BOOLEAN *Max)
EFI_STATUS ResizeGpuBars(IN PCI_BAR_SIZE Size, IN BOOLEAN Increase, IN BOOLEAN UseRbIo)
#define OPEN_CORE_UEFI_DRIVER_PATH
Definition OcMainLib.h:58
#define OC_STORAGE_SAFE_PATH_MAX
#define L_STR_LEN(String)
Definition OcStringLib.h:26
CHAR8 *EFIAPI OcAsciiStriStr(IN CONST CHAR8 *String, IN CONST CHAR8 *SearchString)
Definition OcAsciiLib.c:327
#define OC_BLOB_GET(Blob)
BOOLEAN AsciiDevicePathIsLegal(IN CONST CHAR8 *AsciiDevicePath)
UINT32 ReportError(IN CONST CHAR8 *FuncName, IN UINT32 ErrorCount)
BOOLEAN StringIsDuplicated(IN CONST CHAR8 *EntrySection, IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
UINT32 FindArrayDuplication(IN VOID *First, IN UINTN Number, IN UINTN Size, IN DUPLICATION_CHECK DupChecker)
BOOLEAN AsciiCommentIsLegal(IN CONST CHAR8 *Comment)
BOOLEAN AsciiUefiDriverIsLegal(IN CONST CHAR8 *Driver, IN CONST UINTN DriverIndex)
STATIC BOOLEAN ValidateReservedMemoryType(IN CONST CHAR8 *Type)
STATIC UINT32 CheckUefiQuirks(IN OC_GLOBAL_CONFIG *Config)
STATIC UINT32 CheckUefiDrivers(IN OC_GLOBAL_CONFIG *Config)
STATIC UINT32 CheckUefiAudio(IN OC_GLOBAL_CONFIG *Config)
STATIC UINT32 CheckUefiReservedMemory(IN OC_GLOBAL_CONFIG *Config)
STATIC UINT32 CheckUefiAPFS(IN OC_GLOBAL_CONFIG *Config)
STATIC BOOLEAN UefiReservedMemoryHasOverlap(IN CONST VOID *PrimaryEntry, IN CONST VOID *SecondaryEntry)
STATIC BOOLEAN UefiDriverHasDuplication(IN CONST VOID *PrimaryDriver, IN CONST VOID *SecondaryDriver)
STATIC UINT32 CheckUefiInput(IN OC_GLOBAL_CONFIG *Config)
STATIC UINT32 CheckUefiAppleInput(IN OC_GLOBAL_CONFIG *Config)
STATIC UINT32 CheckUefiOutput(IN OC_GLOBAL_CONFIG *Config)
STATIC UINT32 CheckUefiGain(INT8 Gain, CHAR8 *GainName, INT8 GainAbove, OPTIONAL CHAR8 *GainAboveName OPTIONAL)
UINT32 CheckUefi(IN OC_GLOBAL_CONFIG *Config)
UINT32(* CONFIG_CHECK)(IN OC_GLOBAL_CONFIG *Config)
Definition ocvalidate.h:27