diff --git a/Include/Library/OcAppleBootCompatLib.h b/Include/Library/OcAppleBootCompatLib.h index 586c0870..0808b98b 100644 --- a/Include/Library/OcAppleBootCompatLib.h +++ b/Include/Library/OcAppleBootCompatLib.h @@ -20,25 +20,31 @@ **/ typedef struct OC_ABC_SETTINGS_ { /// - /// Protect from boot.efi from defragmenting runtime memory and setup virtual memory - /// early mapping. This fixes NVRAM support on many firmwares. + /// Protect from boot.efi from defragmenting runtime memory. This fixes UEFI runtime services + /// (date and time, NVRAM, power control, etc.) support on many firmwares. + /// Needed basically by everyone that uses SMM implementation of variable services. /// - BOOLEAN SetupAppleMap; + BOOLEAN AvoidRuntimeDefrag; + /// + /// Setup virtual memory mapping after SetVirtualAddresses call. This fixes crashes in many + /// firmwares at early boot as they accidentally access virtual addresses after ExitBootServices. + /// + BOOLEAN SetupVirtualMap; /// /// Provide custom Apple KASLR slide calculation for firmwares with polluted low memory ranges. /// This also ensures that slide= argument is never passed to the operating system. /// - BOOLEAN SetupAppleSlide; + BOOLEAN ProvideCustomSlide; /// /// Discard UEFI memory map after waking from hibernation and preserve the original mapping. /// - BOOLEAN DiscardAppleS4Map; + BOOLEAN DiscardHibernateMap; /// /// Try to patch Apple bootloader to have KASLR enabled even in SafeMode. /// - BOOLEAN EnableAppleSmSlide; + BOOLEAN EnableSafeModeSlide; /// - /// Attempt to protect certain CSM memory regions from being used by the kernel . + /// Attempt to protect certain CSM memory regions from being used by the kernel. /// On older firmwares this caused wake issues. /// BOOLEAN ProtectCsmRegion; @@ -50,6 +56,16 @@ typedef struct OC_ABC_SETTINGS_ { /// Ensure that ExitBootServices call succeeds even with outdated MemoryMap key. /// BOOLEAN ForceExitBootServices; + /// + /// Disable NVRAM variable write support to protect from malware or to prevent + /// buggy NVRAM implementations cause system issues. + /// + BOOLEAN DisableVariableWrite; + /// + /// Permit writing to executable memory in UEFI runtime services. Fixes crashes + /// on many APTIO V firmwares. + /// + BOOLEAN EnableWriteUnprotector; } OC_ABC_SETTINGS; /** diff --git a/Include/Library/OcConfigurationLib.h b/Include/Library/OcConfigurationLib.h index b6a5870f..02f16bcd 100644 --- a/Include/Library/OcConfigurationLib.h +++ b/Include/Library/OcConfigurationLib.h @@ -100,13 +100,16 @@ /// Apple bootloader quirks. /// #define OC_BOOTER_QUIRKS_FIELDS(_, __) \ - _(BOOLEAN , SetupAppleMap , , FALSE , ()) \ - _(BOOLEAN , SetupAppleSlide , , FALSE , ()) \ - _(BOOLEAN , DiscardAppleS4Map , , FALSE , ()) \ - _(BOOLEAN , EnableAppleSmSlide , , FALSE , ()) \ - _(BOOLEAN , ProtectCsmRegion , , FALSE , ()) \ - _(BOOLEAN , ShrinkMemoryMap , , FALSE , ()) \ - _(BOOLEAN , ForceExitBootServices , , FALSE , ()) + _(BOOLEAN , AvoidRuntimeDefrag , , FALSE , ()) \ + _(BOOLEAN , DisableVariableWrite , , FALSE , ()) \ + _(BOOLEAN , DiscardHibernateMap , , FALSE , ()) \ + _(BOOLEAN , EnableSafeModeSlide , , FALSE , ()) \ + _(BOOLEAN , EnableWriteUnprotector , , FALSE , ()) \ + _(BOOLEAN , ForceExitBootServices , , FALSE , ()) \ + _(BOOLEAN , ProtectCsmRegion , , FALSE , ()) \ + _(BOOLEAN , ProvideCustomSlide , , FALSE , ()) \ + _(BOOLEAN , SetupVirtualMap , , FALSE , ()) \ + _(BOOLEAN , ShrinkMemoryMap , , FALSE , ()) OC_DECLARE (OC_BOOTER_QUIRKS) /// diff --git a/Include/Protocol/OcFirmwareRuntime.h b/Include/Protocol/OcFirmwareRuntime.h index 608a5975..0cc2fb01 100644 --- a/Include/Protocol/OcFirmwareRuntime.h +++ b/Include/Protocol/OcFirmwareRuntime.h @@ -15,46 +15,110 @@ #ifndef OC_FIRMWARE_RUNTIME_PROTOCOL_H #define OC_FIRMWARE_RUNTIME_PROTOCOL_H -#define OC_FIRMWARE_RUNTIME_REVISION 1 +#include -// -// OC_FIRMWARE_RUNTIME_PROTOCOL_GUID -// 9C820F96-F16C-4FFD-B266-DF0A8FDFC455 -// +#define OC_FIRMWARE_RUNTIME_REVISION 2 + +/** + OC_FIRMWARE_RUNTIME_PROTOCOL_GUID + 570332E4-FC50-4B21-ABE8-AE72F05B4FF7 +**/ #define OC_FIRMWARE_RUNTIME_PROTOCOL_GUID \ - { 0x9C820F96, 0xF16C, 0x4FFD, \ - { 0xB2, 0x66, 0xDF, 0x0A, 0x8F, 0xDF, 0xC4, 0x55 } } + { 0x570332E4, 0xFC50, 0x4B21, \ + { 0xAB, 0xE8, 0xAE, 0x72, 0xF0, 0x5B, 0x4F, 0xF7 } } +/** + Configuration request to change firmware runtime behaviour. +**/ +typedef struct OC_FWRT_CONFIG_ { + /// + /// Enforce restricted access to OpenCore read-only and write-only GUIDs. + /// + BOOLEAN RestrictedVariables; + /// + /// Enforce BootXXXX variable redirection to OpenCore vendor GUID. + /// + BOOLEAN BootVariableRedirect; + /// + /// Make SetVariable do nothing and always return EFI_SECURITY_VIOLATION. + /// When we do not want variables to be stored in NVRAM or NVRAM implementation + /// is buggy we can disable variable writing. + /// + BOOLEAN WriteProtection; + /// + /// Make UEFI runtime services drop CR0 WP bit on calls to allow writing + /// to read only memory. This workarounds a bug in many APTIO firmwares + /// that do not survive W^X. + /// Latest Windows brings Virtualization-based security and monitors + /// CR0 by launching itself under a hypevisor. Since we need WP disable + /// on macOS to let NVRAM work, and for the time being no other OS + /// requires it, here we decide to use it for macOS exclusively. + /// + BOOLEAN WriteUnprotector; +} OC_FWRT_CONFIG; -// -// Set NVRAM routing, returns previous value. -// +/** + Get current used configuration data. + + @param[out] Config Current configuration to store. +**/ typedef -BOOLEAN -EFIAPI -(*OC_FWRT_NVRAM_REDIRECT) ( - IN BOOLEAN NewValue +VOID +(EFIAPI *OC_FWRT_GET_CURRENT_CONFIG) ( + OUT OC_FWRT_CONFIG *Config ); -// -// Set GetVariable override for customising values. -// +/** + Set main configuration. + + @param[in] Config Runtime services configuration to apply. +**/ +typedef +VOID +(EFIAPI *OC_FWRT_SET_MAIN_CONFIG) ( + IN CONST OC_FWRT_CONFIG *Config + ); + +/** + Perform configuration override, NULL Config implies disable override. + + @param[in] Config Runtime services configuration to apply, optional. +**/ +typedef +VOID +(EFIAPI *OC_FWRT_SET_OVERRIDE_CONFIG) ( + IN CONST OC_FWRT_CONFIG *Config OPTIONAL + ); + +/** + Set GetVariable override for customising values. + + @param[in] GetVariable GetVariable to call on each call. + @param[out] OrgGetVariable Original GetVariable to call from GetVariable. + + @retval EFI_SUCCESS on successful override. +**/ typedef EFI_STATUS -EFIAPI -(*OC_FWRT_ON_GET_VARIABLE) ( +(EFIAPI *OC_FWRT_ON_GET_VARIABLE) ( IN EFI_GET_VARIABLE GetVariable, OUT EFI_GET_VARIABLE *OrgGetVariable OPTIONAL ); -// -// Check for revision to ensure binary compatibility. -// +/** + Firmware runtime protocol instance. + Check for revision to ensure binary compatibility. +**/ typedef struct { - UINTN Revision; - OC_FWRT_NVRAM_REDIRECT SetNvram; - OC_FWRT_ON_GET_VARIABLE OnGetVariable; + UINTN Revision; + OC_FWRT_GET_CURRENT_CONFIG GetCurrent; + OC_FWRT_SET_MAIN_CONFIG SetMain; + OC_FWRT_SET_OVERRIDE_CONFIG SetOverride; + OC_FWRT_ON_GET_VARIABLE OnGetVariable; } OC_FIRMWARE_RUNTIME_PROTOCOL; +/** + Firmware runtime protocol GUID. +**/ extern EFI_GUID gOcFirmwareRuntimeProtocolGuid; #endif // OC_FIRMWARE_RUNTIME_PROTOCOL_H diff --git a/Library/OcAppleBootCompatLib/BootCompatInternal.h b/Library/OcAppleBootCompatLib/BootCompatInternal.h index 9835858f..a3d47421 100644 --- a/Library/OcAppleBootCompatLib/BootCompatInternal.h +++ b/Library/OcAppleBootCompatLib/BootCompatInternal.h @@ -25,6 +25,7 @@ #include #include +#include #ifdef MDE_CPU_X64 #include "X64/ContextSwitch.h" @@ -161,31 +162,35 @@ typedef struct SERVICES_OVERRIDE_STATE_ { /// /// GetVariable arrival event. /// - EFI_EVENT GetVariableEvent; + EFI_EVENT GetVariableEvent; + /// + /// Firmware runtime protocol instance. + /// + OC_FIRMWARE_RUNTIME_PROTOCOL *FwRuntime; /// /// Minimum address allocated by AlocatePages. /// - EFI_PHYSICAL_ADDRESS MinAllocatedAddr; + EFI_PHYSICAL_ADDRESS MinAllocatedAddr; /// /// Apple hibernate image address allocated by AlocatePages. /// - EFI_PHYSICAL_ADDRESS HibernateImageAddress; + EFI_PHYSICAL_ADDRESS HibernateImageAddress; /// /// Last descriptor size obtained from GetMemoryMap. /// - UINTN MemoryMapDescriptorSize; + UINTN MemoryMapDescriptorSize; /// /// Amount of nested boot.efi detected. /// - UINTN AppleBootNestedCount; + UINTN AppleBootNestedCount; /// /// TRUE if we are doing boot.efi hibernate wake. /// - BOOLEAN AppleHibernateWake; + BOOLEAN AppleHibernateWake; /// /// TRUE if we are using custom KASLR slide (via boot arg). /// - BOOLEAN AppleCustomSlide; + BOOLEAN AppleCustomSlide; } SERVICES_OVERRIDE_STATE; /** @@ -328,7 +333,7 @@ GetBootCompatContext ( **/ VOID InstallServiceOverrides ( - IN OUT BOOT_COMPAT_CONTEXT *ServicePtrs + IN OUT BOOT_COMPAT_CONTEXT *BootCompat ); /** @@ -382,14 +387,16 @@ AppleMapPrepareKernelJump ( ); /** - Patch kernel entry point with KernelJump to later land in AppleMapPrepareKernelState. + Prepare memory state and perform virtual address translation. @param[in,out] BootCompat Boot compatibility context. - @param[in] ImageAddress Kernel or hibernation image address. - @param[in] AppleHibernateWake TRUE when ImageAddress points to hibernation image. + @param[in] MemoryMapSize SetVirtualAddresses memory map size argument. + @param[in] DescriptorSize SetVirtualAddresses descriptor size argument. + @param[in] DescriptorVersion SetVirtualAddresses descriptor version argument. + @param[in] MemoryMap SetVirtualAddresses memory map argument. **/ EFI_STATUS -AppleMapPrepareVmState ( +AppleMapPrepareMemState ( IN OUT BOOT_COMPAT_CONTEXT *BootCompat, IN UINTN MemoryMapSize, IN UINTN DescriptorSize, diff --git a/Library/OcAppleBootCompatLib/KernelSupport.c b/Library/OcAppleBootCompatLib/KernelSupport.c index 8c58d4c5..9d0c8a77 100644 --- a/Library/OcAppleBootCompatLib/KernelSupport.c +++ b/Library/OcAppleBootCompatLib/KernelSupport.c @@ -334,25 +334,29 @@ AppleMapPrepareForBooting ( OcParseBootArgs (&BA, BootArgs); - // - // Restore the variables we tampered with to support custom slides. - // - AppleSlideRestore (BootCompat, &BA); + if (BootCompat->Settings.ProvideCustomSlide) { + // + // Restore the variables we tampered with to support custom slides. + // + AppleSlideRestore (BootCompat, &BA); + } - MemoryMapSize = *BA.MemoryMapSize; - MemoryMap = (EFI_MEMORY_DESCRIPTOR *)(UINTN) (*BA.MemoryMap); - DescriptorSize = *BA.MemoryMapDescriptorSize; + if (BootCompat->Settings.AvoidRuntimeDefrag) { + MemoryMapSize = *BA.MemoryMapSize; + MemoryMap = (EFI_MEMORY_DESCRIPTOR *)(UINTN) (*BA.MemoryMap); + DescriptorSize = *BA.MemoryMapDescriptorSize; - // - // We must restore EfiRuntimeServicesCode memory area types, because otherwise - // RuntimeServices won't be mapped. - // - RestoreProtectedRtMemoryTypes ( - &BootCompat->RtReloc, - MemoryMapSize, - DescriptorSize, - MemoryMap - ); + // + // We must restore EfiRuntimeServicesCode memory area types, because otherwise + // RuntimeServices won't be mapped. + // + RestoreProtectedRtMemoryTypes ( + &BootCompat->RtReloc, + MemoryMapSize, + DescriptorSize, + MemoryMap + ); + } } /** @@ -398,7 +402,7 @@ AppleMapPrepareForHibernateWake ( Handoff = (IOHibernateHandoff *) EFI_PAGES_TO_SIZE ((UINTN) ImageHeader->handoffPages); while (Handoff->type != kIOHibernateHandoffTypeEnd) { if (Handoff->type == kIOHibernateHandoffTypeMemoryMap) { - if (BootCompat->Settings.DiscardAppleS4Map) { + if (BootCompat->Settings.DiscardHibernateMap) { // // Route 1. Discard the new memory map here, and let XNU use what it had. // It is unknown whether there still are any firmwares that need this. @@ -414,12 +418,17 @@ AppleMapPrepareForHibernateWake ( return; } - RestoreProtectedRtMemoryTypes ( - &BootCompat->RtReloc, - Handoff->bytecount, - BootCompat->KernelState.VmMapDescSize, - (EFI_MEMORY_DESCRIPTOR *)(UINTN) Handoff->data - ); + if (BootCompat->Settings.AvoidRuntimeDefrag) { + // + // I think we should not be there, but ideally all quirks are relatively independent. + // + RestoreProtectedRtMemoryTypes ( + &BootCompat->RtReloc, + Handoff->bytecount, + BootCompat->KernelState.VmMapDescSize, + (EFI_MEMORY_DESCRIPTOR *)(UINTN) Handoff->data + ); + } } break; @@ -458,52 +467,54 @@ AppleMapPrepareBooterState ( // // This function may be called twice, do not redo in this case. // - if (BootCompat->KernelState.SysTableRtArea == 0) { - AppleMapPlatformSaveState ( - &BootCompat->KernelState.AsmState, - &BootCompat->KernelState.KernelJump - ); + AppleMapPlatformSaveState ( + &BootCompat->KernelState.AsmState, + &BootCompat->KernelState.KernelJump + ); - // - // Allocate RT data pages for copy of UEFI system table for kernel. - // This one also has to be 32-bit due to XNU BootArgs structure. - // The reason for this allocation to be required is because XNU uses static - // mapping for directly passed pointers (see ProtectRtMemoryFromRelocation). - // - BootCompat->KernelState.SysTableRtArea = BASE_4GB; - BootCompat->KernelState.SysTableRtAreaSize = gST->Hdr.HeaderSize; - Status = AllocatePagesFromTop ( - EfiRuntimeServicesData, - EFI_SIZE_TO_PAGES (gST->Hdr.HeaderSize), - &BootCompat->KernelState.SysTableRtArea, - GetMemoryMap, - NULL - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "OCABC: Failed to allocate system table memory - %r\n", - Status - )); - BootCompat->KernelState.SysTableRtArea = 0; - return; + if (BootCompat->Settings.AvoidRuntimeDefrag) { + if (BootCompat->KernelState.SysTableRtArea == 0) { + // + // Allocate RT data pages for copy of UEFI system table for kernel. + // This one also has to be 32-bit due to XNU BootArgs structure. + // The reason for this allocation to be required is because XNU uses static + // mapping for directly passed pointers (see ProtectRtMemoryFromRelocation). + // + BootCompat->KernelState.SysTableRtArea = BASE_4GB; + BootCompat->KernelState.SysTableRtAreaSize = gST->Hdr.HeaderSize; + Status = AllocatePagesFromTop ( + EfiRuntimeServicesData, + EFI_SIZE_TO_PAGES (gST->Hdr.HeaderSize), + &BootCompat->KernelState.SysTableRtArea, + GetMemoryMap, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "OCABC: Failed to allocate system table memory - %r\n", + Status + )); + BootCompat->KernelState.SysTableRtArea = 0; + return; + } + + // + // Copy UEFI system table to the new location. + // + CopyMem ( + (VOID *)(UINTN) BootCompat->KernelState.SysTableRtArea, + gST, + gST->Hdr.HeaderSize + ); } // - // Copy UEFI system table to the new location. + // Assign loaded image with custom system table. // - CopyMem ( - (VOID *)(UINTN) BootCompat->KernelState.SysTableRtArea, - gST, - gST->Hdr.HeaderSize - ); + LoadedImage->SystemTable = + (EFI_SYSTEM_TABLE *)(UINTN) BootCompat->KernelState.SysTableRtArea; } - - // - // Assign loaded image with custom system table. - // - LoadedImage->SystemTable = - (EFI_SYSTEM_TABLE *)(UINTN) BootCompat->KernelState.SysTableRtArea; } VOID @@ -517,6 +528,21 @@ AppleMapPrepareKernelJump ( UINT32 KernelEntry; IOHibernateImageHeader *ImageHeader; + // + // There is no reason to patch the kernel when we do not need it. + // + if (!BootCompat->Settings.AvoidRuntimeDefrag && !BootCompat->Settings.DiscardHibernateMap) { + return; + } + + // + // Check whether we have image address and abort if not. + // + if (ImageAddress == 0) { + RUNTIME_DEBUG ((DEBUG_ERROR, "OCABC: Failed to find image address, hibernate %d\n", AppleHibernateWake)); + return; + } + if (!AppleHibernateWake) { // // ImageAddress points to the first kernel segment, __HIB. @@ -572,7 +598,7 @@ AppleMapPrepareKernelJump ( } EFI_STATUS -AppleMapPrepareVmState ( +AppleMapPrepareMemState ( IN OUT BOOT_COMPAT_CONTEXT *BootCompat, IN UINTN MemoryMapSize, IN UINTN DescriptorSize, @@ -585,34 +611,47 @@ AppleMapPrepareVmState ( // // Protect RT areas from relocation by marking then MemMapIO. // - ProtectRtMemoryFromRelocation ( - &BootCompat->RtReloc, - MemoryMapSize, - DescriptorSize, - MemoryMap, - BootCompat->KernelState.SysTableRtArea, - BootCompat->KernelState.SysTableRtAreaSize - ); + if (BootCompat->Settings.AvoidRuntimeDefrag) { + ProtectRtMemoryFromRelocation ( + &BootCompat->RtReloc, + MemoryMapSize, + DescriptorSize, + MemoryMap, + BootCompat->KernelState.SysTableRtArea, + BootCompat->KernelState.SysTableRtAreaSize + ); + } // // Virtualize RT services with all needed fixes. // - Status = PerformRtMemoryVirtualMapping ( - &BootCompat->KernelState, - MemoryMapSize, - DescriptorSize, - DescriptorVersion, - MemoryMap - ); + if (BootCompat->Settings.SetupVirtualMap) { + Status = PerformRtMemoryVirtualMapping ( + &BootCompat->KernelState, + MemoryMapSize, + DescriptorSize, + DescriptorVersion, + MemoryMap + ); + } else { + Status = gRT->SetVirtualAddressMap ( + MemoryMapSize, + DescriptorSize, + DescriptorVersion, + MemoryMap + ); + } // // Copy now virtualized UEFI system table for boot.efi to hand it to the kernel. // - CopyMem ( - (VOID *)(UINTN) BootCompat->KernelState.SysTableRtArea, - gST, - gST->Hdr.HeaderSize - ); + if (BootCompat->Settings.AvoidRuntimeDefrag) { + CopyMem ( + (VOID *)(UINTN) BootCompat->KernelState.SysTableRtArea, + gST, + gST->Hdr.HeaderSize + ); + } return Status; } diff --git a/Library/OcAppleBootCompatLib/ServiceOverrides.c b/Library/OcAppleBootCompatLib/ServiceOverrides.c index 5da02901..cbf063ef 100644 --- a/Library/OcAppleBootCompatLib/ServiceOverrides.c +++ b/Library/OcAppleBootCompatLib/ServiceOverrides.c @@ -15,9 +15,12 @@ #include "BootCompatInternal.h" +#include + #include #include +#include #include #include #include @@ -178,6 +181,8 @@ OcStartImage ( EFI_STATUS Status; EFI_LOADED_IMAGE_PROTOCOL *AppleLoadedImage; BOOT_COMPAT_CONTEXT *BootCompat; + OC_FWRT_CONFIG Config; + UINTN DataSize; BootCompat = GetBootCompatContext (); AppleLoadedImage = OcGetAppleBootLoadedImage (ImageHandle); @@ -200,20 +205,57 @@ OcStartImage ( L_STR_LEN ("slide=") ); - if (BootCompat->Settings.EnableAppleSmSlide) { + if (BootCompat->Settings.EnableSafeModeSlide) { AppleSlideUnlockForSafeMode ( (UINT8 *) AppleLoadedImage->ImageBase, AppleLoadedImage->ImageSize ); } - if (BootCompat->Settings.SetupAppleMap) { - AppleMapPrepareBooterState ( - BootCompat, - AppleLoadedImage, - BootCompat->ServicePtrs.GetMemoryMap - ); + AppleMapPrepareBooterState ( + BootCompat, + AppleLoadedImage, + BootCompat->ServicePtrs.GetMemoryMap + ); + } + + if (BootCompat->ServiceState.FwRuntime != NULL) { + BootCompat->ServiceState.FwRuntime->GetCurrent (&Config); + + // + // Support for ReadOnly and WriteOnly variables is OpenCore & Lilu security basics. + // For now always enable it. + // + Config.RestrictedVariables = TRUE; + + // + // Enable Boot#### variable redirection if OpenCore requested it. + // Do NOT disable it once enabled for stability reasons. + // + DataSize = sizeof (Config.BootVariableRedirect); + BootCompat->ServicePtrs.GetVariable ( + OC_BOOT_REDIRECT_VARIABLE_NAME, + &gOcVendorVariableGuid, + NULL, + &DataSize, + &Config.BootVariableRedirect + ); + + // + // Enable Apple-specific changes if requested. + // Disable them when this is no longer Apple. + // + if (BootCompat->ServiceState.AppleBootNestedCount > 0) { + Config.WriteProtection = BootCompat->Settings.DisableVariableWrite; + Config.WriteUnprotector = BootCompat->Settings.EnableWriteUnprotector; + } else { + Config.WriteProtection = FALSE; + Config.WriteUnprotector = FALSE; } + + BootCompat->ServiceState.FwRuntime->SetMain ( + &Config + ); } Status = BootCompat->ServicePtrs.StartImage ( @@ -369,18 +411,6 @@ OcExitBootServices ( ); } - // - // We need hibernate image address for wake, check it quickly before - // killing boot services to be able to print the error. - // - if (BootCompat->Settings.SetupAppleMap - && BootCompat->ServiceState.AppleHibernateWake - && BootCompat->ServiceState.HibernateImageAddress == 0) { - DEBUG ((DEBUG_ERROR, "OCABC: Failed to find hibernate image address\n")); - gBS->Stall (SECONDS_TO_MICROSECONDS (5)); - return EFI_INVALID_PARAMETER; - } - if (BootCompat->Settings.ForceExitBootServices) { Status = ForceExitBootServices ( ImageHandle, @@ -396,9 +426,9 @@ OcExitBootServices ( } // - // Abort on error or when we are not supposed to do extra mapping. + // Abort on error. // - if (EFI_ERROR (Status) || !BootCompat->Settings.SetupAppleMap) { + if (EFI_ERROR (Status)) { return Status; } @@ -447,27 +477,13 @@ OcSetVirtualAddressMap ( gRT->Hdr.CRC32 = 0; gRT->Hdr.CRC32 = CalculateCrc32 (gRT, gRT->Hdr.HeaderSize); - // - // For non-macOS operating systems return directly. - // Also do nothing for custom mapping. - // - if (BootCompat->ServiceState.AppleBootNestedCount == 0 - || !BootCompat->Settings.SetupAppleMap) { - Status = gRT->SetVirtualAddressMap ( - MemoryMapSize, - DescriptorSize, - DescriptorVersion, - MemoryMap - ); - } else { - Status = AppleMapPrepareVmState ( - BootCompat, - MemoryMapSize, - DescriptorSize, - DescriptorVersion, - MemoryMap - ); - } + Status = AppleMapPrepareMemState ( + BootCompat, + MemoryMapSize, + DescriptorSize, + DescriptorVersion, + MemoryMap + ); return Status; } @@ -493,7 +509,7 @@ OcGetVariable ( BootCompat = GetBootCompatContext (); if (BootCompat->ServiceState.AppleBootNestedCount > 0 - && BootCompat->Settings.SetupAppleSlide) { + && BootCompat->Settings.ProvideCustomSlide) { Status = AppleSlideGetVariable ( BootCompat, BootCompat->ServicePtrs.GetVariable, @@ -522,7 +538,7 @@ OcGetVariable ( We do not override GetVariable ourselves but let our runtime do that. @param[in] Event Event handle. - @param[in] Context Services pointers context. + @param[in] Context Apple boot compatibility context. **/ STATIC VOID @@ -534,11 +550,11 @@ SetGetVariableHookHandler ( { EFI_STATUS Status; OC_FIRMWARE_RUNTIME_PROTOCOL *FwRuntime; - UEFI_SERVICES_POINTERS *ServicePtrs; + BOOT_COMPAT_CONTEXT *BootCompat; - ServicePtrs = (UEFI_SERVICES_POINTERS *) Context; + BootCompat = (BOOT_COMPAT_CONTEXT *) Context; - if (ServicePtrs->GetVariable == NULL) { + if (BootCompat->ServicePtrs.GetVariable == NULL) { Status = gBS->LocateProtocol ( &gOcFirmwareRuntimeProtocolGuid, NULL, @@ -546,7 +562,16 @@ SetGetVariableHookHandler ( ); if (!EFI_ERROR (Status) && FwRuntime->Revision == OC_FIRMWARE_RUNTIME_REVISION) { - FwRuntime->OnGetVariable (OcGetVariable, &ServicePtrs->GetVariable); + Status = FwRuntime->OnGetVariable (OcGetVariable, &BootCompat->ServicePtrs.GetVariable); + } else { + Status = EFI_UNSUPPORTED; + } + + // + // Mark protocol as useable. + // + if (!EFI_ERROR (Status)) { + BootCompat->ServiceState.FwRuntime = FwRuntime; } } } @@ -588,7 +613,7 @@ InstallServiceOverrides ( // // Allocate memory pool if needed. // - if (BootCompat->Settings.SetupAppleMap) { + if (BootCompat->Settings.SetupVirtualMap) { AppleMapPrepareMemoryPool ( BootCompat ); @@ -597,9 +622,9 @@ InstallServiceOverrides ( // // Update GetVariable handle with the help of external runtime services. // - SetGetVariableHookHandler (NULL, ServicePtrs); + SetGetVariableHookHandler (NULL, BootCompat); - if (ServicePtrs->GetVariable != NULL) { + if (BootCompat->ServicePtrs.GetVariable != NULL) { return; } @@ -607,7 +632,7 @@ InstallServiceOverrides ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, SetGetVariableHookHandler, - ServicePtrs, + BootCompat, &BootCompat->ServiceState.GetVariableEvent ); diff --git a/Library/OcConfigurationLib/OcConfigurationLib.c b/Library/OcConfigurationLib/OcConfigurationLib.c index 0425a372..d4048cc2 100644 --- a/Library/OcConfigurationLib/OcConfigurationLib.c +++ b/Library/OcConfigurationLib/OcConfigurationLib.c @@ -147,13 +147,16 @@ mAcpiConfigurationSchema[] = { STATIC OC_SCHEMA mBooterQuirksSchema[] = { - OC_SCHEMA_BOOLEAN_IN ("DiscardAppleS4Map", OC_GLOBAL_CONFIG, Booter.Quirks.DiscardAppleS4Map), - OC_SCHEMA_BOOLEAN_IN ("EnableAppleSmSlide", OC_GLOBAL_CONFIG, Booter.Quirks.EnableAppleSmSlide), - OC_SCHEMA_BOOLEAN_IN ("ForceExitBootServices", OC_GLOBAL_CONFIG, Booter.Quirks.ForceExitBootServices), - OC_SCHEMA_BOOLEAN_IN ("ProtectCsmRegion", OC_GLOBAL_CONFIG, Booter.Quirks.ProtectCsmRegion), - OC_SCHEMA_BOOLEAN_IN ("SetupAppleMap", OC_GLOBAL_CONFIG, Booter.Quirks.SetupAppleMap), - OC_SCHEMA_BOOLEAN_IN ("SetupAppleSlide", OC_GLOBAL_CONFIG, Booter.Quirks.SetupAppleSlide), - OC_SCHEMA_BOOLEAN_IN ("ShrinkMemoryMap", OC_GLOBAL_CONFIG, Booter.Quirks.ShrinkMemoryMap), + OC_SCHEMA_BOOLEAN_IN ("AvoidRuntimeDefrag", OC_GLOBAL_CONFIG, Booter.Quirks.AvoidRuntimeDefrag), + OC_SCHEMA_BOOLEAN_IN ("DisableVariableWrite", OC_GLOBAL_CONFIG, Booter.Quirks.DisableVariableWrite), + OC_SCHEMA_BOOLEAN_IN ("DiscardHibernateMap", OC_GLOBAL_CONFIG, Booter.Quirks.DiscardHibernateMap), + OC_SCHEMA_BOOLEAN_IN ("EnableSafeModeSlide", OC_GLOBAL_CONFIG, Booter.Quirks.EnableSafeModeSlide), + OC_SCHEMA_BOOLEAN_IN ("EnableWriteUnprotector", OC_GLOBAL_CONFIG, Booter.Quirks.EnableWriteUnprotector), + OC_SCHEMA_BOOLEAN_IN ("ForceExitBootServices", OC_GLOBAL_CONFIG, Booter.Quirks.ForceExitBootServices), + OC_SCHEMA_BOOLEAN_IN ("ProtectCsmRegion", OC_GLOBAL_CONFIG, Booter.Quirks.ProtectCsmRegion), + OC_SCHEMA_BOOLEAN_IN ("ProvideCustomSlide", OC_GLOBAL_CONFIG, Booter.Quirks.ProvideCustomSlide), + OC_SCHEMA_BOOLEAN_IN ("SetupVirtualMap", OC_GLOBAL_CONFIG, Booter.Quirks.SetupVirtualMap), + OC_SCHEMA_BOOLEAN_IN ("ShrinkMemoryMap", OC_GLOBAL_CONFIG, Booter.Quirks.ShrinkMemoryMap), }; STATIC diff --git a/OcSupportPkg.dec b/OcSupportPkg.dec index 1ff630f4..6e87ed2c 100644 --- a/OcSupportPkg.dec +++ b/OcSupportPkg.dec @@ -45,7 +45,7 @@ gOcAppleBootCompatProtocolGuid = { 0xC7CBA84E, 0xCC77, 0x461D, { 0x9E, 0x3C, 0x6B, 0xE0, 0xCB, 0x79, 0xA7, 0xC1 } } ## Include/Protocol/OcFirmwareRuntime.h - gOcFirmwareRuntimeProtocolGuid = { 0x9C820F96, 0xF16C, 0x4FFD, { 0xB2, 0x66, 0xDF, 0x0A, 0x8F, 0xDF, 0xC4, 0x55 }} + gOcFirmwareRuntimeProtocolGuid = { 0x570332E4, 0xFC50, 0x4B21, { 0xAB, 0xE8, 0xAE, 0x72, 0xF0, 0x5B, 0x4F, 0xF7 }} ## Include/Protocol/LegacyRegion.h gEfiLegacyRegionProtocolGuid = { 0x0fc9013a, 0x0568, 0x4ba9, { 0x9b, 0x7e, 0xc9, 0xc3, 0x90, 0xa6, 0x60, 0x9b }}