From 6b3ac9cbf8fd8364dd372f0191f2938d53911a93 Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Mon, 3 Jun 2024 10:52:53 +0800 Subject: MdeModulePkg: Add VarCheckHiiLibMmDependency library. VarCheckHiiLibMmDependency retrieve data (mVarCheckHiiBin) at the end of the DXE phase, and pass the acquired data to the VarCheckHiiLibStandaloneMm through a communication protocol. Cc: Liming Gao Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan Cc: Dandan Bi Signed-off-by: Yuanhao Xie --- MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h | 7 ++ .../Library/VarCheckHiiLib/VarCheckHiiGen.c | 1 + .../VarCheckHiiLib/VarCheckHiiLibMmDependency.c | 138 +++++++++++++++++++++ .../VarCheckHiiLib/VarCheckHiiLibMmDependency.inf | 53 ++++++++ 4 files changed, 199 insertions(+) create mode 100644 MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.c create mode 100644 MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf (limited to 'MdeModulePkg') diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h index f6894c9cb3..59b51e8155 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h @@ -51,4 +51,11 @@ DumpVarCheckHii ( IN UINTN VarCheckHiiBinSize ); +#define VAR_CHECK_RECEIVED_HII_BIN_HANDLER_GUID \ + { \ + 0xe63095c7, 0x2b34, 0x4163, { 0x80, 0x3d, 0xc8, 0x3c, 0x2e, 0xd6, 0xa0, 0x37 } \ + } + +extern EFI_GUID gVarCheckReceivedHiiBinHandlerGuid; + #endif diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c index 5e54e19bc1..e6e92af4e2 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c @@ -7,6 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "VarCheckHiiGen.h" +#include "VarCheckHii.h" VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin = NULL; UINTN mVarCheckHiiBinSize = 0; diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.c new file mode 100644 index 0000000000..9ba75b7299 --- /dev/null +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.c @@ -0,0 +1,138 @@ +/** @file + VarCheckHiiLib Dependency library. + It sends HII variable checking data to SMM via the MM Communication protocol. + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include "InternalVarCheckStructure.h" +#include "VarCheckHiiGen.h" +#include "VarCheckHii.h" +#include +#include + +extern VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin; +extern UINTN mVarCheckHiiBinSize; +EFI_GUID gVarCheckReceivedHiiBinHandlerGuid = VAR_CHECK_RECEIVED_HII_BIN_HANDLER_GUID; + +/** + Sends HII variable checking data to SMM at the end of DXE phase. + This function is triggered by the End of DXE. It locates a memory + region for MM communication, prepares the communication buffer with HII variable + checking data, and communicates with SMM using the MM Communication protocol. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context The pointer to the notification function's context, which + is implementation-dependent. +**/ +VOID +EFIAPI +VarCheckHiiLibSmmEndOfDxeNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_MM_COMMUNICATION_PROTOCOL *MmCommunication; + EFI_MM_COMMUNICATE_HEADER *CommHeader; + EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable; + EFI_MEMORY_DESCRIPTOR *MmCommMemRegion; + UINTN CommBufferSize; + UINTN Index; + VAR_CHECK_HII_VARIABLE_HEADER *VarCheckHiiVariable; + + DEBUG ((DEBUG_INFO, "%a starts.\n", __func__)); + VarCheckHiiGen (); + if ((mVarCheckHiiBinSize == 0) || (mVarCheckHiiBin == NULL)) { + DEBUG ((DEBUG_INFO, "%a: mVarCheckHiiBinSize = 0x%x, mVarCheckHiiBin = 0x%x \n", __func__, mVarCheckHiiBinSize, mVarCheckHiiBin)); + return; + } + + // + // Retrieve SMM Communication Region Table + // + Status = EfiGetSystemConfigurationTable ( + &gEdkiiPiSmmCommunicationRegionTableGuid, + (VOID **)&PiSmmCommunicationRegionTable + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to get PiSmmCommunicationRegionTable - %r\n", __func__, Status)); + return; + } + + ASSERT (PiSmmCommunicationRegionTable != NULL); + // + // Find a memory region for MM communication + // + CommBufferSize = 0; + MmCommMemRegion = (EFI_MEMORY_DESCRIPTOR *)(PiSmmCommunicationRegionTable + 1); + for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) { + if (MmCommMemRegion->Type == EfiConventionalMemory) { + CommBufferSize = EFI_PAGES_TO_SIZE ((UINTN)MmCommMemRegion->NumberOfPages); + if (CommBufferSize >= (sizeof (EFI_MM_COMMUNICATE_HEADER) + mVarCheckHiiBinSize)) { + break; + } + } + + MmCommMemRegion = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MmCommMemRegion + PiSmmCommunicationRegionTable->DescriptorSize); + } + + if (Index >= PiSmmCommunicationRegionTable->NumberOfEntries) { + DEBUG ((DEBUG_ERROR, "%a: Failed to find a suitable memory region for MM communication!\n", __func__)); + return; + } + + // + // Prepare the communication buffer + // + CommHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)MmCommMemRegion->PhysicalStart; + CommBufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + mVarCheckHiiBinSize; + ZeroMem (CommHeader, CommBufferSize); + CopyGuid (&CommHeader->HeaderGuid, &gVarCheckReceivedHiiBinHandlerGuid); + CommHeader->MessageLength = mVarCheckHiiBinSize; + VarCheckHiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)(CommHeader->Data); + CopyMem (VarCheckHiiVariable, mVarCheckHiiBin, mVarCheckHiiBinSize); + // + // Locate the MM Communication protocol and signal SMI + // + Status = gBS->LocateProtocol (&gEfiMmCommunicationProtocolGuid, NULL, (VOID **)&MmCommunication); + + if (!EFI_ERROR (Status)) { + Status = MmCommunication->Communicate (MmCommunication, CommHeader, &CommBufferSize); + DEBUG ((DEBUG_INFO, "%a: Communicate to smm environment = %r\n", __func__, Status)); + } else { + DEBUG ((DEBUG_ERROR, "%a: Failed to locate MmCommunication protocol - %r\n", __func__, Status)); + return; + } + + DEBUG ((DEBUG_INFO, "%a ends.\n", __func__)); + return; +} + +/** + Constructor function of the VarCheckHiiLibMmDependency. + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the Management mode System Table. + @retval EFI_SUCCESS The protocol was successfully installed into the DXE database. +**/ +EFI_STATUS +EFIAPI +VarCheckHiiLibMmDependencyConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT Event; + + DEBUG ((DEBUG_INFO, "%a starts.\n", __func__)); + Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_NOTIFY, VarCheckHiiLibSmmEndOfDxeNotify, NULL, &gEfiEndOfDxeEventGroupGuid, &Event); + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_INFO, "%a ends.\n", __func__)); + return Status; +} diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf new file mode 100644 index 0000000000..9798a1b4dd --- /dev/null +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf @@ -0,0 +1,53 @@ +## @file +# VarCheckHiiLib Dependency library. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = VarCheckHiiLibMmDependency + FILE_GUID = DF61C3DC-B08C-44B7-B771-9E4BCBBE0811 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL + CONSTRUCTOR = VarCheckHiiLibMmDependencyConstructor + +[Sources] + VarCheckHiiLibMmDependency.c + VarCheckHii.h + VarCheckHiiGenFromFv.c + VarCheckHiiGenFromHii.c + VarCheckHiiGen.c + VarCheckHiiGen.h + InternalVarCheckStructure.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + DebugLib + UefiBootServicesTableLib + BaseLib + BaseMemoryLib + MemoryAllocationLib + UefiLib + PcdLib + +[Guids] + gEdkiiIfrBitVarstoreGuid + gEfiEndOfDxeEventGroupGuid + gEdkiiPiSmmCommunicationRegionTableGuid + +[Protocols] + gEfiMmEndOfDxeProtocolGuid + gEfiMmCommunicationProtocolGuid + gEfiFirmwareVolume2ProtocolGuid ## SOMETIMES_CONSUMES + gEfiFirmwareVolumeBlock2ProtocolGuid ## SOMETIMES_CONSUMES + gEfiHiiDatabaseProtocolGuid ## SOMETIMES_CONSUMES + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdVarCheckVfrDriverGuidArray ## SOMETIMES_CONSUMES -- cgit v1.2.3