From 207315a9fadbfbe7de68cec9e47a0a9be8fea882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20B=C4=83l=C4=83nic=C4=83?= Date: Sun, 31 Dec 2023 21:04:23 +0200 Subject: [PATCH 11/16] =?UTF-8?q?=EF=BB=BFPlatform/RaspberryPi:=20Add=20op?= =?UTF-8?q?tion=20to=20disable=20EFI=20Memory=20Attribute=20Protocol?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a driver that allows disabling this protocol via a HII option. Default is enabled, which can also be overridden at build time by changing `gRaspberryPiTokenSpaceGuid.PcdMemoryAttributeEnabledDefault`. This should probably be done in core EDK2 though, it's clear that it will take distros more time to catch up and suddenly breaking compatibility like this isn't great for end users. Signed-off-by: Mario Bălănică --- .../MemoryAttributeManagerDxe.c | 180 ++++++++++++++++++ .../MemoryAttributeManagerDxe.h | 22 +++ .../MemoryAttributeManagerDxe.inf | 47 +++++ .../MemoryAttributeManagerDxeHii.uni | 17 ++ .../MemoryAttributeManagerDxeHii.vfr | 35 ++++ .../Guid/MemoryAttributeManagerFormSet.h | 17 ++ Platform/RaspberryPi/RPi3/RPi3.dsc | 5 + Platform/RaspberryPi/RPi3/RPi3.fdf | 5 + Platform/RaspberryPi/RPi4/RPi4.dsc | 5 + Platform/RaspberryPi/RPi4/RPi4.fdf | 5 + Platform/RaspberryPi/RPi5/RPi5.dsc | 5 + Platform/RaspberryPi/RPi5/RPi5.fdf | 5 + Platform/RaspberryPi/RaspberryPi.dec | 2 + 13 files changed, 350 insertions(+) create mode 100644 Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c create mode 100644 Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h create mode 100644 Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf create mode 100644 Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni create mode 100644 Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr create mode 100644 Platform/RaspberryPi/Include/Guid/MemoryAttributeManagerFormSet.h diff --git a/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c b/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c new file mode 100644 index 00000000..0c6f6e28 --- /dev/null +++ b/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c @@ -0,0 +1,180 @@ +/** @file + * + * Copyright (c) 2023, Mario Bălănică + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include +#include +#include +#include +#include +#include + +#include "MemoryAttributeManagerDxe.h" + +extern UINT8 MemoryAttributeManagerDxeHiiBin[]; +extern UINT8 MemoryAttributeManagerDxeStrings[]; + +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} HII_VENDOR_DEVICE_PATH; + +STATIC HII_VENDOR_DEVICE_PATH mVendorDevicePath = { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8)(sizeof (VENDOR_DEVICE_PATH)), + (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8) + } + }, + MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8)(END_DEVICE_PATH_LENGTH), + (UINT8)((END_DEVICE_PATH_LENGTH) >> 8) + } + } +}; + +STATIC +EFI_STATUS +EFIAPI +InstallHiiPages ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HII_HANDLE HiiHandle; + EFI_HANDLE DriverHandle; + + DriverHandle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &DriverHandle, + &gEfiDevicePathProtocolGuid, + &mVendorDevicePath, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + HiiHandle = HiiAddPackages ( + &gMemoryAttributeManagerFormSetGuid, + DriverHandle, + MemoryAttributeManagerDxeStrings, + MemoryAttributeManagerDxeHiiBin, + NULL + ); + + if (HiiHandle == NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + DriverHandle, + &gEfiDevicePathProtocolGuid, + &mVendorDevicePath, + NULL + ); + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + This function uninstalls the recently added EFI_MEMORY_ATTRIBUTE_PROTOCOL + to workaround older versions of OS loaders/shims using it incorrectly and + throwing a Synchronous Exception. + See: + - https://github.com/microsoft/mu_silicon_arm_tiano/issues/124 + - https://edk2.groups.io/g/devel/topic/99631663 +**/ +STATIC +VOID +UninstallEfiMemoryAttributeProtocol ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + UINTN Size; + VOID *MemoryAttributeProtocol; + + Size = sizeof (Handle); + Status = gBS->LocateHandle ( + ByProtocol, + &gEfiMemoryAttributeProtocolGuid, + NULL, + &Size, + &Handle + ); + if (EFI_ERROR (Status)) { + ASSERT (Status == EFI_NOT_FOUND); + return; + } + + Status = gBS->HandleProtocol ( + Handle, + &gEfiMemoryAttributeProtocolGuid, + &MemoryAttributeProtocol + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return; + } + + Status = gBS->UninstallProtocolInterface ( + Handle, + &gEfiMemoryAttributeProtocolGuid, + MemoryAttributeProtocol + ); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "%a: Done!\n", __func__)); +} + +EFI_STATUS +EFIAPI +MemoryAttributeManagerInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINTN Size; + MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA Config; + + Config.Enabled = PROTOCOL_ENABLED_DEFAULT; + + Size = sizeof (MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA); + Status = gRT->GetVariable ( + MEMORY_ATTRIBUTE_MANAGER_DATA_VAR_NAME, + &gMemoryAttributeManagerFormSetGuid, + NULL, + &Size, + &Config + ); + if (EFI_ERROR (Status)) { + Status = gRT->SetVariable ( + MEMORY_ATTRIBUTE_MANAGER_DATA_VAR_NAME, + &gMemoryAttributeManagerFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + Size, + &Config + ); + ASSERT_EFI_ERROR (Status); + } + + if (!Config.Enabled) { + UninstallEfiMemoryAttributeProtocol (); + } + + return InstallHiiPages (); +} diff --git a/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h b/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h new file mode 100644 index 00000000..9db0568d --- /dev/null +++ b/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h @@ -0,0 +1,22 @@ +/** @file + * + * Copyright (c) 2023, Mario Bălănică + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#ifndef __MEMORY_ATTRIBUTE_MANAGER_DXE_H__ +#define __MEMORY_ATTRIBUTE_MANAGER_DXE_H__ + +#include + +#define PROTOCOL_ENABLED_DEFAULT FixedPcdGetBool(PcdMemoryAttributeEnabledDefault) + +#define MEMORY_ATTRIBUTE_MANAGER_DATA_VAR_NAME L"MemoryAttributeManagerData" + +typedef struct { + BOOLEAN Enabled; +} MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA; + +#endif // __MEMORY_ATTRIBUTE_MANAGER_DXE_H__ diff --git a/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf b/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf new file mode 100644 index 00000000..ae36810d --- /dev/null +++ b/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf @@ -0,0 +1,47 @@ +#/** @file +# +# Copyright (c) 2023, Mario Bălănică +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#**/ + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = MemoryAttributeManagerDxe + FILE_GUID = 5319346b-66ad-433a-9a91-f7fc286bc9a1 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = MemoryAttributeManagerInitialize + +[Sources] + MemoryAttributeManagerDxe.c + MemoryAttributeManagerDxeHii.uni + MemoryAttributeManagerDxeHii.vfr + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Platform/RaspberryPi/RaspberryPi.dec + +[LibraryClasses] + DebugLib + DevicePathLib + HiiLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + UefiDriverEntryPoint + +[Guids] + gMemoryAttributeManagerFormSetGuid + +[Protocols] + gEfiMemoryAttributeProtocolGuid + +[Pcd] + gRaspberryPiTokenSpaceGuid.PcdMemoryAttributeEnabledDefault + +[Depex] + gEfiVariableArchProtocolGuid + AND gEfiVariableWriteArchProtocolGuid + AND gEfiMemoryAttributeProtocolGuid diff --git a/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni b/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni new file mode 100644 index 00000000..f78ed725 --- /dev/null +++ b/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni @@ -0,0 +1,17 @@ +/** @file + * + * Copyright (c) 2023, Mario Bălănică + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#langdef en-US "English" + +#string STR_NULL_STRING #language en-US "" + +#string STR_FORM_SET_TITLE #language en-US "EFI Memory Attribute Protocol" +#string STR_FORM_SET_TITLE_HELP #language en-US "Configure the state of the EFI Memory Attribute Protocol." + +#string STR_ENABLE_PROTOCOL_PROMPT #language en-US "Enable Protocol" +#string STR_ENABLE_PROTOCOL_HELP #language en-US "Some OS loader versions do not properly support the memory attribute protocol and may cause a Synchronous Exception. This option can be disabled to work around the issue." diff --git a/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr b/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr new file mode 100644 index 00000000..cdf2be8b --- /dev/null +++ b/Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr @@ -0,0 +1,35 @@ +/** @file + * + * Copyright (c) 2023, Mario Bălănică + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include +#include + +#include "MemoryAttributeManagerDxe.h" + +formset + guid = MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID, + title = STRING_TOKEN(STR_FORM_SET_TITLE), + help = STRING_TOKEN(STR_FORM_SET_TITLE_HELP), + classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID, + + efivarstore MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA, + attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, + name = MemoryAttributeManagerData, + guid = MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID; + + form formid = 1, + title = STRING_TOKEN(STR_FORM_SET_TITLE); + + checkbox varid = MemoryAttributeManagerData.Enabled, + prompt = STRING_TOKEN(STR_ENABLE_PROTOCOL_PROMPT), + help = STRING_TOKEN(STR_ENABLE_PROTOCOL_HELP), + flags = CHECKBOX_DEFAULT | CHECKBOX_DEFAULT_MFG | RESET_REQUIRED, + default = PROTOCOL_ENABLED_DEFAULT, + endcheckbox; + endform; +endformset; diff --git a/Platform/RaspberryPi/Include/Guid/MemoryAttributeManagerFormSet.h b/Platform/RaspberryPi/Include/Guid/MemoryAttributeManagerFormSet.h new file mode 100644 index 00000000..b480f313 --- /dev/null +++ b/Platform/RaspberryPi/Include/Guid/MemoryAttributeManagerFormSet.h @@ -0,0 +1,17 @@ +/** @file + * + * Copyright (c) 2023, Mario Bălănică + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#ifndef __MEMORY_ATTRIBUTE_MANAGER_FORMSET_H__ +#define __MEMORY_ATTRIBUTE_MANAGER_FORMSET_H__ + +#define MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID \ + { 0xefab3427, 0x4793, 0x4e9e, { 0xaa, 0x29, 0x88, 0x0c, 0x9a, 0x77, 0x5b, 0x5f } } + +extern EFI_GUID gMemoryAttributeManagerFormSetGuid; + +#endif // __MEMORY_ATTRIBUTE_MANAGER_FORMSET_H__ diff --git a/Platform/RaspberryPi/RPi3/RPi3.dsc b/Platform/RaspberryPi/RPi3/RPi3.dsc index 9c549ac7..99762f20 100644 --- a/Platform/RaspberryPi/RPi3/RPi3.dsc +++ b/Platform/RaspberryPi/RPi3/RPi3.dsc @@ -736,6 +736,11 @@ # Silicon/Broadcom/Bcm283x/Drivers/Bcm2835RngDxe/Bcm2835RngDxe.inf + # + # EFI Memory Attribute Protocol Manager + # + Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf + # # UEFI application (Shell Embedded Boot Loader) # diff --git a/Platform/RaspberryPi/RPi3/RPi3.fdf b/Platform/RaspberryPi/RPi3/RPi3.fdf index 3c569f57..ae1e0628 100644 --- a/Platform/RaspberryPi/RPi3/RPi3.fdf +++ b/Platform/RaspberryPi/RPi3/RPi3.fdf @@ -230,6 +230,11 @@ READ_LOCK_STATUS = TRUE INF FatPkg/EnhancedFatDxe/Fat.inf INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + # + # EFI Memory Attribute Protocol Manager + # + INF Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf + # # UEFI application (Shell Embedded Boot Loader) # diff --git a/Platform/RaspberryPi/RPi4/RPi4.dsc b/Platform/RaspberryPi/RPi4/RPi4.dsc index ba839fd1..a48092c1 100644 --- a/Platform/RaspberryPi/RPi4/RPi4.dsc +++ b/Platform/RaspberryPi/RPi4/RPi4.dsc @@ -782,6 +782,11 @@ # MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf + # + # EFI Memory Attribute Protocol Manager + # + Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf + # # UEFI application (Shell Embedded Boot Loader) # diff --git a/Platform/RaspberryPi/RPi4/RPi4.fdf b/Platform/RaspberryPi/RPi4/RPi4.fdf index 81692776..4f2fc5bd 100644 --- a/Platform/RaspberryPi/RPi4/RPi4.fdf +++ b/Platform/RaspberryPi/RPi4/RPi4.fdf @@ -227,6 +227,11 @@ READ_LOCK_STATUS = TRUE INF FatPkg/EnhancedFatDxe/Fat.inf INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + # + # EFI Memory Attribute Protocol Manager + # + INF Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf + # # UEFI application (Shell Embedded Boot Loader) # diff --git a/Platform/RaspberryPi/RPi5/RPi5.dsc b/Platform/RaspberryPi/RPi5/RPi5.dsc index f2a1992e..15f6e1a3 100644 --- a/Platform/RaspberryPi/RPi5/RPi5.dsc +++ b/Platform/RaspberryPi/RPi5/RPi5.dsc @@ -668,6 +668,11 @@ # MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf + # + # EFI Memory Attribute Protocol Manager + # + Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf + # # UEFI application (Shell Embedded Boot Loader) # diff --git a/Platform/RaspberryPi/RPi5/RPi5.fdf b/Platform/RaspberryPi/RPi5/RPi5.fdf index bfe6a90e..1507e39d 100644 --- a/Platform/RaspberryPi/RPi5/RPi5.fdf +++ b/Platform/RaspberryPi/RPi5/RPi5.fdf @@ -228,6 +228,11 @@ READ_LOCK_STATUS = TRUE INF FatPkg/EnhancedFatDxe/Fat.inf INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + # + # EFI Memory Attribute Protocol Manager + # + INF Platform/RaspberryPi/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf + # # UEFI application (Shell Embedded Boot Loader) # diff --git a/Platform/RaspberryPi/RaspberryPi.dec b/Platform/RaspberryPi/RaspberryPi.dec index d0025cf6..0c636cbf 100644 --- a/Platform/RaspberryPi/RaspberryPi.dec +++ b/Platform/RaspberryPi/RaspberryPi.dec @@ -26,6 +26,7 @@ gRaspberryPiTokenSpaceGuid = {0xCD7CC258, 0x31DB, 0x11E6, {0x9F, 0xD3, 0x63, 0xB0, 0xB8, 0xEE, 0xD6, 0xB5}} gRaspberryPiEventResetGuid = {0xCD7CC258, 0x31DB, 0x11E6, {0x9F, 0xD3, 0x63, 0xB4, 0xB4, 0xE4, 0xD4, 0xB4}} gConfigDxeFormSetGuid = {0xCD7CC258, 0x31DB, 0x22E6, {0x9F, 0x22, 0x63, 0xB0, 0xB8, 0xEE, 0xD6, 0xB5}} + gMemoryAttributeManagerFormSetGuid = { 0xefab3427, 0x4793, 0x4e9e, { 0xaa, 0x29, 0x88, 0x0c, 0x9a, 0x77, 0x5b, 0x5f } } [PcdsFixedAtBuild.common] # @@ -75,3 +76,4 @@ gRaspberryPiTokenSpaceGuid.PcdXhciPci|0|UINT32|0x00000022 gRaspberryPiTokenSpaceGuid.PcdMiniUartClockRate|0|UINT32|0x00000023 gRaspberryPiTokenSpaceGuid.PcdXhciReload|0|UINT32|0x00000024 + gRaspberryPiTokenSpaceGuid.PcdMemoryAttributeEnabledDefault|TRUE|BOOLEAN|0x00000025 -- 2.51.2