From efaf8931bbfa33a81b8792fbf9e2ccc239d53204 Mon Sep 17 00:00:00 2001 From: Min M Xu Date: Tue, 6 Aug 2024 02:01:55 -0400 Subject: [PATCH 001/280] OvmfPkg/TdTcg2Dxe: Fix the SeparatorEvent issue in RTMRs According to the TCG EFI platform specification, the firmware must measure the EV_SEPARATOR event into PCRs 0-7. As PCR[1] and PCR[7] map to RTMR[0], and PCRs [2-6] map to RTMR[1], it is necessary to measure one EV_SEPARATOR event into RTMR[0] and another one into RTMR[1]. An issue is found in TdTcg2Dxe that 2 EV_SEPARATOR events are measured to RTMR[0] but no EV_SEPARATOR event is measured to RTMR[1]. This patch fixes the above issue. Cc: Erdem Aktas Cc: Jiewen Yao Cc: Gerd Hoffmann Cc: Qinkun Bao Cc: Tom Lendacky Cc: Michael Roth Signed-off-by: Min Xu --- OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c b/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c index 0a23bff5a1f9..6d2de0e83840 100644 --- a/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c +++ b/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c @@ -2160,11 +2160,17 @@ OnReadyToBoot ( // // 2. Draw a line between pre-boot env and entering post-boot env. - // PCR[7] (is RTMR[0]) is already done. // - Status = MeasureSeparatorEvent (1); + // According to UEFI Spec 2.10 Section 38.4.1 the mapping between MrIndex and Intel + // TDX Measurement Register is: + // MrIndex 0 <--> MRTD + // MrIndex 1-3 <--> RTMR[0-2] + // RTMR[0] (i.e. MrIndex 1) is already done. So SepartorEvent shall be extended to + // RTMR[1] (i.e. MrIndex 2) as well. + // + Status = MeasureSeparatorEvent (CC_MR_INDEX_2_RTMR1); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n")); + DEBUG ((DEBUG_ERROR, "Separator Event not Measured to RTMR[1]. Error!\n")); } // From b2a431868c4ae0ad99def0a504d2fe097e16cd4f Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Fri, 23 Aug 2024 14:47:55 -0700 Subject: [PATCH 002/280] UefiCpuPkg: CpuPageTableLibTestHost: Disable Random Test Suite Commit 2f499c36db51980ad43fc6b578c7678a1720bd9c commented out the RandomTestCase tests in CpuPageTableLibTestHost, but it left the test suite being registered without any tests. This causes a failure for tools that check to ensure tests are being registered with test suites. This patch comments out the test suite in addition to the tests being added to it. Signed-off-by: Oliver Smith-Denny --- .../UnitTest/CpuPageTableLibUnitTestHost.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c b/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c index a61001117938..056aabc238c8 100644 --- a/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c +++ b/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c @@ -838,7 +838,8 @@ UefiTestMain ( EFI_STATUS Status; UNIT_TEST_FRAMEWORK_HANDLE Framework; UNIT_TEST_SUITE_HANDLE ManualTestCase; - UNIT_TEST_SUITE_HANDLE RandomTestCase; + + // UNIT_TEST_SUITE_HANDLE RandomTestCase; Framework = NULL; @@ -874,12 +875,12 @@ UefiTestMain ( // // Populate the Random Test Cases. // - Status = CreateUnitTestSuite (&RandomTestCase, Framework, "Random Test Cases", "CpuPageTableLib.Random", NULL, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for Random Test Cases\n")); - Status = EFI_OUT_OF_RESOURCES; - goto EXIT; - } + // Status = CreateUnitTestSuite (&RandomTestCase, Framework, "Random Test Cases", "CpuPageTableLib.Random", NULL, NULL); + // if (EFI_ERROR (Status)) { + // DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for Random Test Cases\n")); + // Status = EFI_OUT_OF_RESOURCES; + // goto EXIT; + // } // AddTestCase (RandomTestCase, "Random Test for Paging4Level", "Random Test Case1", TestCaseforRandomTest, NULL, NULL, &mTestContextPaging4Level); // AddTestCase (RandomTestCase, "Random Test for Paging4Level1G", "Random Test Case2", TestCaseforRandomTest, NULL, NULL, &mTestContextPaging4Level1GB); From a0594ca403e77f68b317cc15b9b5c6b39e36e0fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 13:36:14 +0000 Subject: [PATCH 003/280] GitHub Action: Bump github/issue-labeler from 3.1 to 3.4 Bumps [github/issue-labeler](https://github.com/github/issue-labeler) from 3.1 to 3.4. - [Release notes](https://github.com/github/issue-labeler/releases) - [Commits](https://github.com/github/issue-labeler/compare/v3.1...v3.4) --- updated-dependencies: - dependency-name: github/issue-labeler dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/pr-labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 1b7daa61fa41..b98489808454 100644 --- a/.github/workflows/pr-labeler.yml +++ b/.github/workflows/pr-labeler.yml @@ -29,7 +29,7 @@ jobs: steps: - name: Apply Labels Based on PR Description - uses: github/issue-labeler@v3.1 + uses: github/issue-labeler@v3.4 with: configuration-path: .github/workflows/pr-labeler/regex.yml enable-versioned-regex: 0 From cc7bb9a86e61ef80c225510f941dfc64dc9b4560 Mon Sep 17 00:00:00 2001 From: Aravind P R Date: Mon, 8 Jul 2024 17:02:24 +0530 Subject: [PATCH 004/280] IntelFsp2Pkg: Correcting Data Region Length of MCUD section REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4793 MCUD Data Region Length(DATA_LEN_OF_MCUD) pushed to stack is incorrect for 64-bit. The Data occupied by MCUD section is 32 bytes in 64-bit instead of 16 bytes in 32-bit. This commit inputs the correct the Data Region Length for the MCUD Section and also corrects the code that retrieves this data. Signed-off-by: Aravind P R --- IntelFsp2Pkg/FspSecCore/SecFsp.c | 19 +++++++++---------- IntelFsp2Pkg/FspSecCore/X64/FspApiEntryT.nasm | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/IntelFsp2Pkg/FspSecCore/SecFsp.c b/IntelFsp2Pkg/FspSecCore/SecFsp.c index 281d39a24b70..c4d4d11687e8 100644 --- a/IntelFsp2Pkg/FspSecCore/SecFsp.c +++ b/IntelFsp2Pkg/FspSecCore/SecFsp.c @@ -53,7 +53,7 @@ SecGetPlatformData ( FSP_PLAT_DATA *FspPlatformData; UINT32 TopOfCar; UINT32 *StackPtr; - UINT32 DwordSize; + UINT32 DataSize; UINT32 TemporaryRamSize; FspPlatformData = &FspData->PlatformData; @@ -89,22 +89,21 @@ SecGetPlatformData ( // // This following data was pushed onto stack after TempRamInit API // - DwordSize = 4; - StackPtr = StackPtr - 1 - DwordSize; - CopyMem (&(FspPlatformData->MicrocodeRegionBase), StackPtr, (DwordSize << 2)); - StackPtr--; + DataSize = *(StackPtr); + DataSize = DataSize / sizeof (DataSize); + StackPtr -= DataSize; + CopyMem (&(FspPlatformData->MicrocodeRegionBase), StackPtr + 1, 4 * sizeof (UINTN)); } else if (*(StackPtr - 1) == FSP_PER0_SIGNATURE) { // // This is the performance data for InitTempMemory API entry/exit // - DwordSize = 4; - StackPtr = StackPtr - 1 - DwordSize; - CopyMem (FspData->PerfData, StackPtr, (DwordSize << 2)); + DataSize = *(StackPtr); + DataSize = DataSize / sizeof (DataSize); + StackPtr -= DataSize; + CopyMem (FspData->PerfData, StackPtr + 1, 2 * sizeof (UINT64)); // Copy from the end of the PER0 data ((UINT8 *)(&FspData->PerfData[0]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_ENTRY; ((UINT8 *)(&FspData->PerfData[1]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_EXIT; - - StackPtr--; } else { StackPtr -= (*StackPtr); } diff --git a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryT.nasm b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryT.nasm index f1c06732092e..3e7a6400a277 100644 --- a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryT.nasm +++ b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryT.nasm @@ -30,7 +30,7 @@ extern ASM_PFX(SecCarInit) ; Define the data length that we saved on the stack top ; DATA_LEN_OF_PER0 EQU 18h -DATA_LEN_OF_MCUD EQU 18h +DATA_LEN_OF_MCUD EQU 28h DATA_LEN_AT_STACK_TOP EQU (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4) ; From ded4191e1087c56e0bdeb118fd519d18cb353ef3 Mon Sep 17 00:00:00 2001 From: Nate DeSimone Date: Tue, 27 Aug 2024 12:10:21 -0700 Subject: [PATCH 005/280] Maintainers.txt: Remove Susovan Mohapatra Susovan is no longer an active contributor. Signed-off-by: Nate DeSimone Cc: Andrew Fish Cc: Leif Lindholm Cc: Michael D Kinney --- Maintainers.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/Maintainers.txt b/Maintainers.txt index d22929b85b97..d2e69a9f33c7 100644 --- a/Maintainers.txt +++ b/Maintainers.txt @@ -225,7 +225,6 @@ M: Duggapu Chinni B [cbduggap] R: Star Zeng [lzeng14] R: Ted Kuo [tedkuo1] R: Ashraf Ali S [AshrafAliS] -R: Susovan Mohapatra [susovanmohapatra] IntelFsp2WrapperPkg F: IntelFsp2WrapperPkg/ @@ -237,7 +236,6 @@ M: Chen Gang C [chengangc] R: Star Zeng [lzeng14] R: Ted Kuo [tedkuo1] R: Ashraf Ali S [AshrafAliS] -R: Susovan Mohapatra [susovanmohapatra] MdeModulePkg F: MdeModulePkg/ From 39a999eb1decf486c615489174912f2d278636d1 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Wed, 21 Aug 2024 13:59:15 -0700 Subject: [PATCH 006/280] ArmPlatformPkg: Initialize Serial Port Before Writing PrePeiCore and Sec directly write the firmware version to the serial port. They relies on another component to initialize the serial port, however in certain configurations (such as release builds that don't use a DebugLib that initializes the serial port), the serial port can be uninitialized at this point, causing a crash when SerialPortWrite is called here. This patch updates PrePeiCore and Sec to call SerialPortInitialize before calling SerialPortWrite directly, which follows the pattern of other serial port writes. It is accepted to call the initialization routine multiple times, it is supposed to dump out if the serial port is already initialized. Signed-off-by: Oliver Smith-Denny --- ArmPlatformPkg/PrePeiCore/PrePeiCore.c | 4 ++++ ArmPlatformPkg/Sec/Sec.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c index cbaccbbad97f..5911c3a08a23 100644 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c +++ b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c @@ -76,6 +76,10 @@ PrintFirmwareVersion ( __TIME__, __DATE__ ); + + // Because we are directly bit banging the serial port instead of going through the DebugLib, we need to make sure + // the serial port is initialized before we write to it + SerialPortInitialize (); SerialPortWrite ((UINT8 *)Buffer, CharCount); } diff --git a/ArmPlatformPkg/Sec/Sec.c b/ArmPlatformPkg/Sec/Sec.c index 482e68ad4237..9a700e5ef25b 100644 --- a/ArmPlatformPkg/Sec/Sec.c +++ b/ArmPlatformPkg/Sec/Sec.c @@ -139,6 +139,10 @@ PrintFirmwareVersion ( __TIME__, __DATE__ ); + + // Because we are directly bit banging the serial port instead of going through the DebugLib, we need to make sure + // the serial port is initialized before we write to it + SerialPortInitialize (); SerialPortWrite ((UINT8 *)Buffer, CharCount); } From 25da777d95c0e76b3e0a15ff617870105c228b7b Mon Sep 17 00:00:00 2001 From: Nate DeSimone Date: Tue, 27 Aug 2024 16:32:24 -0700 Subject: [PATCH 007/280] Maintainers.txt: Cleanup inactive maintainers. The following individuals are no longer active maintainers: - Wenxing Hou - Zhichao Gao - Chan Laura - Catharine West Signed-off-by: Nate DeSimone Cc: Andrew Fish Cc: Leif Lindholm Cc: Michael D Kinney --- Maintainers.txt | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/Maintainers.txt b/Maintainers.txt index d2e69a9f33c7..ff206648d700 100644 --- a/Maintainers.txt +++ b/Maintainers.txt @@ -175,7 +175,6 @@ F: CryptoPkg/ W: https://github.com/tianocore/tianocore.github.io/wiki/CryptoPkg M: Jiewen Yao [jyao1] M: Yi Li [liyi77] -R: Wenxing Hou [Wenxing-hou] DynamicTablesPkg F: DynamicTablesPkg/ @@ -257,23 +256,8 @@ F: MdeModulePkg/Universal/DevicePathDxe/ F: MdeModulePkg/Universal/DriverHealthManagerDxe/ F: MdeModulePkg/Universal/LoadFileOnFv2/ F: MdeModulePkg/Universal/SecurityStubDxe/Defer3rdPartyImageLoad.* -R: Zhichao Gao [ZhichaoGao] R: Ray Ni [niruiyu] -MdeModulePkg: Console and Graphics modules -F: MdeModulePkg/*Logo*/ -F: MdeModulePkg/Include/*Logo*.h -F: MdeModulePkg/Include/Guid/ConnectConInEvent.h -F: MdeModulePkg/Include/Guid/Console*.h -F: MdeModulePkg/Include/Guid/StandardErrorDevice.h -F: MdeModulePkg/Include/Guid/TtyTerm.h -F: MdeModulePkg/Include/Library/BmpSupportLib.h -F: MdeModulePkg/Include/Library/FrameBufferBltLib.h -F: MdeModulePkg/Library/BaseBmpSupportLib/ -F: MdeModulePkg/Library/FrameBufferBltLib/ -F: MdeModulePkg/Universal/Console/ -R: Zhichao Gao [ZhichaoGao] - MdeModulePkg: Core services (PEI, DXE and Runtime) modules F: MdeModulePkg/*Mem*/ F: MdeModulePkg/*SectionExtract*/ @@ -322,7 +306,6 @@ R: Ray Ni [niruiyu] MdeModulePkg: Disk modules F: MdeModulePkg/Universal/Disk/ R: Ray Ni [niruiyu] -R: Zhichao Gao [ZhichaoGao] MdeModulePkg: Firmware Update modules F: MdeModulePkg/*Capsule*/ @@ -364,22 +347,11 @@ MdeModulePkg: Pei Core F: MdeModulePkg/Core/Pei/ R: Liming Gao [lgao4] -MdeModulePkg: Reset modules -F: MdeModulePkg/*Reset*/ -F: MdeModulePkg/Include/*Reset*.h -R: Zhichao Gao [ZhichaoGao] - -MdeModulePkg: Serial modules -F: MdeModulePkg/*Serial*/ -F: MdeModulePkg/Include/*SerialPort*.h -R: Zhichao Gao [ZhichaoGao] - MdeModulePkg: SMBIOS modules F: MdeModulePkg/Universal/Smbios*/ R: Zhiguang Liu [LiuZhiguang001] R: Dandan Bi [dandanbi] R: Star Zeng [lzeng14] -R: Zhichao Gao [ZhichaoGao] MdeModulePkg: UEFI Variable modules F: MdeModulePkg/*Var*/ @@ -434,7 +406,6 @@ F: MdePkg/Include/Library/TraceHubDebugSysTLib.h F: MdePkg/Include/Library/MipiSysTLib.h M: Gua Guo [gguo11837463] M: Prakashan Krishnadas Veliyathuparambil [kprakas2] -R: Chan Laura [lauracha] R: K N Karthik [karthikkabbigere1] MdePkg: FDT related library instance @@ -621,7 +592,6 @@ R: Rahul Kumar [rahul1-kumar] ShellPkg F: ShellPkg/ W: https://github.com/tianocore/tianocore.github.io/wiki/ShellPkg -M: Zhichao Gao [ZhichaoGao] SignedCapsulePkg F: SignedCapsulePkg/ @@ -646,11 +616,6 @@ R: Rahul Kumar [rahul1-kumar] R: Gerd Hoffmann [kraxel] R: Jiaxin Wu [jiaxinwu] -UefiCpuPkg: Sec related modules -F: UefiCpuPkg/SecCore/ -F: UefiCpuPkg/ResetVector/ -R: Catharine West [catharine-intl] - UefiCpuPkg: AMD related files F: UefiCpuPkg/Library/MmSaveStateLib/*Amd*.* F: UefiCpuPkg/Library/SmmCpuFeaturesLib/*Amd*.* From 99e4c8ea93fa0e98bc1bdb968e9d5bb42ff5d39c Mon Sep 17 00:00:00 2001 From: Chao Li Date: Tue, 27 Aug 2024 10:30:36 +0800 Subject: [PATCH 008/280] OvmfPkg/LoongArchVirt: Clear the PGD series registers Since the PGD series registers are in an unknown state when reset, some simulators will hang when restarting if these registers are not cleared, so they are cleared in this patch. Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Cc: Bibo Mao Signed-off-by: Chao Li --- OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c b/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c index be2d98cc9ac6..9091b70c01d0 100644 --- a/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c +++ b/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c @@ -141,6 +141,12 @@ ConfigureMemoryManagementUnit ( return EFI_UNSUPPORTED; } + // + // Clear PGD series registers. + // + CsrWrite (LOONGARCH_CSR_PGDL, 0x0); + CsrWrite (LOONGARCH_CSR_PGDH, 0x0); + PageTable = 0; while (MemoryTable->NumberOfPages != 0) { DEBUG (( From 90d0ec17e7074905de347ccf2accdd6b8e8ee968 Mon Sep 17 00:00:00 2001 From: Nhi Pham Date: Sun, 25 Aug 2024 12:26:28 +0700 Subject: [PATCH 009/280] MdePkg/BaseFdtLib: Add FdtNodeOffsetByCompatible() This adds FdtNodeOffsetByCompatible() to support finding the offset of the first node with a given 'compatible' value after an offset. Signed-off-by: Nhi Pham --- MdePkg/Include/Library/FdtLib.h | 17 +++++++++++++++++ MdePkg/Library/BaseFdtLib/FdtLib.c | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/MdePkg/Include/Library/FdtLib.h b/MdePkg/Include/Library/FdtLib.h index 65d74609cd15..89aa1e00f92d 100644 --- a/MdePkg/Include/Library/FdtLib.h +++ b/MdePkg/Include/Library/FdtLib.h @@ -432,4 +432,21 @@ FdtNodeDepth ( IN INT32 NodeOffset ); +/** + Find nodes with a given 'compatible' value. + + @param[in] Fdt The pointer to FDT blob. + @param[in] StartOffset Only find nodes after this offset. + @param[in] Compatible The string to match against. + + @retval The offset of the first node after StartOffset. +**/ +INT32 +EFIAPI +FdtNodeOffsetByCompatible ( + IN CONST VOID *Fdt, + IN INT32 StartOffset, + IN CONST CHAR8 *Compatible + ); + #endif /* FDT_LIB_H_ */ diff --git a/MdePkg/Library/BaseFdtLib/FdtLib.c b/MdePkg/Library/BaseFdtLib/FdtLib.c index c9514af6739e..9b1ceac551e0 100644 --- a/MdePkg/Library/BaseFdtLib/FdtLib.c +++ b/MdePkg/Library/BaseFdtLib/FdtLib.c @@ -442,3 +442,23 @@ FdtNodeDepth ( { return fdt_node_depth (Fdt, NodeOffset); } + +/** + Find nodes with a given 'compatible' value. + + @param[in] Fdt The pointer to FDT blob. + @param[in] StartOffset Only find nodes after this offset. + @param[in] Compatible The string to match against. + + @retval The offset of the first node after StartOffset. +**/ +INT32 +EFIAPI +FdtNodeOffsetByCompatible ( + IN CONST VOID *Fdt, + IN INT32 StartOffset, + IN CONST CHAR8 *Compatible + ) +{ + return fdt_node_offset_by_compatible (Fdt, StartOffset, Compatible); +} From c3997e329a3ec13c2fed163475eed14ba765b31a Mon Sep 17 00:00:00 2001 From: Linus Liu Date: Wed, 21 Aug 2024 01:03:26 -0700 Subject: [PATCH 010/280] MdePkg: Fix build error after enable FDT support. REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4786 Disable some compiling warnings caused by submodule code. Those can be removed later once issues fixed by submodule owner. Signed-off-by: Linus Liu --- MdePkg/Library/BaseFdtLib/BaseFdtLib.inf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf b/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf index 730e568ff605..b5815380c5ee 100644 --- a/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf +++ b/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf @@ -57,6 +57,9 @@ BaseMemoryLib [BuildOptions] - MSFT:*_*_IA32_CC_FLAGS = /wd4146 /wd4245 - MSFT:*_*_X64_CC_FLAGS = /wd4146 /wd4244 /wd4245 /wd4267 +# warning C4706: assignment within conditional expression +# if ((err = fdt_splice_(fdt, p, oldlen, newlen))) +# in BaseFdtLib\libfdt\libfdt\fdt_rw.c (wait for sub module update to remove this) + MSFT:*_*_IA32_CC_FLAGS = /wd4146 /wd4245 /wd4706 + MSFT:*_*_X64_CC_FLAGS = /wd4146 /wd4244 /wd4245 /wd4267 /wd4706 From 04d8d94a42e2b5d193bd2a8476dac117c01fe284 Mon Sep 17 00:00:00 2001 From: Linus Liu Date: Wed, 21 Aug 2024 01:06:56 -0700 Subject: [PATCH 011/280] UefiPayloadPkg: Addd header files for FDT structure and function. REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4786 Add Library header, DeviceTree hob header and PCD definitions. Signed-off-by: Linus Liu --- .../Include/Guid/UniversalPayloadBase.h | 10 +++ ...iversalPayloadSerialPortDeviceParentInfo.h | 28 ++++++++ UefiPayloadPkg/Include/Library/BuildFdtLib.h | 22 ++++++ UefiPayloadPkg/Include/Library/FdtParserLib.h | 64 +++++++++++++++++ UefiPayloadPkg/Include/Library/HobParserLib.h | 70 +++++++++++++++++++ .../Include/UniversalPayload/DeviceTree.h | 30 ++++++++ UefiPayloadPkg/UefiPayloadPkg.dec | 27 +++++++ 7 files changed, 251 insertions(+) create mode 100644 UefiPayloadPkg/Include/Guid/UniversalPayloadSerialPortDeviceParentInfo.h create mode 100644 UefiPayloadPkg/Include/Library/BuildFdtLib.h create mode 100644 UefiPayloadPkg/Include/Library/FdtParserLib.h create mode 100644 UefiPayloadPkg/Include/Library/HobParserLib.h create mode 100644 UefiPayloadPkg/Include/UniversalPayload/DeviceTree.h diff --git a/UefiPayloadPkg/Include/Guid/UniversalPayloadBase.h b/UefiPayloadPkg/Include/Guid/UniversalPayloadBase.h index 60f2aa37dd3e..26a999df8d4d 100644 --- a/UefiPayloadPkg/Include/Guid/UniversalPayloadBase.h +++ b/UefiPayloadPkg/Include/Guid/UniversalPayloadBase.h @@ -16,4 +16,14 @@ typedef struct { EFI_PHYSICAL_ADDRESS Entry; } UNIVERSAL_PAYLOAD_BASE; +#define UNIVERSAL_PAYLOAD_BASE_REVISION 1 + +#define N_NON_RELOCATABLE BIT31 +#define P_PREFETCHABLE BIT30 +#define SS_CONFIGURATION_SPACE 0 +#define SS_IO_SPACE BIT24 +#define SS_32BIT_MEMORY_SPACE BIT25 +#define SS_64BIT_MEMORY_SPACE BIT24+BIT25 +#define DWORDS_TO_NEXT_ADDR_TYPE 7 + #endif // UNIVERSAL_PAYLOAD_BASE_H_ diff --git a/UefiPayloadPkg/Include/Guid/UniversalPayloadSerialPortDeviceParentInfo.h b/UefiPayloadPkg/Include/Guid/UniversalPayloadSerialPortDeviceParentInfo.h new file mode 100644 index 000000000000..969befe2cb77 --- /dev/null +++ b/UefiPayloadPkg/Include/Guid/UniversalPayloadSerialPortDeviceParentInfo.h @@ -0,0 +1,28 @@ +/** @file + Universal Payload serial port parent device information definitions. + +Copyright (c) 2024, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO_ +#define UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO_ + +extern GUID gUniversalPayloadSerialPortParentDeviceInfoGuid; + +// IsIsaCompatible +// TRUE: the serial port device is under an ISA compatible bus, which means the parent device is ISA/LPC/eSPI bus controller. +// FALSE: the serial port device is native PCI device under PCI bridge. +#pragma pack(1) +typedef struct { + UINT32 Revision; + BOOLEAN IsIsaCompatible; + UINT8 Reserved[3]; + UINT64 ParentDevicePcieBaseAddress; +} UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO; +#pragma pack() + +#define UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO_REVISION 1 + +#endif // UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO_ diff --git a/UefiPayloadPkg/Include/Library/BuildFdtLib.h b/UefiPayloadPkg/Include/Library/BuildFdtLib.h new file mode 100644 index 000000000000..2bde7ab66a9d --- /dev/null +++ b/UefiPayloadPkg/Include/Library/BuildFdtLib.h @@ -0,0 +1,22 @@ +/** @file + This library will Build the FDT (flat device tree) table information. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef BUILD_FDT_LIB_H_ +#define BUILD_FDT__LIB_H_ + +/** + It will build FDT for UPL consumed. + @param[in] FdtBase Address of the Fdt data. + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to build required FDT. +**/ + +BuildFdtForUPL ( + IN VOID *FdtBase + ); + +#endif diff --git a/UefiPayloadPkg/Include/Library/FdtParserLib.h b/UefiPayloadPkg/Include/Library/FdtParserLib.h new file mode 100644 index 000000000000..87109f1190bd --- /dev/null +++ b/UefiPayloadPkg/Include/Library/FdtParserLib.h @@ -0,0 +1,64 @@ +/** @file + This library will parse the FDT (flat device tree) table information. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef FDT_PARSER_LIB_H_ +#define FDT_PARSER_LIB_H_ + +/** + It will parse FDT based on DTB. + + @param[in] FdtBase Address of the Fdt data. + + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to parse DTB. +**/ +UINTN +EFIAPI +ParseDtb ( + IN VOID *FdtBase + ); + +/** + It will Parse FDT -node based on information. + @param[in] FdtBase The starting memory address of FdtBase + @retval HobList The base address of Hoblist. + +**/ +UINT64 +EFIAPI +FdtNodeParser ( + IN VOID *FdtBase + ); + +/** + It will Parse FDT -custom node based on information. + @param[in] FdtBase The starting memory address of FdtBase + @param[in] HostList The starting memory address of New Hob list. + +**/ +UINTN +EFIAPI +CustomFdtNodeParser ( + IN VOID *FdtBase, + IN VOID *HostList + ); + +/** + It will initialize HOBs for UPL. + + @param[in] FdtBase Address of the Fdt data. + + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to initialize HOBs. +**/ +UINTN +EFIAPI +UplInitHob ( + IN VOID *FdtBase + ); + +#endif diff --git a/UefiPayloadPkg/Include/Library/HobParserLib.h b/UefiPayloadPkg/Include/Library/HobParserLib.h new file mode 100644 index 000000000000..98a64b809709 --- /dev/null +++ b/UefiPayloadPkg/Include/Library/HobParserLib.h @@ -0,0 +1,70 @@ +/** @file + This library will provide services for handling HOB data. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef HOB_PARSER_LIB_H_ +#define HOB_PARSER_LIB_H_ + +/** + * + Add HOB into HOB list + + @param[in] Hob The HOB to be added into the HOB list. +**/ +VOID +AddNewHob ( + IN EFI_PEI_HOB_POINTERS *Hob + ); + +/** + Found the Resource Descriptor HOB that contains a range (Base, Top) + + @param[in] HobList Hob start address + @param[in] Base Memory start address + @param[in] Top Memory end address. + + @retval The pointer to the Resource Descriptor HOB. +**/ +EFI_HOB_RESOURCE_DESCRIPTOR * +FindResourceDescriptorByRange ( + IN VOID *HobList, + IN EFI_PHYSICAL_ADDRESS Base, + IN EFI_PHYSICAL_ADDRESS Top + ); + +/** + Find the highest below 4G memory resource descriptor, except the input Resource Descriptor. + + @param[in] HobList Hob start address + @param[in] MinimalNeededSize Minimal needed size. + @param[in] ExceptResourceHob Ignore this Resource Descriptor. + + @retval The pointer to the Resource Descriptor HOB. +**/ +EFI_HOB_RESOURCE_DESCRIPTOR * +FindAnotherHighestBelow4GResourceDescriptor ( + IN VOID *HobList, + IN UINTN MinimalNeededSize, + IN EFI_HOB_RESOURCE_DESCRIPTOR *ExceptResourceHob + ); + +/** + Check the HOB and decide if it is need inside Payload + + Payload maintainer may make decision which HOB is need or needn't + Then add the check logic in the function. + + @param[in] Hob The HOB to check + + @retval TRUE If HOB is need inside Payload + @retval FALSE If HOB is needn't inside Payload +**/ +BOOLEAN +IsHobNeed ( + EFI_PEI_HOB_POINTERS Hob + ); + +#endif diff --git a/UefiPayloadPkg/Include/UniversalPayload/DeviceTree.h b/UefiPayloadPkg/Include/UniversalPayload/DeviceTree.h new file mode 100644 index 000000000000..b7c2163e1e0d --- /dev/null +++ b/UefiPayloadPkg/Include/UniversalPayload/DeviceTree.h @@ -0,0 +1,30 @@ +/** @file + This file defines the structure for the PCI Root Bridges. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + - Universal Payload Specification 0.8 (https://universalpayload.github.io/spec/) +**/ + +#ifndef UNIVERSAL_PAYLOAD_DEVICE_TREE_H_ +#define UNIVERSAL_PAYLOAD_DEVICE_TREE_H_ + +#include +#include + +#pragma pack (1) + +typedef struct { + UNIVERSAL_PAYLOAD_GENERIC_HEADER Header; + EFI_PHYSICAL_ADDRESS DeviceTreeAddress; +} UNIVERSAL_PAYLOAD_DEVICE_TREE; + +#pragma pack() + +#define UNIVERSAL_PAYLOAD_DEVICE_TREE_REVISION 1 + +extern GUID gUniversalPayloadDeviceTreeGuid; + +#endif // UNIVERSAL_PAYLOAD_SMBIOS_TABLE_H_ diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayloadPkg.dec index 23dcdf9a0c9c..4df8c211dc84 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dec +++ b/UefiPayloadPkg/UefiPayloadPkg.dec @@ -27,6 +27,11 @@ ## Include/Guid/UniversalPayloadBase.h gUniversalPayloadBaseGuid = { 0x03d4c61d, 0x2713, 0x4ec5, {0xa1, 0xcc, 0x88, 0x3b, 0xe9, 0xdc, 0x18, 0xe5 } } + ## Include/Guid/UniversalPayloadSerialPortDeviceParentInfo.h + gUniversalPayloadSerialPortParentDeviceInfoGuid = { 0xc89c359c, 0xd316, 0x4ff8, {0xa9, 0x8f, 0x60, 0x7d, 0x2c, 0xed, 0x1f, 0xed } } + + ## Include/UniversalPayload/DeviceTree.h + gUniversalPayloadDeviceTreeGuid = { 0x6784b889, 0xb13c, 0x4c3b, {0xae, 0x4b, 0xf, 0xa, 0x2e, 0x32, 0xe, 0xa3 } } gEdkiiDebugPrintErrorLevelGuid = { 0xad82f436, 0x75c5, 0x4aa9, { 0x92, 0x93, 0xc5, 0x55, 0x0a, 0x7f, 0xf9, 0x71 }} gUefiAcpiBoardInfoGuid = {0xad3d31b, 0xb3d8, 0x4506, {0xae, 0x71, 0x2e, 0xf1, 0x10, 0x6, 0xd9, 0xf}} gUefiSerialPortInfoGuid = { 0x6c6872fe, 0x56a9, 0x4403, { 0xbb, 0x98, 0x95, 0x8d, 0x62, 0xde, 0x87, 0xf1 } } @@ -42,6 +47,13 @@ [Ppis] gEfiPayLoadHobBasePpiGuid = { 0xdbe23aa1, 0xa342, 0x4b97, {0x85, 0xb6, 0xb2, 0x26, 0xf1, 0x61, 0x73, 0x89} } + # + # This PPI is used to trigger Payload callback event in end of PEI. + # + gUplReadyToPayloadPpiGuid = { 0x67c8dfb1, 0x61f4, 0x439c, { 0x84, 0x4e, 0x2b, 0xdf, 0xf1, 0x07, 0xad, 0x51 }} + +[Protocols] + ################################################################################ # # PCD Declarations section - list of all PCDs Declared by this Package @@ -75,3 +87,18 @@ gUefiPayloadPkgTokenSpaceGuid.PcdBootManagerEscape|FALSE|BOOLEAN|0x00000020 ## FFS filename to find the default variable initial data file. # @Prompt FFS Name of variable initial data file gUefiPayloadPkgTokenSpaceGuid.PcdNvsDataFile |{ 0x1a, 0xf1, 0xb1, 0xae, 0x42, 0xcc, 0xcf, 0x4e, 0xac, 0x60, 0xdb, 0xab, 0xf6, 0xca, 0x69, 0xe6 }|VOID*|0x00000025 + + +## Indicates if Universal payload support FDT +#- PcdHandOffFdtEnable is TRUE, HandOffData is FDT +#- PcdHandOffFdtEnable is FALSE, HandOffData is HOB +gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable|FALSE|BOOLEAN|0x00000026 + + +gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemBase |0xFFFFFFFF |UINT32|0x00000027 +gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemLimit |0x00000000 |UINT32|0x00000028 +gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemAbove4GBBase |0xFFFFFFFFFFFFFFFF |UINT64|0x00000029 +gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemAbove4GBLimit|0x0000000000000000 |UINT64|0x0000002A + +gUefiPayloadPkgTokenSpaceGuid.SizeOfIoSpace|0|UINT8|0x0000002B +gUefiPayloadPkgTokenSpaceGuid.PcdFDTPageSize|8|UINT8|0x0000002C From a297b81b623cc2c9a817a0a0c5b798353ea87064 Mon Sep 17 00:00:00 2001 From: Linus Liu Date: Wed, 21 Aug 2024 01:10:28 -0700 Subject: [PATCH 012/280] UefiPayloadPkg: Support Debug function when Hob was not available. REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4786 Initialize mUartInfo with PCD for debug message when Hob was not available. Signed-off-by: Linus Liu --- UefiPayloadPkg/Include/Library/BuildFdtLib.h | 4 +- .../BaseSerialPortLibHob.c | 69 +++++++++++++++++++ .../BaseSerialPortLibHob.inf | 6 ++ .../DxeBaseSerialPortLibHob.inf | 10 ++- .../DebugPrintErrorLevelLibHob.c | 4 ++ .../Library/PayloadEntryHobLib/Hob.c | 6 +- .../Library/PayloadEntryHobLib/HobLib.inf | 2 - .../Library/PlatformHookLib/PlatformHookLib.c | 4 ++ 8 files changed, 97 insertions(+), 8 deletions(-) diff --git a/UefiPayloadPkg/Include/Library/BuildFdtLib.h b/UefiPayloadPkg/Include/Library/BuildFdtLib.h index 2bde7ab66a9d..b674a6cab283 100644 --- a/UefiPayloadPkg/Include/Library/BuildFdtLib.h +++ b/UefiPayloadPkg/Include/Library/BuildFdtLib.h @@ -6,7 +6,7 @@ **/ #ifndef BUILD_FDT_LIB_H_ -#define BUILD_FDT__LIB_H_ +#define BUILD_FDT_LIB_H_ /** It will build FDT for UPL consumed. @@ -14,7 +14,7 @@ @retval EFI_SUCCESS If it completed successfully. @retval Others If it failed to build required FDT. **/ - +EFI_STATUS BuildFdtForUPL ( IN VOID *FdtBase ); diff --git a/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.c b/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.c index 82d0dd585508..55e85dce8598 100644 --- a/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.c +++ b/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.c @@ -143,6 +143,75 @@ SerialPortInitialize ( return RETURN_SUCCESS; } + if (GetHobList () == NULL) { + mUartCount = 0; + SerialRegisterBase = PcdGet64 (PcdSerialRegisterBase); + MmioEnable = PcdGetBool (PcdSerialUseMmio); + BaudRate = PcdGet32 (PcdSerialBaudRate); + RegisterStride = (UINT8)PcdGet32 (PcdSerialRegisterStride); + + mUartInfo[mUartCount].BaseAddress = SerialRegisterBase; + mUartInfo[mUartCount].UseMmio = MmioEnable; + mUartInfo[mUartCount].BaudRate = BaudRate; + mUartInfo[mUartCount].RegisterStride = RegisterStride; + mUartCount++; + + Divisor = PcdGet32 (PcdSerialClockRate) / (BaudRate * 16); + if ((PcdGet32 (PcdSerialClockRate) % (BaudRate * 16)) >= BaudRate * 8) { + Divisor++; + } + + // + // See if the serial port is already initialized + // + Initialized = TRUE; + if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnable, RegisterStride) & 0x3F) != (PcdGet8 (PcdSerialLineControl) & 0x3F)) { + Initialized = FALSE; + } + + Value = (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnable, RegisterStride) | B_UART_LCR_DLAB); + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, Value, MmioEnable, RegisterStride); + CurrentDivisor = SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_HIGH, MmioEnable, RegisterStride) << 8; + CurrentDivisor |= (UINT32)SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_LOW, MmioEnable, RegisterStride); + Value = (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnable, RegisterStride) & ~B_UART_LCR_DLAB); + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, Value, MmioEnable, RegisterStride); + if (CurrentDivisor != Divisor) { + Initialized = FALSE; + } + + // + // Configure baud rate + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB, MmioEnable, RegisterStride); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)(Divisor >> 8), MmioEnable, RegisterStride); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8)(Divisor & 0xff), MmioEnable, RegisterStride); + + // + // Clear DLAB and configure Data Bits, Parity, and Stop Bits. + // Strip reserved bits from PcdSerialLineControl + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(PcdGet8 (PcdSerialLineControl) & 0x3F), MmioEnable, RegisterStride); + + // + // Enable and reset FIFOs + // Strip reserved bits from PcdSerialFifoControl + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, 0x00, MmioEnable, RegisterStride); + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64)), MmioEnable, RegisterStride); + + // + // Set FIFO Polled Mode by clearing IER after setting FCR + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_IER, 0x00, MmioEnable, RegisterStride); + + // + // Put Modem Control Register(MCR) into its reset state of 0x00. + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, 0x00, MmioEnable, RegisterStride); + + return RETURN_SUCCESS; + } + GuidHob = GetFirstGuidHob (&gUniversalPayloadSerialPortInfoGuid); while (GuidHob != NULL) { SerialPortInfo = (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *)GET_GUID_HOB_DATA (GuidHob); diff --git a/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf b/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf index ac857d3eea7c..5ebfe99f651e 100644 --- a/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf +++ b/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf @@ -34,6 +34,12 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride ## CONSUMES + + [Guids] gUniversalPayloadSerialPortInfoGuid diff --git a/UefiPayloadPkg/Library/BaseSerialPortLibHob/DxeBaseSerialPortLibHob.inf b/UefiPayloadPkg/Library/BaseSerialPortLibHob/DxeBaseSerialPortLibHob.inf index 7bb3a6ae96dd..d79fc5aa70cc 100644 --- a/UefiPayloadPkg/Library/BaseSerialPortLibHob/DxeBaseSerialPortLibHob.inf +++ b/UefiPayloadPkg/Library/BaseSerialPortLibHob/DxeBaseSerialPortLibHob.inf @@ -6,7 +6,6 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent # ## - [Defines] INF_VERSION = 0x00010005 BASE_NAME = DxeBaseSerialPortLibHob @@ -15,7 +14,6 @@ VERSION_STRING = 1.0 LIBRARY_CLASS = SerialPortLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER CONSTRUCTOR = DxeBaseSerialPortLibHobConstructor - [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec @@ -25,7 +23,7 @@ IoLib HobLib TimerLib - + PlatformHookLib [Sources] DxeBaseSerialPortLibHob.c BaseSerialPortLibHob.c @@ -36,6 +34,12 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride ## CONSUMES + + [Guids] gUniversalPayloadSerialPortInfoGuid diff --git a/UefiPayloadPkg/Library/DebugPrintErrorLevelLibHob/DebugPrintErrorLevelLibHob.c b/UefiPayloadPkg/Library/DebugPrintErrorLevelLibHob/DebugPrintErrorLevelLibHob.c index 10bdbe2bbc1f..ecffc5c3a989 100644 --- a/UefiPayloadPkg/Library/DebugPrintErrorLevelLibHob/DebugPrintErrorLevelLibHob.c +++ b/UefiPayloadPkg/Library/DebugPrintErrorLevelLibHob/DebugPrintErrorLevelLibHob.c @@ -35,6 +35,10 @@ GetDebugPrintErrorLevel ( UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader; UEFI_PAYLOAD_DEBUG_PRINT_ERROR_LEVEL *DebugPrintErrorLevel; + if (GetHobList () == NULL) { + return PcdGet32 (PcdDebugPrintErrorLevel); + } + if (!gDebugPrintErrorLevelInitialized) { gDebugPrintErrorLevelInitialized = TRUE; gDebugPrintErrorLevel = PcdGet32 (PcdDebugPrintErrorLevel); diff --git a/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c b/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c index 51c2e28d7ddd..dea64767110c 100644 --- a/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c +++ b/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c @@ -31,7 +31,6 @@ GetHobList ( VOID ) { - ASSERT (mHobList != NULL); return mHobList; } @@ -109,6 +108,7 @@ CreateHob ( VOID *Hob; HandOffHob = GetHobList (); + ASSERT (HandOffHob != NULL); // // Check Length to avoid data overflow. @@ -175,6 +175,7 @@ BuildResourceDescriptorHob ( Hob->ResourceAttribute = ResourceAttribute; Hob->PhysicalStart = PhysicalStart; Hob->ResourceLength = NumberOfBytes; + ZeroMem (&(Hob->Owner), sizeof (EFI_GUID)); } /** @@ -305,6 +306,7 @@ GetFirstGuidHob ( VOID *HobList; HobList = GetHobList (); + ASSERT (HobList != NULL); return GetNextGuidHob (Guid, HobList); } @@ -651,6 +653,7 @@ UpdateStackHob ( EFI_PEI_HOB_POINTERS Hob; Hob.Raw = GetHobList (); + ASSERT (Hob.Raw != NULL); while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) { if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) { // @@ -709,6 +712,7 @@ BuildMemoryAllocationHob ( } ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID)); + Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress; Hob->AllocDescriptor.MemoryLength = Length; Hob->AllocDescriptor.MemoryType = MemoryType; diff --git a/UefiPayloadPkg/Library/PayloadEntryHobLib/HobLib.inf b/UefiPayloadPkg/Library/PayloadEntryHobLib/HobLib.inf index cbb4f02efc15..496a5c8319da 100644 --- a/UefiPayloadPkg/Library/PayloadEntryHobLib/HobLib.inf +++ b/UefiPayloadPkg/Library/PayloadEntryHobLib/HobLib.inf @@ -26,7 +26,6 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec - UefiPayloadPkg/UefiPayloadPkg.dec [LibraryClasses] BaseLib @@ -36,4 +35,3 @@ [Guids] gEfiHobMemoryAllocModuleGuid gEfiHobMemoryAllocStackGuid - diff --git a/UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c b/UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c index 60a17b8fc256..efaab326bb68 100644 --- a/UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c +++ b/UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c @@ -51,6 +51,10 @@ PlatformHookSerialPortInitialize ( UINT8 *GuidHob; UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader; + if (GetHobList () == NULL) { + return RETURN_SUCCESS; + } + GuidHob = GetFirstGuidHob (&gUniversalPayloadSerialPortInfoGuid); if (GuidHob == NULL) { return EFI_NOT_FOUND; From b0c6b049c4b2ba5a63615b490e974771cd0a40a4 Mon Sep 17 00:00:00 2001 From: Linus Liu Date: Wed, 21 Aug 2024 02:04:12 -0700 Subject: [PATCH 013/280] UefiPayloadPkg: Add FDT Paser relative LIBs. REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4786 Add FDTParser and CustomFdtNodePaser to retrive all FDT node and create the relate hobs. Signed-off-by: Linus Liu --- .../Library/BuildFdtLib/BuildFdtLib.inf | 65 ++ .../Library/BuildFdtLib/X86_BuildFdtLib.c | 945 ++++++++++++++++++ .../CustomFdtNodeParserLib.c | 164 +++ .../CustomFdtNodeParserLib.inf | 46 + .../CustomFdtNodeParserNullLib.c | 46 + .../CustomFdtNodeParserNullLib.inf | 27 + .../Library/FdtParserLib/FdtParseLib.inf | 64 ++ .../Library/FdtParserLib/FdtParserLib.c | 944 +++++++++++++++++ .../Library/HobParseLib/HobParseLib.c | 280 ++++++ .../Library/HobParseLib/HobParseLib.inf | 40 + UefiPayloadPkg/UefiPayloadPkg.dsc | 1 + 11 files changed, 2622 insertions(+) create mode 100644 UefiPayloadPkg/Library/BuildFdtLib/BuildFdtLib.inf create mode 100644 UefiPayloadPkg/Library/BuildFdtLib/X86_BuildFdtLib.c create mode 100644 UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.c create mode 100644 UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf create mode 100644 UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.c create mode 100644 UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.inf create mode 100644 UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf create mode 100644 UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c create mode 100644 UefiPayloadPkg/Library/HobParseLib/HobParseLib.c create mode 100644 UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf diff --git a/UefiPayloadPkg/Library/BuildFdtLib/BuildFdtLib.inf b/UefiPayloadPkg/Library/BuildFdtLib/BuildFdtLib.inf new file mode 100644 index 000000000000..12461a96067f --- /dev/null +++ b/UefiPayloadPkg/Library/BuildFdtLib/BuildFdtLib.inf @@ -0,0 +1,65 @@ +## @file +# Flat Device Tree Table Build Library. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BuildFdtLib + FILE_GUID = 5DA69A29-C990-49EE-A4E6-BA5311A1ADAF + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = BuildFdtLib + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + X86_BuildFdtLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec + +[LibraryClasses] + DebugLib + PcdLib + HobLib + FdtLib + +[Guids] + gUniversalPayloadDeviceTreeGuid + gEfiGraphicsInfoHobGuid + gEfiGraphicsDeviceInfoHobGuid + gUniversalPayloadAcpiTableGuid + gUniversalPayloadSerialPortInfoGuid + gEfiHobMemoryAllocModuleGuid + gEfiHobMemoryAllocStackGuid + gEfiHobMemoryAllocBspStoreGuid + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + +[Ppis] + gEdkiiPeiPciDevicePpiGuid ## CONSUMES + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = /wd4305 + GCC:*_*_IA32_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_X64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_ARM_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_AARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_RISCV64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_LOONGARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast diff --git a/UefiPayloadPkg/Library/BuildFdtLib/X86_BuildFdtLib.c b/UefiPayloadPkg/Library/BuildFdtLib/X86_BuildFdtLib.c new file mode 100644 index 000000000000..8df78a0afc0e --- /dev/null +++ b/UefiPayloadPkg/Library/BuildFdtLib/X86_BuildFdtLib.c @@ -0,0 +1,945 @@ +/** @file + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IGD_BUS_NUM 0x00 +#define IGD_DEV_NUM 0x02 +#define IGD_FUN_NUM 0x00 + +EDKII_PCI_DEVICE_PPI *mPciDevicePpi; +BOOLEAN mResourceAssigned; + +CHAR8 *mMemoryAllocType[] = { + "Reserved", + "LoaderCode", + "LoaderData", + "boot-code", + "boot-data", + "runtime-code", + "runtime-data", + "ConventionalMemory", + "UnusableMemory", + "acpi", + "acpi-nvs", + "mmio", + "MemoryMappedIOPortSpace", + "PalCode", + "PersistentMemory", +}; + +/** + The wrapper function of PeiServicesLocatePpi() for gEdkiiPeiPciDevicePpiGuid + and Save the PPI to mPciDevicePpi. + @retval EFI_SUCCESS If it locate gEdkiiPeiPciDevicePpiGuid successfully. + @retval EFI_NOT_FOUND If it can't find gEdkiiPeiPciDevicePpiGuid. +**/ +EFI_STATUS +EFIAPI +LocatePciDevicePpi ( + VOID + ) +{ + EFI_STATUS Status; + EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; + + mPciDevicePpi = NULL; + Status = PeiServicesLocatePpi ( + &gEdkiiPeiPciDevicePpiGuid, + 0, + &PpiDescriptor, + (void **)&mPciDevicePpi + ); + if (EFI_ERROR (Status) || (mPciDevicePpi == NULL)) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +/** + It will build FDT based on memory information from Hobs. + @param[in] FdtBase Address of the Fdt data. + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to build required FDT. +**/ +EFI_STATUS +BuildFdtForMemory ( + IN VOID *FdtBase + ) +{ + EFI_STATUS Status; + EFI_PEI_HOB_POINTERS Hob; + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; + VOID *HobStart; + VOID *Fdt; + INT32 TempNode; + CHAR8 TempStr[32]; + UINT64 RegTmp[2]; + + Fdt = FdtBase; + + HobStart = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR); + // + // Scan resource descriptor hobs to set memory nodes + // + for (Hob.Raw = HobStart; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { + if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + ResourceHob = Hob.ResourceDescriptor; + // Memory + if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) { + // DEBUG ((DEBUG_ERROR, "Found hob for memory: base %016lX length %016lX\n", ResourceHob->PhysicalStart, ResourceHob->ResourceLength)); + + Status = AsciiSPrint (TempStr, sizeof (TempStr), "memory@%lX", ResourceHob->PhysicalStart); + TempNode = FdtAddSubnode (Fdt, 0, TempStr); + ASSERT (TempNode > 0); + + RegTmp[0] = CpuToFdt64 (ResourceHob->PhysicalStart); + RegTmp[1] = CpuToFdt64 (ResourceHob->ResourceLength); + Status = FdtSetProp (Fdt, TempNode, "reg", &RegTmp, sizeof (RegTmp)); + ASSERT_EFI_ERROR (Status); + + Status = FdtSetProp (Fdt, TempNode, "device_type", "memory", (UINT32)(AsciiStrLen ("memory")+1)); + ASSERT_EFI_ERROR (Status); + } + } + } + + return Status; +} + +/** + It will build FDT based on memory allocation information from Hobs. + @param[in] FdtBase Address of the Fdt data. + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to build required FDT. +**/ +EFI_STATUS +BuildFdtForMemAlloc ( + IN VOID *FdtBase + ) +{ + EFI_STATUS Status; + EFI_PEI_HOB_POINTERS Hob; + VOID *HobStart; + VOID *Fdt; + INT32 ParentNode; + INT32 TempNode; + CHAR8 TempStr[32]; + UINT64 RegTmp[2]; + UINT32 AllocMemType; + EFI_GUID *AllocMemName; + UINT8 IsStackHob; + UINT8 IsBspStore; + UINT32 Data32; + + Fdt = FdtBase; + + ParentNode = FdtAddSubnode (Fdt, 0, "reserved-memory"); + ASSERT (ParentNode > 0); + + Data32 = CpuToFdt32 (2); + Status = FdtSetProp (Fdt, ParentNode, "#address-cells", &Data32, sizeof (UINT32)); + Status = FdtSetProp (Fdt, ParentNode, "#size-cells", &Data32, sizeof (UINT32)); + + HobStart = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION); + // + // Scan memory allocation hobs to set memory type + // + for (Hob.Raw = HobStart; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { + if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) { + AllocMemName = NULL; + IsStackHob = 0; + IsBspStore = 0; + if (CompareGuid (&(Hob.MemoryAllocationModule->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid)) { + continue; + } else if (IsZeroGuid (&(Hob.MemoryAllocationModule->MemoryAllocationHeader.Name)) == FALSE) { + AllocMemName = &(Hob.MemoryAllocationModule->MemoryAllocationHeader.Name); + + if (CompareGuid (AllocMemName, &gEfiHobMemoryAllocStackGuid)) { + IsStackHob = 1; + } else if (CompareGuid (AllocMemName, &gEfiHobMemoryAllocBspStoreGuid)) { + IsBspStore = 1; + } + } + + DEBUG (( + DEBUG_ERROR, + "Found hob for rsvd memory alloc: base %016lX length %016lX type %x\n", + Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress, + Hob.MemoryAllocation->AllocDescriptor.MemoryLength, + Hob.MemoryAllocation->AllocDescriptor.MemoryType + )); + + AllocMemType = Hob.MemoryAllocation->AllocDescriptor.MemoryType; + if (IsStackHob == 1) { + Status = AsciiSPrint ( + TempStr, + sizeof (TempStr), + "%a@%lX", + "stackhob", + Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress + ); + } else if (IsBspStore == 1) { + Status = AsciiSPrint ( + TempStr, + sizeof (TempStr), + "%a@%lX", + "bspstore", + Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress + ); + } else { + Status = AsciiSPrint ( + TempStr, + sizeof (TempStr), + "%a@%lX", + mMemoryAllocType[AllocMemType], + Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress + ); + } + + if (AsciiStrCmp (mMemoryAllocType[AllocMemType], "ConventionalMemory") == 0) { + continue; + } + + if (AsciiStrCmp (mMemoryAllocType[AllocMemType], "mmio") == 0) { + Status = AsciiSPrint (TempStr, sizeof (TempStr), "mmio@%lX", Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress); + } else { + Status = AsciiSPrint (TempStr, sizeof (TempStr), "memory@%lX", Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress); + } + + TempNode = FdtAddSubnode (Fdt, ParentNode, TempStr); + DEBUG ((DEBUG_INFO, "FdtAddSubnode %x", TempNode)); + if (TempNode < 0) { + continue; + } + + RegTmp[0] = CpuToFdt64 (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress); + RegTmp[1] = CpuToFdt64 (Hob.MemoryAllocation->AllocDescriptor.MemoryLength); + Status = FdtSetProp (Fdt, TempNode, "reg", &RegTmp, sizeof (RegTmp)); + ASSERT_EFI_ERROR (Status); + + if (!(AsciiStrCmp (mMemoryAllocType[AllocMemType], "mmio") == 0)) { + Status = FdtSetProp (Fdt, TempNode, "compatible", mMemoryAllocType[AllocMemType], (UINT32)(AsciiStrLen (mMemoryAllocType[AllocMemType])+1)); + ASSERT_EFI_ERROR (Status); + } + } + } + + return Status; +} + +/** + It will build FDT based on serial information. + @param[in] ISANode ISANode. + @param[in] FdtBase Address of the Fdt data. + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to build required FDT. +**/ +EFI_STATUS +BuildFdtForSerial ( + IN INT32 ISANode, + IN VOID *FdtBase + ) +{ + EFI_STATUS Status; + VOID *Fdt; + INT32 TempNode; + UINT64 RegisterBase; + CHAR8 TempStr[32]; + UINT32 RegData[3]; + UINT32 Data32; + UINT64 Data64; + + Fdt = FdtBase; + RegisterBase = 0; + + // + // Create SerialPortInfo FDT node. + // + Status = AsciiSPrint (TempStr, sizeof (TempStr), "serial@%lX", (RegisterBase == 0) ? PcdGet64 (PcdSerialRegisterBase) : RegisterBase); + TempNode = FdtAddSubnode (Fdt, ISANode, TempStr); + ASSERT (TempNode > 0); + + Data32 = CpuToFdt32 (PcdGet32 (PcdSerialBaudRate)); + Status = FdtSetProp (Fdt, TempNode, "current-speed", &Data32, sizeof (Data32)); + ASSERT_EFI_ERROR (Status); + + if (PcdGetBool (PcdSerialUseMmio)) { + Data32 = 0; + RegData[0] = CpuToFdt32 (Data32); + } else { + Data32 = 1; + RegData[0] = CpuToFdt32 (Data32); + } + + Data64 = (RegisterBase == 0) ? PcdGet64 (PcdSerialRegisterBase) : RegisterBase; + Data32 = (UINT32)((Data64 & 0x0FFFFFFFF)); + RegData[1] = CpuToFdt32 (Data32); + RegData[2] = CpuToFdt32 (8); + Status = FdtSetProp (Fdt, TempNode, "reg", &RegData, sizeof (RegData)); + ASSERT_EFI_ERROR (Status); + + Data32 = CpuToFdt32 (1); + Status = FdtSetProp (Fdt, TempNode, "reg-io-width", &Data32, sizeof (Data32)); + ASSERT_EFI_ERROR (Status); + + Status = FdtSetProp (Fdt, TempNode, "compatible", "isa", (UINT32)(AsciiStrLen ("isa")+1)); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + It will build FDT based on serial information. + + @param[in] ISANode ISANode. + @param[in] FdtBase Address of the Fdt data. + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to build required FDT. +**/ +EFI_STATUS +BuildFdtForSerialLpss ( + IN INT32 ISANode, + IN VOID *FdtBase + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + EFI_STATUS Status; + UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *SerialPortInfo; + VOID *Fdt; + INT32 TempNode; + UINT32 Data32; + UINT32 RegData[2]; + CHAR8 TempStr[32]; + + Status = EFI_SUCCESS; + SerialPortInfo = NULL; + Fdt = FdtBase; + + DEBUG ((DEBUG_INFO, "BuildFdtForSerialLpss start \n")); + GuidHob = GetFirstGuidHob (&gUniversalPayloadSerialPortInfoGuid); + while (GuidHob != NULL) { + SerialPortInfo = (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *)GET_GUID_HOB_DATA (GuidHob); + + if (!SerialPortInfo->UseMmio) { + GuidHob = GET_NEXT_HOB (GuidHob); + GuidHob = GetNextGuidHob (&gUniversalPayloadSerialPortInfoGuid, GuidHob); + continue; + } + + DEBUG ((DEBUG_INFO, "Create SerialPortInfo LPSS FDT node \n")); + // + // Create SerialPortInfo FDT node. + // + Status = AsciiSPrint (TempStr, sizeof (TempStr), "serial@%lX", SerialPortInfo->RegisterBase); + TempNode = FdtAddSubnode (Fdt, ISANode, TempStr); + ASSERT (TempNode > 0); + + Data32 = CpuToFdt32 (SerialPortInfo->BaudRate); + Status = FdtSetProp (Fdt, TempNode, "current-speed", &Data32, sizeof (Data32)); + ASSERT_EFI_ERROR (Status); + + RegData[0] = CpuToFdt32 ((UINT32)SerialPortInfo->RegisterBase); + RegData[1] = CpuToFdt32 (0x80); + Status = FdtSetProp (Fdt, TempNode, "reg", &RegData, sizeof (RegData)); + ASSERT_EFI_ERROR (Status); + + Data32 = CpuToFdt32 (4); + Status = FdtSetProp (Fdt, TempNode, "reg-io-width", &Data32, sizeof (Data32)); + ASSERT_EFI_ERROR (Status); + + Status = FdtSetProp (Fdt, TempNode, "compatible", "ns16550a", (UINT32)(AsciiStrLen ("ns16550a")+1)); + ASSERT_EFI_ERROR (Status); + + GuidHob = GET_NEXT_HOB (GuidHob); + GuidHob = GetNextGuidHob (&gUniversalPayloadSerialPortInfoGuid, GuidHob); + } + + return Status; +} + +/** + It will build FDT based on BuildFdtForPciRootBridge information. + @param[in] FdtBase Address of the Fdt data. + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to build required FDT. +**/ +EFI_STATUS +BuildFdtForPciRootBridge ( + IN VOID *FdtBase + ) +{ + EFI_STATUS Status; + VOID *Fdt; + INT32 TempNode; + INT32 GmaNode; + INT32 eSPINode; + CHAR8 TempStr[32]; + CHAR8 GmaStr[32]; + CHAR8 eSPIStr[32]; + UINT32 RegTmp[2]; + UINT32 RegData[21]; + UINT32 DMARegData[8]; + UINT32 Data32; + UINT64 Data64; + UINT8 BusNumber; + UINT8 BusLimit; + UINT8 BusBase; + UINT8 DevBase; + UINT8 FunBase; + EFI_HOB_GUID_TYPE *GuidHob; + UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader; + UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo; + UINT8 Index; + PCI_TYPE00 PciData; + UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO *SerialParent; + + Fdt = FdtBase; + BusNumber = 0; + BusLimit = 0; + BusBase = 0x80; + DevBase = 0x31; + FunBase = 0; + Status = EFI_SUCCESS; + PciRootBridgeInfo = NULL; + + DEBUG ((DEBUG_INFO, "%a: #1 \n", __func__)); + // + // Create BuildFdtForPciRootBridge FDT node. + // + + GuidHob = GetFirstGuidHob (&gUniversalPayloadPciRootBridgeInfoGuid); + if (GuidHob != NULL) { + GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob); + if ((sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) <= GET_GUID_HOB_DATA_SIZE (GuidHob)) && (GenericHeader->Length <= GET_GUID_HOB_DATA_SIZE (GuidHob))) { + if ((GenericHeader->Revision == UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION) && (GenericHeader->Length >= sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES))) { + DEBUG ((DEBUG_INFO, "%a: #2 \n", __func__)); + + // + // UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES structure is used when Revision equals to UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION + // + PciRootBridgeInfo = (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *)GET_GUID_HOB_DATA (GuidHob); + } + } + } + + GuidHob = GetFirstGuidHob (&gUniversalPayloadSerialPortParentDeviceInfoGuid); + if (GuidHob != NULL) { + SerialParent = (UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO *)GET_GUID_HOB_DATA (GuidHob); + BusBase = (SerialParent->ParentDevicePcieBaseAddress >> 20) & 0xFF; + DevBase = (SerialParent->ParentDevicePcieBaseAddress >> 15) & 0x1F; + FunBase = (SerialParent->ParentDevicePcieBaseAddress >> 12) & 0x07; + } + + DEBUG ((DEBUG_INFO, "PciRootBridgeInfo->Count %x\n", PciRootBridgeInfo->Count)); + DEBUG ((DEBUG_INFO, "PciRootBridge->Segment %x, \n", PciRootBridgeInfo->RootBridge[0].Segment)); + + DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.Base %x, \n", PciRootBridgeInfo->RootBridge[0].Bus.Base)); + DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.limit %x, \n", PciRootBridgeInfo->RootBridge[0].Bus.Limit)); + + DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base %x, \n", PciRootBridgeInfo->RootBridge[0].Mem.Base)); + DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.limit %x, \n", PciRootBridgeInfo->RootBridge[0].Mem.Limit)); + + DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base %llx, \n", PciRootBridgeInfo->RootBridge[0].MemAbove4G.Base)); + DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.limit %llx, \n", PciRootBridgeInfo->RootBridge[0].MemAbove4G.Limit)); + + DEBUG ((DEBUG_INFO, "PciRootBridge->PMem.Base %llx, \n", PciRootBridgeInfo->RootBridge[0].PMem.Base)); + DEBUG ((DEBUG_INFO, "PciRootBridge->PMem.limit %llx, \n", PciRootBridgeInfo->RootBridge[0].PMem.Limit)); + + DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.Base %x, \n", PciRootBridgeInfo->RootBridge[1].Bus.Base)); + DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.limit %x, \n", PciRootBridgeInfo->RootBridge[1].Bus.Limit)); + + DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base %x, \n", PciRootBridgeInfo->RootBridge[1].Mem.Base)); + DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.limit %x, \n", PciRootBridgeInfo->RootBridge[1].Mem.Limit)); + + DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base %llx, \n", PciRootBridgeInfo->RootBridge[1].MemAbove4G.Base)); + DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.limit %llx, \n", PciRootBridgeInfo->RootBridge[1].MemAbove4G.Limit)); + + DEBUG ((DEBUG_INFO, "PciRootBridge->PMem.Base %x, \n", PciRootBridgeInfo->RootBridge[1].PMem.Base)); + DEBUG ((DEBUG_INFO, "PciRootBridge->PMem.limit %x, \n", PciRootBridgeInfo->RootBridge[1].PMem.Limit)); + + if (PciRootBridgeInfo != NULL) { + for (Index = 0; Index < PciRootBridgeInfo->Count; Index++) { + UINTN PciExpressBaseAddress; + + mResourceAssigned = PciRootBridgeInfo->ResourceAssigned; + PciExpressBaseAddress = PcdGet64 (PcdPciExpressBaseAddress) + (PCI_LIB_ADDRESS (PciRootBridgeInfo->RootBridge[Index].Bus.Base, 0, 0, 0)); + Status = AsciiSPrint (TempStr, sizeof (TempStr), "pci-rb%d@%lX", Index, PciExpressBaseAddress); + TempNode = FdtAddSubnode (Fdt, 0, TempStr); + ASSERT (TempNode > 0); + SetMem (RegData, sizeof (RegData), 0); + + // non-reloc/non-prefetch/mmio, child-addr, parent-addr, length + Data32 = (N_NON_RELOCATABLE + SS_32BIT_MEMORY_SPACE); + RegData[0] = CpuToFdt32 (Data32); + DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base RegData[0] %x, \n", Data32)); + + // child-addr + RegData[1] = CpuToFdt32 (0); + Data32 = (UINT32)PciRootBridgeInfo->RootBridge[Index].Mem.Base; + RegData[2] = CpuToFdt32 (Data32); + DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base RegData[2] %x, \n", Data32)); + + // parent-addr + RegData[3] = CpuToFdt32 (0); + RegData[4] = CpuToFdt32 (Data32); + DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base RegData[4] %x, \n", Data32)); + + // size + Data64 = (PciRootBridgeInfo->RootBridge[Index].Mem.Limit - PciRootBridgeInfo->RootBridge[Index].Mem.Base + 1); + if (Data64 & 0xFFFFFFFF00000000) { + Data32 = (UINT32)RShiftU64 ((Data64 & 0xFFFFFFFF00000000), 31); + } else { + Data32 = 0; + } + + DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.size RegData[5] %x, \n", Data32)); + RegData[5] = CpuToFdt32 (Data32); + Data32 = (UINT32)((Data64 & 0x0FFFFFFFF)); + DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.size RegData[6] %x, \n", Data32)); + + RegData[6] = CpuToFdt32 (Data32); + + // non-reloc/non-prefetch/64 mmio, child-addr, parent-addr, length + Data32 = (N_NON_RELOCATABLE + SS_64BIT_MEMORY_SPACE); + RegData[7] = CpuToFdt32 (Data32); + DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base RegData[7] %x, \n", Data32)); + + // child-addr + Data64 = PciRootBridgeInfo->RootBridge[Index].MemAbove4G.Base; + Data32 = (UINT32)RShiftU64 ((Data64 & 0xFFFFFFFF00000000), 32); + + RegData[8] = CpuToFdt32 (Data32); + DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base RegData[8] %x, \n", Data32)); + Data32 = (UINT32)((Data64 & 0x0FFFFFFFF)); + RegData[9] = CpuToFdt32 (Data32); + DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base RegData[9] %x, \n", Data32)); + + // parent-addr + RegData[10] = RegData[8]; + RegData[11] = RegData[9]; + + // size + Data64 = (PciRootBridgeInfo->RootBridge[Index].MemAbove4G.Limit - PciRootBridgeInfo->RootBridge[Index].MemAbove4G.Base + 1); + if (Data64 & 0xFFFFFFFF00000000) { + Data32 = (UINT32)RShiftU64 ((Data64 & 0xFFFFFFFF00000000), 32); + } else { + Data32 = 0; + } + + RegData[12] = CpuToFdt32 (Data32); + DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.size RegData[12] %x, \n", Data32)); + + Data32 = (UINT32)((Data64 & 0x0FFFFFFFF)); + RegData[13] = CpuToFdt32 (Data32); + DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.size RegData[13] %x, \n", Data32)); + + // non-reloc/32bit/io, child-addr, parent-addr, length + Data32 = (N_NON_RELOCATABLE + SS_IO_SPACE); + + RegData[14] = CpuToFdt32 (Data32); + DEBUG ((DEBUG_INFO, "PciRootBridge->Io.base RegData[14] %x, \n", Data32)); + + Data32 = (UINT32)PciRootBridgeInfo->RootBridge[Index].Io.Base; + // child-addr + RegData[15] = CpuToFdt32 (0); + RegData[16] = CpuToFdt32 (Data32); + DEBUG ((DEBUG_INFO, "PciRootBridge->Io.base RegData[16] %x, \n", Data32)); + + // parent-addr + RegData[17] = CpuToFdt32 (0); + RegData[18] = CpuToFdt32 (Data32); + // size + Data64 = (PciRootBridgeInfo->RootBridge[Index].Io.Limit - PciRootBridgeInfo->RootBridge[Index].Io.Base + 1); + if (Data64 & 0xFFFFFFFF00000000) { + Data32 = (UINT32)RShiftU64 ((Data64 & 0xFFFFFFFF00000000), 32); + } else { + Data32 = 0; + } + + RegData[19] = CpuToFdt32 (Data32); + DEBUG ((DEBUG_INFO, "PciRootBridge->Io.base size [19] %x, \n", Data32)); + + Data32 = (UINT32)((Data64 & 0x0FFFFFFFF)); + RegData[20] = CpuToFdt32 (Data32); + DEBUG ((DEBUG_INFO, "PciRootBridge->Io.base size [20] %x, \n", Data32)); + + Status = FdtSetProp (Fdt, TempNode, "ranges", &RegData, sizeof (RegData)); + ASSERT_EFI_ERROR (Status); + + // non-reloc/non-prefetch/memory, child-addr, parent-addr, length + // indicate rb1 does not support above 4GB DMA + Data32 = (N_NON_RELOCATABLE + SS_32BIT_MEMORY_SPACE); + + DMARegData[0] = CpuToFdt32 (Data32); + DEBUG ((DEBUG_INFO, "PciRootBridge->DMA base RegData[0] %x, \n", Data32)); + + // child-addr + DMARegData[2] = CpuToFdt32 (0); + DMARegData[3] = CpuToFdt32 (0); + // parent-addr + DMARegData[4] = CpuToFdt32 (0); + DMARegData[5] = CpuToFdt32 (0); + // size + DMARegData[6] = CpuToFdt32 (1); + DMARegData[7] = CpuToFdt32 (0); + + Status = FdtSetProp (Fdt, TempNode, "dma-ranges", &DMARegData, sizeof (DMARegData)); + ASSERT_EFI_ERROR (Status); + + Data32 = CpuToFdt32 (2); + Status = FdtSetProp (Fdt, TempNode, "#size-cells", &Data32, sizeof (UINT32)); + + Data32 = CpuToFdt32 (3); + Status = FdtSetProp (Fdt, TempNode, "#address-cells", &Data32, sizeof (UINT32)); + + BusNumber = PciRootBridgeInfo->RootBridge[Index].Bus.Base & 0xFF; + RegTmp[0] = CpuToFdt32 (BusNumber); + BusLimit = PciRootBridgeInfo->RootBridge[Index].Bus.Limit & 0xFF; + RegTmp[1] = CpuToFdt32 (BusLimit); + DEBUG ((DEBUG_INFO, "PciRootBridge->BusNumber %x, \n", BusNumber)); + DEBUG ((DEBUG_INFO, "PciRootBridge->BusLimit %x, \n", BusLimit)); + + Status = FdtSetProp (Fdt, TempNode, "bus-range", &RegTmp, sizeof (RegTmp)); + ASSERT_EFI_ERROR (Status); + + Status = FdtSetProp (Fdt, TempNode, "compatible", "pci-rb", (UINT32)(AsciiStrLen ("pci-rb")+1)); + ASSERT_EFI_ERROR (Status); + + if (Index == 0) { + PciExpressBaseAddress = PcdGet64 (PcdPciExpressBaseAddress) + (PCI_LIB_ADDRESS (IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, 0)); + Status = AsciiSPrint (GmaStr, sizeof (GmaStr), "gma@%lX", PciExpressBaseAddress); + GmaNode = FdtAddSubnode (Fdt, TempNode, GmaStr); + Status = LocatePciDevicePpi (); + if (!EFI_ERROR (Status)) { + Status = mPciDevicePpi->PciIo.Pci.Read ( + &mPciDevicePpi->PciIo, + (EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint16, + PCI_VENDOR_ID_OFFSET, + sizeof (PciData.Hdr.VendorId), + &(PciData.Hdr.VendorId) + ); + + Status = mPciDevicePpi->PciIo.Pci.Read ( + &mPciDevicePpi->PciIo, + (EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint16, + PCI_DEVICE_ID_OFFSET, + sizeof (PciData.Hdr.DeviceId), + &(PciData.Hdr.DeviceId) + ); + + Status = mPciDevicePpi->PciIo.Pci.Read ( + &mPciDevicePpi->PciIo, + (EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint8, + PCI_REVISION_ID_OFFSET, + sizeof (PciData.Hdr.RevisionID), + &(PciData.Hdr.RevisionID) + ); + + Status = mPciDevicePpi->PciIo.Pci.Read ( + &mPciDevicePpi->PciIo, + (EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint16, + PCI_SVID_OFFSET, + sizeof (PciData.Device.SubsystemVendorID), + &(PciData.Device.SubsystemVendorID) + ); + + Status = mPciDevicePpi->PciIo.Pci.Read ( + &mPciDevicePpi->PciIo, + (EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint16, + PCI_SID_OFFSET, + sizeof (PciData.Device.SubsystemID), + &(PciData.Device.SubsystemID) + ); + } + + Data32 = CpuToFdt32 (PciData.Device.SubsystemID); + Status = FdtSetProp (Fdt, GmaNode, "subsystem-id", &Data32, sizeof (UINT32)); + + Data32 = CpuToFdt32 (PciData.Device.SubsystemVendorID); + Status = FdtSetProp (Fdt, GmaNode, "subsystem-vendor-id", &Data32, sizeof (UINT32)); + + Data32 = CpuToFdt32 (PciData.Hdr.RevisionID); + Status = FdtSetProp (Fdt, GmaNode, "revision-id", &Data32, sizeof (UINT32)); + + Data32 = CpuToFdt32 (PciData.Hdr.DeviceId); + Status = FdtSetProp (Fdt, GmaNode, "device-id", &Data32, sizeof (UINT32)); + + Data32 = CpuToFdt32 (PciData.Hdr.VendorId); + Status = FdtSetProp (Fdt, GmaNode, "vendor-id", &Data32, sizeof (UINT32)); + } + + if (SerialParent != NULL) { + DEBUG ((DEBUG_INFO, "SerialParent->IsIsaCompatible :%x , SerialParent->ParentDevicePcieBaseAddress :%x\n", SerialParent->IsIsaCompatible, SerialParent->ParentDevicePcieBaseAddress)); + DEBUG ((DEBUG_INFO, "BusBase :%x , PciRootBridgeInfo->RootBridge[Index].Bus.Base :%x\n", BusBase, PciRootBridgeInfo->RootBridge[Index].Bus.Base)); + } + + { + if ((BusBase >= PciRootBridgeInfo->RootBridge[Index].Bus.Base) && (BusBase <= PciRootBridgeInfo->RootBridge[Index].Bus.Limit)) { + eSPINode = TempNode; + if (SerialParent != NULL) { + if (SerialParent->IsIsaCompatible) { + Status = AsciiSPrint (eSPIStr, sizeof (eSPIStr), "isa@%X,%X", DevBase, FunBase); + eSPINode = FdtAddSubnode (Fdt, TempNode, eSPIStr); + Status = FdtSetProp (Fdt, eSPINode, "compatible", "isa", (UINT32)(AsciiStrLen ("isa")+1)); + ASSERT_EFI_ERROR (Status); + Data32 = CpuToFdt32 (1); + Status = FdtSetProp (Fdt, eSPINode, "#size-cells", &Data32, sizeof (UINT32)); + Data32 = CpuToFdt32 (2); + Status = FdtSetProp (Fdt, eSPINode, "#address-cells", &Data32, sizeof (UINT32)); + Status = BuildFdtForSerial (eSPINode, FdtBase); + ASSERT_EFI_ERROR (Status); + } + } else { + Status = BuildFdtForSerialLpss (eSPINode, FdtBase); + ASSERT_EFI_ERROR (Status); + } + } + } + } + } + + DEBUG ((DEBUG_INFO, "%a: #3 \n", __func__)); + + return Status; +} + +/** + It will build FDT based on FrameBuffer. + @param[in] FdtBase Address of the Fdt data. + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to build required FDT. +**/ +EFI_STATUS +BuildFdtForFrameBuffer ( + IN VOID *FdtBase + ) +{ + EFI_STATUS Status; + VOID *Fdt; + INT32 TempNode; + UINT32 Data32; + CHAR8 TempStr[32]; + UINT64 RegData[2]; + EFI_HOB_GUID_TYPE *GuidHob; + EFI_PEI_GRAPHICS_INFO_HOB *GraphicsInfo; + + Fdt = FdtBase; + + GuidHob = GetFirstGuidHob (&gEfiGraphicsInfoHobGuid); + if (GuidHob != NULL) { + GraphicsInfo = (EFI_PEI_GRAPHICS_INFO_HOB *)(GET_GUID_HOB_DATA (GuidHob)); + Status = AsciiSPrint (TempStr, sizeof (TempStr), "framebuffer@%lX", GraphicsInfo->FrameBufferBase); + TempNode = FdtAddSubnode (Fdt, 0, TempStr); + ASSERT (TempNode > 0); + + Status = FdtSetProp (Fdt, TempNode, "display", "&gma", (UINT32)(AsciiStrLen ("&gma")+1)); + ASSERT_EFI_ERROR (Status); + + Status = FdtSetProp (Fdt, TempNode, "format", "a8r8g8b8", (UINT32)(AsciiStrLen ("a8r8g8b8")+1)); + ASSERT_EFI_ERROR (Status); + + Data32 = CpuToFdt32 (GraphicsInfo->GraphicsMode.VerticalResolution); + Status = FdtSetProp (Fdt, TempNode, "height", &Data32, sizeof (UINT32)); + ASSERT_EFI_ERROR (Status); + + Data32 = CpuToFdt32 (GraphicsInfo->GraphicsMode.HorizontalResolution); + Status = FdtSetProp (Fdt, TempNode, "width", &Data32, sizeof (UINT32)); + ASSERT_EFI_ERROR (Status); + + RegData[0] = CpuToFdt64 (GraphicsInfo->FrameBufferBase); + RegData[1] = CpuToFdt64 (GraphicsInfo->FrameBufferSize); + Status = FdtSetProp (Fdt, TempNode, "reg", &RegData, sizeof (RegData)); + ASSERT_EFI_ERROR (Status); + + Status = FdtSetProp (Fdt, TempNode, "compatible", "simple-framebuffer", (UINT32)(AsciiStrLen ("simple-framebuffer")+1)); + ASSERT_EFI_ERROR (Status); + } else { + Status = AsciiSPrint (TempStr, sizeof (TempStr), "framebuffer@%lX", 0xB0000000); + TempNode = FdtAddSubnode (Fdt, 0, TempStr); + ASSERT (TempNode > 0); + + Status = FdtSetProp (Fdt, TempNode, "display", "&gma", (UINT32)(AsciiStrLen ("&gma")+1)); + ASSERT_EFI_ERROR (Status); + + Status = FdtSetProp (Fdt, TempNode, "format", "a8r8g8b8", (UINT32)(AsciiStrLen ("a8r8g8b8")+1)); + ASSERT_EFI_ERROR (Status); + + Data32 = CpuToFdt32 (1024); + Status = FdtSetProp (Fdt, TempNode, "height", &Data32, sizeof (UINT32)); + ASSERT_EFI_ERROR (Status); + + Data32 = CpuToFdt32 (1280); + Status = FdtSetProp (Fdt, TempNode, "width", &Data32, sizeof (UINT32)); + ASSERT_EFI_ERROR (Status); + + RegData[0] = CpuToFdt64 (0xB0000000); + RegData[1] = CpuToFdt64 (0x500000); + Status = FdtSetProp (Fdt, TempNode, "reg", &RegData, sizeof (RegData)); + ASSERT_EFI_ERROR (Status); + + Status = FdtSetProp (Fdt, TempNode, "compatible", "simple-framebuffer", (UINT32)(AsciiStrLen ("simple-framebuffer")+1)); + ASSERT_EFI_ERROR (Status); + } + + return Status; +} + +/** + It will build FDT for UPL required data. + @param[in] FdtBase Address of the Fdt data. + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to build required FDT. +**/ +EFI_STATUS +BuildFdtForUplRequired ( + IN VOID *FdtBase + ) +{ + EFI_STATUS Status; + VOID *Fdt; + VOID *Fit; + INT32 ParentNode; + INT32 CustomNode; + INT32 UPLParaNode; + INT32 UPLImageNode; + EFI_HOB_CPU *CpuHob; + UINT64 Data64; + UINT32 Data32; + VOID *HobPtr; + EFI_BOOT_MODE BootMode; + CHAR8 TempStr[32]; + UINT8 *GuidHob; + UNIVERSAL_PAYLOAD_BASE *PayloadBase; + + Fdt = FdtBase; + Fit = NULL; + + // + // Create Hob list FDT node. + // + ParentNode = FdtAddSubnode (Fdt, 0, "options"); + ASSERT (ParentNode > 0); + + UPLParaNode = FdtAddSubnode (Fdt, ParentNode, "upl-params"); + ASSERT (UPLParaNode > 0); + + // + // Create CPU info FDT node + // + CpuHob = GetFirstHob (EFI_HOB_TYPE_CPU); + ASSERT (CpuHob != NULL); + + if (mResourceAssigned) { + Status = FdtSetProp (Fdt, UPLParaNode, "pci-enum-done", NULL, 0); + ASSERT_EFI_ERROR (Status); + } + + BootMode = GetBootModeHob (); + + Data32 = CpuToFdt32 ((UINT32)CpuHob->SizeOfMemorySpace); + Status = FdtSetProp (Fdt, UPLParaNode, "addr-width", &Data32, sizeof (Data32)); + ASSERT_EFI_ERROR (Status); + + if (BootMode == BOOT_WITH_FULL_CONFIGURATION) { + Status = FdtSetProp (Fdt, UPLParaNode, "boot-mode", "normal", (UINT32)(AsciiStrLen ("normal")+1)); + } else if (BootMode == BOOT_WITH_MINIMAL_CONFIGURATION) { + Status = FdtSetProp (Fdt, UPLParaNode, "boot-mode", "fast", (UINT32)(AsciiStrLen ("fast")+1)); + } else if (BootMode == BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS) { + Status = FdtSetProp (Fdt, UPLParaNode, "boot-mode", "full", (UINT32)(AsciiStrLen ("full")+1)); + } else if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) { + Status = FdtSetProp (Fdt, UPLParaNode, "boot-mode", "default", (UINT32)(AsciiStrLen ("default")+1)); + } else if (BootMode == BOOT_ON_S4_RESUME) { + Status = FdtSetProp (Fdt, UPLParaNode, "boot-mode", "s4", (UINT32)(AsciiStrLen ("s4")+1)); + } else if (BootMode == BOOT_ON_S3_RESUME) { + Status = FdtSetProp (Fdt, UPLParaNode, "boot-mode", "s3", (UINT32)(AsciiStrLen ("s3")+1)); + } else { + Status = FdtSetProp (Fdt, UPLParaNode, "boot-mode", "na", (UINT32)(AsciiStrLen ("na")+1)); + } + + ASSERT_EFI_ERROR (Status); + + Status = FdtSetProp (Fdt, UPLParaNode, "compatible", "upl", (UINT32)(AsciiStrLen ("upl")+1)); + ASSERT_EFI_ERROR (Status); + + GuidHob = GetFirstGuidHob (&gUniversalPayloadBaseGuid); + if (GuidHob != NULL) { + PayloadBase = (UNIVERSAL_PAYLOAD_BASE *)GET_GUID_HOB_DATA (GuidHob); + Fit = (VOID *)(UINTN)PayloadBase->Entry; + DEBUG ((DEBUG_INFO, "PayloadBase Entry = 0x%08x\n", PayloadBase->Entry)); + + Status = AsciiSPrint (TempStr, sizeof (TempStr), "upl-images@%lX", (UINTN)(Fit)); + UPLImageNode = FdtAddSubnode (Fdt, ParentNode, TempStr); + + Data64 = CpuToFdt64 ((UINTN)Fit); + Status = FdtSetProp (FdtBase, UPLImageNode, "addr", &Data64, sizeof (Data64)); + } + + CustomNode = FdtAddSubnode (Fdt, ParentNode, "upl-custom"); + ASSERT (CustomNode > 0); + + HobPtr = GetHobList (); + Data64 = CpuToFdt64 ((UINT64)(EFI_PHYSICAL_ADDRESS)HobPtr); + Status = FdtSetProp (Fdt, CustomNode, "hoblistptr", &Data64, sizeof (Data64)); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + It will build FDT for UPL consumed. + @param[in] FdtBase Address of the Fdt data. + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to build required FDT. +**/ +EFI_STATUS +BuildFdtForUPL ( + IN VOID *FdtBase + ) +{ + EFI_STATUS Status; + + // + // Build FDT for memory related + // + Status = BuildFdtForMemory (FdtBase); + ASSERT_EFI_ERROR (Status); + + Status = BuildFdtForMemAlloc (FdtBase); + ASSERT_EFI_ERROR (Status); + + Status = BuildFdtForPciRootBridge (FdtBase); + ASSERT_EFI_ERROR (Status); + + Status = BuildFdtForFrameBuffer (FdtBase); + ASSERT_EFI_ERROR (Status); + + Status = BuildFdtForUplRequired (FdtBase); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.c b/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.c new file mode 100644 index 000000000000..0c454496dcca --- /dev/null +++ b/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.c @@ -0,0 +1,164 @@ +/** @file + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Add a new HOB to the HOB List. + + @param HobType Type of the new HOB. + @param HobLength Length of the new HOB to allocate. + + @return NULL if there is no space to create a hob. + @return The address point to the new created hob. + +**/ +VOID * +EFIAPI +CreateHob ( + IN UINT16 HobType, + IN UINT16 HobLength + ); + +/** + Add HOB into HOB list + @param[in] Hob The HOB to be added into the HOB list. +**/ +VOID +AddNewHob ( + IN EFI_PEI_HOB_POINTERS *Hob + ); + +/** + Check the HOB and decide if it is need inside Payload + Payload maintainer may make decision which HOB is need or needn't + Then add the check logic in the function. + @param[in] Hob The HOB to check + @retval TRUE If HOB is need inside Payload + @retval FALSE If HOB is needn't inside Payload +**/ +BOOLEAN +EFIAPI +FitIsHobNeed ( + EFI_PEI_HOB_POINTERS Hob + ) +{ + if (FixedPcdGetBool (PcdHandOffFdtEnable)) { + if (Hob.Header->HobType == EFI_HOB_TYPE_HANDOFF) { + return FALSE; + } + + if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) { + if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gUniversalPayloadDeviceTreeGuid)) { + return FALSE; + } + + if (CompareGuid (&Hob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) { + return FALSE; + } + + if ((Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiReservedMemoryType) || + (Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiBootServicesCode) || + (Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiBootServicesData) || + (Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiRuntimeServicesCode) || + (Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiRuntimeServicesData) || + (Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiACPIReclaimMemory) || + (Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiACPIMemoryNVS)) + { + return FALSE; + } + } + + if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) { + return FALSE; + } + } + + if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) { + if (CompareGuid (&Hob.Guid->Name, &gUniversalPayloadSerialPortInfoGuid)) { + return FALSE; + } + + if (CompareGuid (&Hob.Guid->Name, &gUniversalPayloadAcpiTableGuid)) { + return FALSE; + } + + if (CompareGuid (&Hob.Guid->Name, &gUniversalPayloadPciRootBridgeInfoGuid)) { + return FALSE; + } + } + } + + // Arrive here mean the HOB is need + return TRUE; +} + +/** + It will Parse FDT -custom node based on information from bootloaders. + @param[in] FdtBase The starting memory address of FdtBase + @param[in] HobList The starting memory address of New Hob list. + +**/ +UINTN +EFIAPI +CustomFdtNodeParser ( + IN VOID *FdtBase, + IN VOID *HobList + ) +{ + INT32 Node, CustomNode; + INT32 TempLen; + UINT64 *Data64; + UINTN CHobList; + CONST FDT_PROPERTY *PropertyPtr; + EFI_PEI_HOB_POINTERS Hob; + + CHobList = (UINTN)HobList; + + DEBUG ((DEBUG_INFO, "%a() #1 \n", __func__)); + + // + // Look for if exists hob list node + // + Node = FdtSubnodeOffsetNameLen (FdtBase, 0, "options", (INT32)AsciiStrLen ("options")); + if (Node > 0) { + DEBUG ((DEBUG_INFO, " Found options node (%08X)", Node)); + CustomNode = FdtSubnodeOffsetNameLen (FdtBase, Node, "upl-custom", (INT32)AsciiStrLen ("upl-custom")); + if (CustomNode > 0) { + DEBUG ((DEBUG_INFO, " Found upl-custom node (%08X)", CustomNode)); + PropertyPtr = FdtGetProperty (FdtBase, CustomNode, "hoblistptr", &TempLen); + Data64 = (UINT64 *)(PropertyPtr->Data); + CHobList = (UINTN)Fdt64ToCpu (*Data64); + DEBUG ((DEBUG_INFO, " Found hob list node (%08X)", CustomNode)); + DEBUG ((DEBUG_INFO, " -pointer %016lX\n", CHobList)); + } + } + + Hob.Raw = (UINT8 *)CHobList; + + // + // Since payload created new Hob, move all hobs except PHIT from boot loader hob list. + // + while (!END_OF_HOB_LIST (Hob)) { + if (FitIsHobNeed (Hob)) { + // Add this hob to payload HOB + AddNewHob (&Hob); + } + + Hob.Raw = GET_NEXT_HOB (Hob); + } + + return CHobList; +} diff --git a/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf b/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf new file mode 100644 index 000000000000..036ed4315dd0 --- /dev/null +++ b/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf @@ -0,0 +1,46 @@ +## @file +# Custom FDT Node Parse Library. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CustomFdtNodeParserLib + FILE_GUID = 732B2B8F-65AD-4BF8-A98F-6E0D330F7A60 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = CustomFdtNodeParserLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + CustomFdtNodeParserLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + FdtLib + HobLib + PcdLib + +[Guids] + gUniversalPayloadPciRootBridgeInfoGuid + gUniversalPayloadSerialPortInfoGuid + gUniversalPayloadDeviceTreeGuid + gUniversalPayloadAcpiTableGuid + gEfiHobMemoryAllocModuleGuid + +[Pcd] + gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable diff --git a/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.c b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.c new file mode 100644 index 000000000000..4b2a8b92389a --- /dev/null +++ b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.c @@ -0,0 +1,46 @@ +/** @file + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include +#include +#include + +/** + Check the HOB and decide if it is need inside Payload + Payload maintainer may make decision which HOB is need or needn't + Then add the check logic in the function. + @param[in] Hob The HOB to check + @retval TRUE If HOB is need inside Payload + @retval FALSE If HOB is needn't inside Payload +**/ +BOOLEAN +FitIsHobNeed ( + EFI_PEI_HOB_POINTERS Hob + ) +{ + return FALSE; +} + +/** + It will Parse FDT -custom node based on information from bootloaders. + @param[in] FdtBase The starting memory address of FdtBase. + @param[in] HobList The starting memory address of New Hob list. + @retval HobList The base address of Hoblist. + +**/ +UINTN +CustomFdtNodeParser ( + IN VOID *Fdt, + IN VOID *HobList + ) +{ + UINTN CHobList; + + CHobList = 0; + if (HobList != NULL) { + CHobList = (UINTN)HobList; + } + + return CHobList; +} diff --git a/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.inf b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.inf new file mode 100644 index 000000000000..8410f04c9d70 --- /dev/null +++ b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.inf @@ -0,0 +1,27 @@ +## @file +# Custom FDT Node Parse Library. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CustomFdtNodeParserLibNull + FILE_GUID = 386496E4-37DB-4531-BA0C-16D126E63C55 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = CustomFdtNodeParserLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + CustomFdtNodeParserNullLib.c + +[Packages] + MdePkg/MdePkg.dec diff --git a/UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf b/UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf new file mode 100644 index 000000000000..b9b7e90edcb0 --- /dev/null +++ b/UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf @@ -0,0 +1,64 @@ +## @file +# Coreboot Table Parse Library. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FdtParseLib + FILE_GUID = 8956F72D-9626-4959-98B7-1BD4A3EA687E + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = FdtParseLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + FdtParserLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec + +[LibraryClasses] + DebugLib + PcdLib + HobLib + FdtLib + CustomFdtNodeParserLib + +[Guids] + gUniversalPayloadDeviceTreeGuid + gEfiGraphicsInfoHobGuid + gEfiGraphicsDeviceInfoHobGuid + gUniversalPayloadAcpiTableGuid + gUniversalPayloadSerialPortInfoGuid + +[Pcd.IA32,Pcd.X64] + gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize + gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize + gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable + gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase + gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemBase + gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemLimit + gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemAbove4GBBase + gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemAbove4GBLimit + gUefiPayloadPkgTokenSpaceGuid.SizeOfIoSpace + + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = /wd4305 + GCC:*_*_IA32_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_X64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_ARM_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_AARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_RISCV64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_LOONGARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast diff --git a/UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c b/UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c new file mode 100644 index 000000000000..421b22904f8d --- /dev/null +++ b/UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c @@ -0,0 +1,944 @@ +/** @file + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef enum { + ReservedMemory = 1, + Memory, + FrameBuffer, + PciRootBridge, + Options, + DoNothing +} FDT_NODE_TYPE; + +#define MEMORY_ATTRIBUTE_DEFAULT (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ + EFI_RESOURCE_ATTRIBUTE_TESTED | \ + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | \ + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | \ + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | \ + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE ) + +#define ROOT_BRIDGE_SUPPORTS_DEFAULT (EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | \ + EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 | \ + EFI_PCI_IO_ATTRIBUTE_ISA_IO_16 | \ + EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | \ + EFI_PCI_IO_ATTRIBUTE_VGA_IO | \ + EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | \ + EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | \ + EFI_PCI_IO_ATTRIBUTE_ISA_IO | \ + EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO ) + +extern VOID *mHobList; +UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *mPciRootBridgeInfo = NULL; +INT32 mNode[0x500] = { 0 }; +UINT32 mNodeIndex = 0; + +/** + Build a Handoff Information Table HOB + + This function initialize a HOB region from EfiMemoryBegin to + EfiMemoryTop. And EfiFreeMemoryBottom and EfiFreeMemoryTop should + be inside the HOB region. + + @param[in] EfiMemoryBottom Total memory start address + @param[in] EfiMemoryTop Total memory end address. + @param[in] EfiFreeMemoryBottom Free memory start address + @param[in] EfiFreeMemoryTop Free memory end address. + + @return The pointer to the handoff HOB table. + +**/ +EFI_HOB_HANDOFF_INFO_TABLE * +EFIAPI +HobConstructor ( + IN VOID *EfiMemoryBottom, + IN VOID *EfiMemoryTop, + IN VOID *EfiFreeMemoryBottom, + IN VOID *EfiFreeMemoryTop + ); + +/** + It will record the memory node initialized. + + @param[in] Node memory node is going to parsing.. +**/ +VOID +RecordMemoryNode ( + INT32 Node + ) +{ + DEBUG ((DEBUG_INFO, "\n RecordMemoryNode %x , mNodeIndex :%x \n", Node, mNodeIndex)); + mNode[mNodeIndex] = Node; + mNodeIndex++; +} + +/** + Check the memory node if initialized. + + @param[in] Node memory node is going to parsing.. + + @return TRUE memory node was initialized. don't parse it again. + @return FALSE memory node wasn't initialized , go to parse it. +**/ +BOOLEAN +CheckMemoryNodeIfInit ( + INT32 Node + ) +{ + UINT32 i; + + for (i = 0; i < mNodeIndex; i++) { + if (mNode[i] == Node) { + return TRUE; + } + } + + return FALSE; +} + +/** + It will check device node from FDT. + + @param[in] NodeString Device node name string. + @param[in] Depth Check layer of Device node , only parse the 1st layer + + @return FDT_NODE_TYPE what type of the device node. +**/ +FDT_NODE_TYPE +CheckNodeType ( + CHAR8 *NodeString, + INT32 Depth + ) +{ + DEBUG ((DEBUG_INFO, "\n CheckNodeType %a \n", NodeString)); + if (AsciiStrnCmp (NodeString, "reserved-memory", AsciiStrLen ("reserved-memory")) == 0 ) { + return ReservedMemory; + } else if (AsciiStrnCmp (NodeString, "memory@", AsciiStrLen ("memory@")) == 0 ) { + return Memory; + } else if (AsciiStrnCmp (NodeString, "framebuffer@", AsciiStrLen ("framebuffer@")) == 0) { + return FrameBuffer; + } else if (AsciiStrnCmp (NodeString, "pci-rb", AsciiStrLen ("pci-rb")) == 0 ) { + return PciRootBridge; + } else if (AsciiStrCmp (NodeString, "options") == 0) { + return Options; + } else { + return DoNothing; + } +} + +/** + It will ParseMemory node from FDT. + + @param[in] Fdt Address of the Fdt data. + @param[in] SubNode first node of the PCI root bridge node. +**/ +VOID +ParseMemory ( + IN VOID *Fdt, + IN INT32 Node + ) +{ + UINT32 Attribute; + UINT8 ECCAttribute; + UINT32 ECCData, ECCData2; + INT32 Property; + CONST FDT_PROPERTY *PropertyPtr; + INT32 TempLen; + CONST CHAR8 *TempStr; + UINT64 *Data64; + UINT32 *Data32; + UINT64 StartAddress; + UINT64 NumberOfBytes; + + Attribute = MEMORY_ATTRIBUTE_DEFAULT; + ECCAttribute = 0; + ECCData = ECCData2 = 0; + for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property = FdtNextPropertyOffset (Fdt, Property)) { + PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen); + TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset), NULL); + if (AsciiStrCmp (TempStr, "reg") == 0) { + Data64 = (UINT64 *)(PropertyPtr->Data); + StartAddress = Fdt64ToCpu (*Data64); + NumberOfBytes = Fdt64ToCpu (*(Data64 + 1)); + } else if (AsciiStrCmp (TempStr, "ecc-detection-bits") == 0) { + Data32 = (UINT32 *)(PropertyPtr->Data); + ECCData = Fdt32ToCpu (*Data32); + } else if (AsciiStrCmp (TempStr, "ecc-correction-bits") == 0) { + Data32 = (UINT32 *)(PropertyPtr->Data); + ECCData2 = Fdt32ToCpu (*Data32); + } + } + + if (ECCData == ECCData2) { + if (ECCData == 1) { + ECCAttribute = EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC; + } else if (ECCData == 2) { + ECCAttribute = EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC; + } + } + + if (ECCAttribute != 0) { + Attribute |= ECCAttribute; + } + + BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, Attribute, StartAddress, NumberOfBytes); +} + +/** + It will ParseReservedMemory node from FDT. + + @param[in] Fdt Address of the Fdt data. + @param[in] SubNode first node of the PCI root bridge node. +**/ +VOID +ParseReservedMemory ( + IN VOID *Fdt, + IN INT32 Node + ) +{ + INT32 SubNode; + INT32 TempLen; + CONST CHAR8 *TempStr; + CONST FDT_PROPERTY *PropertyPtr; + UINT64 *Data64; + UINT64 StartAddress; + UINT64 NumberOfBytes; + UNIVERSAL_PAYLOAD_ACPI_TABLE *PlatformAcpiTable; + FDT_NODE_HEADER *NodePtr; + + PlatformAcpiTable = NULL; + + for (SubNode = FdtFirstSubnode (Fdt, Node); SubNode >= 0; SubNode = FdtNextSubnode (Fdt, SubNode)) { + NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + SubNode + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct)); + DEBUG ((DEBUG_INFO, "\n SubNode(%08X) %a", SubNode, NodePtr->Name)); + PropertyPtr = FdtGetProperty (Fdt, SubNode, "reg", &TempLen); + ASSERT (TempLen > 0); + TempStr = (CHAR8 *)(PropertyPtr->Data); + if (TempLen > 0) { + Data64 = (UINT64 *)(PropertyPtr->Data); + StartAddress = Fdt64ToCpu (*Data64); + NumberOfBytes = Fdt64ToCpu (*(Data64 + 1)); + DEBUG ((DEBUG_INFO, "\n Property %a", TempStr)); + DEBUG ((DEBUG_INFO, " %016lX %016lX", StartAddress, NumberOfBytes)); + } + + RecordMemoryNode (SubNode); + + if (AsciiStrnCmp (NodePtr->Name, "mmio@", AsciiStrLen ("mmio@")) == 0) { + DEBUG ((DEBUG_INFO, " MemoryMappedIO")); + BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiMemoryMappedIO); + } else { + PropertyPtr = FdtGetProperty (Fdt, SubNode, "compatible", &TempLen); + TempStr = (CHAR8 *)(PropertyPtr->Data); + if (AsciiStrnCmp (TempStr, "boot-code", AsciiStrLen ("boot-code")) == 0) { + DEBUG ((DEBUG_INFO, " boot-code")); + BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiBootServicesCode); + } else if (AsciiStrnCmp (TempStr, "boot-data", AsciiStrLen ("boot-data")) == 0) { + DEBUG ((DEBUG_INFO, " boot-data")); + BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiBootServicesData); + } else if (AsciiStrnCmp (TempStr, "runtime-code", AsciiStrLen ("runtime-code")) == 0) { + DEBUG ((DEBUG_INFO, " runtime-code")); + BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiRuntimeServicesCode); + } else if (AsciiStrnCmp (TempStr, "runtime-data", AsciiStrLen ("runtime-data")) == 0) { + DEBUG ((DEBUG_INFO, " runtime-data")); + BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiRuntimeServicesData); + } else if (AsciiStrnCmp (TempStr, "acpi", AsciiStrLen ("acpi")) == 0) { + DEBUG ((DEBUG_INFO, " acpi, StartAddress:%x, NumberOfBytes:%x", StartAddress, NumberOfBytes)); + BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiBootServicesData); + PlatformAcpiTable = BuildGuidHob (&gUniversalPayloadAcpiTableGuid, sizeof (UNIVERSAL_PAYLOAD_ACPI_TABLE)); + if (PlatformAcpiTable != NULL) { + DEBUG ((DEBUG_INFO, " build gUniversalPayloadAcpiTableGuid , NumberOfBytes:%x", NumberOfBytes)); + PlatformAcpiTable->Rsdp = (EFI_PHYSICAL_ADDRESS)(UINTN)StartAddress; + PlatformAcpiTable->Header.Revision = UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION; + PlatformAcpiTable->Header.Length = sizeof (UNIVERSAL_PAYLOAD_ACPI_TABLE); + } + } else if (AsciiStrnCmp (TempStr, "acpi-nvs", AsciiStrLen ("acpi-nvs")) == 0) { + DEBUG ((DEBUG_INFO, " acpi-nvs")); + BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiACPIMemoryNVS); + } else { + BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiReservedMemoryType); + } + } + } +} + +/** + It will ParseFrameBuffer node from FDT. + + @param[in] Fdt Address of the Fdt data. + @param[in] SubNode first Sub node of the PCI root bridge node. + + @return GmaStr Graphic device node name string. +**/ +CHAR8 * +ParseFrameBuffer ( + IN VOID *Fdt, + IN INT32 Node + ) +{ + INT32 Property; + INT32 TempLen; + CONST FDT_PROPERTY *PropertyPtr; + CONST CHAR8 *TempStr; + UINT32 *Data32; + UINT64 FrameBufferBase; + UINT32 FrameBufferSize; + EFI_PEI_GRAPHICS_INFO_HOB *GraphicsInfo; + CHAR8 *GmaStr; + + GmaStr = "Gma"; + // + // Create GraphicInfo HOB. + // + GraphicsInfo = BuildGuidHob (&gEfiGraphicsInfoHobGuid, sizeof (EFI_PEI_GRAPHICS_INFO_HOB)); + ASSERT (GraphicsInfo != NULL); + if (GraphicsInfo == NULL) { + return GmaStr; + } + + ZeroMem (GraphicsInfo, sizeof (EFI_PEI_GRAPHICS_INFO_HOB)); + + for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property = FdtNextPropertyOffset (Fdt, Property)) { + PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen); + TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset), NULL); + if (AsciiStrCmp (TempStr, "reg") == 0) { + Data32 = (UINT32 *)(PropertyPtr->Data); + FrameBufferBase = Fdt32ToCpu (*(Data32 + 0)); + FrameBufferSize = Fdt32ToCpu (*(Data32 + 1)); + GraphicsInfo->FrameBufferBase = FrameBufferBase; + GraphicsInfo->FrameBufferSize = (UINT32)FrameBufferSize; + } else if (AsciiStrCmp (TempStr, "width") == 0) { + Data32 = (UINT32 *)(PropertyPtr->Data); + GraphicsInfo->GraphicsMode.HorizontalResolution = Fdt32ToCpu (*Data32); + } else if (AsciiStrCmp (TempStr, "height") == 0) { + Data32 = (UINT32 *)(PropertyPtr->Data); + GraphicsInfo->GraphicsMode.VerticalResolution = Fdt32ToCpu (*Data32); + } else if (AsciiStrCmp (TempStr, "format") == 0) { + TempStr = (CHAR8 *)(PropertyPtr->Data); + if (AsciiStrCmp (TempStr, "a8r8g8b8") == 0) { + GraphicsInfo->GraphicsMode.PixelFormat = PixelRedGreenBlueReserved8BitPerColor; + } else if (AsciiStrCmp (TempStr, "a8b8g8r8") == 0) { + GraphicsInfo->GraphicsMode.PixelFormat = PixelBlueGreenRedReserved8BitPerColor; + } else { + GraphicsInfo->GraphicsMode.PixelFormat = PixelFormatMax; + } + } else if (AsciiStrCmp (TempStr, "display") == 0) { + GmaStr = (CHAR8 *)(PropertyPtr->Data); + GmaStr++; + DEBUG ((DEBUG_INFO, " display (%s)", GmaStr)); + } + } + + return GmaStr; +} + +/** + It will ParseOptions node from FDT. + + @param[in] Fdt Address of the Fdt data. + @param[in] SubNode first Sub node of the PCI root bridge node. + @param[out] PciEnumDone Init ParsePciRootBridge node for ParsePciRootBridge. + @param[out] BootMode Init the system boot mode +**/ +VOID +ParseOptions ( + IN VOID *Fdt, + IN INT32 Node, + OUT UINT8 *PciEnumDone, + OUT EFI_BOOT_MODE *BootMode + ) +{ + INT32 SubNode; + FDT_NODE_HEADER *NodePtr; + UNIVERSAL_PAYLOAD_BASE *PayloadBase; + CONST FDT_PROPERTY *PropertyPtr; + CONST CHAR8 *TempStr; + INT32 TempLen; + UINT32 *Data32; + UINT64 *Data64; + UINT64 StartAddress; + UINT8 SizeOfMemorySpace; + + for (SubNode = FdtFirstSubnode (Fdt, Node); SubNode >= 0; SubNode = FdtNextSubnode (Fdt, SubNode)) { + NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + SubNode + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct)); + DEBUG ((DEBUG_INFO, "\n SubNode(%08X) %a", SubNode, NodePtr->Name)); + + if (AsciiStrnCmp (NodePtr->Name, "upl-images@", AsciiStrLen ("upl-images@")) == 0) { + DEBUG ((DEBUG_INFO, " Found image@ node \n")); + // + // Build PayloadBase HOB . + // + PayloadBase = BuildGuidHob (&gUniversalPayloadBaseGuid, sizeof (UNIVERSAL_PAYLOAD_BASE)); + ASSERT (PayloadBase != NULL); + if (PayloadBase == NULL) { + return; + } + + PayloadBase->Header.Revision = UNIVERSAL_PAYLOAD_BASE_REVISION; + PayloadBase->Header.Length = sizeof (UNIVERSAL_PAYLOAD_BASE); + + PropertyPtr = FdtGetProperty (Fdt, SubNode, "addr", &TempLen); + + ASSERT (TempLen > 0); + if (TempLen > 0) { + Data64 = (UINT64 *)(PropertyPtr->Data); + StartAddress = Fdt64ToCpu (*Data64); + DEBUG ((DEBUG_INFO, "\n Property(00000000) entry")); + DEBUG ((DEBUG_INFO, " %016lX\n", StartAddress)); + + PayloadBase->Entry = (EFI_PHYSICAL_ADDRESS)StartAddress; + } + } + + if (AsciiStrnCmp (NodePtr->Name, "upl-params", AsciiStrLen ("upl-params")) == 0) { + PropertyPtr = FdtGetProperty (Fdt, SubNode, "addr-width", &TempLen); + if (TempLen > 0) { + Data32 = (UINT32 *)(PropertyPtr->Data); + DEBUG ((DEBUG_INFO, "\n Property(00000000) address_width")); + DEBUG ((DEBUG_INFO, " %X", Fdt32ToCpu (*Data32))); + SizeOfMemorySpace = (UINT8)Fdt32ToCpu (*Data32); + BuildCpuHob (SizeOfMemorySpace, PcdGet8 (SizeOfIoSpace)); + } + + PropertyPtr = FdtGetProperty (Fdt, SubNode, "pci-enum-done", &TempLen); + if (TempLen > 0) { + *PciEnumDone = 1; + DEBUG ((DEBUG_INFO, " Found PciEnumDone (%08X)\n", *PciEnumDone)); + } else { + *PciEnumDone = 0; + DEBUG ((DEBUG_INFO, " Not Found PciEnumDone \n")); + } + + PropertyPtr = FdtGetProperty (Fdt, SubNode, "boot-mode", &TempLen); + if (TempLen > 0) { + TempStr = (CHAR8 *)(PropertyPtr->Data); + if (AsciiStrCmp (TempStr, "normal") == 0) { + *BootMode = BOOT_WITH_FULL_CONFIGURATION; + } else if (AsciiStrCmp (TempStr, "fast") == 0) { + *BootMode = BOOT_WITH_MINIMAL_CONFIGURATION; + } else if (AsciiStrCmp (TempStr, "full") == 0) { + *BootMode = BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS; + } else if (AsciiStrCmp (TempStr, "default") == 0) { + *BootMode = BOOT_WITH_DEFAULT_SETTINGS; + } else if (AsciiStrCmp (TempStr, "s4") == 0) { + *BootMode = BOOT_ON_S4_RESUME; + } else if (AsciiStrCmp (TempStr, "s3") == 0) { + *BootMode = BOOT_ON_S3_RESUME; + } + } + } + } +} + +/** + It will Parsegraphic node from FDT. + + @param[in] Fdt Address of the Fdt data. + @param[in] SubNode first Sub node of the PCI root bridge node. +**/ +VOID +ParsegraphicNode ( + IN VOID *Fdt, + IN INT32 SubNode + ) +{ + EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *GraphicsDev; + CONST FDT_PROPERTY *PropertyPtr; + UINT16 GmaID; + UINT32 *Data32; + INT32 TempLen; + + DEBUG ((DEBUG_INFO, " Found gma@ node \n")); + GraphicsDev = NULL; + // + // Build Graphic info HOB . + // + GraphicsDev = BuildGuidHob (&gEfiGraphicsDeviceInfoHobGuid, sizeof (EFI_PEI_GRAPHICS_DEVICE_INFO_HOB)); + ASSERT (GraphicsDev != NULL); + if (GraphicsDev == NULL) { + return; + } + + SetMem (GraphicsDev, sizeof (EFI_PEI_GRAPHICS_DEVICE_INFO_HOB), 0xFF); + PropertyPtr = FdtGetProperty (Fdt, SubNode, "vendor-id", &TempLen); + ASSERT (TempLen > 0); + if (TempLen > 0) { + Data32 = (UINT32 *)(PropertyPtr->Data); + GmaID = (UINT16)Fdt32ToCpu (*Data32); + DEBUG ((DEBUG_INFO, "\n vendor-id")); + DEBUG ((DEBUG_INFO, " %016lX\n", GmaID)); + GraphicsDev->VendorId = GmaID; + } + + PropertyPtr = FdtGetProperty (Fdt, SubNode, "device-id", &TempLen); + ASSERT (TempLen > 0); + if (TempLen > 0) { + Data32 = (UINT32 *)(PropertyPtr->Data); + GmaID = (UINT16)Fdt32ToCpu (*Data32); + DEBUG ((DEBUG_INFO, "\n device-id")); + DEBUG ((DEBUG_INFO, " %016lX\n", GmaID)); + GraphicsDev->DeviceId = GmaID; + } + + PropertyPtr = FdtGetProperty (Fdt, SubNode, "revision-id", &TempLen); + ASSERT (TempLen > 0); + if (TempLen > 0) { + Data32 = (UINT32 *)(PropertyPtr->Data); + GmaID = (UINT16)Fdt32ToCpu (*Data32); + DEBUG ((DEBUG_INFO, "\n revision-id")); + DEBUG ((DEBUG_INFO, " %016lX\n", GmaID)); + GraphicsDev->RevisionId = (UINT8)GmaID; + } + + PropertyPtr = FdtGetProperty (Fdt, SubNode, "subsystem-vendor-id", &TempLen); + ASSERT (TempLen > 0); + if (TempLen > 0) { + Data32 = (UINT32 *)(PropertyPtr->Data); + GmaID = (UINT16)Fdt32ToCpu (*Data32); + DEBUG ((DEBUG_INFO, "\n subsystem-vendor-id")); + DEBUG ((DEBUG_INFO, " %016lX\n", GmaID)); + GraphicsDev->SubsystemVendorId = GmaID; + } + + PropertyPtr = FdtGetProperty (Fdt, SubNode, "subsystem-id", &TempLen); + ASSERT (TempLen > 0); + if (TempLen > 0) { + Data32 = (UINT32 *)(PropertyPtr->Data); + GmaID = (UINT16)Fdt32ToCpu (*Data32); + DEBUG ((DEBUG_INFO, "\n subsystem-id")); + DEBUG ((DEBUG_INFO, " %016lX\n", GmaID)); + GraphicsDev->SubsystemId = GmaID; + } +} + +/** + It will ParseSerialPort node from FDT. + + @param[in] Fdt Address of the Fdt data. + @param[in] SubNode first Sub node of the PCI root bridge node. +**/ +VOID +ParseSerialPort ( + IN VOID *Fdt, + IN INT32 SubNode + ) +{ + UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *Serial; + CONST FDT_PROPERTY *PropertyPtr; + INT32 TempLen; + CONST CHAR8 *TempStr; + UINT32 *Data32; + UINT32 Attribute; + + // + // Create SerialPortInfo HOB. + // + Serial = BuildGuidHob (&gUniversalPayloadSerialPortInfoGuid, sizeof (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO)); + ASSERT (Serial != NULL); + if (Serial == NULL) { + return; + } + + Serial->Header.Revision = UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO_REVISION; + Serial->Header.Length = sizeof (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO); + Serial->RegisterStride = 1; + Serial->UseMmio = 1; + + PropertyPtr = FdtGetProperty (Fdt, SubNode, "current-speed", &TempLen); + ASSERT (TempLen > 0); + if (TempLen > 0) { + Data32 = (UINT32 *)(PropertyPtr->Data); + DEBUG ((DEBUG_INFO, " %X", Fdt32ToCpu (*Data32))); + Serial->BaudRate = Fdt32ToCpu (*Data32); + } + + PropertyPtr = FdtGetProperty (Fdt, SubNode, "compatible", &TempLen); + TempStr = (CHAR8 *)(PropertyPtr->Data); + if (AsciiStrnCmp (TempStr, "isa", AsciiStrLen ("isa")) == 0) { + DEBUG ((DEBUG_INFO, " find serial compatible isa \n")); + Serial->UseMmio = 0; + PropertyPtr = FdtGetProperty (Fdt, SubNode, "reg", &TempLen); + ASSERT (TempLen > 0); + if (TempLen > 0) { + Data32 = (UINT32 *)(PropertyPtr->Data); + Attribute = Fdt32ToCpu (*(Data32 + 0)); + Serial->RegisterBase = Fdt32ToCpu (*(Data32 + 1)); + Serial->UseMmio = Attribute == 1 ? FALSE : TRUE; + DEBUG ((DEBUG_INFO, "\n in espi serial Property() %a", TempStr)); + DEBUG ((DEBUG_INFO, " StartAddress %016lX\n", Serial->RegisterBase)); + DEBUG ((DEBUG_INFO, " Attribute %016lX\n", Attribute)); + } + } else { + DEBUG ((DEBUG_INFO, " NOT serial compatible isa \n")); + PropertyPtr = FdtGetProperty (Fdt, SubNode, "reg", &TempLen); + ASSERT (TempLen > 0); + if (TempLen > 0) { + Data32 = (UINT32 *)(PropertyPtr->Data); + Serial->RegisterBase = Fdt32ToCpu (*Data32); + } + } +} + +/** + It will ParsePciRootBridge node from FDT. + + @param[in] Fdt Address of the Fdt data. + @param[in] Node first node of the Fdt data. + @param[in] PciEnumDone To use ParsePciRootBridge node. + @param[in] RootBridgeCount Number of pci RootBridge. + @param[in] GmaStr Graphic device node name string. + @param[in] index Index of ParsePciRootBridge node. +**/ +VOID +ParsePciRootBridge ( + IN VOID *Fdt, + IN INT32 Node, + IN UINT8 PciEnumDone, + IN UINT8 RootBridgeCount, + IN CHAR8 *GmaStr, + IN UINT8 *index + ) +{ + INT32 SubNode; + INT32 Property; + INT32 SSubNode; + FDT_NODE_HEADER *NodePtr; + CONST FDT_PROPERTY *PropertyPtr; + INT32 TempLen; + UINT32 *Data32; + UINT32 MemType; + CONST CHAR8 *TempStr; + UINT8 RbIndex; + UINTN HobDataSize; + UINT8 Base; + + RbIndex = *index; + HobDataSize = sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES) + RootBridgeCount *sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE); + // + // Create PCI Root Bridge Info Hob. + // + if (mPciRootBridgeInfo == NULL) { + mPciRootBridgeInfo = BuildGuidHob (&gUniversalPayloadPciRootBridgeInfoGuid, HobDataSize); + ASSERT (mPciRootBridgeInfo != NULL); + if (mPciRootBridgeInfo == NULL) { + return; + } + + ZeroMem (mPciRootBridgeInfo, HobDataSize); + mPciRootBridgeInfo->Header.Length = sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES); + mPciRootBridgeInfo->Header.Revision = UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION; + mPciRootBridgeInfo->Count = RootBridgeCount; + mPciRootBridgeInfo->ResourceAssigned = (BOOLEAN)PciEnumDone; + } + + for (SubNode = FdtFirstSubnode (Fdt, Node); SubNode >= 0; SubNode = FdtNextSubnode (Fdt, SubNode)) { + NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + SubNode + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct)); + DEBUG ((DEBUG_INFO, "\n SubNode(%08X) %a", SubNode, NodePtr->Name)); + + if (AsciiStrnCmp (NodePtr->Name, GmaStr, AsciiStrLen (GmaStr)) == 0) { + DEBUG ((DEBUG_INFO, " Found gma@ node \n")); + ParsegraphicNode (Fdt, SubNode); + } + + if (AsciiStrnCmp (NodePtr->Name, "isa", AsciiStrLen ("isa")) == 0) { + SSubNode = FdtFirstSubnode (Fdt, SubNode); // serial + ParseSerialPort (Fdt, SSubNode); + } + + if (AsciiStrnCmp (NodePtr->Name, "serial@", AsciiStrLen ("serial@")) == 0) { + ParseSerialPort (Fdt, SubNode); + } + } + + DEBUG ((DEBUG_INFO, " RbIndex :%x \n", RbIndex)); + + for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property = FdtNextPropertyOffset (Fdt, Property)) { + PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen); + TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset), NULL); + + if (AsciiStrCmp (TempStr, "ranges") == 0) { + DEBUG ((DEBUG_INFO, " Found ranges Property TempLen (%08X), limit %x\n", TempLen, TempLen/sizeof (UINT32))); + + mPciRootBridgeInfo->RootBridge[RbIndex].AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | EFI_PCI_HOST_BRIDGE_MEM64_DECODE; + mPciRootBridgeInfo->RootBridge[RbIndex].Supports = ROOT_BRIDGE_SUPPORTS_DEFAULT; + mPciRootBridgeInfo->RootBridge[RbIndex].PMemAbove4G.Base = PcdGet64 (PcdPciReservedPMemAbove4GBBase); + mPciRootBridgeInfo->RootBridge[RbIndex].PMemAbove4G.Limit = PcdGet64 (PcdPciReservedPMemAbove4GBLimit); + mPciRootBridgeInfo->RootBridge[RbIndex].PMem.Base = PcdGet32 (PcdPciReservedPMemBase); + mPciRootBridgeInfo->RootBridge[RbIndex].PMem.Limit = PcdGet32 (PcdPciReservedPMemLimit); + mPciRootBridgeInfo->RootBridge[RbIndex].UID = RbIndex; + mPciRootBridgeInfo->RootBridge[RbIndex].HID = EISA_PNP_ID (0x0A03); + + Data32 = (UINT32 *)(PropertyPtr->Data); + for (Base = 0; Base < TempLen/sizeof (UINT32); Base = Base + DWORDS_TO_NEXT_ADDR_TYPE) { + DEBUG ((DEBUG_INFO, " Base :%x \n", Base)); + MemType = Fdt32ToCpu (*(Data32 + Base)); + if (((MemType) & (SS_64BIT_MEMORY_SPACE)) == SS_64BIT_MEMORY_SPACE) { + DEBUG ((DEBUG_INFO, " To program 64 mm \n")); + mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Base = Fdt32ToCpu (*(Data32 + Base + 2)) + LShiftU64 (Fdt32ToCpu (*(Data32 + Base + 1)), 32); + mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Base + LShiftU64 (Fdt32ToCpu (*(Data32 + Base + 5)), 32) + Fdt32ToCpu (*(Data32 + Base + 6)) -1; + } else if (((MemType) & (SS_32BIT_MEMORY_SPACE)) == SS_32BIT_MEMORY_SPACE) { + DEBUG ((DEBUG_INFO, " To program 32 mem \n")); + mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Base = Fdt32ToCpu (*(Data32 + Base + 2)); + mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Base + Fdt32ToCpu (*(Data32 + Base + 6)) -1; + } else if (((MemType) & (SS_IO_SPACE)) == SS_IO_SPACE) { + DEBUG ((DEBUG_INFO, " To program Io\n")); + mPciRootBridgeInfo->RootBridge[RbIndex].Io.Base = Fdt32ToCpu (*(Data32 + Base + 2)); + mPciRootBridgeInfo->RootBridge[RbIndex].Io.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].Io.Base + Fdt32ToCpu (*(Data32 + Base + 6)) -1; + } + } + + DEBUG ((DEBUG_INFO, "RootBridgeCount %x, index :%x\n", RootBridgeCount, RbIndex)); + + DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base %x, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Base)); + DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.limit %x, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Limit)); + + DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Base)); + DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.limit %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Limit)); + + DEBUG ((DEBUG_INFO, "PciRootBridge->Io.Base %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Io.Base)); + DEBUG ((DEBUG_INFO, "PciRootBridge->Io.limit %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Io.Limit)); + } + + if (AsciiStrCmp (TempStr, "bus-range") == 0) { + DEBUG ((DEBUG_INFO, " Found bus-range Property TempLen (%08X)\n", TempLen)); + + Data32 = (UINT32 *)(PropertyPtr->Data); + mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Base = Fdt32ToCpu (*Data32) & 0xFF; + mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Limit = Fdt32ToCpu (*(Data32 + 1)) & 0xFF; + mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Translation = 0; + + DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.Base %x, index %x\n", mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Base, RbIndex)); + DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.limit %x, index %x\n", mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Limit, RbIndex)); + } + } + + if (RbIndex > 0) { + RbIndex--; + } + + DEBUG ((DEBUG_INFO, "After updated RbIndex :%x \n", RbIndex)); + *index = RbIndex; +} + +/** + It will parse FDT based on DTB from bootloaders. + + @param[in] FdtBase Address of the Fdt data. + + @return The address to the new hob list +**/ +UINTN +EFIAPI +ParseDtb ( + IN VOID *FdtBase + ) +{ + VOID *Fdt; + INT32 Node; + INT32 Property; + INT32 Depth; + FDT_NODE_HEADER *NodePtr; + CONST FDT_PROPERTY *PropertyPtr; + CONST CHAR8 *TempStr; + INT32 TempLen; + UINT64 *Data64; + UINT64 StartAddress; + UINT64 NumberOfBytes; + UINTN MinimalNeededSize; + EFI_PHYSICAL_ADDRESS FreeMemoryBottom; + EFI_PHYSICAL_ADDRESS FreeMemoryTop; + EFI_PHYSICAL_ADDRESS MemoryBottom; + EFI_PHYSICAL_ADDRESS MemoryTop; + BOOLEAN IsHobConstructed; + UINTN NewHobList; + UINT8 RootBridgeCount; + UINT8 index; + UINTN HobDataSize; + UINT8 PciEnumDone; + UINT8 NodeType; + EFI_BOOT_MODE BootMode; + CHAR8 *GmaStr; + + Fdt = FdtBase; + Depth = 0; + MinimalNeededSize = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize); + IsHobConstructed = FALSE; + NewHobList = 0; + RootBridgeCount = 0; + index = 0; + HobDataSize = 0; + PciEnumDone = 0; + BootMode = 0; + NodeType = 0; + + DEBUG ((DEBUG_INFO, "FDT = 0x%x %x\n", Fdt, Fdt32ToCpu (*((UINT32 *)Fdt)))); + DEBUG ((DEBUG_INFO, "Start parsing DTB data\n")); + DEBUG ((DEBUG_INFO, "MinimalNeededSize :%x\n", MinimalNeededSize)); + + for (Node = FdtNextNode (Fdt, 0, &Depth); Node >= 0; Node = FdtNextNode (Fdt, Node, &Depth)) { + NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + Node + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct)); + DEBUG ((DEBUG_INFO, "\n Node(%08x) %a Depth %x", Node, NodePtr->Name, Depth)); + // memory node + if (AsciiStrnCmp (NodePtr->Name, "memory@", AsciiStrLen ("memory@")) == 0) { + for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property = FdtNextPropertyOffset (Fdt, Property)) { + PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen); + TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset), NULL); + if (AsciiStrCmp (TempStr, "reg") == 0) { + Data64 = (UINT64 *)(PropertyPtr->Data); + StartAddress = Fdt64ToCpu (*Data64); + NumberOfBytes = Fdt64ToCpu (*(Data64 + 1)); + DEBUG ((DEBUG_INFO, "\n Property(%08X) %a", Property, TempStr)); + DEBUG ((DEBUG_INFO, " %016lX %016lX", StartAddress, NumberOfBytes)); + if (!IsHobConstructed) { + if ((NumberOfBytes > MinimalNeededSize) && (StartAddress < BASE_4GB)) { + MemoryBottom = StartAddress + NumberOfBytes - MinimalNeededSize; + FreeMemoryBottom = MemoryBottom; + FreeMemoryTop = StartAddress + NumberOfBytes; + MemoryTop = FreeMemoryTop; + + DEBUG ((DEBUG_INFO, "MemoryBottom :0x%llx\n", MemoryBottom)); + DEBUG ((DEBUG_INFO, "FreeMemoryBottom :0x%llx\n", FreeMemoryBottom)); + DEBUG ((DEBUG_INFO, "FreeMemoryTop :0x%llx\n", FreeMemoryTop)); + DEBUG ((DEBUG_INFO, "MemoryTop :0x%llx\n", MemoryTop)); + mHobList = HobConstructor ((VOID *)(UINTN)MemoryBottom, (VOID *)(UINTN)MemoryTop, (VOID *)(UINTN)FreeMemoryBottom, (VOID *)(UINTN)FreeMemoryTop); + IsHobConstructed = TRUE; + NewHobList = (UINTN)mHobList; + break; + } + } + } + } + } // end of memory node + else { + PropertyPtr = FdtGetProperty (Fdt, Node, "compatible", &TempLen); + TempStr = (CHAR8 *)(PropertyPtr->Data); + if (AsciiStrnCmp (TempStr, "pci-rb", AsciiStrLen ("pci-rb")) == 0) { + RootBridgeCount++; + } + } + } + + index = RootBridgeCount - 1; + Depth = 0; + for (Node = FdtNextNode (Fdt, 0, &Depth); Node >= 0; Node = FdtNextNode (Fdt, Node, &Depth)) { + NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + Node + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct)); + DEBUG ((DEBUG_INFO, "\n Node(%08x) %a Depth %x", Node, NodePtr->Name, Depth)); + + NodeType = CheckNodeType (NodePtr->Name, Depth); + DEBUG ((DEBUG_INFO, "NodeType :0x%x\n", NodeType)); + switch (NodeType) { + case ReservedMemory: + DEBUG ((DEBUG_INFO, "ParseReservedMemory\n")); + ParseReservedMemory (Fdt, Node); + break; + case Memory: + DEBUG ((DEBUG_INFO, "ParseMemory\n")); + if (!CheckMemoryNodeIfInit (Node)) { + ParseMemory (Fdt, Node); + } else { + DEBUG ((DEBUG_INFO, "Memory has initialized\n")); + } + + break; + case FrameBuffer: + DEBUG ((DEBUG_INFO, "ParseFrameBuffer\n")); + GmaStr = ParseFrameBuffer (Fdt, Node); + break; + case PciRootBridge: + DEBUG ((DEBUG_INFO, "ParsePciRootBridge, index :%x\n", index)); + ParsePciRootBridge (Fdt, Node, PciEnumDone, RootBridgeCount, GmaStr, &index); + DEBUG ((DEBUG_INFO, "After ParsePciRootBridge, index :%x\n", index)); + break; + case Options: + DEBUG ((DEBUG_INFO, "ParseOptions\n")); + ParseOptions (Fdt, Node, &PciEnumDone, &BootMode); + break; + default: + DEBUG ((DEBUG_INFO, "ParseNothing\n")); + break; + } + } + + ((EFI_HOB_HANDOFF_INFO_TABLE *)(mHobList))->BootMode = BootMode; + DEBUG ((DEBUG_INFO, "\n")); + + return NewHobList; +} + +/** + It will Parse FDT -node based on information from bootloaders. + @param[in] FdtBase The starting memory address of FdtBase + @retval HobList The base address of Hoblist. + +**/ +UINTN +EFIAPI +FdtNodeParser ( + IN VOID *FdtBase + ) +{ + return ParseDtb (FdtBase); +} + +/** + It will initialize HOBs for UPL. + + @param[in] FdtBase Address of the Fdt data. + + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to initialize HOBs. +**/ +UINTN +EFIAPI +UplInitHob ( + IN VOID *FdtBase + ) +{ + UINTN NHobAddress; + + NHobAddress = 0; + // + // Check parameter type( + // + if (FdtCheckHeader (FdtBase) == 0) { + DEBUG ((DEBUG_INFO, "%a() FDT blob\n", __func__)); + NHobAddress = FdtNodeParser ((VOID *)FdtBase); + } else { + DEBUG ((DEBUG_INFO, "%a() HOb list\n", __func__)); + mHobList = FdtBase; + + return (UINTN)(mHobList); + } + + return NHobAddress; +} diff --git a/UefiPayloadPkg/Library/HobParseLib/HobParseLib.c b/UefiPayloadPkg/Library/HobParseLib/HobParseLib.c new file mode 100644 index 000000000000..98a5dcfeae61 --- /dev/null +++ b/UefiPayloadPkg/Library/HobParseLib/HobParseLib.c @@ -0,0 +1,280 @@ +/** @file + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ + EFI_RESOURCE_ATTRIBUTE_TESTED | \ + EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED | \ + EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED | \ + EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED | \ + EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED | \ + EFI_RESOURCE_ATTRIBUTE_16_BIT_IO | \ + EFI_RESOURCE_ATTRIBUTE_32_BIT_IO | \ + EFI_RESOURCE_ATTRIBUTE_64_BIT_IO | \ + EFI_RESOURCE_ATTRIBUTE_PERSISTENT ) + +#define TESTED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ + EFI_RESOURCE_ATTRIBUTE_TESTED ) + +extern VOID *mHobList; + +/** + Add a new HOB to the HOB List. + + @param HobType Type of the new HOB. + @param HobLength Length of the new HOB to allocate. + + @return NULL if there is no space to create a hob. + @return The address point to the new created hob. + +**/ +VOID * +EFIAPI +CreateHob ( + IN UINT16 HobType, + IN UINT16 HobLength + ); + +/** + Build a Handoff Information Table HOB + + This function initialize a HOB region from EfiMemoryBegin to + EfiMemoryTop. And EfiFreeMemoryBottom and EfiFreeMemoryTop should + be inside the HOB region. + + @param[in] EfiMemoryBottom Total memory start address + @param[in] EfiMemoryTop Total memory end address. + @param[in] EfiFreeMemoryBottom Free memory start address + @param[in] EfiFreeMemoryTop Free memory end address. + + @return The pointer to the handoff HOB table. + +**/ +EFI_HOB_HANDOFF_INFO_TABLE * +EFIAPI +HobConstructor ( + IN VOID *EfiMemoryBottom, + IN VOID *EfiMemoryTop, + IN VOID *EfiFreeMemoryBottom, + IN VOID *EfiFreeMemoryTop + ); + +/** + Build ACPI board info HOB using infomation from ACPI table + + @param AcpiTableBase ACPI table start address in memory + + @retval A pointer to ACPI board HOB ACPI_BOARD_INFO. Null if build HOB failure. +**/ +ACPI_BOARD_INFO * +BuildHobFromAcpi ( + IN UINT64 AcpiTableBase + ); + +/** + * + Add HOB into HOB list + + @param[in] Hob The HOB to be added into the HOB list. +**/ +VOID +AddNewHob ( + IN EFI_PEI_HOB_POINTERS *Hob + ) +{ + EFI_PEI_HOB_POINTERS NewHob; + + if (Hob->Raw == NULL) { + return; + } + + NewHob.Header = CreateHob (Hob->Header->HobType, Hob->Header->HobLength); + + if (NewHob.Header != NULL) { + CopyMem (NewHob.Header + 1, Hob->Header + 1, Hob->Header->HobLength - sizeof (EFI_HOB_GENERIC_HEADER)); + } +} + +/** + Found the Resource Descriptor HOB that contains a range (Base, Top) + + @param[in] HobList Hob start address + @param[in] Base Memory start address + @param[in] Top Memory end address. + + @retval The pointer to the Resource Descriptor HOB. +**/ +EFI_HOB_RESOURCE_DESCRIPTOR * +FindResourceDescriptorByRange ( + IN VOID *HobList, + IN EFI_PHYSICAL_ADDRESS Base, + IN EFI_PHYSICAL_ADDRESS Top + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; + + for (Hob.Raw = (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { + // + // Skip all HOBs except Resource Descriptor HOBs + // + if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + continue; + } + + // + // Skip Resource Descriptor HOBs that do not describe tested system memory + // + ResourceHob = Hob.ResourceDescriptor; + if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) { + continue; + } + + if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) { + continue; + } + + // + // Skip Resource Descriptor HOBs that do not contain the PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop + // + if (Base < ResourceHob->PhysicalStart) { + continue; + } + + if (Top > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) { + continue; + } + + return ResourceHob; + } + + return NULL; +} + +/** + Find the highest below 4G memory resource descriptor, except the input Resource Descriptor. + + @param[in] HobList Hob start address + @param[in] MinimalNeededSize Minimal needed size. + @param[in] ExceptResourceHob Ignore this Resource Descriptor. + + @retval The pointer to the Resource Descriptor HOB. +**/ +EFI_HOB_RESOURCE_DESCRIPTOR * +FindAnotherHighestBelow4GResourceDescriptor ( + IN VOID *HobList, + IN UINTN MinimalNeededSize, + IN EFI_HOB_RESOURCE_DESCRIPTOR *ExceptResourceHob + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; + EFI_HOB_RESOURCE_DESCRIPTOR *ReturnResourceHob; + + ReturnResourceHob = NULL; + + for (Hob.Raw = (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { + // + // Skip all HOBs except Resource Descriptor HOBs + // + if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + continue; + } + + // + // Skip Resource Descriptor HOBs that do not describe tested system memory + // + ResourceHob = Hob.ResourceDescriptor; + if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) { + continue; + } + + if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) { + continue; + } + + // + // Skip if the Resource Descriptor HOB equals to ExceptResourceHob + // + if (ResourceHob == ExceptResourceHob) { + continue; + } + + // + // Skip Resource Descriptor HOBs that are beyond 4G + // + if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > BASE_4GB) { + continue; + } + + // + // Skip Resource Descriptor HOBs that are too small + // + if (ResourceHob->ResourceLength < MinimalNeededSize) { + continue; + } + + // + // Return the topest Resource Descriptor + // + if (ReturnResourceHob == NULL) { + ReturnResourceHob = ResourceHob; + } else { + if (ReturnResourceHob->PhysicalStart < ResourceHob->PhysicalStart) { + ReturnResourceHob = ResourceHob; + } + } + } + + return ReturnResourceHob; +} + +/** + Check the HOB and decide if it is need inside Payload + + Payload maintainer may make decision which HOB is need or needn't + Then add the check logic in the function. + + @param[in] Hob The HOB to check + + @retval TRUE If HOB is need inside Payload + @retval FALSE If HOB is needn't inside Payload +**/ +BOOLEAN +IsHobNeed ( + EFI_PEI_HOB_POINTERS Hob + ) +{ + if (Hob.Header->HobType == EFI_HOB_TYPE_HANDOFF) { + return FALSE; + } + + if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) { + if (CompareGuid (&Hob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) { + return FALSE; + } + } + + // Arrive here mean the HOB is need + return TRUE; +} diff --git a/UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf b/UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf new file mode 100644 index 000000000000..634c7ff56746 --- /dev/null +++ b/UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf @@ -0,0 +1,40 @@ +## @file +# UPL Hob Parse Library. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = HobParseLib + FILE_GUID = EFB05FE7-604B-40DA-9A59-E2F998528754 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = HobParseLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + HobParseLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + IoLib + DebugLib + PcdLib + HobLib + +[Pcd.IA32,Pcd.X64] + gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize + gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index e94a7db886f7..6199527a9a38 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -318,6 +318,7 @@ FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf SmmRelocationLib|UefiCpuPkg/Library/SmmRelocationLib/SmmRelocationLib.inf HobPrintLib|MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf + BuildFdtLib|UefiPayloadPkg/Library/BuildFdtLib/BuildFdtLib.inf [LibraryClasses.common] !if $(BOOTSPLASH_IMAGE) From 0c4d6bb405351d1705fdbbddfd7ccde6f3fe0516 Mon Sep 17 00:00:00 2001 From: Linus Liu Date: Wed, 21 Aug 2024 02:06:00 -0700 Subject: [PATCH 014/280] UefiPayloadPkg: Update PayloadLoader to suport FDT. REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4786 Create FDT nodes (reserved-memory, serial, pci-rb, options) in FdtPpiNotifyCallback function right after gEfiEndOfPeiSignalPpiGuid. Signed-off-by: Linus Liu --- .../PayloadLoaderPeim/FitPayloadLoaderPeim.c | 248 ++++++++++- .../FitPayloadLoaderPeim.inf | 13 +- .../PayloadLoaderPeim/PayloadLoaderPeim.c | 71 ++- .../PayloadLoaderPeim/PayloadLoaderPeim.inf | 12 + .../UefiPayloadEntry/Ia32/DxeLoadFuncFit.c | 405 ++++++++++++++++++ .../UefiPayloadEntry/X64/DxeLoadFuncFit.c | 135 ++++++ 6 files changed, 855 insertions(+), 29 deletions(-) create mode 100644 UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFuncFit.c create mode 100644 UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFuncFit.c diff --git a/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c b/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c index 856661851120..d659b7547433 100644 --- a/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c +++ b/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c @@ -6,18 +6,34 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include +#include #include #include - +#include #include - +#include +#include #include #include -#include #include #include - +#include +#include +#include #include "FitLib.h" +#define STACK_SIZE 0x20000 + +CONST EFI_PEI_PPI_DESCRIPTOR gReadyToPayloadSignalPpi = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gUplReadyToPayloadPpiGuid, + NULL +}; + +EFI_PEI_PPI_DESCRIPTOR mEndOfPeiSignalPpi = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + NULL +}; /** The wrapper function of PeiLoadImageLoadImage(). @@ -50,6 +66,15 @@ PeiLoadFileLoadPayload ( UINTN Delta; UINTN Index; + #if (FixedPcdGetBool (PcdHandOffFdtEnable)) + VOID *BaseOfStack; + VOID *TopOfStack; + UNIVERSAL_PAYLOAD_DEVICE_TREE *Fdt; + VOID *Hob; + + Fdt = NULL; + #endif + Instance = 0; do { Status = PeiServicesFfsFindSectionData3 (EFI_SECTION_RAW, Instance++, FileHandle, &Binary, AuthenticationState); @@ -66,13 +91,15 @@ PeiLoadFileLoadPayload ( return Status; } - DEBUG (( - DEBUG_INFO, - "Before Rebase Payload File Base: 0x%08x, File Size: 0x%08X, EntryPoint: 0x%08x\n", - Context.PayloadBaseAddress, - Context.PayloadSize, - Context.PayloadEntryPoint - )); + DEBUG ( + ( + DEBUG_INFO, + "Before Rebase Payload File Base: 0x%08x, File Size: 0x%08X, EntryPoint: 0x%08x\n", + Context.PayloadBaseAddress, + Context.PayloadSize, + Context.PayloadEntryPoint + ) + ); Context.PayloadBaseAddress = (EFI_PHYSICAL_ADDRESS)AllocatePages (EFI_SIZE_TO_PAGES (Context.PayloadSize)); RelocateTable = (FIT_RELOCATE_ITEM *)(UINTN)(Context.PayloadBaseAddress + Context.RelocateTableOffset); @@ -96,13 +123,15 @@ PeiLoadFileLoadPayload ( } } - DEBUG (( - DEBUG_INFO, - "After Rebase Payload File Base: 0x%08x, File Size: 0x%08X, EntryPoint: 0x%08x\n", - Context.PayloadBaseAddress, - Context.PayloadSize, - Context.PayloadEntryPoint - )); + DEBUG ( + ( + DEBUG_INFO, + "After Rebase Payload File Base: 0x%08x, File Size: 0x%08X, EntryPoint: 0x%08x\n", + Context.PayloadBaseAddress, + Context.PayloadSize, + Context.PayloadEntryPoint + ) + ); Length = sizeof (UNIVERSAL_PAYLOAD_BASE); PayloadBase = BuildGuidHob ( @@ -115,6 +144,42 @@ PeiLoadFileLoadPayload ( *ImageSizeArg = Context.PayloadSize; *EntryPoint = Context.PayloadEntryPoint; + Status = PeiServicesInstallPpi (&mEndOfPeiSignalPpi); + ASSERT_EFI_ERROR (Status); + + Status = PeiServicesInstallPpi (&gReadyToPayloadSignalPpi); + ASSERT_EFI_ERROR (Status); + + #if (FixedPcdGetBool (PcdHandOffFdtEnable)) + Hob = GetFirstGuidHob (&gUniversalPayloadDeviceTreeGuid); + if (Hob != NULL) { + Fdt = (UNIVERSAL_PAYLOAD_DEVICE_TREE *)GET_GUID_HOB_DATA (Hob); + } + + // + // Allocate 128KB for the Stack + // + BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE)); + ASSERT (BaseOfStack != NULL); + + // + // Compute the top of the stack we were allocated. Pre-allocate a UINTN + // for safety. + // + TopOfStack = (VOID *)((UINTN)BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + // + // Transfer the control to the entry point of UniveralPayloadEntry. + // + SwitchStack ( + (SWITCH_STACK_ENTRY_POINT)(UINTN)Context.PayloadEntryPoint, + (VOID *)(Fdt->DeviceTreeAddress), + NULL, + TopOfStack + ); + #endif + return EFI_SUCCESS; } @@ -128,11 +193,148 @@ EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = { &mPeiLoadFilePpi }; +#if (FixedPcdGetBool (PcdHandOffFdtEnable)) + +/** + Discover Hobs data and report data into a FDT. + @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param[in] NotifyDescriptor Address of the notification descriptor data structure. + @param[in] Ppi Address of the PPI that was installed. + @retval EFI_SUCCESS Hobs data is discovered. + @return Others No Hobs data is discovered. +**/ +EFI_STATUS +EFIAPI +FdtPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +EFI_PEI_NOTIFY_DESCRIPTOR mReadyToPayloadNotifyList[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gUplReadyToPayloadPpiGuid, + FdtPpiNotifyCallback + } +}; +#endif + +/** + Print FDT data. + @param[in] FdtBase Address of the Fdt data. +**/ +VOID +PrintFdt ( + IN VOID *FdtBase + ) +{ + UINT8 *Fdt; + UINT32 i; + + Fdt = NULL; + i = 0; + + DEBUG ((DEBUG_ERROR, "FDT DTB data:")); + for (Fdt = FdtBase, i = 0; i < Fdt32ToCpu (((FDT_HEADER *)FdtBase)->TotalSize); i++, Fdt++) { + if (i % 16 == 0) { + DEBUG ((DEBUG_ERROR, "\n")); + } + + DEBUG ((DEBUG_ERROR, "%02x ", *Fdt)); + } + + DEBUG ((DEBUG_ERROR, "\n")); +} + +/** + It will build FDT for UPL consumed. + @param[in] FdtBase Address of the Fdt data. + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to build required FDT. +**/ +EFI_STATUS +BuildFdtForUPL ( + IN VOID *FdtBase + ); + +#if (FixedPcdGetBool (PcdHandOffFdtEnable)) + +/** + Discover Hobs data and report data into a FDT. + @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param[in] NotifyDescriptor Address of the notification descriptor data structure. + @param[in] Ppi Address of the PPI that was installed. + @retval EFI_SUCCESS Hobs data is discovered. + @return Others No Hobs data is discovered. +**/ +EFI_STATUS +EFIAPI +FdtPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_STATUS Status; + UNIVERSAL_PAYLOAD_DEVICE_TREE *Fdt; + UINT32 FdtSize; + UINTN FdtPages; + VOID *FdtBase; + UINT32 Data32; + + Fdt = NULL; + FdtSize = PcdGet8 (PcdFDTPageSize) * EFI_PAGE_SIZE; + FdtPages = EFI_SIZE_TO_PAGES (FdtSize); + FdtBase = AllocatePages (FdtPages); + if (FdtBase == NULL) { + DEBUG ((DEBUG_ERROR, "%a: AllocatePages failed\n", __func__)); + return EFI_NOT_FOUND; + } + + Status = FdtCreateEmptyTree (FdtBase, (UINT32)FdtSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: cannot create FDT\n", __func__)); + } + + // Set cell property of root node + Data32 = CpuToFdt32 (2); + Status = FdtSetProp (FdtBase, 0, "#address-cells", &Data32, sizeof (UINT32)); + Status = FdtSetProp (FdtBase, 0, "#size-cells", &Data32, sizeof (UINT32)); + + Status = BuildFdtForUPL (FdtBase); + ASSERT_EFI_ERROR (Status); + + PrintFdt (FdtBase); + + Fdt = BuildGuidHob (&gUniversalPayloadDeviceTreeGuid, sizeof (UNIVERSAL_PAYLOAD_DEVICE_TREE)); + if (Fdt == NULL) { + DEBUG ((DEBUG_ERROR, "%a: Build FDT Hob failed\n", __func__)); + return EFI_NOT_FOUND; + } + + DEBUG (( + DEBUG_ERROR, + "%a: fdt at 0x%x (size %d)\n", + __func__, + FdtBase, + Fdt32ToCpu (((FDT_HEADER *)FdtBase)->TotalSize) + )); + + Fdt->Header.Revision = UNIVERSAL_PAYLOAD_DEVICE_TREE_REVISION; + Fdt->Header.Length = sizeof (UNIVERSAL_PAYLOAD_DEVICE_TREE); + Fdt->DeviceTreeAddress = (UINT64)FdtBase; + + return Status; +} + +#endif + /** Install Pei Load File PPI. @param FileHandle Handle of the file being invoked. @param PeiServices Describes the list of possible PEI Services. - @retval EFI_SUCCESS The entry point executes successfully. + @retval EFI_SUCESS The entry point executes successfully. @retval Others Some error occurs during the execution of this function. **/ EFI_STATUS @@ -146,5 +348,13 @@ InitializeFitPayloadLoaderPeim ( Status = PeiServicesInstallPpi (&gPpiLoadFilePpiList); + #if (FixedPcdGetBool (PcdHandOffFdtEnable)) + + // + // Build FDT in end of PEI notify callback. + // + Status = PeiServicesNotifyPpi (&mReadyToPayloadNotifyList[0]); + ASSERT_EFI_ERROR (Status); + #endif return Status; } diff --git a/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.inf b/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.inf index cd0cb186e138..b891706b772d 100644 --- a/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.inf +++ b/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.inf @@ -35,7 +35,6 @@ [LibraryClasses] PcdLib - MemoryAllocationLib BaseMemoryLib PeiServicesLib HobLib @@ -43,17 +42,27 @@ PeimEntryPoint DebugLib FdtLib +##for testing, remove this for HandOffFdtEnable == FALSE scenario: BuildFdtLib +##Hook this lib to FitPayloadLoaderPeim.inf in platform DSC when HandOffFdtEnable == TRUE. [Ppis] gEfiPeiLoadFilePpiGuid ## PRODUCES + gUplReadyToPayloadPpiGuid ## PRODUCES + gEfiEndOfPeiSignalPpiGuid ## CONSUMES [Pcd] gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister gPcAtChipsetPkgTokenSpaceGuid.PcdRtcTargetRegister + gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable + gUefiPayloadPkgTokenSpaceGuid.PcdFDTPageSize [Guids] - gUniversalPayloadExtraDataGuid ## PRODUCES gUniversalPayloadBaseGuid ## PRODUCES + gUniversalPayloadDeviceTreeGuid ## CONSUMES + gEfiGraphicsInfoHobGuid ## CONSUMES + gUniversalPayloadPciRootBridgeInfoGuid ## CONSUMES + gUniversalPayloadAcpiTableGuid ## CONSUMES + gUniversalPayloadSerialPortParentDeviceInfoGuid [Depex] TRUE diff --git a/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c b/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c index 219a86cfbc63..cdb7c1abf2b0 100644 --- a/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c +++ b/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c @@ -17,9 +17,49 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include - +#include #include "ElfLib.h" +CONST EFI_PEI_PPI_DESCRIPTOR gReadyToPayloadSignalPpi = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gUplReadyToPayloadPpiGuid, + NULL +}; + +/** + Notify ReadyToPayLoad signal. + @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param[in] NotifyDescriptor Address of the notification descriptor data structure. + @param[in] Ppi Address of the PPI that was installed. + @retval EFI_SUCCESS Hobs data is discovered. + @return Others No Hobs data is discovered. +**/ +EFI_STATUS +EFIAPI +EndOfPeiPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_STATUS Status; + + // + // Ready to Payload phase signal + // + Status = PeiServicesInstallPpi (&gReadyToPayloadSignalPpi); + + return Status; +} + +EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiNotifyList[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + EndOfPeiPpiNotifyCallback + } +}; + /** The wrapper function of PeiLoadImageLoadImage(). @@ -47,6 +87,7 @@ PeiLoadFileLoadPayload ( EFI_STATUS Status; VOID *Elf; UNIVERSAL_PAYLOAD_EXTRA_DATA *ExtraData; + UNIVERSAL_PAYLOAD_BASE *PayloadBase; ELF_IMAGE_CONTEXT Context; UINT32 Index; UINT16 ExtraDataIndex; @@ -73,13 +114,22 @@ PeiLoadFileLoadPayload ( Status = ParseElfImage (Elf, &Context); } while (EFI_ERROR (Status)); - DEBUG (( - DEBUG_INFO, - "Payload File Size: 0x%08X, Mem Size: 0x%08x, Reload: %d\n", - Context.FileSize, - Context.ImageSize, - Context.ReloadRequired - )); + Length = sizeof (UNIVERSAL_PAYLOAD_BASE); + PayloadBase = BuildGuidHob ( + &gUniversalPayloadBaseGuid, + Length + ); + PayloadBase->Entry = (EFI_PHYSICAL_ADDRESS)Context.FileBase; + + DEBUG ( + ( + DEBUG_INFO, + "Payload File Size: 0x%08X, Mem Size: 0x%08x, Reload: %d\n", + Context.FileSize, + Context.ImageSize, + Context.ReloadRequired + ) + ); // // Get UNIVERSAL_PAYLOAD_INFO_HEADER and number of additional PLD sections. @@ -153,6 +203,11 @@ PeiLoadFileLoadPayload ( *ImageSizeArg = Context.ImageSize; } + DEBUG ((DEBUG_INFO, "LoadElfImage :%r, EntryPoint :%x\n", Status, (UINTN)Context.EntryPoint)); + + Status = PeiServicesNotifyPpi (&mEndOfPeiNotifyList[0]); + ASSERT_EFI_ERROR (Status); + return Status; } diff --git a/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.inf b/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.inf index 06e83dbadce0..8db026eaa1b8 100644 --- a/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.inf +++ b/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.inf @@ -52,6 +52,8 @@ [Ppis] gEfiPeiLoadFilePpiGuid ## PRODUCES + gEfiEndOfPeiSignalPpiGuid ## CONSUMES + gUplReadyToPayloadPpiGuid ## PRODUCES [Pcd] gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister @@ -59,6 +61,16 @@ [Guids] gUniversalPayloadExtraDataGuid ## PRODUCES + gUniversalPayloadBaseGuid ## PRODUCES [Depex] TRUE + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = /wd4244 + GCC:*_*_IA32_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_X64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_ARM_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_AARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_RISCV64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast + GCC:*_*_LOONGARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast diff --git a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFuncFit.c b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFuncFit.c new file mode 100644 index 000000000000..439d5bee0b8c --- /dev/null +++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFuncFit.c @@ -0,0 +1,405 @@ +/** @file + Ia32-specific functionality for DxeLoad. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "VirtualMemory.h" +#include "UefiPayloadEntry.h" + +#define STACK_SIZE 0x20000 +#define IDT_ENTRY_COUNT 32 + +extern VOID *mHobList; + +typedef struct _X64_IDT_TABLE { + // + // Reserved 4 bytes preceding PeiService and IdtTable, + // since IDT base address should be 8-byte alignment. + // + UINT32 Reserved; + CONST EFI_PEI_SERVICES **PeiService; + X64_IDT_GATE_DESCRIPTOR IdtTable[IDT_ENTRY_COUNT]; +} X64_IDT_TABLE; + +// +// Global Descriptor Table (GDT) +// +GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT gGdtEntries[] = { + /* selector { Global Segment Descriptor } */ + /* 0x00 */ { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, // null descriptor + /* 0x08 */ { + { 0xffff, 0, 0, 0x2, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 } + }, // linear data segment descriptor + /* 0x10 */ { + { 0xffff, 0, 0, 0xf, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 } + }, // linear code segment descriptor + /* 0x18 */ { + { 0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 } + }, // system data segment descriptor + /* 0x20 */ { + { 0xffff, 0, 0, 0xa, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 } + }, // system code segment descriptor + /* 0x28 */ { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, // spare segment descriptor + /* 0x30 */ { + { 0xffff, 0, 0, 0x2, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 } + }, // system data segment descriptor + /* 0x38 */ { + { 0xffff, 0, 0, 0xa, 1, 0, 1, 0xf, 0, 1, 0, 1, 0 } + }, // system code segment descriptor + /* 0x40 */ { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, // spare segment descriptor +}; + +// +// IA32 Gdt register +// +GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR gGdt = { + sizeof (gGdtEntries) - 1, + (UINTN)gGdtEntries +}; + +GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR gLidtDescriptor = { + sizeof (X64_IDT_GATE_DESCRIPTOR) * IDT_ENTRY_COUNT - 1, + 0 +}; + +/** + Allocates and fills in the Page Directory and Page Table Entries to + establish a 4G page table. + + @param[in] StackBase Stack base address. + @param[in] StackSize Stack size. + + @return The address of page table. + +**/ +UINTN +Create4GPageTablesIa32Pae ( + IN EFI_PHYSICAL_ADDRESS StackBase, + IN UINTN StackSize + ) +{ + UINT8 PhysicalAddressBits; + EFI_PHYSICAL_ADDRESS PhysicalAddress; + UINTN IndexOfPdpEntries; + UINTN IndexOfPageDirectoryEntries; + UINT32 NumberOfPdpEntriesNeeded; + PAGE_MAP_AND_DIRECTORY_POINTER *PageMap; + PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry; + PAGE_TABLE_ENTRY *PageDirectoryEntry; + UINTN TotalPagesNum; + UINTN PageAddress; + UINT64 AddressEncMask; + + // + // Make sure AddressEncMask is contained to smallest supported address field + // + AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; + + PhysicalAddressBits = 32; + + // + // Calculate the table entries needed. + // + NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30)); + + TotalPagesNum = NumberOfPdpEntriesNeeded + 1; + PageAddress = (UINTN)AllocatePageTableMemory (TotalPagesNum); + ASSERT (PageAddress != 0); + + PageMap = (VOID *)PageAddress; + PageAddress += SIZE_4KB; + + PageDirectoryPointerEntry = PageMap; + PhysicalAddress = 0; + + for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) { + // + // Each Directory Pointer entries points to a page of Page Directory entires. + // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop. + // + PageDirectoryEntry = (VOID *)PageAddress; + PageAddress += SIZE_4KB; + + // + // Fill in a Page Directory Pointer Entries + // + PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask; + PageDirectoryPointerEntry->Bits.Present = 1; + + for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress += SIZE_2MB) { + if ( (IsNullDetectionEnabled () && (PhysicalAddress == 0)) + || ( (PhysicalAddress < StackBase + StackSize) + && ((PhysicalAddress + SIZE_2MB) > StackBase))) + { + // + // Need to split this 2M page that covers stack range. + // + Split2MPageTo4K (PhysicalAddress, (UINT64 *)PageDirectoryEntry, StackBase, StackSize, 0, 0); + } else { + // + // Fill in the Page Directory entries + // + PageDirectoryEntry->Uint64 = (UINT64)PhysicalAddress | AddressEncMask; + PageDirectoryEntry->Bits.ReadWrite = 1; + PageDirectoryEntry->Bits.Present = 1; + PageDirectoryEntry->Bits.MustBe1 = 1; + } + } + } + + for ( ; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPointerEntry++) { + ZeroMem ( + PageDirectoryPointerEntry, + sizeof (PAGE_MAP_AND_DIRECTORY_POINTER) + ); + } + + // + // Protect the page table by marking the memory used for page table to be + // read-only. + // + EnablePageTableProtection ((UINTN)PageMap, FALSE); + + return (UINTN)PageMap; +} + +/** + The function will check if IA32 PAE is supported. + + @retval TRUE IA32 PAE is supported. + @retval FALSE IA32 PAE is not supported. + +**/ +BOOLEAN +IsIa32PaeSupport ( + VOID + ) +{ + UINT32 RegEax; + UINT32 RegEdx; + BOOLEAN Ia32PaeSupport; + + Ia32PaeSupport = FALSE; + AsmCpuid (0x0, &RegEax, NULL, NULL, NULL); + if (RegEax >= 0x1) { + AsmCpuid (0x1, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT6) != 0) { + Ia32PaeSupport = TRUE; + } + } + + return Ia32PaeSupport; +} + +/** + The function will check if page table should be setup or not. + + @retval TRUE Page table should be created. + @retval FALSE Page table should not be created. + +**/ +BOOLEAN +ToBuildPageTable ( + VOID + ) +{ + if (!IsIa32PaeSupport ()) { + return FALSE; + } + + if (IsNullDetectionEnabled ()) { + return TRUE; + } + + if (PcdGet8 (PcdHeapGuardPropertyMask) != 0) { + return TRUE; + } + + if (PcdGetBool (PcdCpuStackGuard)) { + return TRUE; + } + + if (IsEnableNonExecNeeded ()) { + return TRUE; + } + + return FALSE; +} + +/** + Transfers control to DxeCore. + + This function performs a CPU architecture specific operations to execute + the entry point of DxeCore with the parameters of HobList. + + @param DxeCoreEntryPoint The entry point of DxeCore. + @param HobList The start of HobList passed to DxeCore. + +**/ +VOID +HandOffToDxeCore ( + IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint, + IN EFI_PEI_HOB_POINTERS HobList + ) +{ + EFI_PHYSICAL_ADDRESS BaseOfStack; + EFI_PHYSICAL_ADDRESS TopOfStack; + UINTN PageTables; + X64_IDT_GATE_DESCRIPTOR *IdtTable; + UINTN SizeOfTemplate; + VOID *TemplateBase; + EFI_PHYSICAL_ADDRESS VectorAddress; + UINT32 Index; + X64_IDT_TABLE *IdtTableForX64; + + // Initialize floating point operating environment to be compliant with UEFI spec. + InitializeFloatingPointUnits (); + + // + // Mask off all legacy 8259 interrupt sources + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF); + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF); + + // + // Clear page 0 and mark it as allocated if NULL pointer detection is enabled. + // + if (IsNullDetectionEnabled ()) { + ClearFirst4KPage (HobList.Raw); + BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1), EfiBootServicesData); + } + + BaseOfStack = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE)); + ASSERT (BaseOfStack != 0); + + if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { + // + // Compute the top of the stack we were allocated, which is used to load X64 dxe core. + // Pre-allocate a 32 bytes which confroms to x64 calling convention. + // + // The first four parameters to a function are passed in rcx, rdx, r8 and r9. + // Any further parameters are pushed on the stack. Furthermore, space (4 * 8bytes) for the + // register parameters is reserved on the stack, in case the called function + // wants to spill them; this is important if the function is variadic. + // + TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - 32; + + // + // x64 Calling Conventions requires that the stack must be aligned to 16 bytes + // + TopOfStack = (EFI_PHYSICAL_ADDRESS)(UINTN)ALIGN_POINTER (TopOfStack, 16); + + // + // Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA + // memory, it may be corrupted when copying FV to high-end memory + // + AsmWriteGdtr (&gGdt); + // + // Create page table and save PageMapLevel4 to CR3 + // + PageTables = CreateIdentityMappingPageTables (BaseOfStack, STACK_SIZE, 0, 0); + + // + // Paging might be already enabled. To avoid conflict configuration, + // disable paging first anyway. + // + AsmWriteCr0 (AsmReadCr0 () & (~BIT31)); + AsmWriteCr3 (PageTables); + + // + // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore. + // + UpdateStackHob (BaseOfStack, STACK_SIZE); + + SizeOfTemplate = AsmGetVectorTemplatInfo (&TemplateBase); + + VectorAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (sizeof (X64_IDT_TABLE) + SizeOfTemplate * IDT_ENTRY_COUNT)); + ASSERT (VectorAddress != 0); + + // + // Store EFI_PEI_SERVICES** in the 4 bytes immediately preceding IDT to avoid that + // it may not be gotten correctly after IDT register is re-written. + // + IdtTableForX64 = (X64_IDT_TABLE *)(UINTN)VectorAddress; + IdtTableForX64->PeiService = NULL; + + VectorAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(IdtTableForX64 + 1); + IdtTable = IdtTableForX64->IdtTable; + for (Index = 0; Index < IDT_ENTRY_COUNT; Index++) { + IdtTable[Index].Ia32IdtEntry.Bits.GateType = 0x8e; + IdtTable[Index].Ia32IdtEntry.Bits.Reserved_0 = 0; + IdtTable[Index].Ia32IdtEntry.Bits.Selector = SYS_CODE64_SEL; + + IdtTable[Index].Ia32IdtEntry.Bits.OffsetLow = (UINT16)VectorAddress; + IdtTable[Index].Ia32IdtEntry.Bits.OffsetHigh = (UINT16)(RShiftU64 (VectorAddress, 16)); + IdtTable[Index].Offset32To63 = (UINT32)(RShiftU64 (VectorAddress, 32)); + IdtTable[Index].Reserved = 0; + + CopyMem ((VOID *)(UINTN)VectorAddress, TemplateBase, SizeOfTemplate); + AsmVectorFixup ((VOID *)(UINTN)VectorAddress, (UINT8)Index); + + VectorAddress += SizeOfTemplate; + } + + gLidtDescriptor.Base = (UINTN)IdtTable; + + AsmWriteIdtr (&gLidtDescriptor); + + DEBUG (( + DEBUG_INFO, + "%a() Stack Base: 0x%lx, Stack Size: 0x%x\n", + __func__, + BaseOfStack, + STACK_SIZE + )); + + // + // Go to Long Mode and transfer control to DxeCore. + // Interrupts will not get turned on until the CPU AP is loaded. + // Call x64 drivers passing in single argument, a pointer to the HOBs. + // + AsmEnablePaging64 ( + SYS_CODE64_SEL, + DxeCoreEntryPoint, + (EFI_PHYSICAL_ADDRESS)(UINTN)(HobList.Raw), + 0, + TopOfStack + ); + } else { + // 32bit UEFI payload could be supported if required later. + DEBUG ((DEBUG_ERROR, "NOT support 32bit UEFI payload\n")); + ASSERT (FALSE); + CpuDeadLoop (); + } +} + +/** + Entry point to the C language phase of UEFI payload. + @param[in] BootloaderParameter The starting address of bootloader parameter block. + @retval It will not return if SUCCESS, and return error when passing bootloader parameter. +**/ +EFI_STATUS +EFIAPI +_ModuleEntryPoint ( + IN UINTN BootloaderParameter + ) +{ + return FitUplEntryPoint (BootloaderParameter); +} diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFuncFit.c b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFuncFit.c new file mode 100644 index 000000000000..35b52a911df3 --- /dev/null +++ b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFuncFit.c @@ -0,0 +1,135 @@ +/** @file + x64-specifc functionality for DxeLoad. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "X64/VirtualMemory.h" +#include "UefiPayloadEntry.h" +#define STACK_SIZE 0x20000 + +extern VOID *mHobList; + +/** + Transfers control to DxeCore. + + This function performs a CPU architecture specific operations to execute + the entry point of DxeCore with the parameters of HobList. + It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase. + + @param DxeCoreEntryPoint The entry point of DxeCore. + @param HobList The start of HobList passed to DxeCore. + +**/ +VOID +HandOffToDxeCore ( + IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint, + IN EFI_PEI_HOB_POINTERS HobList + ) +{ + VOID *BaseOfStack; + VOID *TopOfStack; + UINTN PageTables; + VOID *GhcbBase; + UINTN GhcbSize; + + // Initialize floating point operating environment to be compliant with UEFI spec. + InitializeFloatingPointUnits (); + + // + // Mask off all legacy 8259 interrupt sources + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF); + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF); + + // + // Clear page 0 and mark it as allocated if NULL pointer detection is enabled. + // + if (IsNullDetectionEnabled ()) { + ClearFirst4KPage (HobList.Raw); + BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1), EfiBootServicesData); + } + + // + // Allocate 128KB for the Stack + // + BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE)); + ASSERT (BaseOfStack != NULL); + + // + // Compute the top of the stack we were allocated. Pre-allocate a UINTN + // for safety. + // + TopOfStack = (VOID *)((UINTN)BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + // + // Get the address and size of the GHCB pages + // + GhcbBase = 0; + GhcbSize = 0; + + PageTables = 0; + if (FeaturePcdGet (PcdDxeIplBuildPageTables)) { + // + // Create page table and save PageMapLevel4 to CR3 + // + PageTables = CreateIdentityMappingPageTables ( + (EFI_PHYSICAL_ADDRESS)(UINTN)BaseOfStack, + STACK_SIZE, + (EFI_PHYSICAL_ADDRESS)(UINTN)GhcbBase, + GhcbSize + ); + } else { + // + // Set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE + // for the DxeIpl and the DxeCore are both X64. + // + ASSERT (PcdGetBool (PcdSetNxForStack) == FALSE); + ASSERT (PcdGetBool (PcdCpuStackGuard) == FALSE); + } + + if (FeaturePcdGet (PcdDxeIplBuildPageTables)) { + AsmWriteCr3 (PageTables); + } + + // + // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore. + // + UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN)BaseOfStack, STACK_SIZE); + + // + // Transfer the control to the entry point of DxeCore. + // + SwitchStack ( + (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint, + HobList.Raw, + NULL, + TopOfStack + ); +} + +/** + Entry point to the C language phase of UEFI payload. + @param[in] BootloaderParameter The starting address of bootloader parameter block. + @retval It will not return if SUCCESS, and return error when passing bootloader parameter. +**/ +EFI_STATUS +EFIAPI +_ModuleEntryPoint ( + IN UINTN BootloaderParameter + ) +{ + return FitUplEntryPoint (BootloaderParameter); +} From a0ac7cf67afd382b4bd13a402bb6100a435b5b7b Mon Sep 17 00:00:00 2001 From: Linus Liu Date: Mon, 29 Apr 2024 03:04:10 -0700 Subject: [PATCH 015/280] UefiPayloadPkg: Update UefiPayload driver for FDT support. REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4786 Add FDT detection and comsume FDT when needed. Move some x86 specific function in the x86 folder. Create HandOffHob via FDT memory node. Signed-off-by: Linus Liu --- .../FitUniversalPayloadEntry.c | 372 +++++++----------- .../FitUniversalPayloadEntry.inf | 21 +- .../UefiPayloadEntry/Ia32/DxeLoadFunc.c | 12 + .../UefiPayloadEntry/MemoryAllocation.c | 50 +++ .../UefiPayloadEntry/UefiPayloadEntry.h | 68 ++++ .../UefiPayloadEntry/UniversalPayloadEntry.c | 6 - .../UniversalPayloadEntry.inf | 14 - .../UefiPayloadEntry/X64/DxeLoadFunc.c | 12 + UefiPayloadPkg/UefiPayloadPkg.dsc | 28 +- 9 files changed, 325 insertions(+), 258 deletions(-) diff --git a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c index eb0b325369a0..7af1276d60d2 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c +++ b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c @@ -6,6 +6,9 @@ #include "UefiPayloadEntry.h" #include #include +#include +#include +#include #define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ @@ -23,6 +26,15 @@ EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ EFI_RESOURCE_ATTRIBUTE_TESTED ) +GLOBAL_REMOVE_IF_UNREFERENCED EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = { + { EfiACPIReclaimMemory, FixedPcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory) }, + { EfiACPIMemoryNVS, FixedPcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS) }, + { EfiReservedMemoryType, FixedPcdGet32 (PcdMemoryTypeEfiReservedMemoryType) }, + { EfiRuntimeServicesData, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesData) }, + { EfiRuntimeServicesCode, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode) }, + { EfiMaxMemoryType, 0 } +}; + extern VOID *mHobList; CHAR8 *mLineBuffer = NULL; @@ -36,6 +48,12 @@ PrintHob ( IN CONST VOID *HobStart ); +VOID +EFIAPI +ProcessLibraryConstructorList ( + VOID + ); + /** Find the first substring. @param String Point to the string where to find the substring. @@ -191,187 +209,6 @@ FixUpPcdDatabase ( return EFI_SUCCESS; } -/** - Add HOB into HOB list - @param[in] Hob The HOB to be added into the HOB list. -**/ -VOID -AddNewHob ( - IN EFI_PEI_HOB_POINTERS *Hob - ) -{ - EFI_PEI_HOB_POINTERS NewHob; - - if (Hob->Raw == NULL) { - return; - } - - NewHob.Header = CreateHob (Hob->Header->HobType, Hob->Header->HobLength); - ASSERT (NewHob.Header != NULL); - if (NewHob.Header == NULL) { - return; - } - - CopyMem (NewHob.Header + 1, Hob->Header + 1, Hob->Header->HobLength - sizeof (EFI_HOB_GENERIC_HEADER)); -} - -/** - Found the Resource Descriptor HOB that contains a range (Base, Top) - @param[in] HobList Hob start address - @param[in] Base Memory start address - @param[in] Top Memory end address. - @retval The pointer to the Resource Descriptor HOB. -**/ -EFI_HOB_RESOURCE_DESCRIPTOR * -FindResourceDescriptorByRange ( - IN VOID *HobList, - IN EFI_PHYSICAL_ADDRESS Base, - IN EFI_PHYSICAL_ADDRESS Top - ) -{ - EFI_PEI_HOB_POINTERS Hob; - EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; - - for (Hob.Raw = (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { - // - // Skip all HOBs except Resource Descriptor HOBs - // - if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - continue; - } - - // - // Skip Resource Descriptor HOBs that do not describe tested system memory - // - ResourceHob = Hob.ResourceDescriptor; - if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) { - continue; - } - - if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) { - continue; - } - - // - // Skip Resource Descriptor HOBs that do not contain the PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop - // - if (Base < ResourceHob->PhysicalStart) { - continue; - } - - if (Top > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) { - continue; - } - - return ResourceHob; - } - - return NULL; -} - -/** - Find the highest below 4G memory resource descriptor, except the input Resource Descriptor. - @param[in] HobList Hob start address - @param[in] MinimalNeededSize Minimal needed size. - @param[in] ExceptResourceHob Ignore this Resource Descriptor. - @retval The pointer to the Resource Descriptor HOB. -**/ -EFI_HOB_RESOURCE_DESCRIPTOR * -FindAnotherHighestBelow4GResourceDescriptor ( - IN VOID *HobList, - IN UINTN MinimalNeededSize, - IN EFI_HOB_RESOURCE_DESCRIPTOR *ExceptResourceHob - ) -{ - EFI_PEI_HOB_POINTERS Hob; - EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; - EFI_HOB_RESOURCE_DESCRIPTOR *ReturnResourceHob; - - ReturnResourceHob = NULL; - - for (Hob.Raw = (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { - // - // Skip all HOBs except Resource Descriptor HOBs - // - if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - continue; - } - - // - // Skip Resource Descriptor HOBs that do not describe tested system memory - // - ResourceHob = Hob.ResourceDescriptor; - if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) { - continue; - } - - if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) { - continue; - } - - // - // Skip if the Resource Descriptor HOB equals to ExceptResourceHob - // - if (ResourceHob == ExceptResourceHob) { - continue; - } - - // - // Skip Resource Descriptor HOBs that are beyond 4G - // - if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > BASE_4GB) { - continue; - } - - // - // Skip Resource Descriptor HOBs that are too small - // - if (ResourceHob->ResourceLength < MinimalNeededSize) { - continue; - } - - // - // Return the topest Resource Descriptor - // - if (ReturnResourceHob == NULL) { - ReturnResourceHob = ResourceHob; - } else { - if (ReturnResourceHob->PhysicalStart < ResourceHob->PhysicalStart) { - ReturnResourceHob = ResourceHob; - } - } - } - - return ReturnResourceHob; -} - -/** - Check the HOB and decide if it is need inside Payload - Payload maintainer may make decision which HOB is need or needn't - Then add the check logic in the function. - @param[in] Hob The HOB to check - @retval TRUE If HOB is need inside Payload - @retval FALSE If HOB is needn't inside Payload -**/ -BOOLEAN -IsHobNeed ( - EFI_PEI_HOB_POINTERS Hob - ) -{ - if (Hob.Header->HobType == EFI_HOB_TYPE_HANDOFF) { - return FALSE; - } - - if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) { - if (CompareGuid (&Hob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) { - return FALSE; - } - } - - // Arrive here mean the HOB is need - return TRUE; -} - /** It will build Fv HOBs based on information from bootloaders. @param[out] DxeFv The pointer to the DXE FV in memory. @@ -400,6 +237,8 @@ BuildFitLoadablesFvHob ( UINT32 DataSize; UINT32 *Data32; + Fdt = NULL; + GuidHob = GetFirstGuidHob (&gUniversalPayloadBaseGuid); if (GuidHob != NULL) { PayloadBase = (UNIVERSAL_PAYLOAD_BASE *)GET_GUID_HOB_DATA (GuidHob); @@ -407,6 +246,10 @@ BuildFitLoadablesFvHob ( DEBUG ((DEBUG_INFO, "PayloadBase Entry = 0x%08x\n", PayloadBase->Entry)); } + if (Fdt == NULL) { + return EFI_UNSUPPORTED; + } + Status = FdtCheckHeader (Fdt); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; @@ -467,31 +310,25 @@ BuildFitLoadablesFvHob ( } /** - It will build HOBs based on information from bootloaders. - @param[in] BootloaderParameter The starting memory address of bootloader parameter block. - @param[out] DxeFv The pointer to the DXE FV in memory. - @retval EFI_SUCCESS If it completed successfully. - @retval Others If it failed to build required HOBs. + * + Create new HOB for new HOB list + + @param[in] BootloaderParameter The HOB to be added into the HOB list. **/ -EFI_STATUS -BuildHobs ( - IN UINTN BootloaderParameter, - OUT EFI_FIRMWARE_VOLUME_HEADER **DxeFv +VOID +CreatNewHobForHoblist ( + IN UINTN BootloaderParameter ) { - EFI_PEI_HOB_POINTERS Hob; - UINTN MinimalNeededSize; - EFI_PHYSICAL_ADDRESS FreeMemoryBottom; - EFI_PHYSICAL_ADDRESS FreeMemoryTop; - EFI_PHYSICAL_ADDRESS MemoryBottom; - EFI_PHYSICAL_ADDRESS MemoryTop; - EFI_HOB_RESOURCE_DESCRIPTOR *PhitResourceHob; - EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; - UINT8 *GuidHob; - EFI_HOB_FIRMWARE_VOLUME *FvHob; - UNIVERSAL_PAYLOAD_ACPI_TABLE *AcpiTable; - ACPI_BOARD_INFO *AcpiBoardInfo; - EFI_HOB_HANDOFF_INFO_TABLE *HobInfo; + EFI_PEI_HOB_POINTERS Hob; + UINTN MinimalNeededSize; + EFI_PHYSICAL_ADDRESS FreeMemoryBottom; + EFI_PHYSICAL_ADDRESS FreeMemoryTop; + EFI_PHYSICAL_ADDRESS MemoryBottom; + EFI_PHYSICAL_ADDRESS MemoryTop; + EFI_HOB_RESOURCE_DESCRIPTOR *PhitResourceHob; + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; + EFI_HOB_HANDOFF_INFO_TABLE *HobInfo; Hob.Raw = (UINT8 *)BootloaderParameter; MinimalNeededSize = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize); @@ -512,7 +349,7 @@ BuildHobs ( // ResourceHob = FindAnotherHighestBelow4GResourceDescriptor (Hob.Raw, MinimalNeededSize, NULL); if (ResourceHob == NULL) { - return EFI_NOT_FOUND; + return; } MemoryBottom = ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MinimalNeededSize; @@ -542,7 +379,7 @@ BuildHobs ( // ResourceHob = FindAnotherHighestBelow4GResourceDescriptor (Hob.Raw, MinimalNeededSize, PhitResourceHob); if (ResourceHob == NULL) { - return EFI_NOT_FOUND; + return; } MemoryBottom = ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MinimalNeededSize; @@ -553,14 +390,7 @@ BuildHobs ( HobInfo = HobConstructor ((VOID *)(UINTN)MemoryBottom, (VOID *)(UINTN)MemoryTop, (VOID *)(UINTN)FreeMemoryBottom, (VOID *)(UINTN)FreeMemoryTop); HobInfo->BootMode = Hob.HandoffInformationTable->BootMode; - // - // From now on, mHobList will point to the new Hob range. - // - // - // Create an empty FvHob for the DXE FV that contains DXE core. - // - BuildFvHob ((EFI_PHYSICAL_ADDRESS)0, 0); // // Since payload created new Hob, move all hobs except PHIT from boot loader hob list. // @@ -573,7 +403,58 @@ BuildHobs ( Hob.Raw = GET_NEXT_HOB (Hob); } - BuildFitLoadablesFvHob (DxeFv); + return; +} + +/** + It will build HOBs based on information from bootloaders. + @param[in] NewFdtBase The pointer to New FdtBase. + @param[out] DxeFv The pointer to the DXE FV in memory. + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to build required HOBs. +**/ +EFI_STATUS +FitBuildHobs ( + IN UINTN NewFdtBase, + OUT EFI_FIRMWARE_VOLUME_HEADER **DxeFv + ) +{ + UINT8 *GuidHob; + UINT32 FdtSize; + EFI_HOB_FIRMWARE_VOLUME *FvHob; + UNIVERSAL_PAYLOAD_ACPI_TABLE *AcpiTable; + ACPI_BOARD_INFO *AcpiBoardInfo; + UNIVERSAL_PAYLOAD_DEVICE_TREE *Fdt; + + if (FixedPcdGetBool (PcdHandOffFdtEnable)) { + // + // Back up FDT in Reserved memory region + // + if (NewFdtBase != 0) { + GuidHob = GetFirstGuidHob (&gUniversalPayloadDeviceTreeGuid); + if (GuidHob != NULL) { + Fdt = (UNIVERSAL_PAYLOAD_DEVICE_TREE *)GET_GUID_HOB_DATA (GuidHob); + if (Fdt != NULL) { + DEBUG ((DEBUG_INFO, "Update FDT base to reserved memory\n")); + FdtSize = PcdGet8 (PcdFDTPageSize) * EFI_PAGE_SIZE; + CopyMem ((VOID *)NewFdtBase, (VOID *)(Fdt->DeviceTreeAddress), FdtSize); + Fdt->DeviceTreeAddress = NewFdtBase; + } + } + } + } + + // + // To create Memory Type Information HOB + // + GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid); + if (GuidHob == NULL) { + BuildGuidDataHob ( + &gEfiMemoryTypeInformationGuid, + mDefaultMemoryTypeInformation, + sizeof (mDefaultMemoryTypeInformation) + ); + } // // Create guid hob for acpi board information @@ -588,6 +469,12 @@ BuildHobs ( } } + // + // Create an empty FvHob for the DXE FV that contains DXE core. + // + BuildFvHob ((EFI_PHYSICAL_ADDRESS)0, 0); + + BuildFitLoadablesFvHob (DxeFv); // // Update DXE FV information to first fv hob in the hob list, which // is the empty FvHob created before. @@ -600,12 +487,12 @@ BuildHobs ( /** Entry point to the C language phase of UEFI payload. - @param[in] BootloaderParameter The starting address of bootloader parameter block. + @param[in] BootloaderParameter The starting address of FDT . @retval It will not return if SUCCESS, and return error when passing bootloader parameter. **/ EFI_STATUS EFIAPI -_ModuleEntryPoint ( +FitUplEntryPoint ( IN UINTN BootloaderParameter ) { @@ -614,13 +501,51 @@ _ModuleEntryPoint ( EFI_PEI_HOB_POINTERS Hob; EFI_FIRMWARE_VOLUME_HEADER *DxeFv; - mHobList = (VOID *)BootloaderParameter; - DxeFv = NULL; + #if FixedPcdGetBool (PcdHandOffFdtEnable) == 1 + PHYSICAL_ADDRESS HobListPtr; + VOID *FdtBase; + #endif + VOID *FdtBaseResvd; + + if (FixedPcdGetBool (PcdHandOffFdtEnable)) { + mHobList = (VOID *)NULL; + } else { + mHobList = (VOID *)BootloaderParameter; + } + + DxeFv = NULL; + FdtBaseResvd = 0; // Call constructor for all libraries ProcessLibraryConstructorList (); DEBUG ((DEBUG_INFO, "Entering Universal Payload...\n")); DEBUG ((DEBUG_INFO, "sizeof(UINTN) = 0x%x\n", sizeof (UINTN))); + DEBUG ((DEBUG_INFO, "BootloaderParameter = 0x%x\n", BootloaderParameter)); + + DEBUG ((DEBUG_INFO, "Start init Hobs...\n")); + #if FixedPcdGetBool (PcdHandOffFdtEnable) == 1 + HobListPtr = UplInitHob ((VOID *)BootloaderParameter); + + // + // Found hob list node + // + if (HobListPtr != 0) { + FdtBase = (VOID *)BootloaderParameter; + if (FdtCheckHeader (FdtBase) == 0) { + CustomFdtNodeParser ((VOID *)FdtBase, (VOID *)HobListPtr); + FdtBaseResvd = PayloadAllocatePages (PcdGet8 (PcdFDTPageSize), EfiReservedMemoryType); + } + } + + #else + CreatNewHobForHoblist (BootloaderParameter); + #endif + + // Build HOB based on information from Bootloader + Status = FitBuildHobs ((UINTN)FdtBaseResvd, &DxeFv); + + // Call constructor for all libraries again since hobs were built + ProcessLibraryConstructorList (); DEBUG_CODE ( // @@ -629,23 +554,10 @@ _ModuleEntryPoint ( PrintHob (mHobList); ); - // Initialize floating point operating environment to be compliant with UEFI spec. - InitializeFloatingPointUnits (); - - // Build HOB based on information from Bootloader - Status = BuildHobs (BootloaderParameter, &DxeFv); - ASSERT_EFI_ERROR (Status); - FixUpPcdDatabase (DxeFv); Status = UniversalLoadDxeCore (DxeFv, &DxeCoreEntryPoint); ASSERT_EFI_ERROR (Status); - // - // Mask off all legacy 8259 interrupt sources - // - IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF); - IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF); - Hob.HandoffInformationTable = (EFI_HOB_HANDOFF_INFO_TABLE *)GetFirstHob (EFI_HOB_TYPE_HANDOFF); HandOffToDxeCore (DxeCoreEntryPoint, Hob); diff --git a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf index 04d0a795dc23..37e3cc8efa26 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf @@ -30,13 +30,13 @@ [Sources.Ia32] X64/VirtualMemory.h X64/VirtualMemory.c - Ia32/DxeLoadFunc.c + Ia32/DxeLoadFuncFit.c Ia32/IdtVectorAsm.nasm [Sources.X64] X64/VirtualMemory.h X64/VirtualMemory.c - X64/DxeLoadFunc.c + X64/DxeLoadFuncFit.c [Packages] MdePkg/MdePkg.dec @@ -55,6 +55,8 @@ CpuLib FdtLib HobPrintLib + CustomFdtNodeParserLib + PcdLib [Guids] gEfiMemoryTypeInformationGuid @@ -72,6 +74,7 @@ gUniversalPayloadAcpiTableGuid gUniversalPayloadPciRootBridgeInfoGuid gUniversalPayloadSmbios3TableGuid + gUniversalPayloadDeviceTreeGuid [FeaturePcd.IA32] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES @@ -79,7 +82,6 @@ [FeaturePcd.X64] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables ## CONSUMES - [Pcd.IA32,Pcd.X64] gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES @@ -89,11 +91,20 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize ## CONSUMES - gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize - gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES + gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable + gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS + gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory + gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType + gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData + gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode + gUefiPayloadPkgTokenSpaceGuid.PcdFDTPageSize + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = /wd4244 /wd4305 + GCC:*_*_*_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast diff --git a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c index 61a9f01ec9e7..cf9c03a9a8e9 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c +++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c @@ -15,12 +15,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include "VirtualMemory.h" #include "UefiPayloadEntry.h" #define STACK_SIZE 0x20000 #define IDT_ENTRY_COUNT 32 +extern VOID *mHobList; + typedef struct _X64_IDT_TABLE { // // Reserved 4 bytes preceding PeiService and IdtTable, @@ -268,6 +271,15 @@ HandOffToDxeCore ( UINT32 Index; X64_IDT_TABLE *IdtTableForX64; + // Initialize floating point operating environment to be compliant with UEFI spec. + InitializeFloatingPointUnits (); + + // + // Mask off all legacy 8259 interrupt sources + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF); + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF); + // // Clear page 0 and mark it as allocated if NULL pointer detection is enabled. // diff --git a/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c b/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c index 9a65b7dbfe9d..23bbf196ccb4 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c +++ b/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c @@ -10,6 +10,56 @@ #include "UefiPayloadEntry.h" +/** + Allocates one or more pages of type EfiBootServicesData. + + Allocates the number of pages of MemoryType and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. + If Pages is 0, then NULL is returned. + If there is not enough memory availble to satisfy the request, then NULL + is returned. + + @param Pages The number of 4 KB pages to allocate. + @param MemoryType The MemoryType + @return A pointer to the allocated buffer or NULL if allocation fails. +**/ +VOID * +EFIAPI +PayloadAllocatePages ( + IN UINTN Pages, + IN EFI_MEMORY_TYPE MemoryType + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_PHYSICAL_ADDRESS Offset; + EFI_HOB_HANDOFF_INFO_TABLE *HobTable; + + Hob.Raw = GetHobList (); + HobTable = Hob.HandoffInformationTable; + + if (Pages == 0) { + return NULL; + } + + // Make sure allocation address is page alligned. + Offset = HobTable->EfiFreeMemoryTop & EFI_PAGE_MASK; + if (Offset != 0) { + HobTable->EfiFreeMemoryTop -= Offset; + } + + // + // Check available memory for the allocation + // + if (HobTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) < HobTable->EfiFreeMemoryBottom) { + return NULL; + } + + HobTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE; + BuildMemoryAllocationHob (HobTable->EfiFreeMemoryTop, Pages * EFI_PAGE_SIZE, MemoryType); + + return (VOID *)(UINTN)HobTable->EfiFreeMemoryTop; +} + /** Allocates one or more pages of type EfiBootServicesData. diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h index 80ccc5072c55..09fce8dbcf35 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #define LEGACY_8259_MASK_REGISTER_MASTER 0x21 @@ -134,6 +135,31 @@ UniversalLoadDxeCore ( OUT PHYSICAL_ADDRESS *DxeCoreEntryPoint ); +/** + It will Parse FDT -node based on information. + @param[in] FdtBase The starting memory address of FdtBase + @retval HobList The base address of Hoblist. + +**/ +UINT64 +EFIAPI +FdtNodeParser ( + IN VOID *FdtBase + ); + +/** + It will Parse FDT -custom node based on information. + @param[in] FdtBase The starting memory address of FdtBase + @param[in] HostList The starting memory address of New Hob list. + +**/ +UINTN +EFIAPI +CustomFdtNodeParser ( + IN VOID *FdtBase, + IN VOID *HostList + ); + /** Transfers control to DxeCore. @@ -206,4 +232,46 @@ BuildHobFromAcpi ( IN UINT64 AcpiTableBase ); +/** + Allocates one or more pages . + + Allocates the number of pages of MemoryType and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. + If Pages is 0, then NULL is returned. + If there is not enough memory availble to satisfy the request, then NULL + is returned. + + @param Pages The number of 4 KB pages to allocate. + @param MemoryType The Memorytype + @return A pointer to the allocated buffer or NULL if allocation fails. +**/ +VOID * +EFIAPI +PayloadAllocatePages ( + IN UINTN Pages, + IN EFI_MEMORY_TYPE MemoryType + ); + +/** + Entry point to the C language phase of UEFI payload. + @param[in] FdtPrt The starting address of FDT . + @retval It will not return if SUCCESS, and return error when passing bootloader parameter. +**/ +EFI_STATUS +EFIAPI +FitUplEntryPoint ( + IN UINTN BootloaderParameter + ); + +/** + Entry point to the C language phase of UEFI payload. + @param[in] BootloaderParameter The starting address of bootloader parameter block. + @retval It will not return if SUCCESS, and return error when passing bootloader parameter. +**/ +EFI_STATUS +EFIAPI +UplEntryPoint ( + IN UINTN BootloaderParameter + ); + #endif diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c index f37c00fad774..5b864eeefe10 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c @@ -486,12 +486,6 @@ _ModuleEntryPoint ( Status = UniversalLoadDxeCore (DxeFv, &DxeCoreEntryPoint); ASSERT_EFI_ERROR (Status); - // - // Mask off all legacy 8259 interrupt sources - // - IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF); - IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF); - Hob.HandoffInformationTable = (EFI_HOB_HANDOFF_INFO_TABLE *)GetFirstHob (EFI_HOB_TYPE_HANDOFF); HandOffToDxeCore (DxeCoreEntryPoint, Hob); diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf index c3571e3c287f..01bb9a118a7d 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf @@ -6,44 +6,37 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent # ## - [Defines] INF_VERSION = 1.30 BASE_NAME = UniversalPayloadEntry FILE_GUID = D4F0F269-1209-4A66-8039-C4D5A700EA4E MODULE_TYPE = SEC VERSION_STRING = 1.0 - # # The following information is for reference only and not required by the build tools. # # VALID_ARCHITECTURES = IA32 X64 # - [Sources] UniversalPayloadEntry.c LoadDxeCore.c MemoryAllocation.c PrintHob.c AcpiTable.c - [Sources.Ia32] X64/VirtualMemory.h X64/VirtualMemory.c Ia32/DxeLoadFunc.c Ia32/IdtVectorAsm.nasm - [Sources.X64] X64/VirtualMemory.h X64/VirtualMemory.c X64/DxeLoadFunc.c - [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec UefiCpuPkg/UefiCpuPkg.dec UefiPayloadPkg/UefiPayloadPkg.dec - [LibraryClasses] BaseMemoryLib DebugLib @@ -70,14 +63,10 @@ gUniversalPayloadAcpiTableGuid gUniversalPayloadPciRootBridgeInfoGuid gUniversalPayloadSmbios3TableGuid - [FeaturePcd.IA32] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES - [FeaturePcd.X64] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables ## CONSUMES - - [Pcd.IA32,Pcd.X64] gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES @@ -87,12 +76,9 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize ## CONSUMES - gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize - gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES - diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c index 346e3feb0459..6c3603f12098 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c +++ b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c @@ -13,10 +13,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include "X64/VirtualMemory.h" #include "UefiPayloadEntry.h" #define STACK_SIZE 0x20000 +extern VOID *mHobList; + /** Transfers control to DxeCore. @@ -40,6 +43,15 @@ HandOffToDxeCore ( VOID *GhcbBase; UINTN GhcbSize; + // Initialize floating point operating environment to be compliant with UEFI spec. + InitializeFloatingPointUnits (); + + // + // Mask off all legacy 8259 interrupt sources + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF); + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF); + // // Clear page 0 and mark it as allocated if NULL pointer detection is enabled. // diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 6199527a9a38..9a73c7fd80aa 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -226,6 +226,7 @@ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf HobLib|UefiPayloadPkg/Library/DxeHobLib/DxeHobLib.inf + CustomFdtNodeParserLib|UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.inf # # UEFI & PI @@ -472,6 +473,8 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0 gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable|TRUE + gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile|{ 0x57, 0x72, 0xcf, 0x80, 0xab, 0x87, 0xf9, 0x47, 0xa3, 0xfe, 0xD5, 0x0B, 0x76, 0xd8, 0x95, 0x41 } @@ -515,10 +518,13 @@ !endif !endif + [PcdsPatchableInModule.X64] !if $(NETWORK_DRIVER_ENABLE) == TRUE gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections|TRUE !endif + gUefiPayloadPkgTokenSpaceGuid.SizeOfIoSpace|16 + gUefiPayloadPkgTokenSpaceGuid.PcdFDTPageSize|8 [PcdsPatchableInModule.common] gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } @@ -542,7 +548,7 @@ # The following parameters are set by Library/PlatformHookLib # gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|FALSE - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x3F8 gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|$(BAUD_RATE) gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|1 @@ -638,7 +644,15 @@ !if $(UNIVERSAL_PAYLOAD_FORMAT) == "ELF" UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf !elseif $(UNIVERSAL_PAYLOAD_FORMAT) == "FIT" - UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf + UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf { + + !if gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable == TRUE + FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf + CustomFdtNodeParserLib|UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf + NULL|UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf + !endif + NULL|UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf + } !else UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf !endif @@ -651,7 +665,15 @@ !if $(UNIVERSAL_PAYLOAD_FORMAT) == "ELF" UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf !elseif $(UNIVERSAL_PAYLOAD_FORMAT) == "FIT" - UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf + UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf { + + !if gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable == TRUE + FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf + CustomFdtNodeParserLib|UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf + NULL|UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf + !endif + NULL|UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf + } !else UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf !endif From 1fd2f9ec8f16cc8efb949888db94eb42006f77c6 Mon Sep 17 00:00:00 2001 From: Hongbin1 Zhang Date: Fri, 26 Jul 2024 10:16:42 +0800 Subject: [PATCH 016/280] IntelFsp2Pkg: Align FSP global data pointer for X64 build When it used 32 bits for set FSP global data pointer under X64 build, it should get FSP global data pointer with 32 bits data under X64 build. Signed-off-by: Hongbin1 Zhang Cc: Chasel Chiu Cc: Nate DeSimone Cc: Duggapu Chinni B Cc: Star Zeng Cc: Ted Kuo Cc: Ashraf Ali S --- IntelFsp2Pkg/FspSecCore/SecFspApiChk.c | 12 ++++++------ IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c b/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c index 5f599385185c..644c374bd6c0 100644 --- a/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c +++ b/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c @@ -31,7 +31,7 @@ FspApiCallingCheck ( // // NotifyPhase check // - if ((FspData == NULL) || ((UINTN)FspData == MAX_ADDRESS) || ((UINTN)FspData == MAX_UINT32)) { + if ((FspData == NULL) || ((UINT32)(UINTN)FspData == MAX_UINT32)) { Status = EFI_UNSUPPORTED; } else { if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) { @@ -42,7 +42,7 @@ FspApiCallingCheck ( // // FspMemoryInit check // - if (((UINTN)FspData != MAX_ADDRESS) && ((UINTN)FspData != MAX_UINT32)) { + if ((UINT32)(UINTN)FspData != MAX_UINT32) { Status = EFI_UNSUPPORTED; } else if (ApiParam == NULL) { Status = EFI_SUCCESS; @@ -53,7 +53,7 @@ FspApiCallingCheck ( // // TempRamExit check // - if ((FspData == NULL) || ((UINTN)FspData == MAX_ADDRESS) || ((UINTN)FspData == MAX_UINT32)) { + if ((FspData == NULL) || ((UINT32)(UINTN)FspData == MAX_UINT32)) { Status = EFI_UNSUPPORTED; } else { if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) { @@ -64,7 +64,7 @@ FspApiCallingCheck ( // // FspSiliconInit check // - if ((FspData == NULL) || ((UINTN)FspData == MAX_ADDRESS) || ((UINTN)FspData == MAX_UINT32)) { + if ((FspData == NULL) || ((UINT32)(UINTN)FspData == MAX_UINT32)) { Status = EFI_UNSUPPORTED; } else { if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) { @@ -83,14 +83,14 @@ FspApiCallingCheck ( } } } else if (ApiIdx == FspMultiPhaseMemInitApiIndex) { - if ((FspData == NULL) || ((UINTN)FspData == MAX_ADDRESS) || ((UINTN)FspData == MAX_UINT32)) { + if ((FspData == NULL) || ((UINT32)(UINTN)FspData == MAX_UINT32)) { Status = EFI_UNSUPPORTED; } } else if (ApiIdx == FspSmmInitApiIndex) { // // FspSmmInitApiIndex check // - if ((FspData == NULL) || ((UINTN)FspData == MAX_ADDRESS) || ((UINTN)FspData == MAX_UINT32)) { + if ((FspData == NULL) || ((UINT32)(UINTN)FspData == MAX_UINT32)) { Status = EFI_UNSUPPORTED; } else { if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) { diff --git a/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c index d33d01fe22ad..54dbf546c360 100644 --- a/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c +++ b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c @@ -89,10 +89,10 @@ GetFspGlobalDataPointer ( VOID ) { - FSP_GLOBAL_DATA *FspData; + UINT32 FspDataAddress; - FspData = *(FSP_GLOBAL_DATA **)(UINTN)PcdGet32 (PcdGlobalDataPointerAddress); - return FspData; + FspDataAddress = *(UINT32 *)(UINTN)PcdGet32 (PcdGlobalDataPointerAddress); + return (FSP_GLOBAL_DATA *)(UINTN)FspDataAddress; } /** From 82b1f691961f3e845e2e46873823c4843b660a7a Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 24 May 2024 09:36:52 +0800 Subject: [PATCH 017/280] MdePkg/MdePkg.dec: Add gEfiMmEndOfPeiProtocol definition This protocol is defined at PI Spec, Vol 4, section 4. It's a MM Protocol published by a standalone MM Foundation code if MM Foundation is loaded in PEI phase. This protocol should be installed immediately after DXE IPL installs EFI_PEI_END_OF_PEI_PHASE_PPI. Signed-off-by: Hongbin1 Zhang Co-authored-by: Jiaxin Wu Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Cc: Ray Ni Cc: Star Zeng Cc: Wei6 Xu Cc: Dun Tan Cc: Yuanhao Xie --- MdePkg/MdePkg.dec | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index f8c30d3e762b..d36bd2eda37e 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -1385,6 +1385,10 @@ ## Include/Protocol/MmCommunication.h gEfiMmCommunicationProtocolGuid = { 0xc68ed8e2, 0x9dc6, 0x4cbd, { 0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32 }} + ## This protocol is a MM protocol published by a standalone MM Foundation code if MM Foundation is loaded in PEI phase. + ## This protocol should be installed immediately after DXE IPL installs EFI_PEI_END_OF_PEI_PHASE_PPI + gEfiMmEndOfPeiProtocol = { 0xf33e1bf3, 0x980b, 0x4bfb, { 0xa2, 0x9a, 0xb2, 0x9c, 0x86, 0x45, 0x37, 0x32 }} + # # Protocols defined in PI 1.6. # From ff04469d33512d29a5b1afa9c99ec3a152795360 Mon Sep 17 00:00:00 2001 From: Hongbin1 Zhang Date: Fri, 31 May 2024 15:26:10 +0800 Subject: [PATCH 018/280] MdeModulePkg: Add MM Communication Buffer definition The MM communicate buffer facilitates data sharing between non-MM and MM code. The MM IPL code allocates a "fixed" runtime type memory as the MM communication buffer, and communicates its address and size to MM Core via MmCommBuffer GUIDed HOB. Here, "fixed" implies that the buffer's location remains constant throughout the boot process. Data is exchanged between the MM Communication PPI/Protocol and a software MMI handler using this fixed MM communication buffer. Signed-off-by: Hongbin1 Zhang Co-authored-by: Jiaxin Wu Cc: Liming Gao Co-authored-by: Ray Ni Cc: Star Zeng Cc: Wei6 Xu Cc: Dun Tan Cc: Yuanhao Xie --- MdeModulePkg/Include/Guid/MmCommBuffer.h | 63 ++++++++++++++++++++++++ MdeModulePkg/MdeModulePkg.dec | 3 ++ 2 files changed, 66 insertions(+) create mode 100644 MdeModulePkg/Include/Guid/MmCommBuffer.h diff --git a/MdeModulePkg/Include/Guid/MmCommBuffer.h b/MdeModulePkg/Include/Guid/MmCommBuffer.h new file mode 100644 index 000000000000..df4ea317ebeb --- /dev/null +++ b/MdeModulePkg/Include/Guid/MmCommBuffer.h @@ -0,0 +1,63 @@ +/** @file + MM Communication buffer data. + +Copyright (c) 2024, Intel Corporation. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef MM_COMM_BUFFER_H_ +#define MM_COMM_BUFFER_H_ + +/// +/// The GUID of the MM Communication buffer HOB. +/// +#define MM_COMM_BUFFER_HOB_GUID \ + { 0x6c2a2520, 0x0131, 0x4aee, { 0xa7, 0x50, 0xcc, 0x38, 0x4a, 0xac, 0xe8, 0xc6 }} + +/// +/// The MM communicate buffer facilitates data sharing between non-MM and MM code. +/// The MM IPL code allocates a "fixed" runtime type memory as the MM communication buffer, +/// and communicates its address and size to MM Core via MmCommBuffer GUIDed HOB. +/// Here, "fixed" implies that the buffer's location remains constant throughout the boot process. +/// Data is exchanged between the MM Communication PPI/Protocol and a software MMI handler +/// using this fixed MM communication buffer. +/// +typedef struct { + /// + /// The address of the 4-KiB aligned fixed MM communication buffer. + /// + EFI_PHYSICAL_ADDRESS PhysicalStart; + + /// + /// Size of the fixed MM communication buffer, in 4KiB pages. + /// + UINT64 NumberOfPages; + + /// + /// Point to MM_COMM_BUFFER_STATUS structure. + /// + EFI_PHYSICAL_ADDRESS Status; +} MM_COMM_BUFFER; + +typedef struct { + /// + /// Whether the data in the fixed MM communication buffer is valid when entering from non-MM to MM. + /// + BOOLEAN IsCommBufferValid; + + /// + /// The return status when returning from MM to non-MM. + /// + UINT64 ReturnStatus; + + /// + /// The size in bytes of the output buffer when returning from MM to non-MM. + /// + UINT64 ReturnBufferSize; +} MM_COMM_BUFFER_STATUS; + +extern EFI_GUID gMmCommBufferHobGuid; + +#endif diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 693e45911b66..e71a4dd5e392 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -485,6 +485,9 @@ ## HOB GUID to get ACPI table after FSP is done. The ACPI table that related SOC will be pass by this HOB. gAcpiTableHobGuid = { 0xf9886b57, 0x8a35, 0x455e, { 0xbb, 0xb1, 0x14, 0x65, 0x5e, 0x7b, 0xe7, 0xec }} + ## Include/Guid/MmCommBuffer.h + gMmCommBufferHobGuid = { 0x6c2a2520, 0x0131, 0x4aee, { 0xa7, 0x50, 0xcc, 0x38, 0x4a, 0xac, 0xe8, 0xc6 }} + [Ppis] ## Include/Ppi/FirmwareVolumeShadowPpi.h gEdkiiPeiFirmwareVolumeShadowPpiGuid = { 0x7dfe756c, 0xed8d, 0x4d77, {0x9e, 0xc4, 0x39, 0x9a, 0x8a, 0x81, 0x51, 0x16 } } From 45098bf1b84c9d798fcd4fafff46efb6d4e9c21e Mon Sep 17 00:00:00 2001 From: Hongbin1 Zhang Date: Fri, 31 May 2024 15:28:34 +0800 Subject: [PATCH 019/280] MdeModulePkg/MdeModulePkg.dec: Add PcdMmCommBufferPages PCD PcdMmCommBufferPages is to specify the page count allocated for the MM communication buffer. Signed-off-by: Hongbin1 Zhang Co-authored-by: Jiaxin Wu Cc: Liming Gao Co-authored-by: Ray Ni Cc: Star Zeng Cc: Wei6 Xu Cc: Dun Tan Cc: Yuanhao Xie --- MdeModulePkg/MdeModulePkg.dec | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index e71a4dd5e392..a25f380d0281 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -1190,6 +1190,10 @@ # @Prompt Delay access XHCI register after it issues HCRST (us) gEfiMdeModulePkgTokenSpaceGuid.PcdDelayXhciHCReset|2000|UINT16|0x30001060 + ## Specifies the page count allocated for the MM communication buffer. + # @Prompt Defines the page allocation for the MM communication buffer; default is 128 pages (512KB). + gEfiMdeModulePkgTokenSpaceGuid.PcdMmCommBufferPages|128|UINT32|0x30001061 + [PcdsFixedAtBuild, PcdsPatchableInModule] ## Dynamic type PCD can be registered callback function for Pcd setting action. # PcdMaxPeiPcdCallBackNumberPerPcdEntry indicates the maximum number of callback function From 21a2c8ae2a3802198838a9b5e3ae5a7d2ba0e7d8 Mon Sep 17 00:00:00 2001 From: Yuanhao Xie Date: Fri, 24 May 2024 14:45:09 +0800 Subject: [PATCH 020/280] UefiCpuPkg: Add Unblock Region HOB definition Add Unblock Region HOB which defines the GUIDed HOB that describes the memory region to be unblocked in MM environment. Signed-off-by: Yuanhao Xie Co-authored-by: Jiaxin Wu Co-authored-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan --- UefiCpuPkg/Include/Guid/MmUnblockRegion.h | 42 +++++++++++++++++++++++ UefiCpuPkg/UefiCpuPkg.dec | 3 ++ 2 files changed, 45 insertions(+) create mode 100644 UefiCpuPkg/Include/Guid/MmUnblockRegion.h diff --git a/UefiCpuPkg/Include/Guid/MmUnblockRegion.h b/UefiCpuPkg/Include/Guid/MmUnblockRegion.h new file mode 100644 index 000000000000..f6a33c348ba5 --- /dev/null +++ b/UefiCpuPkg/Include/Guid/MmUnblockRegion.h @@ -0,0 +1,42 @@ +/** @file + Defines the GUIDed HOB that describes the memory region to be unblocked in MM environment. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef MM_UNBLOCK_REGION_H_ +#define MM_UNBLOCK_REGION_H_ + +/// +/// The GUID of the UnblockRegion GUIDed HOB. +/// +#define MM_UNBLOCK_REGION_HOB_GUID \ + { \ + 0x7c316fb3, 0x849e, 0x4ee7, {0x87, 0xfc, 0x16, 0x2d, 0x0b, 0x03, 0x42, 0xbf } \ + } + +/// +/// The structure defines the data layout of the UnblockRegion GUIDed HOB. +/// +typedef struct { + /// + /// Physical address of the first byte in the memory region. PhysicalStart must be + /// aligned on a 4 KiB boundary. + /// + EFI_PHYSICAL_ADDRESS PhysicalStart; + + /// + /// Number of 4 KiB pages in the memory region. + /// + UINT64 NumberOfPages; + + /// + /// GUID to identify the memory region. + /// + EFI_GUID IdentifierGuid; +} MM_UNBLOCK_REGION; + +extern EFI_GUID gMmUnblockRegionHobGuid; + +#endif diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index c026cf535b86..5ee4efc3fab4 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -108,6 +108,9 @@ ## Include/Guid/GhcbApicIds.h gGhcbApicIdsGuid = { 0xbc964338, 0xee39, 0x4fc8, { 0xa2, 0x24, 0x10, 0x10, 0x8b, 0x17, 0x80, 0x1b }} + ## Include/Guid/MmUnblockRegion.h + gMmUnblockRegionHobGuid = { 0x7c316fb3, 0x849e, 0x4ee7, { 0x87, 0xfc, 0x16, 0x2d, 0x0b, 0x03, 0x42, 0xbf }} + [Protocols] ## Include/Protocol/SmmCpuService.h gEfiSmmCpuServiceProtocolGuid = { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }} From 2c5d329e20f0a50af58c572af332825f8cb40ad5 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 24 May 2024 14:51:47 +0800 Subject: [PATCH 021/280] UefiCpuPkg: Add MM Profile related definitions Signed-off-by: Jiaxin Wu Co-authored-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan Cc: Yuanhao Xie --- UefiCpuPkg/Include/Guid/MmProfileData.h | 35 +++++++++++++++++++++++++ UefiCpuPkg/UefiCpuPkg.dec | 3 +++ 2 files changed, 38 insertions(+) create mode 100644 UefiCpuPkg/Include/Guid/MmProfileData.h diff --git a/UefiCpuPkg/Include/Guid/MmProfileData.h b/UefiCpuPkg/Include/Guid/MmProfileData.h new file mode 100644 index 000000000000..64c9f78ccda7 --- /dev/null +++ b/UefiCpuPkg/Include/Guid/MmProfileData.h @@ -0,0 +1,35 @@ +/** @file + This file contains related definitions to support MM Profile feature in standalone MM. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef MM_PROFILE_DATA_H_ +#define MM_PROFILE_DATA_H_ + +/// +/// This GUID is assigned to the Name field of EFI_HOB_MEMORY_ALLOCATION.AllocDescriptor. +/// It signifies that the corresponding EFI_HOB_MEMORY_ALLOCATION HOB points to the location of MM Profile data. +/// MM Profile is a feature designed to log accesses to non-MM regions by standalone MM. +/// It stores these access logs within the MM Profile data. +/// +#define MM_PROFILE_DATA_HOB_GUID \ + { \ + 0x26ef081d, 0x19b0, 0x4c42, {0xa2, 0x57, 0xa7, 0xf5, 0x9f, 0x8b, 0xd0, 0x38} \ + } + +/// +/// In standalone MM, the policy for accessing non-MM regions is simplified: +/// Non-MM regions and their access policies are specified by EFI_HOB_RESOURCE_DESCRIPTOR HOBs. +/// Accesses to regions marked with the MM_RESOURCE_ATTRIBUTE_LOGGING attribute +/// are permitted in standalone MM, and these accesses are logged in the MM Profile data. +/// This attribute is not utilized by the SMM Profile feature in traditional SMM. +/// +#define MM_RESOURCE_ATTRIBUTE_LOGGING 0x10000000 + +extern EFI_GUID gMmProfileDataHobGuid; + +#endif diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 5ee4efc3fab4..140500d52152 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -111,6 +111,9 @@ ## Include/Guid/MmUnblockRegion.h gMmUnblockRegionHobGuid = { 0x7c316fb3, 0x849e, 0x4ee7, { 0x87, 0xfc, 0x16, 0x2d, 0x0b, 0x03, 0x42, 0xbf }} + ## Include/Guid/MmProfileData.h + gMmProfileDataHobGuid = { 0x26ef081d, 0x19b0, 0x4c42, { 0xa2, 0x57, 0xa7, 0xf5, 0x9f, 0x8b, 0xd0, 0x38 }} + [Protocols] ## Include/Protocol/SmmCpuService.h gEfiSmmCpuServiceProtocolGuid = { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }} From 39d9e15a9ed47ca3a72c06d4279c390869fd2793 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 24 May 2024 15:17:59 +0800 Subject: [PATCH 022/280] UefiCpuPkg: Add MM CPU Sync Config definitions MM CPU Sync Config controls how BSP synchronizes with APs in x86 SMM environment. Signed-off-by: Jiaxin Wu Cc: Dun Tan Co-authored-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/Include/Guid/MmCpuSyncConfig.h | 53 +++++++++++++++++++++++ UefiCpuPkg/UefiCpuPkg.dec | 3 ++ 2 files changed, 56 insertions(+) create mode 100644 UefiCpuPkg/Include/Guid/MmCpuSyncConfig.h diff --git a/UefiCpuPkg/Include/Guid/MmCpuSyncConfig.h b/UefiCpuPkg/Include/Guid/MmCpuSyncConfig.h new file mode 100644 index 000000000000..16d96a829022 --- /dev/null +++ b/UefiCpuPkg/Include/Guid/MmCpuSyncConfig.h @@ -0,0 +1,53 @@ +/** @file + This file defines MM_CPU_SYNC_CONFIG which controls how BSP synchronizes with APs + in x86 SMM environment. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef MM_CPU_SYNC_CONFIG_H_ +#define MM_CPU_SYNC_CONFIG_H_ + +/// +/// The GUID of the MmCpuSyncConfig GUIDed HOB. +/// +#define MM_CPU_SYNC_CONFIG_HOB_GUID \ + { \ + 0x8b90bd26, 0xe4f9, 0x45c2, {0x92, 0xa2, 0x9e, 0xac, 0xe6, 0x0e, 0x9d, 0xcc} \ + } + +typedef enum { + MmCpuSyncModeTradition, + MmCpuSyncModeRelaxedAp, + MmCpuSyncModeMax +} MM_CPU_SYNC_MODE; + +/// +/// The structure defines the data layout of the MmCpuSyncConfig GUIDed HOB. +/// +typedef struct { + /// + /// 0: Traditional CPU synchronization method is used when processing an SMI. + /// 1: Relaxed CPU synchronization method is used when processing an SMI. + /// + MM_CPU_SYNC_MODE RelaxedApMode; + + /// + /// The 1st BSP/AP synchronization timeout value in SMM. + /// The value shall match with the PcdCpuSmmApSyncTimeout. + /// + UINT64 Timeout; + + /// + /// The 2nd BSP/AP synchronization timeout value in SMM. + /// The value shall match with the PcdCpuSmmApSyncTimeout2. + /// + UINT64 Timeout2; +} MM_CPU_SYNC_CONFIG; + +extern EFI_GUID gMmCpuSyncConfigHobGuid; + +#endif diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 140500d52152..5ae4af3e36bb 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -114,6 +114,9 @@ ## Include/Guid/MmProfileData.h gMmProfileDataHobGuid = { 0x26ef081d, 0x19b0, 0x4c42, { 0xa2, 0x57, 0xa7, 0xf5, 0x9f, 0x8b, 0xd0, 0x38 }} + ## Include/Guid/MmCpuSyncConfig.h + gMmCpuSyncConfigHobGuid = { 0x8b90bd26, 0xe4f9, 0x45c2, { 0x92, 0xa2, 0x9e, 0xac, 0xe6, 0x0e, 0x9d, 0xcc }} + [Protocols] ## Include/Protocol/SmmCpuService.h gEfiSmmCpuServiceProtocolGuid = { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }} From 0f36b5fa0a7834c0a4bf66125f6d37ebd0ce6c01 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 24 May 2024 15:46:51 +0800 Subject: [PATCH 023/280] UefiCpuPkg: Add ACPI S3 Enable HOB definition This HOB indicates to x86 standalone MM whether S3 is enabled. The value shall match with the PcdAcpiS3Enable. Signed-off-by: Jiaxin Wu Co-Authored-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan Cc: Yuanhao Xie --- UefiCpuPkg/Include/Guid/MmAcpiS3Enable.h | 34 ++++++++++++++++++++++++ UefiCpuPkg/UefiCpuPkg.dec | 3 +++ 2 files changed, 37 insertions(+) create mode 100644 UefiCpuPkg/Include/Guid/MmAcpiS3Enable.h diff --git a/UefiCpuPkg/Include/Guid/MmAcpiS3Enable.h b/UefiCpuPkg/Include/Guid/MmAcpiS3Enable.h new file mode 100644 index 000000000000..8c1655914ea7 --- /dev/null +++ b/UefiCpuPkg/Include/Guid/MmAcpiS3Enable.h @@ -0,0 +1,34 @@ +/** @file + This file defines ACPI_S3_ENABLE structure which indicates to x86 standalone MM whether S3 is enabled. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef MM_ACPI_S3_ENABLE_H_ +#define MM_ACPI_S3_ENABLE_H_ + +/// +/// The GUID of the MmAcpiS3Enable GUIDed HOB. +/// +#define MM_ACPI_S3_ENABLE_HOB_GUID \ + { \ + 0xe7402821, 0x2654, 0x4c1b, {0x99, 0x0e, 0x04, 0x8f, 0x8d, 0x82, 0xcf, 0x67} \ + } + +/// +/// The structure defines the data layout of the MmAcpiS3Enable GUIDed HOB. +/// +typedef struct { + /// + /// Whether ACPI S3 is enabled. + /// The value shall match with the PcdAcpiS3Enable. + /// + BOOLEAN AcpiS3Enable; +} MM_ACPI_S3_ENABLE; + +extern EFI_GUID gMmAcpiS3EnableHobGuid; + +#endif diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 5ae4af3e36bb..2cabf5fc0333 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -117,6 +117,9 @@ ## Include/Guid/MmCpuSyncConfig.h gMmCpuSyncConfigHobGuid = { 0x8b90bd26, 0xe4f9, 0x45c2, { 0x92, 0xa2, 0x9e, 0xac, 0xe6, 0x0e, 0x9d, 0xcc }} + # Include/Guid/MmAcpiS3Enable.h + gMmAcpiS3EnableHobGuid = { 0xe7402821, 0x2654, 0x4c1b, { 0x99, 0x0e, 0x04, 0x8f, 0x8d, 0x82, 0xcf, 0x67 }} + [Protocols] ## Include/Protocol/SmmCpuService.h gEfiSmmCpuServiceProtocolGuid = { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }} From 43e88014109e76909c21686783470b4d4b5d5b14 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 24 May 2024 10:16:22 +0800 Subject: [PATCH 024/280] StandaloneMmPkg: Add MmPlatformHobProducerLib library class CreateMmPlatformHob() is defined in the MmPlatformHobProducerLib library class. The function is for StandaloneMm IPL to create all Platform specific HOBs that required by the Standalone MM env. Signed-off-by: Dun Tan Co-authored-by: Jiaxin Wu Cc: Jiewen Yao Co-authored-by: Ray Ni Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- .../Library/MmPlatformHobProducerLib.h | 54 +++++++++++++++++++ StandaloneMmPkg/StandaloneMmPkg.dec | 3 ++ 2 files changed, 57 insertions(+) create mode 100644 StandaloneMmPkg/Include/Library/MmPlatformHobProducerLib.h diff --git a/StandaloneMmPkg/Include/Library/MmPlatformHobProducerLib.h b/StandaloneMmPkg/Include/Library/MmPlatformHobProducerLib.h new file mode 100644 index 000000000000..2f302bb5b18c --- /dev/null +++ b/StandaloneMmPkg/Include/Library/MmPlatformHobProducerLib.h @@ -0,0 +1,54 @@ +/** @file + MM Platform HOB Producer Library Class. + + CreateMmPlatformHob() function is called by StandaloneMm IPL to create all + Platform specific HOBs that required by Standalone MM environment. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef MM_PLATFORM_HOB_PRODUCER_LIB_H_ +#define MM_PLATFORM_HOB_PRODUCER_LIB_H_ + +/** + Create the platform specific HOBs needed by the Standalone MM environment. + + The following HOBs are created by StandaloneMm IPL common logic + hence they should NOT be created by this function: + * Single EFI_HOB_TYPE_FV to describe the Firmware Volume where MM Core resides. + * Single GUIDed (gEfiSmmSmramMemoryGuid) HOB to describe the MM regions. + * Single EFI_HOB_MEMORY_ALLOCATION_MODULE to describe the MM region used by MM Core. + * Multiple EFI_HOB_RESOURCE_DESCRIPTOR to describe the non-MM regions and their access permissions. + Note: All accessible non-MM regions should be described by EFI_HOB_RESOURCE_DESCRIPTOR HOBs. + * Single GUIDed (gMmCommBufferHobGuid) HOB to identify MM Communication buffer in non-MM region. + * Multiple GUIDed (gSmmBaseHobGuid) HOB to describe the SMM base address of each processor. + * Multiple GUIDed (gMpInformation2HobGuid) HOB to describe the MP information. + * Single GUIDed (gMmCpuSyncConfigHobGuid) HOB to describe how BSP synchronizes with APs in x86 SMM. + * Single GUIDed (gMmAcpiS3EnableHobGuid) HOB to describe the ACPI S3 enable status. + * Single GUIDed (gEfiAcpiVariableGuid) HOB to identify the S3 data root region in x86. + * Single GUIDed (gMmProfileDataHobGuid) HOB to describe the MM profile data region. + + @param[in] Buffer The free buffer to be used for HOB creation. + @param[in, out] BufferSize The buffer size. + On return, the expected/used size. + + @retval RETURN_INVALID_PARAMETER BufferSize is NULL. + @retval RETURN_INVALID_PARAMETER Buffer is NULL and BufferSize is not 0. + @retval RETURN_BUFFER_TOO_SMALL The buffer is too small for HOB creation. + BufferSize is updated to indicate the expected buffer size. + When the input BufferSize is bigger than the expected buffer size, + the BufferSize value will be changed to the used buffer size. + @retval RETURN_SUCCESS The HOB list is created successfully. + +**/ +EFI_STATUS +EFIAPI +CreateMmPlatformHob ( + IN VOID *Buffer, + IN OUT UINTN *BufferSize + ); + +#endif diff --git a/StandaloneMmPkg/StandaloneMmPkg.dec b/StandaloneMmPkg/StandaloneMmPkg.dec index fc91bb4c3e11..a23a0f8f2fce 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dec +++ b/StandaloneMmPkg/StandaloneMmPkg.dec @@ -29,6 +29,9 @@ ## MM Memory Operation. MemLib|Include/Library/StandaloneMmMemLib.h +[LibraryClasses.X64.PEIM] + MmPlatformHobProducerLib|Include/Library/MmPlatformHobProducerLib.h + [LibraryClasses.AArch64, LibraryClasses.ARM] ## @libraryclass Defines a set of interfaces for the MM core entrypoint for ## AArch64 and ARM. From 56908fd4be285b0ebb96855fe4dec1124879c5c2 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Thu, 23 May 2024 14:26:37 +0800 Subject: [PATCH 025/280] StandaloneMmPkg/StandaloneMmPkg.dec: Add gEventMmDispatchGuid MmIpl shall use gEventMmDispatchGuid to initialize EFI_MM_COMMUNICATE_HEADER structure, and then communicate with MmCore to dispatch all StandaloneMm drivers in SMM environment. Signed-off-by: Jiaxin Wu Co-authored-by: Hongbin1 Zhang Cc: Jiewen Yao Co-Authored-by: Ray Ni Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Star Zeng Co-Authored-by: Wei6 Xu Cc: Dun Tan Cc: Yuanhao Xie --- StandaloneMmPkg/StandaloneMmPkg.dec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/StandaloneMmPkg/StandaloneMmPkg.dec b/StandaloneMmPkg/StandaloneMmPkg.dec index a23a0f8f2fce..25e660b2476d 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dec +++ b/StandaloneMmPkg/StandaloneMmPkg.dec @@ -3,6 +3,7 @@ # required by Standalone MM platform. # # Copyright (c) 2016-2021, Arm Ltd. All rights reserved.
+# Copyright (c) 2024, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -51,6 +52,8 @@ gEfiStandaloneMmNonSecureBufferGuid = { 0xf00497e3, 0xbfa2, 0x41a1, { 0x9d, 0x29, 0x54, 0xc2, 0xe9, 0x37, 0x21, 0xc5 }} gEfiMmCpuDriverEpDescriptorGuid = { 0x6ecbd5a1, 0xc0f8, 0x4702, { 0x83, 0x01, 0x4f, 0xc2, 0xc5, 0x47, 0x0a, 0x51 }} + gEventMmDispatchGuid = { 0x7e6efffa, 0x69b4, 0x4c1b, { 0xa4, 0xc7, 0xaf, 0xf9, 0xc9, 0x24, 0x4f, 0xee }} + [PcdsFixedAtBuild, PcdsPatchableInModule] ## Maximum permitted encapsulation levels of sections in a firmware volume, # in the MM phase. Minimum value is 1. Sections nested more deeply are rejected. From 630e819bf3fb4aa3485f29ba498341c8b277e02b Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 24 May 2024 09:35:22 +0800 Subject: [PATCH 026/280] StandaloneMmPkg/StandaloneMmPkg.ci.yaml: Add UefiCpuPkg dependency StandaloneMmPkg need to use header file defined under UefiCpuPkg to support StandaloneMm features. Signed-off-by: Hongbin1 Zhang Cc: Jiewen Yao Cc: Ray Ni Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Star Zeng Cc: Wei6 Xu Cc: Dun Tan Cc: Yuanhao Xie Acked-by: Jiaxin Wu --- StandaloneMmPkg/StandaloneMmPkg.ci.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/StandaloneMmPkg/StandaloneMmPkg.ci.yaml b/StandaloneMmPkg/StandaloneMmPkg.ci.yaml index 4777532a7ede..e11449c6fb38 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.ci.yaml +++ b/StandaloneMmPkg/StandaloneMmPkg.ci.yaml @@ -1,6 +1,7 @@ ## @file # CI configuration for StandaloneMmPkg # +# Copyright (c) 2024, Intel Corporation. All rights reserved.
# Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent ## @@ -39,7 +40,8 @@ "EmbeddedPkg/EmbeddedPkg.dec", "StandaloneMmPkg/StandaloneMmPkg.dec", "MdeModulePkg/MdeModulePkg.dec", - "MdePkg/MdePkg.dec" + "MdePkg/MdePkg.dec", + "UefiCpuPkg/UefiCpuPkg.dec" ], # For host based unit tests "AcceptableDependencies-HOST_APPLICATION":[ From 8f219119518ea48930c891602fd7609ffb881539 Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Tue, 25 Jun 2024 11:36:48 +0800 Subject: [PATCH 027/280] UefiCpuPkg: Add MM Unblock Page Library This library provides an interface to request non-MMRAM pages to be mapped/unblocked from inside MM environment. For MM modules that need to access areas outside of MMRAMs, the agents responsible for setting up these regions must use this API to enable access to these memory areas from within MM. During the IPL, when RestrictedMemoryAccess is enabled, this unblocked memory is specifically used to create a BuildResourceHob, which allocates storage for the SMM accessible DRAM (non-MMIO) range. Cc: Liming Gao Cc: Jiaxin Wu Cc: Ray Ni Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan Signed-off-by: Yuanhao Xie --- .../MmUnblockMemoryLib/MmUnblockMemoryLib.c | 81 +++++++++++++++++++ .../MmUnblockMemoryLib/MmUnblockMemoryLib.inf | 47 +++++++++++ 2 files changed, 128 insertions(+) create mode 100644 UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.c create mode 100644 UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.inf diff --git a/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.c b/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.c new file mode 100644 index 000000000000..790392b19d0d --- /dev/null +++ b/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.c @@ -0,0 +1,81 @@ +/** @file + The instance of MM Unblock Page Library. + This library provides an interface to request non-MMRAM pages to be mapped/unblocked + from inside MM environment. + For MM modules that need to access regions outside of MMRAMs, the agents that set up + these regions are responsible for invoking this API in order for these memory areas + to be accessed from inside MM. + + Copyright (c) Microsoft Corporation. + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include +#include +#include +#include +#include +#include +#include +#include + +/** + This API provides a way to unblock certain data pages to be accessible inside MM environment. + + @param UnblockAddress The address of buffer caller requests to unblock, the address + has to be page aligned. + @param NumberOfPages The number of pages requested to be unblocked from MM + environment. + @retval RETURN_SUCCESS The request goes through successfully. + @retval RETURN_NOT_AVAILABLE_YET The requested functionality is not produced yet. + @retval RETURN_UNSUPPORTED The requested functionality is not supported on current platform. + @retval RETURN_SECURITY_VIOLATION The requested address failed to pass security check for + unblocking. + @retval RETURN_INVALID_PARAMETER Input address either NULL pointer or not page aligned. + @retval RETURN_ACCESS_DENIED The request is rejected due to system has passed certain boot + phase. +**/ +EFI_STATUS +EFIAPI +MmUnblockMemoryRequest ( + IN EFI_PHYSICAL_ADDRESS UnblockAddress, + IN UINT64 NumberOfPages + ) +{ + EFI_STATUS Status; + MM_UNBLOCK_REGION *MmUnblockMemoryHob; + EFI_PEI_MM_COMMUNICATION_PPI *MmCommunicationPpi; + + if (!IS_ALIGNED (UnblockAddress, SIZE_4KB)) { + DEBUG ((DEBUG_ERROR, "Error: UnblockAddress is not 4KB aligned: %p\n", UnblockAddress)); + return EFI_INVALID_PARAMETER; + } + + // + // Unblock requests are rejected when MmIpl finishes execution. + // + Status = PeiServicesLocatePpi (&gEfiPeiMmCommunicationPpiGuid, 0, NULL, (VOID **)&MmCommunicationPpi); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Unblock requests are rejected since the MmIpl finishes execution\n")); + return RETURN_ACCESS_DENIED; + } + + // + // Build the GUID'd HOB for MmCore + // + MmUnblockMemoryHob = BuildGuidHob (&gMmUnblockRegionHobGuid, sizeof (MM_UNBLOCK_REGION)); + if (MmUnblockMemoryHob == NULL) { + DEBUG ((DEBUG_ERROR, "MmUnblockMemoryRequest: Failed to allocate hob for unblocked data parameter!!\n")); + return Status; + } + + ZeroMem (MmUnblockMemoryHob, sizeof (MM_UNBLOCK_REGION)); + + // + // Caller ID is filled in. + // + CopyGuid (&MmUnblockMemoryHob->IdentifierGuid, &gEfiCallerIdGuid); + MmUnblockMemoryHob->PhysicalStart = UnblockAddress; + MmUnblockMemoryHob->NumberOfPages = NumberOfPages; + return EFI_SUCCESS; +} diff --git a/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.inf b/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.inf new file mode 100644 index 000000000000..c3c748d398ac --- /dev/null +++ b/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.inf @@ -0,0 +1,47 @@ +## @file +# Instance of MM Unblock Page Library. +# +# This library provides an interface to request non-MMRAM pages to be mapped/unblocked +# from inside MM environment. +# +# For MM modules that need to access regions outside of MMRAMs, the agents that set up +# these regions are responsible for invoking this API in order for these memory areas +# to be accessed from inside MM. +# +# Copyright (c) Microsoft Corporation. +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = MmUnblockMemoryLib + FILE_GUID = CBFE5800-70FD-4D9A-AA78-DB617294077E + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = MmUnblockMemoryLib + +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + MmUnblockMemoryLib.c + +[Packages] + UefiCpuPkg/UefiCpuPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + HobLib + DebugLib + BaseMemoryLib + PeiServicesLib + +[Ppis] + gEfiPeiMmCommunicationPpiGuid + +[Guids] + gMmUnblockRegionHobGuid From c0b1ad64e45ff356657b0220c532211096c4d5bd Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Fri, 5 Jul 2024 15:05:35 +0800 Subject: [PATCH 028/280] UefiCpuPkg: Enable MmUnblockMemoryLib Cc: Liming Gao Cc: Jiaxin Wu Cc: Ray Ni Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan Signed-off-by: Yuanhao Xie --- UefiCpuPkg/UefiCpuPkg.dsc | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 1b52760e1a60..34d0d45bf624 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -128,6 +128,7 @@ UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf UefiCpuPkg/MicrocodeMeasurementDxe/MicrocodeMeasurementDxe.inf + UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.inf [Components.IA32, Components.X64] UefiCpuPkg/CpuDxe/CpuDxe.inf From 0806fb60d4502c05f378cdbf4cdeca9be5ff502a Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Tue, 11 Jun 2024 12:16:42 +0800 Subject: [PATCH 029/280] StandaloneMmPkg: Create null instance for MmPlatformHobProducerLib Create null instance MmPlatformHobProducerLibNull.inf for MmPlatformHobProducerLib. Signed-off-by: Dun Tan --- .../MmPlatformHobProducerLibNull.c | 66 +++++++++++++++++++ .../MmPlatformHobProducerLibNull.inf | 28 ++++++++ StandaloneMmPkg/StandaloneMmPkg.dsc | 2 + 3 files changed, 96 insertions(+) create mode 100644 StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.c create mode 100644 StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf diff --git a/StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.c b/StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.c new file mode 100644 index 000000000000..814ea1c4a0e2 --- /dev/null +++ b/StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.c @@ -0,0 +1,66 @@ +/** @file + Null instance of MM Platform HOB Producer Library Class. + + CreateMmPlatformHob() function is called by StandaloneMm IPL to create all + Platform specific HOBs that required by Standalone MM environment. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +/** + Create the platform specific HOBs needed by the Standalone MM environment. + + The following HOBs are created by StandaloneMm IPL common logic. + Hence they should NOT be created by this function: + * Single EFI_HOB_TYPE_FV to describe the Firmware Volume where MM Core resides. + * Single GUIDed (gEfiSmmSmramMemoryGuid) HOB to describe the MM regions. + * Single EFI_HOB_MEMORY_ALLOCATION_MODULE to describe the MM region used by MM Core. + * Multiple EFI_HOB_RESOURCE_DESCRIPTOR to describe the non-MM regions and their access permissions. + Note: All accessible non-MM regions should be described by EFI_HOB_RESOURCE_DESCRIPTOR HOBs. + * Single GUIDed (gMmCommBufferHobGuid) HOB to identify MM Communication buffer in non-MM region. + * Multiple GUIDed (gSmmBaseHobGuid) HOB to describe the SMM base address of each processor. + * Multiple GUIDed (gMpInformation2HobGuid) HOB to describe the MP information. + * Single GUIDed (gMmCpuSyncConfigHobGuid) HOB to describe how BSP synchronizes with APs in x86 SMM. + * Single GUIDed (gMmAcpiS3EnableHobGuid) HOB to describe the ACPI S3 enable status. + * Single GUIDed (gEfiAcpiVariableGuid) HOB to identify the S3 data root region in x86. + * Single GUIDed (gMmProfileDataHobGuid) HOB to describe the MM profile data region. + + @param[in] Buffer The free buffer to be used for HOB creation. + @param[in, out] BufferSize The buffer size. + On return, the expected/used size. + + @retval RETURN_INVALID_PARAMETER BufferSize is NULL. + @retval RETURN_INVALID_PARAMETER Buffer is NULL and BufferSize is not 0. + @retval RETURN_BUFFER_TOO_SMALL The buffer is too small for HOB creation. + BufferSize is updated to indicate the expected buffer size. + When the input BufferSize is bigger than the expected buffer size, + the BufferSize value will be changed to the used buffer size. + @retval RETURN_SUCCESS The HOB list is created successfully. + +**/ +EFI_STATUS +EFIAPI +CreateMmPlatformHob ( + IN VOID *Buffer, + IN OUT UINTN *BufferSize + ) +{ + if (BufferSize == NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((*BufferSize != 0) && (Buffer == NULL)) { + return RETURN_INVALID_PARAMETER; + } + + *BufferSize = 0; + + return EFI_SUCCESS; +} diff --git a/StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf b/StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf new file mode 100644 index 000000000000..64e1ac185fdf --- /dev/null +++ b/StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf @@ -0,0 +1,28 @@ +## @file +# Null instance of MM Platform HOB Producer Library Class. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = MmPlatformHobProducerLibNull + FILE_GUID = DE6B5E7C-6636-4646-90F8-776408157750 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = MmPlatformHobProducerLib + +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + MmPlatformHobProducerLibNull.c + +[Packages] + MdePkg/MdePkg.dec + StandaloneMmPkg/StandaloneMmPkg.dec diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc index 39aea898bbe1..fc2c12447dd9 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -60,6 +60,7 @@ StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf VariableMmDependency|StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf HobPrintLib|MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf + MmPlatformHobProducerLib|StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf [LibraryClasses.AARCH64, LibraryClasses.ARM] ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf @@ -119,6 +120,7 @@ StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.inf + StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf [Components.AARCH64, Components.ARM] StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf From eef29d5100b4f4879d8280f5074ccc00e5067e01 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Wed, 12 Jun 2024 10:59:53 +0800 Subject: [PATCH 030/280] StandaloneMmPkg: Add a new MmCommunicationDxe driver Add a new MmCommunicationDxe driver. The driver is to: 1.Install gEfiMmCommunication2ProtocolGuid 2.Install gEfiMmCommunicationProtocolGuid 3.Create the notifications of some protocols and event that the Standalone Mm requires Signed-off-by: Dun Tan --- .../MmCommunicationDxe/MmCommunicationDxe.c | 30 +++++++++++++++ .../MmCommunicationDxe/MmCommunicationDxe.h | 11 ++++++ .../MmCommunicationDxe/MmCommunicationDxe.inf | 37 +++++++++++++++++++ StandaloneMmPkg/StandaloneMmPkg.dsc | 11 ++++++ 4 files changed, 89 insertions(+) create mode 100644 StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c create mode 100644 StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h create mode 100644 StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c new file mode 100644 index 000000000000..a985d9b8039a --- /dev/null +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c @@ -0,0 +1,30 @@ +/** @file + MmCommunicationDxe driver produces MmCommunication protocol and + create the notifications of some protocols and event. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MmCommunicationDxe.h" + +/** + The Entry Point for MmCommunicateDxe driver. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval Other Some error occurred when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +MmCommunicationEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return EFI_SUCCESS; +} diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h new file mode 100644 index 000000000000..1e98aa1e8b8a --- /dev/null +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h @@ -0,0 +1,11 @@ +/** @file + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef MM_COMMUNICATION_DXE_H_ +#define MM_COMMUNICATION_DXE_H_ + +#endif diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf new file mode 100644 index 000000000000..acfc5e433c44 --- /dev/null +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf @@ -0,0 +1,37 @@ +## @file +# MmCommunicationDxe driver produces MmCommunication protocol and +# create the notifications of some protocols and event. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = MmCommunicationDxe + FILE_GUID = 8d4b8bc7-e66b-4be2-add8-4988e08743ed + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x00010032 + ENTRY_POINT = MmCommunicationEntryPoint + +[Sources] + MmCommunicationDxe.c + MmCommunicationDxe.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + StandaloneMmPkg/StandaloneMmPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + +[Guids] + +[Protocols] + +[Depex] diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc index fc2c12447dd9..20a05d0ebfc2 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -78,6 +78,16 @@ [LibraryClasses.common.MM_STANDALONE] MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf +[LibraryClasses.common.DXE_RUNTIME_DRIVER] + UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + ################################################################################ # # Pcd Section - list of all EDK II PCD Entries defined by this Platform @@ -121,6 +131,7 @@ StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.inf StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf + StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf [Components.AARCH64, Components.ARM] StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf From cf9b5684059e9740ff63da9af7bbc8172c9247dd Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Wed, 12 Jun 2024 11:04:37 +0800 Subject: [PATCH 031/280] StandaloneMmPkg: Install gEfiMmCommunication2ProtocolGuid Install gEfiMmCommunication2ProtocolGuid in the MmCommunicationDxe driver. Signed-off-by: Dun Tan --- .../MmCommunicationDxe/MmCommunicationDxe.c | 196 ++++++++++++++++++ .../MmCommunicationDxe/MmCommunicationDxe.h | 51 +++++ .../MmCommunicationDxe/MmCommunicationDxe.inf | 13 ++ 3 files changed, 260 insertions(+) diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c index a985d9b8039a..e216de529fe3 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c @@ -9,6 +9,161 @@ #include "MmCommunicationDxe.h" +// +// PI 1.7 MM Communication Protocol 2 instance +// +EFI_MM_COMMUNICATION2_PROTOCOL mMmCommunication2 = { + MmCommunicate2 +}; + +MM_COMM_BUFFER mMmCommonBuffer; +EFI_SMM_CONTROL2_PROTOCOL *mSmmControl2; + +/** + Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE. + + This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event. + It convers pointer to new virtual address. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +MmVirtualAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EfiConvertPointer (0x0, (VOID **)&mMmCommonBuffer.Status); + EfiConvertPointer (0x0, (VOID **)&mMmCommonBuffer.PhysicalStart); + EfiConvertPointer (0x0, (VOID **)&mSmmControl2); +} + +/** + Processes the communication buffer for Mm communication protocols. + + This function encapsulates the common logic for handling communication buffers + used by MmCommunicate2 functions. + + @param[in, out] CommBuffer Pointer to the MM communication buffer + @param[in, out] CommSize The size of the data buffer being passed in. On exit, the size of data + being returned. Zero if the handler does not wish to reply with any data. + This parameter is optional and may be NULL. + + @retval EFI_SUCCESS The message was successfully posted. + @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. + @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation. + If this error is returned, the MessageLength field + in the CommBuffer header or the integer pointed by + CommSize, are updated to reflect the maximum payload + size the implementation can accommodate. + @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter, + if not omitted, are in address range that cannot be + accessed by the MM environment. +**/ +EFI_STATUS +EFIAPI +ProcessCommunicationBuffer ( + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommSize OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_MM_COMMUNICATE_HEADER *CommunicateHeader; + MM_COMM_BUFFER_STATUS *CommonBufferStatus; + UINTN BufferSize; + + // + // Check parameters + // + if (CommBuffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)CommBuffer; + BufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength; + + if (CommSize != NULL) { + ASSERT (*CommSize == BufferSize); + } + + CommonBufferStatus = (MM_COMM_BUFFER_STATUS *)(UINTN)mMmCommonBuffer.Status; + + // + // Copy the content at input CommBuffer to fixed MM communication buffer + // if CommBuffer is not equal to fixed MM communication buffer. + // + if ((UINTN)CommBuffer != mMmCommonBuffer.PhysicalStart) { + CopyMem ((VOID *)(UINTN)mMmCommonBuffer.PhysicalStart, CommBuffer, BufferSize); + } + + CommonBufferStatus->IsCommBufferValid = TRUE; + + // + // Generate Software SMI + // + Status = mSmmControl2->Trigger (mSmmControl2, NULL, NULL, FALSE, 0); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + // + // Copy the returned data to the non-mmram buffer (CommBuffer) + // + if ((UINTN)CommBuffer != mMmCommonBuffer.PhysicalStart) { + CopyMem (CommBuffer, (VOID *)(UINTN)mMmCommonBuffer.PhysicalStart, CommonBufferStatus->ReturnBufferSize); + } + + // + // Retrieve BufferSize and return status from CommonBufferStatus + // + if (CommSize != NULL) { + *CommSize = CommonBufferStatus->ReturnBufferSize; + } + + CommonBufferStatus->IsCommBufferValid = FALSE; + + return CommonBufferStatus->ReturnStatus; +} + +/** + Communicates with a registered handler. + + This function provides a service to send and receive messages from a registered UEFI service. + + @param[in] This The EFI_MM_COMMUNICATION_PROTOCOL instance. + @param[in, out] CommBufferPhysical Physical address of the MM communication buffer. + @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer. + @param[in, out] CommSize The size of the data buffer being passed in. On exit, the size of data + being returned. Zero if the handler does not wish to reply with any data. + This parameter is optional and may be NULL. + + @retval EFI_SUCCESS The message was successfully posted. + @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. + @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation. + If this error is returned, the MessageLength field + in the CommBuffer header or the integer pointed by + CommSize, are updated to reflect the maximum payload + size the implementation can accommodate. + @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter, + if not omitted, are in address range that cannot be + accessed by the MM environment. + +**/ +EFI_STATUS +EFIAPI +MmCommunicate2 ( + IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This, + IN OUT VOID *CommBufferPhysical, + IN OUT VOID *CommBufferVirtual, + IN OUT UINTN *CommSize OPTIONAL + ) +{ + return ProcessCommunicationBuffer (CommBufferVirtual, CommSize); +} + /** The Entry Point for MmCommunicateDxe driver. @@ -26,5 +181,46 @@ MmCommunicationEntryPoint ( IN EFI_SYSTEM_TABLE *SystemTable ) { + EFI_STATUS Status; + EFI_HANDLE Handle; + EFI_HOB_GUID_TYPE *GuidHob; + MM_COMM_BUFFER *MmCommonBuffer; + + // + // Locate gMmCommBufferHobGuid and cache the content + // + GuidHob = GetFirstGuidHob (&gMmCommBufferHobGuid); + ASSERT (GuidHob != NULL); + MmCommonBuffer = GET_GUID_HOB_DATA (GuidHob); + CopyMem (&mMmCommonBuffer, MmCommonBuffer, sizeof (MM_COMM_BUFFER)); + + // + // Get SMM Control2 Protocol + // + Status = gBS->LocateProtocol (&gEfiSmmControl2ProtocolGuid, NULL, (VOID **)&mSmmControl2); + ASSERT_EFI_ERROR (Status); + + Handle = NULL; + Status = gBS->InstallProtocolInterface ( + &Handle, + &gEfiMmCommunication2ProtocolGuid, + EFI_NATIVE_INTERFACE, + &mMmCommunication2 + ); + ASSERT_EFI_ERROR (Status); + + // + // Register the event to convert the pointer for runtime. + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + MmVirtualAddressChangeEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + NULL + ); + ASSERT_EFI_ERROR (Status); + return EFI_SUCCESS; } diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h index 1e98aa1e8b8a..90cab5e64f26 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h @@ -8,4 +8,55 @@ #ifndef MM_COMMUNICATION_DXE_H_ #define MM_COMMUNICATION_DXE_H_ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +/** + Communicates with a registered handler. + + This function provides a service to send and receive messages from a registered UEFI service. + + @param[in] This The EFI_MM_COMMUNICATION_PROTOCOL instance. + @param[in, out] CommBufferPhysical Physical address of the MM communication buffer. + @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer. + @param[in, out] CommSize The size of the data buffer being passed in. On exit, the size of data + being returned. Zero if the handler does not wish to reply with any data. + This parameter is optional and may be NULL. + + @retval EFI_SUCCESS The message was successfully posted. + @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. + @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation. + If this error is returned, the MessageLength field + in the CommBuffer header or the integer pointed by + CommSize, are updated to reflect the maximum payload + size the implementation can accommodate. + @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter, + if not omitted, are in address range that cannot be + accessed by the MM environment. + +**/ +EFI_STATUS +EFIAPI +MmCommunicate2 ( + IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This, + IN OUT VOID *CommBufferPhysical, + IN OUT VOID *CommBufferVirtual, + IN OUT UINTN *CommSize OPTIONAL + ); + #endif diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf index acfc5e433c44..55c6611258a3 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf @@ -29,9 +29,22 @@ [LibraryClasses] UefiDriverEntryPoint + BaseLib + DebugLib + HobLib + BaseMemoryLib + MemoryAllocationLib + UefiBootServicesTableLib + UefiLib + UefiRuntimeLib [Guids] + gMmCommBufferHobGuid + gEfiEventVirtualAddressChangeGuid [Protocols] + gEfiMmCommunication2ProtocolGuid + gEfiSmmControl2ProtocolGuid [Depex] + gEfiSmmControl2ProtocolGuid From a2a8558958cee97efd132361a2b29f2ee8339d91 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Tue, 11 Jun 2024 11:37:39 +0800 Subject: [PATCH 032/280] StandaloneMmPkg: Install gEfiMmCommunicationProtocolGuid Install gEfiMmCommunicationProtocolGuid instance in the MmCommunicationDxe driver. Signed-off-by: Dun Tan --- .../MmCommunicationDxe/MmCommunicationDxe.c | 51 ++++++++++++++++++- .../MmCommunicationDxe/MmCommunicationDxe.h | 32 ++++++++++++ .../MmCommunicationDxe/MmCommunicationDxe.inf | 1 + 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c index e216de529fe3..b4c634db7757 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c @@ -16,6 +16,13 @@ EFI_MM_COMMUNICATION2_PROTOCOL mMmCommunication2 = { MmCommunicate2 }; +// +// PI 1.7 MM Communication Protocol instance +// +EFI_MM_COMMUNICATION_PROTOCOL mMmCommunication = { + MmCommunicate +}; + MM_COMM_BUFFER mMmCommonBuffer; EFI_SMM_CONTROL2_PROTOCOL *mSmmControl2; @@ -45,7 +52,7 @@ MmVirtualAddressChangeEvent ( Processes the communication buffer for Mm communication protocols. This function encapsulates the common logic for handling communication buffers - used by MmCommunicate2 functions. + used by MmCommunicate2 and MmCommunicate functions. @param[in, out] CommBuffer Pointer to the MM communication buffer @param[in, out] CommSize The size of the data buffer being passed in. On exit, the size of data @@ -164,6 +171,40 @@ MmCommunicate2 ( return ProcessCommunicationBuffer (CommBufferVirtual, CommSize); } +/** + Communicates with a registered handler. + + This function provides a service to send and receive messages from a registered UEFI service. + + @param[in] This The EFI_MM_COMMUNICATION_PROTOCOL instance. + @param[in, out] CommBuffer Pointer to the MM communication buffer + @param[in, out] CommSize The size of the data buffer being passed in. On exit, the size of data + being returned. Zero if the handler does not wish to reply with any data. + This parameter is optional and may be NULL. + + @retval EFI_SUCCESS The message was successfully posted. + @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. + @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation. + If this error is returned, the MessageLength field + in the CommBuffer header or the integer pointed by + CommSize, are updated to reflect the maximum payload + size the implementation can accommodate. + @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter, + if not omitted, are in address range that cannot be + accessed by the MM environment. + +**/ +EFI_STATUS +EFIAPI +MmCommunicate ( + IN CONST EFI_MM_COMMUNICATION_PROTOCOL *This, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommSize OPTIONAL + ) +{ + return ProcessCommunicationBuffer (CommBuffer, CommSize); +} + /** The Entry Point for MmCommunicateDxe driver. @@ -209,6 +250,14 @@ MmCommunicationEntryPoint ( ); ASSERT_EFI_ERROR (Status); + Status = gBS->InstallProtocolInterface ( + &Handle, + &gEfiMmCommunicationProtocolGuid, + EFI_NATIVE_INTERFACE, + &mMmCommunication + ); + ASSERT_EFI_ERROR (Status); + // // Register the event to convert the pointer for runtime. // diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h index 90cab5e64f26..603cc7691c5a 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -59,4 +60,35 @@ MmCommunicate2 ( IN OUT UINTN *CommSize OPTIONAL ); +/** + Communicates with a registered handler. + + This function provides a service to send and receive messages from a registered UEFI service. + + @param[in] This The EFI_MM_COMMUNICATION_PROTOCOL instance. + @param[in, out] CommBufferPhysical Physical address of the MM communication buffer + @param[in, out] CommSize The size of the data buffer being passed in. On exit, the size of data + being returned. Zero if the handler does not wish to reply with any data. + This parameter is optional and may be NULL. + + @retval EFI_SUCCESS The message was successfully posted. + @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. + @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation. + If this error is returned, the MessageLength field + in the CommBuffer header or the integer pointed by + CommSize, are updated to reflect the maximum payload + size the implementation can accommodate. + @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter, + if not omitted, are in address range that cannot be + accessed by the MM environment. + +**/ +EFI_STATUS +EFIAPI +MmCommunicate ( + IN CONST EFI_MM_COMMUNICATION_PROTOCOL *This, + IN OUT VOID *CommBufferPhysical, + IN OUT UINTN *CommSize OPTIONAL + ); + #endif diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf index 55c6611258a3..c46a3ba8bb85 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf @@ -45,6 +45,7 @@ [Protocols] gEfiMmCommunication2ProtocolGuid gEfiSmmControl2ProtocolGuid + gEfiMmCommunicationProtocolGuid [Depex] gEfiSmmControl2ProtocolGuid From d64766bde654a57e3e329e8e6a906e993df6a58c Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Tue, 11 Jun 2024 11:40:24 +0800 Subject: [PATCH 033/280] StandaloneMmPkg: Create some notification of protocol and Event Create the notifications of some protocols and event that the Standalone Mm requires in MmCommunicationDxe: gEfiDxeMmReadyToLockProtocolGuid gEfiEventExitBootServicesGuid gEfiEventVirtualAddressChangeGuid gEfiEndOfDxeEventGroupGuid gEfiEventReadyToBootGuid Signed-off-by: Dun Tan --- .../MmCommunicationDxe/MmCommunicationDxe.c | 223 +++++++++++++++++- .../MmCommunicationDxe/MmCommunicationDxe.h | 82 +++++++ .../MmCommunicationDxe/MmCommunicationDxe.inf | 7 +- 3 files changed, 301 insertions(+), 11 deletions(-) diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c index b4c634db7757..7b1e0636ff1f 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c @@ -25,6 +25,189 @@ EFI_MM_COMMUNICATION_PROTOCOL mMmCommunication = { MM_COMM_BUFFER mMmCommonBuffer; EFI_SMM_CONTROL2_PROTOCOL *mSmmControl2; +EFI_SMM_ACCESS2_PROTOCOL *mSmmAccess; +BOOLEAN mSmmLocked = FALSE; +BOOLEAN mEndOfDxe = FALSE; + +// +// Table of Protocol notification and GUIDed Event notifications that the Standalone Mm requires +// +MM_EVENT_NOTIFICATION mMmEvents[] = { + // + // Declare protocol notification on DxeMmReadyToLock protocols. When this notification is established, + // the associated event is immediately signalled, so the notification function will be executed and the + // DXE Mm Ready To Lock Protocol will be found if it is already in the handle database. + // + { ProtocolNotify, TRUE, &gEfiDxeMmReadyToLockProtocolGuid, MmReadyToLockEventNotify, &gEfiDxeMmReadyToLockProtocolGuid, NULL }, + // + // Declare event notification on Ready To Boot Event Group. This is an extra event notification that is + // used to make sure SMRAM is locked before any boot options are processed. + // + { EventNotify, TRUE, &gEfiEventReadyToBootGuid, MmReadyToLockEventNotify, &gEfiEventReadyToBootGuid, NULL }, + // + // Declare event notification on Ready To Boot Event Group. This is used to inform the MM Core + // to notify MM driver that system enter ready to boot. + // + { EventNotify, FALSE, &gEfiEventReadyToBootGuid, MmGuidedEventNotify, &gEfiEventReadyToBootGuid, NULL }, + // + // Declare event notification on EndOfDxe event. When this notification is established, + // the associated event is immediately signalled, so the notification function will be executed and the + // End Of Dxe Protocol will be found if it is already in the handle database. + // + { EventNotify, TRUE, &gEfiEndOfDxeEventGroupGuid, MmGuidedEventNotify, &gEfiEndOfDxeEventGroupGuid, NULL }, + // + // Declare event notification on EndOfDxe event. This is used to set EndOfDxe event signaled flag. + // + { EventNotify, TRUE, &gEfiEndOfDxeEventGroupGuid, MmEndOfDxeEventNotify, &gEfiEndOfDxeEventGroupGuid, NULL }, + // + // Declare event notification on Exit Boot Services Event Group. This is used to inform the MM Core + // to notify MM driver that system enter exit boot services. + // + { EventNotify, FALSE, &gEfiEventExitBootServicesGuid, MmGuidedEventNotify, &gEfiEventExitBootServicesGuid, NULL }, + // + // Declare event notification on SetVirtualAddressMap() Event Group. This is used to convert fixed MM communication buffer + // and MM_COMM_BUFFER_STATUS in mMmCommonBuffer, mSmmControl2 from physical addresses to virtual addresses. + // + { EventNotify, FALSE, &gEfiEventVirtualAddressChangeGuid, MmVirtualAddressChangeEvent, NULL, NULL }, + // + // Terminate the table of event notifications + // + { EndNotify, FALSE, NULL, NULL, NULL, NULL } +}; + +/** + Event notification that is fired when GUIDed Event Group is signaled. + + @param Event The Event that is being processed, not used. + @param Context Event Context, not used. + +**/ +VOID +EFIAPI +MmGuidedEventNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + UINTN Size; + EFI_MM_COMMUNICATE_HEADER *CommunicateHeader; + + CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mMmCommonBuffer.PhysicalStart; + + // + // Use Guid to initialize EFI_MM_COMMUNICATE_HEADER structure + // + CopyGuid (&CommunicateHeader->HeaderGuid, (EFI_GUID *)Context); + CommunicateHeader->MessageLength = 1; + CommunicateHeader->Data[0] = 0; + + // + // Generate the Software SMI and return the result + // + Size = sizeof (EFI_MM_COMMUNICATE_HEADER); + MmCommunicate2 (&mMmCommunication2, CommunicateHeader, CommunicateHeader, &Size); +} + +/** + Event notification that is fired every time a DxeSmmReadyToLock protocol is added + or if gEfiEventReadyToBootGuid is signaled. + + @param Event The Event that is being processed, not used. + @param Context Event Context, not used. + +**/ +VOID +EFIAPI +MmReadyToLockEventNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + VOID *Interface; + UINTN Index; + + // + // See if we are already locked + // + if (mSmmLocked) { + return; + } + + // + // Make sure this notification is for this handler + // + if (CompareGuid ((EFI_GUID *)Context, &gEfiDxeMmReadyToLockProtocolGuid)) { + Status = gBS->LocateProtocol (&gEfiDxeMmReadyToLockProtocolGuid, NULL, &Interface); + if (EFI_ERROR (Status)) { + return; + } + } else { + // + // If MM is not locked yet and we got here from gEfiEventReadyToBootGuid being + // signaled, then gEfiDxeMmReadyToLockProtocolGuid was not installed as expected. + // Print a warning on debug builds. + // + DEBUG ((DEBUG_WARN, "DXE Mm Ready To Lock Protocol not installed before Ready To Boot signal\n")); + } + + if (!mEndOfDxe) { + DEBUG ((DEBUG_ERROR, "EndOfDxe Event must be signaled before DxeSmmReadyToLock Protocol installation!\n")); + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED, + (EFI_SOFTWARE_SMM_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE) + ); + ASSERT (FALSE); + } + + // + // Lock the SMRAM (Note: Locking SMRAM may not be supported on all platforms) + // + mSmmAccess->Lock (mSmmAccess); + + // + // Close protocol and event notification events that do not apply after the + // DXE MM Ready To Lock Protocol has been installed or the Ready To Boot + // event has been signalled. + // + for (Index = 0; mMmEvents[Index].NotifyFunction != NULL; Index++) { + if (mMmEvents[Index].CloseOnLock) { + gBS->CloseEvent (mMmEvents[Index].Event); + } + } + + // + // Inform MM Core that the DxeSmmReadyToLock protocol was installed + // + MmGuidedEventNotify (Event, (VOID *)&gEfiDxeMmReadyToLockProtocolGuid); + + // + // Print debug message that the SMRAM window is now locked. + // + DEBUG ((DEBUG_INFO, "MmCommunicationDxe locked SMRAM window\n")); + + // + // Set flag so this operation will not be performed again + // + mSmmLocked = TRUE; +} + +/** + Event notification that is fired when EndOfDxe Event Group is signaled. + + @param Event The Event that is being processed, not used. + @param Context Event Context, not used. + +**/ +VOID +EFIAPI +MmEndOfDxeEventNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + mEndOfDxe = TRUE; +} /** Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE. @@ -226,6 +409,8 @@ MmCommunicationEntryPoint ( EFI_HANDLE Handle; EFI_HOB_GUID_TYPE *GuidHob; MM_COMM_BUFFER *MmCommonBuffer; + UINTN Index; + VOID *Registration; // // Locate gMmCommBufferHobGuid and cache the content @@ -241,6 +426,12 @@ MmCommunicationEntryPoint ( Status = gBS->LocateProtocol (&gEfiSmmControl2ProtocolGuid, NULL, (VOID **)&mSmmControl2); ASSERT_EFI_ERROR (Status); + // + // Get SMM Access Protocol + // + Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&mSmmAccess); + ASSERT_EFI_ERROR (Status); + Handle = NULL; Status = gBS->InstallProtocolInterface ( &Handle, @@ -259,17 +450,29 @@ MmCommunicationEntryPoint ( ASSERT_EFI_ERROR (Status); // - // Register the event to convert the pointer for runtime. + // Create the set of protocol and event notifications that the Standalone Mm requires // - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - MmVirtualAddressChangeEvent, - NULL, - &gEfiEventVirtualAddressChangeGuid, - NULL - ); - ASSERT_EFI_ERROR (Status); + for (Index = 0; mMmEvents[Index].NotificationType != EndNotify; Index++) { + if (mMmEvents[Index].NotificationType == ProtocolNotify) { + mMmEvents[Index].Event = EfiCreateProtocolNotifyEvent ( + mMmEvents[Index].Guid, + TPL_CALLBACK, + mMmEvents[Index].NotifyFunction, + mMmEvents[Index].NotifyContext, + &Registration + ); + } else { + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + mMmEvents[Index].NotifyFunction, + mMmEvents[Index].NotifyContext, + mMmEvents[Index].Guid, + &mMmEvents[Index].Event + ); + ASSERT_EFI_ERROR (Status); + } + } return EFI_SUCCESS; } diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h index 603cc7691c5a..d84d8218eca8 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h @@ -19,14 +19,36 @@ #include #include #include +#include #include #include #include +#include +#include #include #include +typedef enum { + EventNotify, + ProtocolNotify, + EndNotify, +} NOTIFICATION_TYPE; + +// +// Data structure used to declare a table of protocol notifications and event +// notifications required by the Standalone Mm environment +// +typedef struct { + NOTIFICATION_TYPE NotificationType; + BOOLEAN CloseOnLock; + EFI_GUID *Guid; + EFI_EVENT_NOTIFY NotifyFunction; + VOID *NotifyContext; + EFI_EVENT Event; +} MM_EVENT_NOTIFICATION; + /** Communicates with a registered handler. @@ -91,4 +113,64 @@ MmCommunicate ( IN OUT UINTN *CommSize OPTIONAL ); +/** + Event notification that is fired every time a DxeSmmReadyToLock protocol is added + or if gEfiEventReadyToBootGuid is signaled. + + @param Event The Event that is being processed, not used. + @param Context Event Context, not used. + +**/ +VOID +EFIAPI +MmReadyToLockEventNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Event notification that is fired when GUIDed Event Group is signaled. + + @param Event The Event that is being processed, not used. + @param Context Event Context, not used. + +**/ +VOID +EFIAPI +MmGuidedEventNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Event notification that is fired when EndOfDxe Event Group is signaled. + + @param Event The Event that is being processed, not used. + @param Context Event Context, not used. + +**/ +VOID +EFIAPI +MmEndOfDxeEventNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE. + + This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event. + It convers pointer to new virtual address. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +MmVirtualAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ); + #endif diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf index c46a3ba8bb85..821df02fdc9d 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf @@ -37,15 +37,20 @@ UefiBootServicesTableLib UefiLib UefiRuntimeLib + ReportStatusCodeLib [Guids] gMmCommBufferHobGuid gEfiEventVirtualAddressChangeGuid + gEfiEndOfDxeEventGroupGuid + gEfiEventExitBootServicesGuid [Protocols] gEfiMmCommunication2ProtocolGuid gEfiSmmControl2ProtocolGuid gEfiMmCommunicationProtocolGuid + gEfiDxeMmReadyToLockProtocolGuid + gEfiSmmAccess2ProtocolGuid [Depex] - gEfiSmmControl2ProtocolGuid + gEfiSmmAccess2ProtocolGuid AND gEfiSmmControl2ProtocolGuid From 82d2f6b3c3f24d96c547a980bd8d0b3009fe9da8 Mon Sep 17 00:00:00 2001 From: Zhang Hongbin Date: Thu, 30 May 2024 17:59:50 +0800 Subject: [PATCH 034/280] MdeModulePkg/SmmCommunicationBufferDxe: Re-use FixedCommBuffer SmmCommunicationBufferDxe need to re-use FixedCommBuffer from MmCommBuffer HOB which created under PEI stage. Signed-off-by: Hongbin1 Zhang Cc: Liming Gao Cc: Ray Ni Cc: Star Zeng Cc: Jiaxin Wu --- .../SmmCommunicationBufferDxe.c | 23 +++++++++++++++---- .../SmmCommunicationBufferDxe.inf | 1 + 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.c b/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.c index 663cfff965c1..a47311c3b1ba 100644 --- a/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.c +++ b/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.c @@ -19,7 +19,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include +#include #include #define DEFAULT_COMMON_PI_SMM_COMMUNIATION_REGION_PAGES 4 @@ -44,8 +46,11 @@ SmmCommunicationBufferEntryPoint ( UINT32 DescriptorSize; EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable; EFI_MEMORY_DESCRIPTOR *Entry; + EFI_HOB_GUID_TYPE *GuidHob; + MM_COMM_BUFFER *MmCommBuffer; DescriptorSize = sizeof (EFI_MEMORY_DESCRIPTOR); + // // Make sure Size != sizeof(EFI_MEMORY_DESCRIPTOR). This will // prevent people from having pointer math bugs in their code. @@ -65,11 +70,21 @@ SmmCommunicationBufferEntryPoint ( PiSmmCommunicationRegionTable->DescriptorSize = DescriptorSize; Entry = (EFI_MEMORY_DESCRIPTOR *)(PiSmmCommunicationRegionTable + 1); Entry->Type = EfiConventionalMemory; - Entry->PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateReservedPages (DEFAULT_COMMON_PI_SMM_COMMUNIATION_REGION_PAGES); + + GuidHob = GetFirstGuidHob (&gMmCommBufferHobGuid); + + if (GuidHob == NULL) { + Entry->PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateReservedPages (DEFAULT_COMMON_PI_SMM_COMMUNIATION_REGION_PAGES); + Entry->NumberOfPages = DEFAULT_COMMON_PI_SMM_COMMUNIATION_REGION_PAGES; + } else { + MmCommBuffer = GET_GUID_HOB_DATA (GuidHob); + Entry->PhysicalStart = MmCommBuffer->PhysicalStart; + Entry->NumberOfPages = MmCommBuffer->NumberOfPages; + } + ASSERT (Entry->PhysicalStart != 0); - Entry->VirtualStart = 0; - Entry->NumberOfPages = DEFAULT_COMMON_PI_SMM_COMMUNIATION_REGION_PAGES; - Entry->Attribute = 0; + Entry->VirtualStart = 0; + Entry->Attribute = 0; DEBUG ((DEBUG_INFO, "PiSmmCommunicationRegionTable:(0x%x)\n", PiSmmCommunicationRegionTable)); DEBUG ((DEBUG_INFO, " Version - 0x%x\n", PiSmmCommunicationRegionTable->Version)); diff --git a/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.inf b/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.inf index 5c867ba1de58..1c9bbdc13678 100644 --- a/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.inf +++ b/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.inf @@ -47,6 +47,7 @@ [Guids] gEdkiiPiSmmCommunicationRegionTableGuid ## PRODUCES ## SystemTable + gMmCommBufferHobGuid ## CONSUMES [Depex] TRUE From e363c0b7296be020e7fca753ac5e3af10dd7981f Mon Sep 17 00:00:00 2001 From: Hongbin1 Zhang Date: Sun, 28 Apr 2024 15:30:23 +0800 Subject: [PATCH 035/280] StandaloneMmPkg/MmIpl: StandaloneMmIplPei driver entrypoint StandaloneMmIplPei driver entrypoint for adding StandaloneMm Ipl feature code under PEI stage. Signed-off-by: Hongbin1 Zhang Cc: Jiewen Yao Cc: Ray Ni Cc: Star Zeng Cc: Jiaxin Wu Cc: Wei6 Xu Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Supreeth Venkatesh --- .../StandaloneMmIplPei/StandaloneMmIplPei.c | 31 +++++++++++++ .../StandaloneMmIplPei/StandaloneMmIplPei.h | 12 ++++++ .../StandaloneMmIplPei/StandaloneMmIplPei.inf | 43 +++++++++++++++++++ StandaloneMmPkg/StandaloneMmPkg.dsc | 6 +++ 4 files changed, 92 insertions(+) create mode 100644 StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c create mode 100644 StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h create mode 100644 StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c new file mode 100644 index 000000000000..a3e371f6b934 --- /dev/null +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c @@ -0,0 +1,31 @@ +/** @file + MM IPL that load the MM Core into MMRAM at PEI stage + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "StandaloneMmIplPei.h" + +/** + The Entry Point for MM IPL at PEI stage. + + Load MM Core into MMRAM. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval Other Some error occurred when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +StandaloneMmIplPeiEntry ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + return EFI_SUCCESS; +} diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h new file mode 100644 index 000000000000..1b2aef7062c3 --- /dev/null +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h @@ -0,0 +1,12 @@ +/** @file + Standalone MM IPL Header file + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef STANDALONE_MM_IPL_PEI_H_ +#define STANDALONE_MM_IPL_PEI_H_ + +#endif diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf new file mode 100644 index 000000000000..d5c3c54ebda5 --- /dev/null +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf @@ -0,0 +1,43 @@ +## @file +# This module provide a Standalone MM compliant implementation of MM IPL PEIM. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = StandaloneMmIplPei + FILE_GUID = 578A0D17-2DC0-4C7D-A121-D8D771923BB0 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + ENTRY_POINT = StandaloneMmIplPeiEntry + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = X64 +# + +[Sources] + StandaloneMmIplPei.c + StandaloneMmIplPei.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + PeimEntryPoint + +[Guids] + +[Ppis] + +[Pcd] + +[Depex] + TRUE diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc index 20a05d0ebfc2..140e6eca74dd 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -62,6 +62,9 @@ HobPrintLib|MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf MmPlatformHobProducerLib|StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf +[LibraryClasses.common.PEIM] + PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf + [LibraryClasses.AARCH64, LibraryClasses.ARM] ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf StandaloneMmMmuLib|ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf @@ -137,6 +140,9 @@ StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf +[Components.X64] + StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf + ################################################################################################### # # BuildOptions Section - Define the module specific tool chain flags that should be used as From d7e6b863a16fb05b9570b186c9ed4b5eb908c1e5 Mon Sep 17 00:00:00 2001 From: Hongbin1 Zhang Date: Tue, 7 May 2024 10:48:24 +0800 Subject: [PATCH 036/280] StandaloneMmPkg/MmIpl: build MM communication buffer HOB MM communication buffer HOB data is for StandaloneMm Core and MM communicate DXE driver. Signed-off-by: Hongbin1 Zhang Cc: Jiewen Yao Cc: Ray Ni Cc: Star Zeng Cc: Jiaxin Wu Cc: Wei6 Xu Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Supreeth Venkatesh --- .../StandaloneMmIplPei/StandaloneMmIplPei.c | 67 +++++++++++++++++++ .../StandaloneMmIplPei/StandaloneMmIplPei.h | 6 ++ .../StandaloneMmIplPei/StandaloneMmIplPei.inf | 7 ++ StandaloneMmPkg/StandaloneMmPkg.dsc | 3 + 4 files changed, 83 insertions(+) diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c index a3e371f6b934..659c546d71a6 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c @@ -8,6 +8,65 @@ #include "StandaloneMmIplPei.h" +/** + Build communication buffer HOB. + + @return MM_COMM_BUFFER Pointer of MM communication buffer + +**/ +MM_COMM_BUFFER * +MmIplBuildCommBufferHob ( + VOID + ) +{ + EFI_STATUS Status; + MM_COMM_BUFFER *MmCommBuffer; + UINT64 MmCommBufferPages; + + MmCommBufferPages = PcdGet32 (PcdMmCommBufferPages); + + MmCommBuffer = BuildGuidHob (&gMmCommBufferHobGuid, sizeof (MM_COMM_BUFFER)); + ASSERT (MmCommBuffer != NULL); + + // + // Set MM communicate buffer size + // + MmCommBuffer->NumberOfPages = MmCommBufferPages; + + // + // Allocate runtime memory for MM communicate buffer + // + MmCommBuffer->PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateRuntimePages (MmCommBufferPages); + if (MmCommBuffer->PhysicalStart == 0) { + DEBUG ((DEBUG_ERROR, "Fail to allocate MM communication buffer\n")); + ASSERT (MmCommBuffer->PhysicalStart != 0); + } + + // + // Build MM unblock memory region HOB for MM communication buffer + // + Status = MmUnblockMemoryRequest (MmCommBuffer->PhysicalStart, MmCommBufferPages); + ASSERT_EFI_ERROR (Status); + + // + // Allocate runtime memory for MM communication status parameters : + // ReturnStatus, ReturnBufferSize, IsCommBufferValid + // + MmCommBuffer->Status = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateRuntimePages (EFI_SIZE_TO_PAGES (sizeof (MM_COMM_BUFFER_STATUS))); + if (MmCommBuffer->Status == 0) { + DEBUG ((DEBUG_ERROR, "Fail to allocate memory for MM communication status\n")); + ASSERT (MmCommBuffer->Status != 0); + } + + // + // Build MM unblock memory region HOB for MM communication status + // + Status = MmUnblockMemoryRequest (MmCommBuffer->Status, EFI_SIZE_TO_PAGES (sizeof (MM_COMM_BUFFER_STATUS))); + ASSERT_EFI_ERROR (Status); + + return MmCommBuffer; +} + /** The Entry Point for MM IPL at PEI stage. @@ -27,5 +86,13 @@ StandaloneMmIplPeiEntry ( IN CONST EFI_PEI_SERVICES **PeiServices ) { + MM_COMM_BUFFER *MmCommBuffer; + + // + // Build communication buffer HOB. + // + MmCommBuffer = MmIplBuildCommBufferHob (); + ASSERT (MmCommBuffer != NULL); + return EFI_SUCCESS; } diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h index 1b2aef7062c3..e827852c31cf 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h @@ -9,4 +9,10 @@ #ifndef STANDALONE_MM_IPL_PEI_H_ #define STANDALONE_MM_IPL_PEI_H_ +#include +#include +#include +#include +#include + #endif diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf index d5c3c54ebda5..8811cc9e3696 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf @@ -29,15 +29,22 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + StandaloneMmPkg/StandaloneMmPkg.dec [LibraryClasses] PeimEntryPoint + DebugLib + HobLib + MemoryAllocationLib + MmUnblockMemoryLib [Guids] + gMmCommBufferHobGuid [Ppis] [Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdMmCommBufferPages [Depex] TRUE diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc index 140e6eca74dd..e42a1619478b 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -63,7 +63,10 @@ MmPlatformHobProducerLib|StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf [LibraryClasses.common.PEIM] + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf [LibraryClasses.AARCH64, LibraryClasses.ARM] ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf From 8d764088ea3a182174d36caa9131198301515a89 Mon Sep 17 00:00:00 2001 From: Hongbin1 Zhang Date: Tue, 7 May 2024 15:46:49 +0800 Subject: [PATCH 037/280] StandaloneMmPkg/MmIpl: load MM Core and execute MM Core in MM RAM StandaloneMmIplPei will search the MM Core driver in all FV and relocate it to MM RAM, and enter MM Core entrypoint to run MM Core. Signed-off-by: Hongbin1 Zhang Cc: Jiewen Yao Cc: Ray Ni Cc: Star Zeng Cc: Jiaxin Wu Cc: Wei6 Xu Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Supreeth Venkatesh --- .../StandaloneMmIplPei/StandaloneMmIplPei.c | 337 ++++++++++++++++++ .../StandaloneMmIplPei/StandaloneMmIplPei.h | 6 + .../StandaloneMmIplPei/StandaloneMmIplPei.inf | 5 + StandaloneMmPkg/StandaloneMmPkg.dsc | 2 + 4 files changed, 350 insertions(+) diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c index 659c546d71a6..197e33cc3bd8 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c @@ -8,6 +8,336 @@ #include "StandaloneMmIplPei.h" +/** + Search all the available firmware volumes for MM Core driver. + + @param MmFvBase Base address of FV which included MM Core driver. + @param MmFvSize Size of FV which included MM Core driver. + @param MmCoreFileName GUID of MM Core. + @param MmCoreImageAddress MM Core image address. + + @retval EFI_SUCCESS The specified FFS section was returned. + @retval EFI_NOT_FOUND The specified FFS section could not be found. + +**/ +EFI_STATUS +LocateMmCoreFv ( + OUT EFI_PHYSICAL_ADDRESS *MmFvBase, + OUT UINTN *MmFvSize, + OUT EFI_GUID *MmCoreFileName, + OUT VOID **MmCoreImageAddress + ) +{ + EFI_STATUS Status; + UINTN FvIndex; + EFI_PEI_FV_HANDLE VolumeHandle; + EFI_PEI_FILE_HANDLE FileHandle; + EFI_PE32_SECTION *SectionData; + EFI_FV_INFO VolumeInfo; + + // + // Search all FV + // + VolumeHandle = NULL; + for (FvIndex = 0; ; FvIndex++) { + Status = PeiServicesFfsFindNextVolume (FvIndex, &VolumeHandle); + if (EFI_ERROR (Status)) { + break; + } + + // + // Search MM Core FFS + // + FileHandle = NULL; + Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_MM_CORE_STANDALONE, VolumeHandle, &FileHandle); + if (EFI_ERROR (Status)) { + continue; + } + + ASSERT (FileHandle != NULL); + if (FileHandle != NULL) { + CopyGuid (MmCoreFileName, &((EFI_FFS_FILE_HEADER *)FileHandle)->Name); + } + + // + // Search Section + // + Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, MmCoreImageAddress); + if (EFI_ERROR (Status)) { + continue; + } + + // + // Get MM Core section data. + // + SectionData = (EFI_PE32_SECTION *)((UINT8 *)*MmCoreImageAddress - sizeof (EFI_PE32_SECTION)); + ASSERT (SectionData->Type == EFI_SECTION_PE32); + + // + // This is the FV that contains MM Core. + // + Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo); + if (!EFI_ERROR (Status)) { + *MmFvBase = (EFI_PHYSICAL_ADDRESS)(UINTN)VolumeInfo.FvStart; + *MmFvSize = VolumeInfo.FvSize; + return EFI_SUCCESS; + } else { + return EFI_NOT_FOUND; + } + } + + return EFI_NOT_FOUND; +} + +/** + Find largest unallocated MMRAM in current MMRAM descriptor block + + @param[in, out] LagestMmramRangeIndex Lagest mmram range index. + @param[in] CurrentBlock Current MMRAM descriptor block. + +**/ +VOID +FindLargestMmramRange ( + IN OUT UINTN *LagestMmramRangeIndex, + IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *CurrentBlock + ) +{ + UINTN Index; + UINT64 MaxSize; + BOOLEAN Found; + EFI_MMRAM_DESCRIPTOR *MmramRanges; + + MmramRanges = CurrentBlock->Descriptor; + + // + // Find largest Mmram range. + // + Found = FALSE; + for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < CurrentBlock->NumberOfMmReservedRegions; Index++) { + // + // Skip any MMRAM region that is already allocated, needs testing, or needs ECC initialization + // + if ((MmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) { + continue; + } + + if (MmramRanges[Index].CpuStart >= BASE_1MB) { + if ((MmramRanges[Index].CpuStart + MmramRanges[Index].PhysicalSize) <= BASE_4GB) { + if (MmramRanges[Index].PhysicalSize >= MaxSize) { + Found = TRUE; + *LagestMmramRangeIndex = Index; + MaxSize = MmramRanges[Index].PhysicalSize; + } + } + } + } + + if (Found == FALSE) { + DEBUG ((DEBUG_ERROR, "Not found largest unlocated MMRAM\n")); + ASSERT (FALSE); + CpuDeadLoop (); + } + + return; +} + +/** + Allocate available MMRAM for MM core image. + + @param[in] Pages Page count of MM core image. + @param[out] NewBlock Pointer of new mmram block HOB. + + @return EFI_PHYSICAL_ADDRESS Address for MM core image to be loaded in MMRAM. +**/ +EFI_PHYSICAL_ADDRESS +MmIplAllocateMmramPage ( + IN UINTN Pages, + OUT EFI_MMRAM_HOB_DESCRIPTOR_BLOCK **NewBlock + ) +{ + UINTN LagestMmramRangeIndex; + UINT32 FullMmramRangeCount; + EFI_HOB_GUID_TYPE *MmramInfoHob; + EFI_MMRAM_DESCRIPTOR *Largest; + EFI_MMRAM_DESCRIPTOR *Allocated; + EFI_MMRAM_DESCRIPTOR *FullMmramRanges; + EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *CurrentBlock; + EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *NewDescriptorBlock; + + MmramInfoHob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid); + ASSERT (MmramInfoHob != NULL); + if (MmramInfoHob == NULL) { + DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n")); + return 0; + } + + CurrentBlock = (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *)(GET_GUID_HOB_DATA (MmramInfoHob)); + + // + // 1. Find largest unallocated MMRAM region + // + FindLargestMmramRange (&LagestMmramRangeIndex, CurrentBlock); + ASSERT (LagestMmramRangeIndex < CurrentBlock->NumberOfMmReservedRegions); + + // + // 2. Split the largest region and mark the allocated region as ALLOCATED + // + FullMmramRangeCount = CurrentBlock->NumberOfMmReservedRegions + 1; + NewDescriptorBlock = (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *)BuildGuidHob ( + &gEfiSmmSmramMemoryGuid, + sizeof (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK) + ((FullMmramRangeCount - 1) * sizeof (EFI_MMRAM_DESCRIPTOR)) + ); + ASSERT (NewDescriptorBlock != NULL); + + NewDescriptorBlock->NumberOfMmReservedRegions = FullMmramRangeCount; + FullMmramRanges = NewDescriptorBlock->Descriptor; + + // + // Get current MMRAM descriptors and fill to the full MMRAM ranges + // + CopyMem (NewDescriptorBlock->Descriptor, CurrentBlock->Descriptor, CurrentBlock->NumberOfMmReservedRegions * sizeof (EFI_MMRAM_DESCRIPTOR)); + + Largest = &FullMmramRanges[LagestMmramRangeIndex]; + ASSERT ((Largest->PhysicalSize & EFI_PAGE_MASK) == 0); + ASSERT (Largest->PhysicalSize > EFI_PAGES_TO_SIZE (Pages)); + + Allocated = &NewDescriptorBlock->Descriptor[NewDescriptorBlock->NumberOfMmReservedRegions - 1]; + + // + // Allocate MMRAM + // + Largest->PhysicalSize -= EFI_PAGES_TO_SIZE (Pages); + Allocated->CpuStart = Largest->CpuStart + Largest->PhysicalSize; + Allocated->PhysicalStart = Largest->PhysicalStart + Largest->PhysicalSize; + Allocated->RegionState = Largest->RegionState | EFI_ALLOCATED; + Allocated->PhysicalSize = EFI_PAGES_TO_SIZE (Pages); + + // + // Scrub old one + // + ZeroMem (&MmramInfoHob->Name, sizeof (MmramInfoHob->Name)); + + // + // New MMRAM descriptor block + // + *NewBlock = NewDescriptorBlock; + + return Allocated->CpuStart; +} + +/** + Load the MM Core image into MMRAM and executes the MM Core from MMRAM. + + @param[in] MmCommBuffer MM communicate buffer + + @return EFI_STATUS Execute MM core successfully. + Other Execute MM core failed. +**/ +EFI_STATUS +ExecuteMmCoreFromMmram ( + IN MM_COMM_BUFFER *MmCommBuffer + ) +{ + EFI_STATUS Status; + UINTN PageCount; + VOID *MmHobList; + EFI_GUID MmCoreFileName; + UINTN MmFvSize; + EFI_PHYSICAL_ADDRESS MmFvBase; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + STANDALONE_MM_FOUNDATION_ENTRY_POINT Entry; + EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block; + + MmFvBase = 0; + MmFvSize = 0; + // + // Search all Firmware Volumes for a PE/COFF image in a file of type MM_CORE_STANDALONE. + // + Status = LocateMmCoreFv (&MmFvBase, &MmFvSize, &MmCoreFileName, &ImageContext.Handle); + ASSERT_EFI_ERROR (Status); + + // + // Unblock the MM FV range to be accessible from inside MM + // + if ((MmFvBase != 0) && (MmFvSize != 0)) { + Status = MmUnblockMemoryRequest (MmFvBase, EFI_SIZE_TO_PAGES (MmFvSize)); + ASSERT_EFI_ERROR (Status); + } + + // + // Initialize ImageContext + // + ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; + + // + // Get information about the image being loaded + // + Status = PeCoffLoaderGetImageInfo (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; + } + + PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment); + + // + // Allocate memory for the image being loaded from unallocated mmram range + // + ImageContext.ImageAddress = MmIplAllocateMmramPage (PageCount, &Block); + if (ImageContext.ImageAddress == 0) { + return EFI_NOT_FOUND; + } + + // + // Align buffer on section boundary + // + ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; + ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1); + + // + // Print debug message showing MM Core load address. + // + DEBUG ((DEBUG_INFO, "StandaloneMM IPL loading MM Core at MMRAM address %p\n", (VOID *)(UINTN)ImageContext.ImageAddress)); + + // + // Load the image to our new buffer + // + Status = PeCoffLoaderLoadImage (&ImageContext); + if (!EFI_ERROR (Status)) { + // + // Relocate the image in our new buffer + // + Status = PeCoffLoaderRelocateImage (&ImageContext); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "MmCoreImageBase - 0x%016lx\n", ImageContext.ImageAddress)); + DEBUG ((DEBUG_INFO, "MmCoreImageSize - 0x%016lx\n", ImageContext.ImageSize)); + + // + // Flush the instruction cache so the image data are written before we execute it + // + InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); + + // + // Get HOB list for Standalone MM Core. + // + MmHobList = GetHobList (); + + // + // Print debug message showing Standalone MM Core entry point address. + // + DEBUG ((DEBUG_INFO, "StandaloneMM IPL calling Standalone MM Core at MMRAM address - 0x%016lx\n", ImageContext.EntryPoint)); + + // + // Execute image + // + Entry = (STANDALONE_MM_FOUNDATION_ENTRY_POINT)(UINTN)ImageContext.EntryPoint; + Status = Entry (MmHobList); + ASSERT_EFI_ERROR (Status); + } + } + + return Status; +} + /** Build communication buffer HOB. @@ -86,6 +416,7 @@ StandaloneMmIplPeiEntry ( IN CONST EFI_PEI_SERVICES **PeiServices ) { + EFI_STATUS Status; MM_COMM_BUFFER *MmCommBuffer; // @@ -94,5 +425,11 @@ StandaloneMmIplPeiEntry ( MmCommBuffer = MmIplBuildCommBufferHob (); ASSERT (MmCommBuffer != NULL); + // + // Locate and execute Mm Core to dispatch MM drivers. + // + Status = ExecuteMmCoreFromMmram (MmCommBuffer); + ASSERT_EFI_ERROR (Status); + return EFI_SUCCESS; } diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h index e827852c31cf..f099af5feb6d 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h @@ -9,10 +9,16 @@ #ifndef STANDALONE_MM_IPL_PEI_H_ #define STANDALONE_MM_IPL_PEI_H_ +#include #include +#include #include #include #include +#include #include +#include +#include +#include #endif diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf index 8811cc9e3696..0a03aa0af118 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf @@ -33,13 +33,18 @@ [LibraryClasses] PeimEntryPoint + PeiServicesLib DebugLib HobLib MemoryAllocationLib MmUnblockMemoryLib + BaseMemoryLib + PeCoffLib + CacheMaintenanceLib [Guids] gMmCommBufferHobGuid + gEfiSmmSmramMemoryGuid [Ppis] diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc index e42a1619478b..a2410f37d32f 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -66,6 +66,8 @@ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf + PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf [LibraryClasses.AARCH64, LibraryClasses.ARM] From e98eca076af1793baf55bea26ca3bc6e20c52061 Mon Sep 17 00:00:00 2001 From: Hongbin1 Zhang Date: Thu, 9 May 2024 10:06:09 +0800 Subject: [PATCH 038/280] StandaloneMmPkg/MmIpl: Install MmCommunicationPpi Install MmCommunicationPpi under PEI stage, PEIM could use this PPI to communicate with MM handler Signed-off-by: Hongbin1 Zhang Cc: Jiewen Yao Cc: Ray Ni Cc: Star Zeng Cc: Jiaxin Wu Cc: Wei6 Xu Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Supreeth Venkatesh --- .../StandaloneMmIplPei/StandaloneMmIplPei.c | 119 ++++++++++++++++++ .../StandaloneMmIplPei/StandaloneMmIplPei.h | 26 ++++ .../StandaloneMmIplPei/StandaloneMmIplPei.inf | 4 +- 3 files changed, 148 insertions(+), 1 deletion(-) diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c index 197e33cc3bd8..d92c2659ad73 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c @@ -8,6 +8,119 @@ #include "StandaloneMmIplPei.h" +EFI_PEI_MM_COMMUNICATION_PPI mMmCommunicationPpi = { Communicate }; + +EFI_PEI_PPI_DESCRIPTOR mPpiList = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiMmCommunicationPpiGuid, + &mMmCommunicationPpi +}; + +/** + Communicates with a registered handler. + + This function provides a service to send and receive messages from a registered UEFI service. + + @param[in] This The EFI_PEI_MM_COMMUNICATION_PPI instance. + @param[in, out] CommBuffer A pointer to the buffer to convey into MMRAM. + @param[in, out] CommSize The size of the data buffer being passed in.On exit, the size of data + being returned. Zero if the handler does not wish to reply with any data. + + @retval EFI_SUCCESS The message was successfully posted. + @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. + @retval EFI_NOT_STARTED The service is NOT started. +**/ +EFI_STATUS +EFIAPI +Communicate ( + IN CONST EFI_PEI_MM_COMMUNICATION_PPI *This, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommSize + ) +{ + EFI_STATUS Status; + EFI_PEI_MM_CONTROL_PPI *MmControl; + UINT8 SmiCommand; + UINTN Size; + UINTN TempCommSize; + EFI_HOB_GUID_TYPE *GuidHob; + MM_COMM_BUFFER *MmCommBuffer; + MM_COMM_BUFFER_STATUS *MmCommBufferStatus; + + DEBUG ((DEBUG_INFO, "StandaloneMmIpl Communicate Enter\n")); + + GuidHob = GetFirstGuidHob (&gMmCommBufferHobGuid); + if (GuidHob != NULL) { + MmCommBuffer = GET_GUID_HOB_DATA (GuidHob); + MmCommBufferStatus = (MM_COMM_BUFFER_STATUS *)(UINTN)MmCommBuffer->Status; + } else { + DEBUG ((DEBUG_ERROR, "MmCommBuffer is not existed !!!\n")); + ASSERT (GuidHob != NULL); + return EFI_NOT_FOUND; + } + + SmiCommand = 0; + Size = sizeof (SmiCommand); + + // + // Check parameters + // + if ((CommBuffer == NULL) || (CommSize == NULL)) { + return EFI_INVALID_PARAMETER; + } else { + TempCommSize = *CommSize; + // + // CommSize must hold HeaderGuid and MessageLength + // + if (TempCommSize < OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data)) { + return EFI_INVALID_PARAMETER; + } + } + + if (TempCommSize > EFI_PAGES_TO_SIZE (MmCommBuffer->NumberOfPages)) { + DEBUG ((DEBUG_ERROR, "Communicate buffer size (%d) is over MAX (%d) size!", TempCommSize, EFI_PAGES_TO_SIZE (MmCommBuffer->NumberOfPages))); + return EFI_INVALID_PARAMETER; + } + + CopyMem ((VOID *)(UINTN)MmCommBuffer->PhysicalStart, CommBuffer, TempCommSize); + MmCommBufferStatus->IsCommBufferValid = TRUE; + + // + // Generate Software SMI + // + Status = PeiServicesLocatePpi (&gEfiPeiMmControlPpiGuid, 0, NULL, (VOID **)&MmControl); + ASSERT_EFI_ERROR (Status); + + Status = MmControl->Trigger ( + (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), + MmControl, + (INT8 *)&SmiCommand, + &Size, + FALSE, + 0 + ); + ASSERT_EFI_ERROR (Status); + + // + // Return status from software SMI + // + *CommSize = (UINTN)MmCommBufferStatus->ReturnBufferSize; + + // + // Copy the returned data to the non-mmram buffer (CommBuffer) + // + CopyMem (CommBuffer, (VOID *)(MmCommBuffer->PhysicalStart), *CommSize); + + Status = (EFI_STATUS)MmCommBufferStatus->ReturnStatus; + if (Status != EFI_SUCCESS) { + DEBUG ((DEBUG_ERROR, "StandaloneMmIpl Communicate failed (%r)\n", Status)); + } else { + MmCommBufferStatus->IsCommBufferValid = FALSE; + } + + return Status; +} + /** Search all the available firmware volumes for MM Core driver. @@ -431,5 +544,11 @@ StandaloneMmIplPeiEntry ( Status = ExecuteMmCoreFromMmram (MmCommBuffer); ASSERT_EFI_ERROR (Status); + // + // Install MmCommunicationPpi + // + Status = PeiServicesInstallPpi (&mPpiList); + ASSERT_EFI_ERROR (Status); + return EFI_SUCCESS; } diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h index f099af5feb6d..c385d98ce48b 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h @@ -20,5 +20,31 @@ #include #include #include +#include +#include +#include +#include + +/** + Communicates with a registered handler. + + This function provides a service to send and receive messages from a registered UEFI service. + + @param[in] This The EFI_PEI_MM_COMMUNICATION_PPI instance. + @param[in, out] CommBuffer A pointer to the buffer to convey into MMRAM. + @param[in, out] CommSize The size of the data buffer being passed in.On exit, the size of data + being returned. Zero if the handler does not wish to reply with any data. + + @retval EFI_SUCCESS The message was successfully posted. + @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. + @retval EFI_NOT_STARTED The service is NOT started. +**/ +EFI_STATUS +EFIAPI +Communicate ( + IN CONST EFI_PEI_MM_COMMUNICATION_PPI *This, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommSize + ); #endif diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf index 0a03aa0af118..f462a10e355e 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf @@ -47,9 +47,11 @@ gEfiSmmSmramMemoryGuid [Ppis] + gEfiPeiMmControlPpiGuid + gEfiPeiMmCommunicationPpiGuid [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdMmCommBufferPages [Depex] - TRUE + gEfiPeiMmControlPpiGuid From 3ac296def15a0bd34b095d7009843e76fcdbf418 Mon Sep 17 00:00:00 2001 From: Hongbin1 Zhang Date: Thu, 9 May 2024 16:52:52 +0800 Subject: [PATCH 039/280] StandaloneMmPkg/MmIpl: Install end of PEI notify PPI Install end of PEI notify PPI for issue gEfiMmEndOfPeiProtocol Handler in MM Signed-off-by: Hongbin1 Zhang Cc: Jiewen Yao Cc: Ray Ni Cc: Star Zeng Cc: Jiaxin Wu Cc: Wei6 Xu Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Supreeth Venkatesh --- .../StandaloneMmIplPei/StandaloneMmIplPei.c | 53 +++++++++++++++++++ .../StandaloneMmIplPei/StandaloneMmIplPei.h | 19 +++++++ .../StandaloneMmIplPei/StandaloneMmIplPei.inf | 4 ++ 3 files changed, 76 insertions(+) diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c index d92c2659ad73..90f3e467810e 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c @@ -16,6 +16,12 @@ EFI_PEI_PPI_DESCRIPTOR mPpiList = { &mMmCommunicationPpi }; +EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = { + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEfiEndOfPeiSignalPpiGuid, + EndOfPeiCallback +}; + /** Communicates with a registered handler. @@ -451,6 +457,47 @@ ExecuteMmCoreFromMmram ( return Status; } +/** + This is the callback function on end of PEI. + + This callback is used for call MmEndOfPeiHandler in standalone MM core. + + @param PeiServices General purpose services available to every PEIM. + @param NotifyDescriptor The notification structure this PEIM registered on install. + @param Ppi Pointer to the PPI data associated with this function. + + @retval EFI_SUCCESS Exit boot services successfully. + @retval Other Exit boot services failed. +**/ +EFI_STATUS +EFIAPI +EndOfPeiCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_MM_COMMUNICATE_HEADER CommunicateHeader; + UINTN Size; + EFI_STATUS Status; + + // + // Use Guid to initialize EFI_MM_COMMUNICATE_HEADER structure + // + CopyGuid (&CommunicateHeader.HeaderGuid, &gEfiMmEndOfPeiProtocol); + CommunicateHeader.MessageLength = 1; + CommunicateHeader.Data[0] = 0; + + // + // Generate the Software SMI and return the result + // + Size = sizeof (CommunicateHeader); + Status = Communicate (NULL, &CommunicateHeader, &Size); + ASSERT_EFI_ERROR (Status); + + return Status; +} + /** Build communication buffer HOB. @@ -550,5 +597,11 @@ StandaloneMmIplPeiEntry ( Status = PeiServicesInstallPpi (&mPpiList); ASSERT_EFI_ERROR (Status); + // + // Create end of pei callback to call MmEndOfPeiHandler + // + Status = PeiServicesNotifyPpi (&mNotifyList); + ASSERT_EFI_ERROR (Status); + return EFI_SUCCESS; } diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h index c385d98ce48b..e9be3f556833 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h @@ -47,4 +47,23 @@ Communicate ( IN OUT UINTN *CommSize ); +/** + This is the callback function on end of PEI. + + This callback is used for call MmEndOfPeiHandler in standalone MM core. + + @param PeiServices General purpose services available to every PEIM. + @param NotifyDescriptor The notification structure this PEIM registered on install. + @param Ppi Pointer to the PPI data associated with this function. + @retval EFI_SUCCESS Exit boot services successfully. + @retval Other Exit boot services failed. +**/ +EFI_STATUS +EFIAPI +EndOfPeiCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + #endif diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf index f462a10e355e..9c748539c6f5 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf @@ -49,6 +49,10 @@ [Ppis] gEfiPeiMmControlPpiGuid gEfiPeiMmCommunicationPpiGuid + gEfiEndOfPeiSignalPpiGuid + +[Protocols] + gEfiMmEndOfPeiProtocol [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdMmCommBufferPages From 5aa5ecd5ff1ad845f5fe9d848a66a7a6f89dd9aa Mon Sep 17 00:00:00 2001 From: Hongbin1 Zhang Date: Thu, 9 May 2024 19:26:24 +0800 Subject: [PATCH 040/280] StandaloneMmPkg/MmIpl: Dispatch StandaloneMm drivers in MM MmIpl will issue a SWSMI by MM communicate to call gEventMmDispatchGuid handler to dispatch all StandaloneMm drivers Signed-off-by: Hongbin1 Zhang Cc: Jiewen Yao Cc: Ray Ni Cc: Star Zeng Cc: Jiaxin Wu Cc: Wei6 Xu Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Supreeth Venkatesh --- .../StandaloneMmIplPei/StandaloneMmIplPei.c | 43 +++++++++++++++++++ .../StandaloneMmIplPei/StandaloneMmIplPei.inf | 1 + 2 files changed, 44 insertions(+) diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c index 90f3e467810e..d6406784b70d 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c @@ -498,6 +498,43 @@ EndOfPeiCallback ( return Status; } +/** + Dispatch StandaloneMm drivers in MM. + + StandaloneMm core will exit when MmEntryPoint was registered in CPU + StandaloneMm driver, and issue a software SMI by communicate mode to + dispatch other StandaloneMm drivers. + + @retval EFI_SUCCESS Dispatch StandaloneMm drivers successfully. + @retval Other Dispatch StandaloneMm drivers failed. + +**/ +EFI_STATUS +MmIplDispatchMmDrivers ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Size; + EFI_MM_COMMUNICATE_HEADER CommunicateHeader; + + // + // Use Guid to initialize EFI_MM_COMMUNICATE_HEADER structure + // + CopyGuid (&CommunicateHeader.HeaderGuid, &gEventMmDispatchGuid); + CommunicateHeader.MessageLength = 1; + CommunicateHeader.Data[0] = 0; + + // + // Generate the Software SMI and return the result + // + Size = sizeof (CommunicateHeader); + Status = Communicate (NULL, &CommunicateHeader, &Size); + ASSERT_EFI_ERROR (Status); + + return Status; +} + /** Build communication buffer HOB. @@ -603,5 +640,11 @@ StandaloneMmIplPeiEntry ( Status = PeiServicesNotifyPpi (&mNotifyList); ASSERT_EFI_ERROR (Status); + // + // Dispatch StandaloneMm drivers in MM + // + Status = MmIplDispatchMmDrivers (); + ASSERT_EFI_ERROR (Status); + return EFI_SUCCESS; } diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf index 9c748539c6f5..a873efb0df2d 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf @@ -45,6 +45,7 @@ [Guids] gMmCommBufferHobGuid gEfiSmmSmramMemoryGuid + gEventMmDispatchGuid [Ppis] gEfiPeiMmControlPpiGuid From 0d91ebd96f1c5c463b74ac060c8bb0a616f17372 Mon Sep 17 00:00:00 2001 From: Hongbin1 Zhang Date: Fri, 10 May 2024 09:09:30 +0800 Subject: [PATCH 041/280] StandaloneMmPkg/MmIpl: Create standalone MM foundation related HOBs Create the HobList which included the HOBs Standalone MM foundation needed, it included communication buffer HOB, StandaloneMm Core module HOB and StandaloneMm Core FV HOB Signed-off-by: Hongbin1 Zhang Cc: Jiewen Yao Cc: Ray Ni Cc: Star Zeng Cc: Jiaxin Wu Cc: Wei6 Xu Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Supreeth Venkatesh --- .../StandaloneMmIplPei/MmFoundationHob.c | 292 ++++++++++++++++++ .../StandaloneMmIplPei/StandaloneMmIplPei.c | 141 ++++++++- .../StandaloneMmIplPei/StandaloneMmIplPei.h | 60 ++++ .../StandaloneMmIplPei/StandaloneMmIplPei.inf | 2 + 4 files changed, 494 insertions(+), 1 deletion(-) create mode 100644 StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c new file mode 100644 index 000000000000..df3355f3fc0b --- /dev/null +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c @@ -0,0 +1,292 @@ +/** @file + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +/** + Add a new HOB to the HOB List. + + @param[in] Hob The pointer of new HOB buffer. + @param[in] HobType Type of the new HOB. + @param[in] HobLength Length of the new HOB to allocate. + + @return NULL if there is no space to create a hob. + @return The address point to the new created hob. + +**/ +VOID * +MmIplCreateHob ( + IN VOID *Hob, + IN UINT16 HobType, + IN UINT16 HobLength + ) +{ + // + // Check Length to avoid data overflow. + // + ASSERT (HobLength < MAX_UINT16 - 0x7); + + HobLength = (UINT16)ALIGN_VALUE (HobLength, 8); + + ((EFI_HOB_GENERIC_HEADER *)Hob)->HobType = HobType; + ((EFI_HOB_GENERIC_HEADER *)Hob)->HobLength = HobLength; + ((EFI_HOB_GENERIC_HEADER *)Hob)->Reserved = 0; + + return Hob; +} + +/** + Builds a Firmware Volume HOB. + + This function builds a Firmware Volume HOB. + It can only be invoked during PEI phase; + If new HOB buffer is NULL, then ASSERT(). + + @param[in] Hob The pointer of new HOB buffer. + @param[in, out] HobBufferSize The available size of the HOB buffer when as input. + The used size of when as output. + @param[in] BaseAddress The base address of the Firmware Volume. + @param[in] Length The size of the Firmware Volume in bytes. + +**/ +VOID +MmIplBuildFvHob ( + IN UINT8 *Hob, + IN OUT UINTN *HobBufferSize, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + EFI_HOB_FIRMWARE_VOLUME *FvHob; + UINT16 HobLength; + + ASSERT (Hob != NULL); + + HobLength = ALIGN_VALUE (sizeof (EFI_HOB_FIRMWARE_VOLUME), 8); + if (*HobBufferSize >= HobLength) { + MmIplCreateHob (Hob, EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME)); + + FvHob = (EFI_HOB_FIRMWARE_VOLUME *)Hob; + FvHob->BaseAddress = BaseAddress; + FvHob->Length = Length; + } + + *HobBufferSize = HobLength; +} + +/** + Copies a data buffer to a newly-built HOB for GUID HOB + + This function builds a customized HOB tagged with a GUID for identification, copies the + input data to the HOB data field and returns the start address of the GUID HOB data. + If new HOB buffer is NULL or the GUID HOB could not found, then ASSERT(). + + @param[in] HobBuffer The pointer of HOB buffer. + @param[in, out] HobBufferSize The available size of the HOB buffer when as input. + The used size of when as output. + @param[in] Guid The GUID of the GUID type HOB. + @param[in] MultiInstances TRUE indicating copying multiple HOBs with the same Guid. +**/ +VOID +MmIplCopyGuidHob ( + IN UINT8 *HobBuffer, + IN OUT UINTN *HobBufferSize, + IN EFI_GUID *Guid, + IN BOOLEAN MultiInstances + ) +{ + EFI_HOB_GENERIC_HEADER *GuidHob; + UINTN UsedSize; + + UsedSize = 0; + GuidHob = GetFirstGuidHob (Guid); + ASSERT (GuidHob != NULL); + + while (GuidHob != NULL) { + if (*HobBufferSize >= UsedSize + GuidHob->HobLength) { + CopyMem (HobBuffer + UsedSize, GuidHob, GuidHob->HobLength); + } + + UsedSize += GuidHob->HobLength; + + if (!MultiInstances) { + break; + } + + GuidHob = GetNextGuidHob (Guid, GET_NEXT_HOB (GuidHob)); + } + + *HobBufferSize = UsedSize; +} + +/** + Builds a HOB for a loaded PE32 module. + + This function builds a HOB for a loaded PE32 module. + It can only be invoked during PEI phase; + If physical address of the Module is not 4K aligned, then ASSERT(). + If new HOB buffer is NULL, then ASSERT(). + + @param[in] Hob The pointer of new HOB buffer. + @param[in, out] HobBufferSize The available size of the HOB buffer when as input. + The used size of when as output. + @param[in] ModuleName The GUID File Name of the module. + @param[in] Base The 64 bit physical address of the module. + @param[in] Length The length of the module in bytes. + @param[in] EntryPoint The 64 bit physical address of the module entry point. + +**/ +VOID +MmIplBuildMmCoreModuleHob ( + IN UINT8 *Hob, + IN OUT UINTN *HobBufferSize, + IN CONST EFI_GUID *ModuleName, + IN EFI_PHYSICAL_ADDRESS Base, + IN UINT64 Length, + IN EFI_PHYSICAL_ADDRESS EntryPoint + ) +{ + UINT16 HobLength; + EFI_HOB_MEMORY_ALLOCATION_MODULE *MmCoreModuleHob; + + ASSERT (Hob != NULL); + ASSERT (ADDRESS_IS_ALIGNED (Base, EFI_PAGE_SIZE)); + ASSERT (IS_ALIGNED (Length, EFI_PAGE_SIZE)); + ASSERT (EntryPoint >= Base && EntryPoint < Base + Length); + + HobLength = ALIGN_VALUE (sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE), 8); + if (*HobBufferSize >= HobLength) { + MmIplCreateHob (Hob, EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE)); + + MmCoreModuleHob = (EFI_HOB_MEMORY_ALLOCATION_MODULE *)Hob; + CopyGuid (&MmCoreModuleHob->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid); + MmCoreModuleHob->MemoryAllocationHeader.MemoryBaseAddress = Base; + MmCoreModuleHob->MemoryAllocationHeader.MemoryLength = Length; + MmCoreModuleHob->MemoryAllocationHeader.MemoryType = EfiReservedMemoryType; + ZeroMem (MmCoreModuleHob->MemoryAllocationHeader.Reserved, sizeof (MmCoreModuleHob->MemoryAllocationHeader.Reserved)); + + CopyGuid (&MmCoreModuleHob->ModuleName, ModuleName); + MmCoreModuleHob->EntryPoint = EntryPoint; + } + + *HobBufferSize = HobLength; +} + +/** + Get remaining size for building HOBs. + + @param[in] TotalHobSize Total size of foundation HOBs. + @param[in] UsedSize Required HOBs' size. + + @retval MAX remaining size for building HOBs +**/ +UINTN +GetRemainingHobSize ( + IN UINTN TotalHobSize, + IN UINTN UsedSize + ) +{ + if (TotalHobSize > UsedSize) { + return TotalHobSize - UsedSize; + } else { + return 0; + } +} + +/** + Create the MM foundation specific HOB list which StandaloneMm Core needed. + + This function build the MM foundation specific HOB list needed by StandaloneMm Core + based on the PEI HOB list. + + @param[in] FoundationHobList The foundation HOB list to be used for HOB creation. + @param[in, out] FoundationHobSize The foundation HOB size. + On return, the expected/used size. + @param[in] PlatformHobList Platform HOB list. + @param[in] PlatformHobSize Platform HOB size. + @param[in] MmFvBase Base of firmare volume which included MM core dirver. + @param[in] MmFvSize Size of firmare volume which included MM core dirver. + @param[in] MmCoreFileName File name of MM core dirver. + @param[in] MmCoreImageAddress Image address of MM core dirver. + @param[in] MmCoreImageSize Image size of MM core dirver. + @param[in] MmCoreEntryPoint Entry pinter of MM core dirver. + @param[in] Block Pointer of MMRAM descriptor block. + + @retval RETURN_BUFFER_TOO_SMALL The buffer is too small for HOB creation. + BufferSize is updated to indicate the expected buffer size. + When the input BufferSize is bigger than the expected buffer size, + the BufferSize value will be changed the used buffer size. + @retval RETURN_SUCCESS HOB List is created/updated successfully or the input Length is 0. + +**/ +RETURN_STATUS +CreateMmFoundationHobList ( + IN UINT8 *FoundationHobList, + IN OUT UINTN *FoundationHobSize, + IN UINT8 *PlatformHobList, + IN UINTN PlatformHobSize, + IN EFI_PHYSICAL_ADDRESS MmFvBase, + IN UINT64 MmFvSize, + IN EFI_GUID *MmCoreFileName, + IN EFI_PHYSICAL_ADDRESS MmCoreImageAddress, + IN UINT64 MmCoreImageSize, + IN EFI_PHYSICAL_ADDRESS MmCoreEntryPoint, + IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block + ) +{ + UINTN UsedSize; + RETURN_STATUS Status; + UINTN HobLength; + + ASSERT (FoundationHobSize != NULL); + + ASSERT ( + ((*FoundationHobSize != 0) && (FoundationHobList != NULL)) || + ((*FoundationHobSize == 0) && (FoundationHobList == NULL)) + ); + + UsedSize = 0; + + // + // Build communication buffer HOB in MM HOB list + // + HobLength = *FoundationHobSize; + MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gMmCommBufferHobGuid, FALSE); + UsedSize += HobLength; + + // + // Build MmCore module HOB in MM HOB list + // + HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); + MmIplBuildMmCoreModuleHob ( + FoundationHobList + UsedSize, + &HobLength, + MmCoreFileName, + MmCoreImageAddress, + MmCoreImageSize, + MmCoreEntryPoint + ); + + UsedSize += HobLength; + + // + // BFV address for StandaloneMm Core + // + HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); + MmIplBuildFvHob (FoundationHobList + UsedSize, &HobLength, MmFvBase, MmFvSize); + UsedSize += HobLength; + + if (*FoundationHobSize < UsedSize) { + Status = RETURN_BUFFER_TOO_SMALL; + } else { + Status = RETURN_SUCCESS; + } + + *FoundationHobSize = UsedSize; + return Status; +} diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c index d6406784b70d..89dd05c1b76b 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c @@ -208,6 +208,132 @@ LocateMmCoreFv ( return EFI_NOT_FOUND; } +/** + Create HOB list for Standalone MM core. + + @param[out] HobSize HOB size of fundation and platform HOB list. + @param[in] MmCommBuffer Pointer of MM communication buffer. + @param[in] MmFvBase Base of MM FV which included MM core driver. + @param[in] MmFvSize Size of MM FV which included MM core driver. + @param[in] MmCoreFileName File GUID of MM core driver. + @param[in] MmCoreImageAddress Address of MM core image. + @param[in] MmCoreImageSize Size of MM core image. + @param[in] MmCoreEntryPoint Entry point of MM core driver. + @param[in] Block Pointer of MMRAM descriptor block. + + @retval HobList If fundation and platform HOBs not existed, + it is pointed to PEI HOB List. If existed, + it is pointed to fundation and platform HOB list. +**/ +VOID * +CreatMmHobList ( + OUT UINTN *HobSize, + IN MM_COMM_BUFFER *MmCommBuffer, + IN EFI_PHYSICAL_ADDRESS MmFvBase, + IN UINT64 MmFvSize, + IN EFI_GUID *MmCoreFileName, + IN PHYSICAL_ADDRESS MmCoreImageAddress, + IN UINT64 MmCoreImageSize, + IN PHYSICAL_ADDRESS MmCoreEntryPoint, + IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block + ) +{ + EFI_STATUS Status; + VOID *HobList; + VOID *PlatformHobList; + UINTN PlatformHobSize; + UINTN BufferSize; + UINTN FoundationHobSize; + + // + // Get platform HOBs + // + PlatformHobSize = 0; + Status = CreateMmPlatformHob (NULL, &PlatformHobSize); + if (Status == RETURN_BUFFER_TOO_SMALL) { + ASSERT (PlatformHobSize != 0); + // + // Create platform HOBs for MM foundation to get MMIO HOB data. + // + PlatformHobList = AllocatePages (EFI_SIZE_TO_PAGES (PlatformHobSize)); + ASSERT (PlatformHobList != NULL); + if (PlatformHobList == NULL) { + DEBUG ((DEBUG_ERROR, "%a: Out of resource to create platform MM HOBs\n", __func__)); + CpuDeadLoop (); + } + + BufferSize = PlatformHobSize; + Status = CreateMmPlatformHob (PlatformHobList, &PlatformHobSize); + ASSERT_EFI_ERROR (Status); + ASSERT (BufferSize == PlatformHobSize); + } + + ASSERT_EFI_ERROR (Status); + + // + // Get size of foundation HOBs + // + FoundationHobSize = 0; + Status = CreateMmFoundationHobList ( + NULL, + &FoundationHobSize, + PlatformHobList, + PlatformHobSize, + MmFvBase, + MmFvSize, + MmCoreFileName, + MmCoreImageAddress, + MmCoreImageSize, + MmCoreEntryPoint, + Block + ); + FreePages (PlatformHobList, EFI_SIZE_TO_PAGES (PlatformHobSize)); + ASSERT (Status == RETURN_BUFFER_TOO_SMALL); + ASSERT (FoundationHobSize != 0); + + // + // Final result includes platform HOBs, foundation HOBs and a END node. + // + *HobSize = PlatformHobSize + FoundationHobSize + sizeof (EFI_HOB_GENERIC_HEADER); + HobList = AllocatePages (EFI_SIZE_TO_PAGES (*HobSize)); + ASSERT (HobList != NULL); + if (HobList == NULL) { + DEBUG ((DEBUG_ERROR, "Out of resource to create MM HOBs\n")); + CpuDeadLoop (); + } + + // + // Get platform HOBs + // + Status = CreateMmPlatformHob (HobList, &PlatformHobSize); + ASSERT_EFI_ERROR (Status); + + // + // Get foundation HOBs + // + Status = CreateMmFoundationHobList ( + (UINT8 *)HobList + PlatformHobSize, + &FoundationHobSize, + HobList, + PlatformHobSize, + MmFvBase, + MmFvSize, + MmCoreFileName, + MmCoreImageAddress, + MmCoreImageSize, + MmCoreEntryPoint, + Block + ); + ASSERT_EFI_ERROR (Status); + + // + // Create MM HOB list end. + // + MmIplCreateHob ((UINT8 *)HobList + PlatformHobSize + FoundationHobSize, EFI_HOB_TYPE_END_OF_HOB_LIST, sizeof (EFI_HOB_GENERIC_HEADER)); + + return HobList; +} + /** Find largest unallocated MMRAM in current MMRAM descriptor block @@ -360,6 +486,7 @@ ExecuteMmCoreFromMmram ( EFI_STATUS Status; UINTN PageCount; VOID *MmHobList; + UINTN MmHobSize; EFI_GUID MmCoreFileName; UINTN MmFvSize; EFI_PHYSICAL_ADDRESS MmFvBase; @@ -438,7 +565,18 @@ ExecuteMmCoreFromMmram ( // // Get HOB list for Standalone MM Core. // - MmHobList = GetHobList (); + MmHobSize = 0; + MmHobList = CreatMmHobList ( + &MmHobSize, + MmCommBuffer, + MmFvBase, + MmFvSize, + &MmCoreFileName, + ImageContext.ImageAddress, + ImageContext.ImageSize, + ImageContext.EntryPoint, + Block + ); // // Print debug message showing Standalone MM Core entry point address. @@ -451,6 +589,7 @@ ExecuteMmCoreFromMmram ( Entry = (STANDALONE_MM_FOUNDATION_ENTRY_POINT)(UINTN)ImageContext.EntryPoint; Status = Entry (MmHobList); ASSERT_EFI_ERROR (Status); + FreePages (MmHobList, EFI_SIZE_TO_PAGES (MmHobSize)); } } diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h index e9be3f556833..d99a64ec0871 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h @@ -24,6 +24,7 @@ #include #include #include +#include /** Communicates with a registered handler. @@ -66,4 +67,63 @@ EndOfPeiCallback ( IN VOID *Ppi ); +/** + Add a new HOB to the HOB List. + + @param[in] Hob The pointer of new HOB buffer. + @param[in] HobType Type of the new HOB. + @param[in] HobLength Length of the new HOB to allocate. + + @return NULL if there is no space to create a hob. + @return The address point to the new created hob. + +**/ +VOID * +MmIplCreateHob ( + IN VOID *Hob, + IN UINT16 HobType, + IN UINT16 HobLength + ); + +/** + Create the MM foundation specific HOB list which StandaloneMm Core needed. + + This function build the MM foundation specific HOB list needed by StandaloneMm Core + based on the PEI HOB list. + + @param[in] FoundationHobList The foundation HOB list to be used for HOB creation. + @param[in, out] FoundationHobSize The foundation HOB size. + On return, the expected/used size. + @param[in] PlatformHobList Platform HOB list. + @param[in] PlatformHobSize Platform HOB size. + @param[in] MmFvBase Base of firmare volume which included MM core dirver. + @param[in] MmFvSize Size of firmare volume which included MM core dirver. + @param[in] MmCoreFileName File name of MM core dirver. + @param[in] MmCoreImageAddress Image address of MM core dirver. + @param[in] MmCoreImageSize Image size of MM core dirver. + @param[in] MmCoreEntryPoint Entry pinter of MM core dirver. + @param[in] Block Pointer of MMRAM descriptor block. + + @retval RETURN_BUFFER_TOO_SMALL The buffer is too small for HOB creation. + BufferSize is updated to indicate the expected buffer size. + When the input BufferSize is bigger than the expected buffer size, + the BufferSize value will be changed the used buffer size. + @retval RETURN_SUCCESS HOB List is created/updated successfully or the input Length is 0. + +**/ +RETURN_STATUS +CreateMmFoundationHobList ( + IN UINT8 *FoundationHobList, + IN OUT UINTN *FoundationHobSize, + IN UINT8 *PlatformHobList, + IN UINTN PlatformHobSize, + IN EFI_PHYSICAL_ADDRESS MmFvBase, + IN UINT64 MmFvSize, + IN EFI_GUID *MmCoreFileName, + IN EFI_PHYSICAL_ADDRESS MmCoreImageAddress, + IN UINT64 MmCoreImageSize, + IN EFI_PHYSICAL_ADDRESS MmCoreEntryPoint, + IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block + ); + #endif diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf index a873efb0df2d..94abe6eee7ab 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf @@ -25,6 +25,7 @@ [Sources] StandaloneMmIplPei.c StandaloneMmIplPei.h + MmFoundationHob.c [Packages] MdePkg/MdePkg.dec @@ -41,6 +42,7 @@ BaseMemoryLib PeCoffLib CacheMaintenanceLib + MmPlatformHobProducerLib [Guids] gMmCommBufferHobGuid From c775cc762e5380c391e42f7910e68c6821836bca Mon Sep 17 00:00:00 2001 From: Zhang Hongbin Date: Tue, 2 Jul 2024 17:57:58 +0800 Subject: [PATCH 042/280] StandaloneMmPkg/MmIpl: Create misc HOBs for CPU Create misc HOBs for CPU, it included MM ACPI S3 Enable HOB, MM CPU sync configuration HOB, CPU SMM base HOB, SMRAM memory HOB, MP Information2 HOB and ACPI variable HOB Signed-off-by: Hongbin1 Zhang Cc: Jiewen Yao Cc: Ray Ni Cc: Star Zeng Cc: Jiaxin Wu Cc: Wei6 Xu Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Supreeth Venkatesh --- .../StandaloneMmIplPei/MmFoundationHob.c | 125 ++++++++++++++++++ .../StandaloneMmIplPei/StandaloneMmIplPei.inf | 12 +- 2 files changed, 136 insertions(+), 1 deletion(-) diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c index df3355f3fc0b..dbb13b06a93f 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c @@ -7,6 +7,10 @@ **/ #include +#include +#include +#include +#include /** Add a new HOB to the HOB List. @@ -79,6 +83,85 @@ MmIplBuildFvHob ( *HobBufferSize = HobLength; } +/** + Builds MM ACPI S3 Enable HOB. + + This function builds MM ACPI S3 Enable HOB. + It can only be invoked during PEI phase; + If new HOB buffer is NULL, then ASSERT(). + + @param[in] Hob The pointer of new HOB buffer. + @param[in, out] HobBufferSize The available size of the HOB buffer when as input. + The used size of when as output. + +**/ +VOID +MmIplBuildMmAcpiS3EnableHob ( + IN UINT8 *Hob, + IN OUT UINTN *HobBufferSize + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + MM_ACPI_S3_ENABLE *MmAcpiS3Enable; + UINT16 HobLength; + + ASSERT (Hob != NULL); + + HobLength = ALIGN_VALUE (sizeof (EFI_HOB_GUID_TYPE) + sizeof (MM_ACPI_S3_ENABLE), 8); + if (*HobBufferSize >= HobLength) { + MmIplCreateHob (Hob, EFI_HOB_TYPE_GUID_EXTENSION, HobLength); + + GuidHob = (EFI_HOB_GUID_TYPE *)Hob; + CopyGuid (&GuidHob->Name, &gMmAcpiS3EnableHobGuid); + + MmAcpiS3Enable = (MM_ACPI_S3_ENABLE *)(GuidHob + 1); + MmAcpiS3Enable->AcpiS3Enable = PcdGetBool (PcdAcpiS3Enable); + } + + *HobBufferSize = HobLength; +} + +/** + Builds MM cpu sync configuration HOB. + + This function builds smm cpu sync configuration HOB. + It can only be invoked during PEI phase; + If new HOB buffer is NULL, then ASSERT(). + + @param[in] Hob The pointer of new HOB buffer. + @param[in, out] HobBufferSize The available size of the HOB buffer when as input. + The used size of when as output. + +**/ +VOID +MmIplBuildMmCpuSyncConfigHob ( + IN UINT8 *Hob, + IN OUT UINTN *HobBufferSize + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + MM_CPU_SYNC_CONFIG *MmSyncModeInfoHob; + UINT16 HobLength; + + ASSERT (Hob != NULL); + + GuidHob = (EFI_HOB_GUID_TYPE *)(UINTN)Hob; + + HobLength = ALIGN_VALUE (sizeof (EFI_HOB_GUID_TYPE) + sizeof (MM_CPU_SYNC_CONFIG), 8); + if (*HobBufferSize >= HobLength) { + MmIplCreateHob (GuidHob, EFI_HOB_TYPE_GUID_EXTENSION, HobLength); + + CopyGuid (&GuidHob->Name, &gMmCpuSyncConfigHobGuid); + + MmSyncModeInfoHob = (MM_CPU_SYNC_CONFIG *)(UINTN)(GuidHob + 1); + MmSyncModeInfoHob->RelaxedApMode = (BOOLEAN)(PcdGet8 (PcdCpuSmmSyncMode) == MmCpuSyncModeRelaxedAp); + MmSyncModeInfoHob->Timeout = PcdGet64 (PcdCpuSmmApSyncTimeout); + MmSyncModeInfoHob->Timeout2 = PcdGet64 (PcdCpuSmmApSyncTimeout2); + } + + *HobBufferSize = HobLength; +} + /** Copies a data buffer to a newly-built HOB for GUID HOB @@ -281,6 +364,48 @@ CreateMmFoundationHobList ( MmIplBuildFvHob (FoundationHobList + UsedSize, &HobLength, MmFvBase, MmFvSize); UsedSize += HobLength; + // + // Build MM ACPI S3 Enable HOB + // + HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); + MmIplBuildMmAcpiS3EnableHob (FoundationHobList + UsedSize, &HobLength); + UsedSize += HobLength; + + // + // Build MM CPU sync configuration HOB + // + HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); + MmIplBuildMmCpuSyncConfigHob (FoundationHobList + UsedSize, &HobLength); + UsedSize += HobLength; + + // + // Build CPU SMM base HOB in MM HOB list + // + HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); + MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gSmmBaseHobGuid, TRUE); + UsedSize += HobLength; + + // + // Build SMRAM memory Hob in MM HOB list + // + HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); + MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gEfiSmmSmramMemoryGuid, FALSE); + UsedSize += HobLength; + + // + // Build Mp Information2 Hob in MM HOB list + // + HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); + MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gMpInformation2HobGuid, TRUE); + UsedSize += HobLength; + + // + // Build ACPI variable HOB + // + HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); + MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gEfiAcpiVariableGuid, FALSE); + UsedSize += HobLength; + if (*FoundationHobSize < UsedSize) { Status = RETURN_BUFFER_TOO_SMALL; } else { diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf index 94abe6eee7ab..bf0bdf735f9a 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf @@ -31,6 +31,7 @@ MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec StandaloneMmPkg/StandaloneMmPkg.dec + UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses] PeimEntryPoint @@ -48,6 +49,11 @@ gMmCommBufferHobGuid gEfiSmmSmramMemoryGuid gEventMmDispatchGuid + gSmmBaseHobGuid + gMpInformation2HobGuid + gEfiAcpiVariableGuid + gMmAcpiS3EnableHobGuid + gMmCpuSyncConfigHobGuid [Ppis] gEfiPeiMmControlPpiGuid @@ -59,6 +65,10 @@ [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdMmCommBufferPages + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout2 ## CONSUMES [Depex] - gEfiPeiMmControlPpiGuid + gEfiPeiMmControlPpiGuid AND gEfiPeiMpServicesPpiGuid From 378aff173c3e57374a4df2765b9b971236bb03bd Mon Sep 17 00:00:00 2001 From: Zhang Hongbin Date: Tue, 2 Jul 2024 18:16:16 +0800 Subject: [PATCH 043/280] StandaloneMmPkg/MmIpl: Create MM profile data HOBs Create memory allocation and resource HOB for MM profile data Signed-off-by: Hongbin1 Zhang Cc: Jiewen Yao Cc: Ray Ni Cc: Star Zeng Cc: Jiaxin Wu Cc: Wei6 Xu Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Supreeth Venkatesh --- .../StandaloneMmIplPei/MmFoundationHob.c | 150 ++++++++++++++++++ .../StandaloneMmIplPei/StandaloneMmIplPei.c | 21 ++- .../StandaloneMmIplPei/StandaloneMmIplPei.h | 14 ++ .../StandaloneMmIplPei/StandaloneMmIplPei.inf | 3 + 4 files changed, 182 insertions(+), 6 deletions(-) diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c index dbb13b06a93f..f3f436345110 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include /** Add a new HOB to the HOB List. @@ -44,6 +47,45 @@ MmIplCreateHob ( return Hob; } +/** + Builds a HOB that describes a chunk of system memory. + + This function builds a HOB that describes a chunk of system memory. + If there is no additional space for HOB creation, then ASSERT(). + + @param[in] Hob The pointer of new HOB buffer. + @param[in] ResourceType The type of resource described by this HOB. + @param[in] ResourceAttribute The resource attributes of the memory described by this HOB. + @param[in] PhysicalStart The 64 bit physical address of memory described by this HOB. + @param[in] NumberOfBytes The length of the memory described by this HOB in bytes. + @param[in] Owner The pointer of GUID. + +**/ +VOID +MmIplBuildMemoryResourceHob ( + IN EFI_HOB_RESOURCE_DESCRIPTOR *Hob, + IN EFI_RESOURCE_TYPE ResourceType, + IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute, + IN EFI_PHYSICAL_ADDRESS PhysicalStart, + IN UINT64 NumberOfBytes, + IN EFI_GUID *Owner + ) +{ + ASSERT (Hob != NULL); + MmIplCreateHob (Hob, EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)); + + Hob->ResourceType = EFI_RESOURCE_SYSTEM_MEMORY; + Hob->ResourceAttribute = ResourceAttribute; + Hob->PhysicalStart = PhysicalStart; + Hob->ResourceLength = NumberOfBytes; + + if (Owner != NULL) { + CopyGuid (&Hob->Owner, Owner); + } else { + ZeroMem (&Hob->Owner, sizeof (EFI_GUID)); + } +} + /** Builds a Firmware Volume HOB. @@ -260,6 +302,105 @@ MmIplBuildMmCoreModuleHob ( *HobBufferSize = HobLength; } +/** + Build memory allocation HOB in PEI HOB list for MM profile data. + + This function is to allocate memory for MM profile data. + + @return NULL if MM profile data memory allocation HOB build fail. + @return Pointer of MM profile data memory allocation HOB if build successfully. + +**/ +EFI_HOB_MEMORY_ALLOCATION * +BuildMmProfileDataHobInPeiHobList ( + VOID + ) +{ + EFI_PEI_HOB_POINTERS Hob; + UINTN TotalSize; + VOID *Alloc; + + TotalSize = PcdGet32 (PcdCpuSmmProfileSize); + Alloc = AllocateReservedPages (EFI_SIZE_TO_PAGES (TotalSize)); + if (Alloc == NULL) { + return NULL; + } + + ZeroMem (Alloc, TotalSize); + + Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION); + while (Hob.Raw != NULL) { + if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)Alloc) { + // + // Find the HOB just created and change the Name to gMmProfileDataHobGuid in PEI HOB list + // + CopyGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gMmProfileDataHobGuid); + return Hob.MemoryAllocation; + } + + Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (Hob)); + } + + return NULL; +} + +/** + Build memory allocation and resource HOB for MM profile data + + This function builds HOBs for MM profile data, one is memory + allocation HOB, another is resource HOB. + + @param[in] HobBuffer The pointer of new HOB buffer. + @param[in, out] HobBufferSize The total size of the same GUID HOBs when as input. + The size will be 0 for output when build HOB fail. + +**/ +VOID +MmIplBuildMmProfileHobs ( + IN UINT8 *HobBuffer, + IN OUT UINTN *HobBufferSize + ) +{ + EFI_PEI_HOB_POINTERS Hob; + UINTN HobLength; + + Hob.MemoryAllocation = NULL; + HobLength = ALIGN_VALUE (sizeof (EFI_HOB_MEMORY_ALLOCATION), 8) + ALIGN_VALUE (sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), 8); + + if (*HobBufferSize >= HobLength) { + Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION); + while (Hob.Raw != NULL) { + if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gMmProfileDataHobGuid)) { + break; + } + + Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (Hob)); + } + + ASSERT (Hob.MemoryAllocation != NULL); + + // + // Build memory allocation HOB + // + ASSERT (Hob.MemoryAllocation->Header.HobLength == ALIGN_VALUE (sizeof (EFI_HOB_MEMORY_ALLOCATION), 8)); + CopyMem (HobBuffer, Hob.Raw, Hob.MemoryAllocation->Header.HobLength); + + // + // Build resource HOB + // + MmIplBuildMemoryResourceHob ( + (EFI_HOB_RESOURCE_DESCRIPTOR *)(HobBuffer + Hob.MemoryAllocation->Header.HobLength), + EFI_RESOURCE_SYSTEM_MEMORY, + 0, + Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress, + Hob.MemoryAllocation->AllocDescriptor.MemoryLength, + &gMmProfileDataHobGuid + ); + } + + *HobBufferSize = HobLength; +} + /** Get remaining size for building HOBs. @@ -406,6 +547,15 @@ CreateMmFoundationHobList ( MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gEfiAcpiVariableGuid, FALSE); UsedSize += HobLength; + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + // + // Build memory allocation and resource HOB for MM profile data + // + HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); + MmIplBuildMmProfileHobs (FoundationHobList + UsedSize, &HobLength); + UsedSize += HobLength; + } + if (*FoundationHobSize < UsedSize) { Status = RETURN_BUFFER_TOO_SMALL; } else { diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c index 89dd05c1b76b..b6525b20fcc6 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c @@ -238,12 +238,13 @@ CreatMmHobList ( IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block ) { - EFI_STATUS Status; - VOID *HobList; - VOID *PlatformHobList; - UINTN PlatformHobSize; - UINTN BufferSize; - UINTN FoundationHobSize; + EFI_STATUS Status; + VOID *HobList; + VOID *PlatformHobList; + UINTN PlatformHobSize; + UINTN BufferSize; + UINTN FoundationHobSize; + EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob; // // Get platform HOBs @@ -270,6 +271,14 @@ CreatMmHobList ( ASSERT_EFI_ERROR (Status); + // + // Build memory allocation HOB in PEI HOB list for MM profile data. + // + MmProfileDataHob = NULL; + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + MmProfileDataHob = BuildMmProfileDataHobInPeiHobList (); + } + // // Get size of foundation HOBs // diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h index d99a64ec0871..e167a0d8f1e7 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h @@ -126,4 +126,18 @@ CreateMmFoundationHobList ( IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block ); +/** + Build memory allocation HOB in PEI HOB list for MM profile data. + + This function is to allocate memory for MM profile data. + + @return NULL if MM profile data memory allocation HOB build fail. + @return Pointer of MM profile data memory allocation HOB if build successfully. + +**/ +EFI_HOB_MEMORY_ALLOCATION * +BuildMmProfileDataHobInPeiHobList ( + VOID + ); + #endif diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf index bf0bdf735f9a..325a37342c35 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf @@ -54,6 +54,7 @@ gEfiAcpiVariableGuid gMmAcpiS3EnableHobGuid gMmCpuSyncConfigHobGuid + gMmProfileDataHobGuid [Ppis] gEfiPeiMmControlPpiGuid @@ -69,6 +70,8 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout2 ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileEnable ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## CONSUMES [Depex] gEfiPeiMmControlPpiGuid AND gEfiPeiMpServicesPpiGuid From 6855567d52246d6fb31a2eccc6add3e12fa9b3df Mon Sep 17 00:00:00 2001 From: Zhang Hongbin Date: Tue, 2 Jul 2024 18:57:28 +0800 Subject: [PATCH 044/280] StandaloneMmPkg/MmIpl: Create memory resource HOBs If PcdCpuSmmRestrictedMemoryAccess is TRUE, only unblocked memory Regions are available, if FALSE, all system memory is available. Signed-off-by: Hongbin1 Zhang Cc: Jiewen Yao Cc: Ray Ni Cc: Star Zeng Cc: Jiaxin Wu Cc: Wei6 Xu Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Supreeth Venkatesh --- .../StandaloneMmIplPei/MmFoundationHob.c | 305 ++++++++++++++++++ .../StandaloneMmIplPei/StandaloneMmIplPei.c | 2 + .../StandaloneMmIplPei/StandaloneMmIplPei.h | 2 + .../StandaloneMmIplPei/StandaloneMmIplPei.inf | 4 + 4 files changed, 313 insertions(+) diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c index f3f436345110..b13d4f688f00 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c @@ -12,9 +12,15 @@ #include #include #include +#include #include #include +typedef struct { + EFI_PHYSICAL_ADDRESS Base; + UINT64 Length; +} MM_IPL_MEMORY_REGION; + /** Add a new HOB to the HOB List. @@ -401,6 +407,275 @@ MmIplBuildMmProfileHobs ( *HobBufferSize = HobLength; } +/** + + Build resource Hobs from unblocked memory regions + + This function builds resource HOBs for all unblocked memory regions. + + @param[in] HobBuffer The pointer of new HOB buffer. + @param[in, out] HobBufferSize The total size of the same GUID HOBs when as output. + +**/ +VOID +MmIplBuildResourceHobForUnblockedRegion ( + IN UINT8 *HobBuffer, + IN OUT UINTN *HobBufferSize + ) +{ + MM_UNBLOCK_REGION *UnblockRegion; + EFI_HOB_GENERIC_HEADER *GuidHob; + UINTN UsedSize; + + UsedSize = 0; + + GuidHob = GetFirstGuidHob (&gMmUnblockRegionHobGuid); + while (GuidHob != NULL) { + if (*HobBufferSize >= UsedSize + sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) { + UnblockRegion = GET_GUID_HOB_DATA (GuidHob); + MmIplBuildMemoryResourceHob ( + (EFI_HOB_RESOURCE_DESCRIPTOR *)(HobBuffer + UsedSize), + EFI_RESOURCE_SYSTEM_MEMORY, + 0, + UnblockRegion->PhysicalStart, + EFI_PAGES_TO_SIZE (UnblockRegion->NumberOfPages), + &UnblockRegion->IdentifierGuid + ); + } + + UsedSize += sizeof (EFI_HOB_RESOURCE_DESCRIPTOR); + GuidHob = GetNextGuidHob (&gMmUnblockRegionHobGuid, GET_NEXT_HOB (GuidHob)); + } + + *HobBufferSize = UsedSize; +} + +/** + Create MMIO memory map according to platform HOB. + + @param[in] PlatformHobList Platform HOB list. + @param[in] PlatformHobSize Platform HOB size. + @param[in, out] MemoryRegion Memory regions. + @param[in, out] MemoryRegionCount Count of MMIO regions +**/ +VOID +CollectPlatformMemoryRegions ( + IN UINT8 *PlatformHobList, + IN UINTN PlatformHobSize, + IN OUT MM_IPL_MEMORY_REGION *MemoryRegion, + IN OUT UINTN *MemoryRegionCount + ) +{ + UINTN Index; + EFI_PEI_HOB_POINTERS Hob; + + ASSERT (MemoryRegionCount != NULL); + ASSERT (*MemoryRegionCount == 0 || MemoryRegion != NULL); + + Index = 0; + // + // Get the HOB list for processing + // + Hob.Raw = PlatformHobList; + + // + // Collect memory ranges + // + while (Hob.Raw < PlatformHobList + PlatformHobSize) { + if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + if ( (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_MAPPED_IO) + || (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) + || (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_FIRMWARE_DEVICE) + || (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) + { + if (Index < *MemoryRegionCount) { + MemoryRegion[Index].Base = Hob.ResourceDescriptor->PhysicalStart; + MemoryRegion[Index].Length = Hob.ResourceDescriptor->ResourceLength; + } + + Index++; + } + } + + Hob.Raw = GET_NEXT_HOB (Hob); + } + + *MemoryRegionCount = Index; +} + +/** + Function to compare 2 MM_IPL_MEMORY_REGION pointer based on Base. + + @param[in] Buffer1 pointer to MM_IPL_MEMORY_REGION pointer to compare + @param[in] Buffer2 pointer to second MM_IPL_MEMORY_REGION pointer to compare + + @retval 0 Buffer1 equal to Buffer2 + @retval <0 Buffer1 is less than Buffer2 + @retval >0 Buffer1 is greater than Buffer2 +**/ +INTN +EFIAPI +MemoryRegionBaseAddressCompare ( + IN CONST VOID *Buffer1, + IN CONST VOID *Buffer2 + ) +{ + if (((MM_IPL_MEMORY_REGION *)Buffer1)->Base > ((MM_IPL_MEMORY_REGION *)Buffer2)->Base) { + return 1; + } else if (((MM_IPL_MEMORY_REGION *)Buffer1)->Base < ((MM_IPL_MEMORY_REGION *)Buffer2)->Base) { + return -1; + } + + return 0; +} + +/** + Calculate the maximum support address. + + @return the maximum support address. +**/ +UINT8 +MmIplCalculateMaximumSupportAddress ( + VOID + ) +{ + UINT32 RegEax; + UINT8 PhysicalAddressBits; + VOID *Hob; + + // + // Get physical address bits supported. + // + Hob = GetFirstHob (EFI_HOB_TYPE_CPU); + if (Hob != NULL) { + PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace; + } else { + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); + if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) { + AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL); + PhysicalAddressBits = (UINT8)RegEax; + } else { + PhysicalAddressBits = 36; + } + } + + return PhysicalAddressBits; +} + +/** + Build resource HOB to cover [0, PhysicalAddressBits length] by excluding + all Mmram ranges, MM Profile data and MMIO ranges. + + @param[in] HobBuffer The pointer of new HOB buffer. + @param[in, out] HobBufferSize The available size of the HOB buffer when as input. + The used size of when as output. + @param[in] PlatformHobList Platform HOB list. + @param[in] PlatformHobSize Platform HOB size. + @param[in] Block Pointer of MMRAM descriptor block. + @param[in] MmProfileDataHob Pointer to MM profile data HOB. + +**/ +VOID +MmIplBuildResourceHobForAllSystemMemory ( + IN UINT8 *HobBuffer, + IN OUT UINTN *HobBufferSize, + IN VOID *PlatformHobList, + IN UINTN PlatformHobSize, + IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block, + IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob + ) +{ + UINTN Index; + UINTN Count; + UINTN PlatformRegionCount; + UINTN UsedSize; + UINT64 PreviousAddress; + UINT64 MaxAddress; + MM_IPL_MEMORY_REGION *MemoryRegions; + MM_IPL_MEMORY_REGION SortBuffer; + + MaxAddress = LShiftU64 (1, MmIplCalculateMaximumSupportAddress ()); + + // + // Get the count of platform memory regions + // + PlatformRegionCount = 0; + if ((PlatformHobList != NULL) && (PlatformHobSize != 0)) { + CollectPlatformMemoryRegions (PlatformHobList, PlatformHobSize, NULL, &PlatformRegionCount); + } + + // + // Allocate buffer for platform memory regions, MM Profile data, MMRam ranges, an extra terminator. + // + Count = PlatformRegionCount + Block->NumberOfMmReservedRegions + ((MmProfileDataHob != NULL) ? 1 : 0) + 1; + MemoryRegions = AllocatePages (EFI_SIZE_TO_PAGES (Count * sizeof (*MemoryRegions))); + ASSERT (MemoryRegions != NULL); + if (MemoryRegions == NULL) { + DEBUG ((DEBUG_ERROR, "%a:%d - No enough memory\n", __func__, __LINE__)); + CpuDeadLoop (); + return; + } + + // + // The very last region is the terminator + // + MemoryRegions[Count - 1].Base = MaxAddress; + MemoryRegions[Count - 1].Length = 0; + + // + // Collect platform memory regions + // + if (PlatformRegionCount != 0) { + CollectPlatformMemoryRegions (PlatformHobList, PlatformHobSize, MemoryRegions, &PlatformRegionCount); + } + + // + // Collect SMRAM regions + // + for (Index = 0; Index < Block->NumberOfMmReservedRegions; Index++) { + MemoryRegions[PlatformRegionCount + Index].Base = Block->Descriptor[Index].CpuStart; + MemoryRegions[PlatformRegionCount + Index].Length = Block->Descriptor[Index].PhysicalSize; + } + + // + // Collect MM profile database region + // + if (MmProfileDataHob != NULL) { + MemoryRegions[PlatformRegionCount + Block->NumberOfMmReservedRegions].Base = MmProfileDataHob->AllocDescriptor.MemoryBaseAddress; + MemoryRegions[PlatformRegionCount + Block->NumberOfMmReservedRegions].Length = MmProfileDataHob->AllocDescriptor.MemoryLength; + } + + // + // Build system memory resource HOBs excluding platform memory regions, SMRAM regions, MmProfile database. + // + QuickSort (MemoryRegions, Count, sizeof (*MemoryRegions), MemoryRegionBaseAddressCompare, &SortBuffer); + UsedSize = 0; + PreviousAddress = 0; + for (Index = 0; Index < Count; Index++) { + ASSERT (MaxAddress >= MemoryRegions[Index].Base + MemoryRegions[Index].Length); + + if (MemoryRegions[Index].Base > PreviousAddress) { + if (*HobBufferSize >= UsedSize + sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) { + MmIplBuildMemoryResourceHob ( + (EFI_HOB_RESOURCE_DESCRIPTOR *)(HobBuffer + UsedSize), + EFI_RESOURCE_SYSTEM_MEMORY, + FeaturePcdGet (PcdCpuSmmProfileEnable) ? MM_RESOURCE_ATTRIBUTE_LOGGING : 0, + PreviousAddress, + MemoryRegions[Index].Base - PreviousAddress, + &gEfiCallerIdGuid + ); + } + + UsedSize += sizeof (EFI_HOB_RESOURCE_DESCRIPTOR); + } + + PreviousAddress = MemoryRegions[Index].Base + MemoryRegions[Index].Length; + } + + *HobBufferSize = UsedSize; + FreePages (MemoryRegions, EFI_SIZE_TO_PAGES (Count * sizeof (EFI_MEMORY_DESCRIPTOR))); +} + /** Get remaining size for building HOBs. @@ -439,6 +714,7 @@ GetRemainingHobSize ( @param[in] MmCoreImageAddress Image address of MM core dirver. @param[in] MmCoreImageSize Image size of MM core dirver. @param[in] MmCoreEntryPoint Entry pinter of MM core dirver. + @param[in] MmProfileDataHob Pointer to Mm profile data HOB. @param[in] Block Pointer of MMRAM descriptor block. @retval RETURN_BUFFER_TOO_SMALL The buffer is too small for HOB creation. @@ -460,6 +736,7 @@ CreateMmFoundationHobList ( IN EFI_PHYSICAL_ADDRESS MmCoreImageAddress, IN UINT64 MmCoreImageSize, IN EFI_PHYSICAL_ADDRESS MmCoreEntryPoint, + IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob, IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block ) { @@ -474,6 +751,16 @@ CreateMmFoundationHobList ( ((*FoundationHobSize == 0) && (FoundationHobList == NULL)) ); + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + // + // When SmmProfile is enabled, all DRAM is accessible from SMM drivers' perspective. + // However, underline Cpu SMM driver does not map the DRAM so that every access to it triggers #PF. + // #PF handler records the access then sets up the mapping in the page table to allow the temporary access by current instruction. + // The mapping is revoked before next instruction runs. + // + ASSERT (!PcdGetBool (PcdCpuSmmRestrictedMemoryAccess)); + } + UsedSize = 0; // @@ -556,6 +843,24 @@ CreateMmFoundationHobList ( UsedSize += HobLength; } + HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); + if (PcdGetBool (PcdCpuSmmRestrictedMemoryAccess)) { + // + // Only unblocked memory regions are accessible + // + MmIplBuildResourceHobForUnblockedRegion (FoundationHobList + UsedSize, &HobLength); + } else { + // + // All system memory (DRAM) is accessible. + // When SMM Profile is enabled: + // * Access to regions reported from MmPlatformHobProducerLib do not require logging. + // * Access to other system memory requires logging. + // + MmIplBuildResourceHobForAllSystemMemory (FoundationHobList + UsedSize, &HobLength, PlatformHobList, PlatformHobSize, Block, MmProfileDataHob); + } + + UsedSize += HobLength; + if (*FoundationHobSize < UsedSize) { Status = RETURN_BUFFER_TOO_SMALL; } else { diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c index b6525b20fcc6..b1cd3c1d81e1 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c @@ -294,6 +294,7 @@ CreatMmHobList ( MmCoreImageAddress, MmCoreImageSize, MmCoreEntryPoint, + MmProfileDataHob, Block ); FreePages (PlatformHobList, EFI_SIZE_TO_PAGES (PlatformHobSize)); @@ -331,6 +332,7 @@ CreatMmHobList ( MmCoreImageAddress, MmCoreImageSize, MmCoreEntryPoint, + MmProfileDataHob, Block ); ASSERT_EFI_ERROR (Status); diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h index e167a0d8f1e7..9301b8f3f5c4 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h @@ -102,6 +102,7 @@ MmIplCreateHob ( @param[in] MmCoreImageAddress Image address of MM core dirver. @param[in] MmCoreImageSize Image size of MM core dirver. @param[in] MmCoreEntryPoint Entry pinter of MM core dirver. + @param[in] MmProfileDataHob Pointer to MM profile data HOB. @param[in] Block Pointer of MMRAM descriptor block. @retval RETURN_BUFFER_TOO_SMALL The buffer is too small for HOB creation. @@ -123,6 +124,7 @@ CreateMmFoundationHobList ( IN EFI_PHYSICAL_ADDRESS MmCoreImageAddress, IN UINT64 MmCoreImageSize, IN EFI_PHYSICAL_ADDRESS MmCoreEntryPoint, + IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob, IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block ); diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf index 325a37342c35..dfc181218ed0 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf @@ -55,6 +55,7 @@ gMmAcpiS3EnableHobGuid gMmCpuSyncConfigHobGuid gMmProfileDataHobGuid + gMmUnblockRegionHobGuid [Ppis] gEfiPeiMmControlPpiGuid @@ -73,5 +74,8 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileEnable ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## CONSUMES +[Pcd.X64] + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmRestrictedMemoryAccess ## CONSUMES + [Depex] gEfiPeiMmControlPpiGuid AND gEfiPeiMpServicesPpiGuid From 6dc14fb5b47da8059f65512543afd72624bd7085 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Mon, 6 May 2024 23:45:05 +0800 Subject: [PATCH 045/280] StandaloneMmPkg/Core: Remove traditional MM driver support StandaloneMmCore should not support dispatching traditional MM driver which has dependency on UEFI services. Therefore, remove the related code that supports traditional MM driver. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Core/Dependency.c | 7 ---- StandaloneMmPkg/Core/Dispatcher.c | 52 +------------------------ StandaloneMmPkg/Core/FwVol.c | 41 ++++++------------- StandaloneMmPkg/Core/StandaloneMmCore.c | 1 - StandaloneMmPkg/Core/StandaloneMmCore.h | 1 - 5 files changed, 14 insertions(+), 88 deletions(-) diff --git a/StandaloneMmPkg/Core/Dependency.c b/StandaloneMmPkg/Core/Dependency.c index 2bcb07d34666..0a77ceb20cff 100644 --- a/StandaloneMmPkg/Core/Dependency.c +++ b/StandaloneMmPkg/Core/Dependency.c @@ -231,13 +231,6 @@ MmIsSchedulable ( CopyMem (&DriverGuid, Iterator + 1, sizeof (EFI_GUID)); Status = MmLocateProtocol (&DriverGuid, NULL, &Interface); - if (EFI_ERROR (Status) && (mEfiSystemTable != NULL)) { - // - // For MM Driver, it may depend on uefi protocols - // - Status = mEfiSystemTable->BootServices->LocateProtocol (&DriverGuid, NULL, &Interface); - } - if (EFI_ERROR (Status)) { DEBUG ((DEBUG_DISPATCH, " PUSH GUID(%g) = FALSE\n", &DriverGuid)); Status = PushBool (FALSE); diff --git a/StandaloneMmPkg/Core/Dispatcher.c b/StandaloneMmPkg/Core/Dispatcher.c index 01a2b3af0dcb..31ba236df112 100644 --- a/StandaloneMmPkg/Core/Dispatcher.c +++ b/StandaloneMmPkg/Core/Dispatcher.c @@ -185,45 +185,6 @@ MmLoadImage ( DriverEntry->ImageBuffer = DstBuffer; DriverEntry->NumberOfPage = PageCount; - if (mEfiSystemTable != NULL) { - Status = mEfiSystemTable->BootServices->AllocatePool ( - EfiBootServicesData, - sizeof (EFI_LOADED_IMAGE_PROTOCOL), - (VOID **)&DriverEntry->LoadedImage - ); - if (EFI_ERROR (Status)) { - MmFreePages (DstBuffer, PageCount); - return Status; - } - - ZeroMem (DriverEntry->LoadedImage, sizeof (EFI_LOADED_IMAGE_PROTOCOL)); - // - // Fill in the remaining fields of the Loaded Image Protocol instance. - // Note: ImageBase is an SMRAM address that can not be accessed outside of SMRAM if SMRAM window is closed. - // - DriverEntry->LoadedImage->Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; - DriverEntry->LoadedImage->ParentHandle = NULL; - DriverEntry->LoadedImage->SystemTable = mEfiSystemTable; - DriverEntry->LoadedImage->DeviceHandle = NULL; - DriverEntry->LoadedImage->FilePath = NULL; - - DriverEntry->LoadedImage->ImageBase = (VOID *)(UINTN)DriverEntry->ImageBuffer; - DriverEntry->LoadedImage->ImageSize = ImageContext.ImageSize; - DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode; - DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData; - - // - // Create a new image handle in the UEFI handle database for the MM Driver - // - DriverEntry->ImageHandle = NULL; - Status = mEfiSystemTable->BootServices->InstallMultipleProtocolInterfaces ( - &DriverEntry->ImageHandle, - &gEfiLoadedImageProtocolGuid, - DriverEntry->LoadedImage, - NULL - ); - } - // // Print the load address and the PDB file name if it is available // @@ -464,17 +425,8 @@ MmDispatcher ( // // For each MM driver, pass NULL as ImageHandle // - if (mEfiSystemTable == NULL) { - DEBUG ((DEBUG_INFO, "StartImage - 0x%x (Standalone Mode)\n", DriverEntry->ImageEntryPoint)); - Status = ((MM_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, &gMmCoreMmst); - } else { - DEBUG ((DEBUG_INFO, "StartImage - 0x%x (Tradition Mode)\n", DriverEntry->ImageEntryPoint)); - Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)( - DriverEntry->ImageHandle, - mEfiSystemTable - ); - } - + DEBUG ((DEBUG_INFO, "StartImage - 0x%x (Standalone Mode)\n", DriverEntry->ImageEntryPoint)); + Status = ((MM_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, &gMmCoreMmst); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_INFO, "StartImage Status - %r\n", Status)); MmFreePages (DriverEntry->ImageBuffer, DriverEntry->NumberOfPage); diff --git a/StandaloneMmPkg/Core/FwVol.c b/StandaloneMmPkg/Core/FwVol.c index 07500cee41f3..9c5ee9c41227 100644 --- a/StandaloneMmPkg/Core/FwVol.c +++ b/StandaloneMmPkg/Core/FwVol.c @@ -11,18 +11,6 @@ #include #include -// -// List of file types supported by dispatcher -// -EFI_FV_FILETYPE mMmFileTypes[] = { - EFI_FV_FILETYPE_MM, - 0xE, // EFI_FV_FILETYPE_MM_STANDALONE, - // - // Note: DXE core will process the FV image file, so skip it in MM core - // EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE - // -}; - EFI_STATUS MmAddToDriverList ( IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader, @@ -72,12 +60,10 @@ MmCoreFfsFindMmDriver ( EFI_STATUS Status; EFI_STATUS DepexStatus; EFI_FFS_FILE_HEADER *FileHeader; - EFI_FV_FILETYPE FileType; VOID *Pe32Data; UINTN Pe32DataSize; VOID *Depex; UINTN DepexSize; - UINTN Index; EFI_COMMON_SECTION_HEADER *Section; VOID *SectionData; UINTN SectionDataSize; @@ -224,22 +210,19 @@ MmCoreFfsFindMmDriver ( } } while (TRUE); - for (Index = 0; Index < sizeof (mMmFileTypes) / sizeof (mMmFileTypes[0]); Index++) { - DEBUG ((DEBUG_INFO, "Check MmFileTypes - 0x%x\n", mMmFileTypes[Index])); - FileType = mMmFileTypes[Index]; - FileHeader = NULL; - do { - Status = FfsFindNextFile (FileType, FwVolHeader, &FileHeader); - if (!EFI_ERROR (Status)) { - Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, &Pe32Data, &Pe32DataSize); - DEBUG ((DEBUG_INFO, "Find PE data - 0x%x\n", Pe32Data)); - DepexStatus = FfsFindSectionData (EFI_SECTION_MM_DEPEX, FileHeader, &Depex, &DepexSize); - if (!EFI_ERROR (DepexStatus)) { - MmAddToDriverList (FwVolHeader, Pe32Data, Pe32DataSize, Depex, DepexSize, &FileHeader->Name); - } + DEBUG ((DEBUG_INFO, "Check MmFileTypes - 0x%x\n", EFI_FV_FILETYPE_MM_STANDALONE)); + FileHeader = NULL; + do { + Status = FfsFindNextFile (EFI_FV_FILETYPE_MM_STANDALONE, FwVolHeader, &FileHeader); + if (!EFI_ERROR (Status)) { + Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, &Pe32Data, &Pe32DataSize); + DEBUG ((DEBUG_INFO, "Find PE data - 0x%x\n", Pe32Data)); + DepexStatus = FfsFindSectionData (EFI_SECTION_MM_DEPEX, FileHeader, &Depex, &DepexSize); + if (!EFI_ERROR (DepexStatus)) { + MmAddToDriverList (FwVolHeader, Pe32Data, Pe32DataSize, Depex, DepexSize, &FileHeader->Name); } - } while (!EFI_ERROR (Status)); - } + } + } while (!EFI_ERROR (Status)); return EFI_SUCCESS; diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c index 81db9a953851..b70e340c04ae 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.c +++ b/StandaloneMmPkg/Core/StandaloneMmCore.c @@ -86,7 +86,6 @@ MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = { { NULL, NULL, NULL, FALSE }, }; -EFI_SYSTEM_TABLE *mEfiSystemTable; UINTN mMmramRangeCount; EFI_MMRAM_DESCRIPTOR *mMmramRanges; diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.h b/StandaloneMmPkg/Core/StandaloneMmCore.h index a8fda6dcc210..ae6c840f0c2a 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.h +++ b/StandaloneMmPkg/Core/StandaloneMmCore.h @@ -873,6 +873,5 @@ MmCoreFfsFindMmDriver ( extern UINTN mMmramRangeCount; extern EFI_MMRAM_DESCRIPTOR *mMmramRanges; -extern EFI_SYSTEM_TABLE *mEfiSystemTable; #endif From a44830727ac6bc6e2851f3a2432b177b3168cb56 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Tue, 7 May 2024 01:32:48 +0800 Subject: [PATCH 046/280] StandaloneMmPkg/Core: Install Loaded Image Protocol for MM drivers Install Loaded Image Protocol into MM handle database for each MM driver. Change EFI_MM_DRIVER_ENTRY structure definition to hold the Loaded Image Protocol data directly, instead a pointer to the protocol, to avoid allocating pool for each MM driver. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Core/Dispatcher.c | 32 +++++++++++++++++++++++++ StandaloneMmPkg/Core/StandaloneMmCore.h | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/StandaloneMmPkg/Core/Dispatcher.c b/StandaloneMmPkg/Core/Dispatcher.c index 31ba236df112..dd8f79a2d264 100644 --- a/StandaloneMmPkg/Core/Dispatcher.c +++ b/StandaloneMmPkg/Core/Dispatcher.c @@ -185,6 +185,31 @@ MmLoadImage ( DriverEntry->ImageBuffer = DstBuffer; DriverEntry->NumberOfPage = PageCount; + // + // Fill in the remaining fields of the Loaded Image Protocol instance. + // Note: ImageBase is an SMRAM address that can not be accessed outside of SMRAM if SMRAM window is closed. + // + DriverEntry->LoadedImage.Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; + DriverEntry->LoadedImage.ParentHandle = NULL; + DriverEntry->LoadedImage.SystemTable = NULL; + DriverEntry->LoadedImage.DeviceHandle = NULL; + DriverEntry->LoadedImage.FilePath = NULL; + + DriverEntry->LoadedImage.ImageBase = (VOID *)(UINTN)DriverEntry->ImageBuffer; + DriverEntry->LoadedImage.ImageSize = ImageContext.ImageSize; + DriverEntry->LoadedImage.ImageCodeType = EfiRuntimeServicesCode; + DriverEntry->LoadedImage.ImageDataType = EfiRuntimeServicesData; + + // + // Install Loaded Image protocol into MM handle database for the MM Driver + // + MmInstallProtocolInterface ( + &DriverEntry->ImageHandle, + &gEfiLoadedImageProtocolGuid, + EFI_NATIVE_INTERFACE, + &DriverEntry->LoadedImage + ); + // // Print the load address and the PDB file name if it is available // @@ -430,6 +455,13 @@ MmDispatcher ( if (EFI_ERROR (Status)) { DEBUG ((DEBUG_INFO, "StartImage Status - %r\n", Status)); MmFreePages (DriverEntry->ImageBuffer, DriverEntry->NumberOfPage); + if (DriverEntry->ImageHandle != NULL) { + MmUninstallProtocolInterface ( + DriverEntry->ImageHandle, + &gEfiLoadedImageProtocolGuid, + &DriverEntry->LoadedImage + ); + } } } diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.h b/StandaloneMmPkg/Core/StandaloneMmCore.h index ae6c840f0c2a..c08d1d76c062 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.h +++ b/StandaloneMmPkg/Core/StandaloneMmCore.h @@ -85,7 +85,7 @@ typedef struct { BOOLEAN DepexProtocolError; EFI_HANDLE ImageHandle; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_LOADED_IMAGE_PROTOCOL LoadedImage; // // Image EntryPoint in MMRAM // From dd775aa4d4699440f6f3a1ad7a59e6d9bb6b07c4 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Tue, 7 May 2024 01:59:46 +0800 Subject: [PATCH 047/280] StandaloneMmPkg/Core: Install Loaded Image Protocol for MM Core Retrieves the MM Core image info from Memory Allocation HOB reported by MM IPL. Then install Loaded Image Protocol for MM Core with the image info from HOB. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Core/StandaloneMmCore.c | 85 +++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c index b70e340c04ae..c6f8886750bf 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.c +++ b/StandaloneMmPkg/Core/StandaloneMmCore.c @@ -317,6 +317,86 @@ MmEndOfDxeHandler ( return Status; } +/** + Install LoadedImage protocol for MM Core. + +**/ +VOID +MmCoreInstallLoadedImage ( + VOID + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS MmCoreImageBaseAddress; + UINT64 MmCoreImageLength; + EFI_PEI_HOB_POINTERS Hob; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_HANDLE ImageHandle; + + // + // Searching for Memory Allocation HOB + // + Hob.Raw = GetHobList (); + while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) { + // + // Find MM Core HOB + // + if (CompareGuid ( + &Hob.MemoryAllocationModule->MemoryAllocationHeader.Name, + &gEfiHobMemoryAllocModuleGuid + )) + { + if (CompareGuid (&Hob.MemoryAllocationModule->ModuleName, &gEfiCallerIdGuid)) { + break; + } + } + + Hob.Raw = GET_NEXT_HOB (Hob); + } + + if (Hob.Raw == NULL) { + return; + } + + MmCoreImageBaseAddress = Hob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress; + MmCoreImageLength = Hob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength; + + // + // Allocate a Loaded Image Protocol in MM + // + LoadedImage = AllocatePool (sizeof (EFI_LOADED_IMAGE_PROTOCOL)); + ASSERT (LoadedImage != NULL); + if (LoadedImage == NULL) { + return; + } + + ZeroMem (LoadedImage, sizeof (EFI_LOADED_IMAGE_PROTOCOL)); + + // + // Fill in the remaining fields of the Loaded Image Protocol instance. + // + LoadedImage->Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; + LoadedImage->ParentHandle = NULL; + LoadedImage->SystemTable = NULL; + + LoadedImage->ImageBase = (VOID *)(UINTN)MmCoreImageBaseAddress; + LoadedImage->ImageSize = MmCoreImageLength; + LoadedImage->ImageCodeType = EfiRuntimeServicesCode; + LoadedImage->ImageDataType = EfiRuntimeServicesData; + + // + // Create a new image handle in the MM handle database for the MM Core + // + ImageHandle = NULL; + Status = MmInstallProtocolInterface ( + &ImageHandle, + &gEfiLoadedImageProtocolGuid, + EFI_NATIVE_INTERFACE, + LoadedImage + ); + ASSERT_EFI_ERROR (Status); +} + /** The main entry point to MM Foundation. @@ -657,6 +737,11 @@ StandaloneMmMain ( DEBUG ((DEBUG_INFO, "MmiHandlerRegister - GUID %g - Status %d\n", mMmCoreMmiHandlers[Index].HandlerType, Status)); } + // + // Install Loaded Image Protocol form MM Core + // + MmCoreInstallLoadedImage (); + DEBUG ((DEBUG_INFO, "MmMain Done!\n")); return EFI_SUCCESS; From 68487b4736291e3f3efc5181e1b13d0b63bffe80 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Tue, 7 May 2024 09:13:17 +0800 Subject: [PATCH 048/280] StandaloneMmPkg/Core: Switch to MM HobList after MM HostList is ready Switch to MM HobList as soon as MM HostList is initialized to avoid StandaloneMmCore still using the HobList which is outside of MMRAM. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Core/StandaloneMmCore.c | 1 + 1 file changed, 1 insertion(+) diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c index c6f8886750bf..14e76fa67e05 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.c +++ b/StandaloneMmPkg/Core/StandaloneMmCore.c @@ -703,6 +703,7 @@ StandaloneMmMain ( CopyMem (MmHobStart, HobStart, HobSize); Status = MmInstallConfigurationTable (&gMmCoreMmst, &gEfiHobListGuid, MmHobStart, HobSize); ASSERT_EFI_ERROR (Status); + gHobList = MmHobStart; // // Register notification for EFI_MM_CONFIGURATION_PROTOCOL registration and From 24e41d1fa3e08972ced64617df651b105411e13a Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Mon, 13 May 2024 23:51:45 +0800 Subject: [PATCH 049/280] StandaloneMmPkg/Core: Introduce MM Communication Buffer Get the MM Communication context from the MM Communication Buffer, instead of the pointer inside gMmCorePrivate. In the MmEntryPoint, check IsCommBufferValid from MM_COMM_BUFFER to decide whether the MMI is Synchronous MMI or Asynchronous MMI. If it is a Synchronous MMI, MM Core shadows the communication buffer into a internal copy, then invokes the MMI handlers, lastly copies data back to the MM Communication Buffer and set the return status. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Core/StandaloneMmCore.c | 142 ++++++++++++++++++---- StandaloneMmPkg/Core/StandaloneMmCore.h | 1 + StandaloneMmPkg/Core/StandaloneMmCore.inf | 1 + 3 files changed, 120 insertions(+), 24 deletions(-) diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c index 14e76fa67e05..7e129832fce4 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.c +++ b/StandaloneMmPkg/Core/StandaloneMmCore.c @@ -88,6 +88,8 @@ MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = { UINTN mMmramRangeCount; EFI_MMRAM_DESCRIPTOR *mMmramRanges; +MM_COMM_BUFFER *mMmCommunicationBuffer; +VOID *mInternalCommBufferCopy; /** Place holder function until all the MM System Table Service are available. @@ -397,6 +399,62 @@ MmCoreInstallLoadedImage ( ASSERT_EFI_ERROR (Status); } +/** + Prepare communication buffer for MMI. +**/ +VOID +MmCorePrepareCommunicationBuffer ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HOB_GUID_TYPE *GuidHob; + EFI_PHYSICAL_ADDRESS Buffer; + + mMmCommunicationBuffer = NULL; + mInternalCommBufferCopy = NULL; + + GuidHob = GetFirstGuidHob (&gMmCommBufferHobGuid); + ASSERT (GuidHob != NULL); + if (GuidHob == NULL) { + return; + } + + mMmCommunicationBuffer = (MM_COMM_BUFFER *)GET_GUID_HOB_DATA (GuidHob); + DEBUG (( + DEBUG_INFO, + "MM Communication Buffer is at %x, number of pages is %x\n", + mMmCommunicationBuffer->PhysicalStart, + mMmCommunicationBuffer->NumberOfPages + )); + ASSERT (mMmCommunicationBuffer->PhysicalStart != 0 && mMmCommunicationBuffer->NumberOfPages != 0); + + if (!MmIsBufferOutsideMmValid ( + mMmCommunicationBuffer->PhysicalStart, + EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages) + )) + { + mMmCommunicationBuffer = NULL; + DEBUG ((DEBUG_ERROR, "MM Communication Buffer is invalid!\n")); + ASSERT (FALSE); + return; + } + + Status = MmAllocatePages ( + AllocateAnyPages, + EfiRuntimeServicesData, + mMmCommunicationBuffer->NumberOfPages, + &Buffer + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return; + } + + mInternalCommBufferCopy = (VOID *)(UINTN)Buffer; + DEBUG ((DEBUG_INFO, "Internal Communication Buffer Copy is at %p\n", mInternalCommBufferCopy)); +} + /** The main entry point to MM Foundation. @@ -414,6 +472,8 @@ MmEntryPoint ( { EFI_STATUS Status; EFI_MM_COMMUNICATE_HEADER *CommunicateHeader; + MM_COMM_BUFFER_STATUS *CommunicationStatus; + UINTN BufferSize; DEBUG ((DEBUG_INFO, "MmEntryPoint ...\n")); @@ -440,33 +500,65 @@ MmEntryPoint ( // Check to see if this is a Synchronous MMI sent through the MM Communication // Protocol or an Asynchronous MMI // - if (gMmCorePrivate->CommunicationBuffer != 0) { - // - // Synchronous MMI for MM Core or request from Communicate protocol - // - if (!MmIsBufferOutsideMmValid ((UINTN)gMmCorePrivate->CommunicationBuffer, gMmCorePrivate->BufferSize)) { - // - // If CommunicationBuffer is not in valid address scope, return EFI_INVALID_PARAMETER - // - gMmCorePrivate->CommunicationBuffer = 0; - gMmCorePrivate->ReturnStatus = EFI_INVALID_PARAMETER; - } else { - CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)gMmCorePrivate->CommunicationBuffer; - gMmCorePrivate->BufferSize -= OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data); - Status = MmiManage ( - &CommunicateHeader->HeaderGuid, - NULL, - CommunicateHeader->Data, - (UINTN *)&gMmCorePrivate->BufferSize - ); + if ((mMmCommunicationBuffer != NULL) && (mInternalCommBufferCopy != NULL)) { + CommunicationStatus = (MM_COMM_BUFFER_STATUS *)(UINTN)mMmCommunicationBuffer->Status; + if (CommunicationStatus->IsCommBufferValid) { // - // Update CommunicationBuffer, BufferSize and ReturnStatus - // Communicate service finished, reset the pointer to CommBuffer to NULL + // Synchronous MMI for MM Core or request from Communicate protocol // - gMmCorePrivate->BufferSize += OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data); - gMmCorePrivate->CommunicationBuffer = 0; - gMmCorePrivate->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND; + CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mMmCommunicationBuffer->PhysicalStart; + BufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength; + if (BufferSize <= EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)) { + // + // Shadow the data from MM Communication Buffer to internal buffer + // + CopyMem ( + mInternalCommBufferCopy, + (VOID *)(UINTN)mMmCommunicationBuffer->PhysicalStart, + BufferSize + ); + ZeroMem ( + (UINT8 *)mInternalCommBufferCopy + BufferSize, + EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages) - BufferSize + ); + + CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mInternalCommBufferCopy; + BufferSize = CommunicateHeader->MessageLength; + Status = MmiManage ( + &CommunicateHeader->HeaderGuid, + NULL, + CommunicateHeader->Data, + &BufferSize + ); + + BufferSize = BufferSize + OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data); + if (BufferSize <= EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)) { + // + // Copy the data back to MM Communication Buffer + // + CopyMem ( + (VOID *)(UINTN)mMmCommunicationBuffer->PhysicalStart, + mInternalCommBufferCopy, + BufferSize + ); + } else { + DEBUG ((DEBUG_ERROR, "Returned buffer size is larger than the size of MM Communication Buffer\n")); + ASSERT (FALSE); + } + + // + // Update CommunicationBuffer, BufferSize and ReturnStatus + // Communicate service finished, reset the pointer to CommBuffer to NULL + // + CommunicationStatus->ReturnBufferSize = BufferSize; + CommunicationStatus->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND; + } else { + DEBUG ((DEBUG_ERROR, "Input buffer size is larger than the size of MM Communication Buffer\n")); + ASSERT (FALSE); + } } + } else { + DEBUG ((DEBUG_ERROR, "No valid communication buffer, no Synchronous MMI will be processed\n")); } // @@ -738,6 +830,8 @@ StandaloneMmMain ( DEBUG ((DEBUG_INFO, "MmiHandlerRegister - GUID %g - Status %d\n", mMmCoreMmiHandlers[Index].HandlerType, Status)); } + MmCorePrepareCommunicationBuffer (); + // // Install Loaded Image Protocol form MM Core // diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.h b/StandaloneMmPkg/Core/StandaloneMmCore.h index c08d1d76c062..1d34bb643e27 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.h +++ b/StandaloneMmPkg/Core/StandaloneMmCore.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf index 8cc9638db558..726a9468833c 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.inf +++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf @@ -76,6 +76,7 @@ gEfiEventLegacyBootGuid gEfiEventExitBootServicesGuid gEfiEventReadyToBootGuid + gMmCommBufferHobGuid [Pcd] gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth ##CONSUMES From 18591343b224316df6f616441d69a954b8350e22 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Tue, 14 May 2024 00:56:58 +0800 Subject: [PATCH 050/280] StandaloneMmPkg/Core: Drop MM_CORE_PRIVATE_DATA MM_CORE_PRIVATE_DATA is not used as shared structures between MM IPL and MM Core, therefore clean up the code related to gMmCorePrivate. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Core/StandaloneMmCore.c | 119 +++++------------- StandaloneMmPkg/Core/StandaloneMmCore.h | 5 +- StandaloneMmPkg/Core/StandaloneMmCore.inf | 1 - .../Core/StandaloneMmCorePrivateData.h | 2 - 4 files changed, 30 insertions(+), 97 deletions(-) diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c index 7e129832fce4..49d3e6d4076e 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.c +++ b/StandaloneMmPkg/Core/StandaloneMmCore.c @@ -19,11 +19,6 @@ MmDispatcher ( // EFI_HANDLE mMmCpuHandle = NULL; -// -// Physical pointer to private structure shared between MM IPL and the MM Core -// -MM_CORE_PRIVATE_DATA *gMmCorePrivate; - // // MM Core global variable for MM System Table. Only accessed as a physical structure in MMRAM. // @@ -86,6 +81,7 @@ MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = { { NULL, NULL, NULL, FALSE }, }; +BOOLEAN mMmEntryPointRegistered = FALSE; UINTN mMmramRangeCount; EFI_MMRAM_DESCRIPTOR *mMmramRanges; MM_COMM_BUFFER *mMmCommunicationBuffer; @@ -487,15 +483,6 @@ MmEntryPoint ( // // PlatformHookBeforeMmDispatch (); - // - // If a legacy boot has occurred, then make sure gMmCorePrivate is not accessed - // - - // - // TBD: Mark the InMm flag as TRUE - // - gMmCorePrivate->InMm = TRUE; - // // Check to see if this is a Synchronous MMI sent through the MM Communication // Protocol or an Asynchronous MMI @@ -570,11 +557,6 @@ MmEntryPoint ( // TBD: Do not use private data structure ? // - // - // Clear the InMm flag as we are going to leave MM - // - gMmCorePrivate->InMm = FALSE; - DEBUG ((DEBUG_INFO, "MmEntryPoint Done\n")); } @@ -605,19 +587,19 @@ MmConfigurationMmNotify ( // // Register the MM Entry Point provided by the MM Core with the MM COnfiguration protocol // - Status = MmConfiguration->RegisterMmEntry (MmConfiguration, (EFI_MM_ENTRY_POINT)(UINTN)gMmCorePrivate->MmEntryPoint); + Status = MmConfiguration->RegisterMmEntry (MmConfiguration, (EFI_MM_ENTRY_POINT)MmEntryPoint); ASSERT_EFI_ERROR (Status); // // Set flag to indicate that the MM Entry Point has been registered which // means that MMIs are now fully operational. // - gMmCorePrivate->MmEntryPointRegistered = TRUE; + mMmEntryPointRegistered = TRUE; // // Print debug message showing MM Core entry point address. // - DEBUG ((DEBUG_INFO, "MM Core registered MM Entry Point address %p\n", (VOID *)(UINTN)gMmCorePrivate->MmEntryPoint)); + DEBUG ((DEBUG_INFO, "MM Core registered MM Entry Point address %p\n", MmEntryPoint)); return EFI_SUCCESS; } @@ -671,8 +653,6 @@ StandaloneMmMain ( VOID *MmHobStart; UINTN HobSize; VOID *Registration; - EFI_HOB_GUID_TYPE *GuidHob; - MM_CORE_DATA_HOB_DATA *DataInHob; EFI_HOB_GUID_TYPE *MmramRangesHob; EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData; EFI_MMRAM_DESCRIPTOR *MmramRanges; @@ -688,58 +668,20 @@ StandaloneMmMain ( ); // - // Determine if the caller has passed a reference to a MM_CORE_PRIVATE_DATA - // structure in the Hoblist. This choice will govern how boot information is - // extracted later. + // Extract the MMRAM ranges from the MMRAM descriptor HOB // - GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart); - if (GuidHob == NULL) { - // - // Allocate and zero memory for a MM_CORE_PRIVATE_DATA table and then - // initialise it - // - gMmCorePrivate = (MM_CORE_PRIVATE_DATA *)AllocateRuntimePages (EFI_SIZE_TO_PAGES (sizeof (MM_CORE_PRIVATE_DATA))); - SetMem ((VOID *)(UINTN)gMmCorePrivate, sizeof (MM_CORE_PRIVATE_DATA), 0); - gMmCorePrivate->Signature = MM_CORE_PRIVATE_DATA_SIGNATURE; - gMmCorePrivate->MmEntryPointRegistered = FALSE; - gMmCorePrivate->InMm = FALSE; - gMmCorePrivate->ReturnStatus = EFI_SUCCESS; - - // - // Extract the MMRAM ranges from the MMRAM descriptor HOB - // - MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart); - if (MmramRangesHob == NULL) { - return EFI_UNSUPPORTED; - } - - MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); - ASSERT (MmramRangesHobData != NULL); - MmramRanges = MmramRangesHobData->Descriptor; - MmramRangeCount = (UINTN)MmramRangesHobData->NumberOfMmReservedRegions; - ASSERT (MmramRanges); - ASSERT (MmramRangeCount); - - // - // Copy the MMRAM ranges into MM_CORE_PRIVATE_DATA table just in case any - // code relies on them being present there - // - gMmCorePrivate->MmramRangeCount = (UINT64)MmramRangeCount; - gMmCorePrivate->MmramRanges = - (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (MmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR)); - ASSERT (gMmCorePrivate->MmramRanges != 0); - CopyMem ( - (VOID *)(UINTN)gMmCorePrivate->MmramRanges, - MmramRanges, - MmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR) - ); - } else { - DataInHob = GET_GUID_HOB_DATA (GuidHob); - gMmCorePrivate = (MM_CORE_PRIVATE_DATA *)(UINTN)DataInHob->Address; - MmramRanges = (EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate->MmramRanges; - MmramRangeCount = (UINTN)gMmCorePrivate->MmramRangeCount; + MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart); + if (MmramRangesHob == NULL) { + return EFI_UNSUPPORTED; } + MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); + ASSERT (MmramRangesHobData != NULL); + MmramRanges = MmramRangesHobData->Descriptor; + MmramRangeCount = (UINTN)MmramRangesHobData->NumberOfMmReservedRegions; + ASSERT (MmramRanges); + ASSERT (MmramRangeCount); + // // Print the MMRAM ranges passed by the caller // @@ -764,19 +706,6 @@ StandaloneMmMain ( ASSERT (mMmramRanges != NULL); CopyMem (mMmramRanges, (VOID *)(UINTN)MmramRanges, mMmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR)); - // - // Get Boot Firmware Volume address from the BFV Hob - // - BfvHob = GetFirstHob (EFI_HOB_TYPE_FV); - if (BfvHob != NULL) { - DEBUG ((DEBUG_INFO, "BFV address - 0x%x\n", BfvHob->BaseAddress)); - DEBUG ((DEBUG_INFO, "BFV size - 0x%x\n", BfvHob->Length)); - gMmCorePrivate->StandaloneBfvAddress = BfvHob->BaseAddress; - } - - gMmCorePrivate->Mmst = (EFI_PHYSICAL_ADDRESS)(UINTN)&gMmCoreMmst; - gMmCorePrivate->MmEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)MmEntryPoint; - // // No need to initialize memory service. // It is done in the constructor of StandaloneMmCoreMemoryAllocationLib(), @@ -810,12 +739,20 @@ StandaloneMmMain ( ASSERT_EFI_ERROR (Status); // - // Dispatch standalone BFV + // Get Boot Firmware Volume address from the BFV Hob // - DEBUG ((DEBUG_INFO, "Mm Dispatch StandaloneBfvAddress - 0x%08x\n", gMmCorePrivate->StandaloneBfvAddress)); - if (gMmCorePrivate->StandaloneBfvAddress != 0) { - MmCoreFfsFindMmDriver ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)gMmCorePrivate->StandaloneBfvAddress, 0); - MmDispatcher (); + BfvHob = GetFirstHob (EFI_HOB_TYPE_FV); + if (BfvHob != NULL) { + DEBUG ((DEBUG_INFO, "BFV address - 0x%x\n", BfvHob->BaseAddress)); + DEBUG ((DEBUG_INFO, "BFV size - 0x%x\n", BfvHob->Length)); + // + // Dispatch standalone BFV + // + if (BfvHob->BaseAddress != 0) { + DEBUG ((DEBUG_INFO, "Mm Dispatch StandaloneBfvAddress - 0x%08x\n", BfvHob->BaseAddress)); + MmCoreFfsFindMmDriver ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)BfvHob->BaseAddress, 0); + MmDispatcher (); + } } // diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.h b/StandaloneMmPkg/Core/StandaloneMmCore.h index 1d34bb643e27..84d1632505dd 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.h +++ b/StandaloneMmPkg/Core/StandaloneMmCore.h @@ -175,9 +175,8 @@ typedef struct { // // MM Core Global Variables // -extern MM_CORE_PRIVATE_DATA *gMmCorePrivate; -extern EFI_MM_SYSTEM_TABLE gMmCoreMmst; -extern LIST_ENTRY gHandleList; +extern EFI_MM_SYSTEM_TABLE gMmCoreMmst; +extern LIST_ENTRY gHandleList; /** Called to initialize the memory service. diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf index 726a9468833c..dd9af16ca432 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.inf +++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf @@ -71,7 +71,6 @@ gZeroGuid ## SOMETIMES_CONSUMES ## GUID gEfiHobListGuid gEfiHobMemoryAllocModuleGuid - gMmCoreDataHobGuid gMmFvDispatchGuid gEfiEventLegacyBootGuid gEfiEventExitBootServicesGuid diff --git a/StandaloneMmPkg/Core/StandaloneMmCorePrivateData.h b/StandaloneMmPkg/Core/StandaloneMmCorePrivateData.h index 58d3bc380352..03b0261ef005 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCorePrivateData.h +++ b/StandaloneMmPkg/Core/StandaloneMmCorePrivateData.h @@ -11,8 +11,6 @@ #ifndef _STANDALONE_MM_CORE_PRIVATE_DATA_H_ #define _STANDALONE_MM_CORE_PRIVATE_DATA_H_ -#include - // // Page management // From 189398dcf8652efcd54de71f1f1395813d903c5e Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Tue, 14 May 2024 01:20:38 +0800 Subject: [PATCH 051/280] StandaloneMmCoreMemoryAllocationLib: Drop MM_CORE_PRIVATE_DATA MM_CORE_PRIVATE_DATA is not used as shared structures between MM IPL and MM Core, therefore clean up the code related to gMmCorePrivate. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- .../StandaloneMmCoreMemoryAllocationLib.c | 44 +++++++------------ ...StandaloneMmCoreMemoryAllocationServices.h | 2 - 2 files changed, 16 insertions(+), 30 deletions(-) diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c index 2246823886b1..afced78cdeb4 100644 --- a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c +++ b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c @@ -845,9 +845,6 @@ MemoryAllocationLibConstructor ( IN EFI_MM_SYSTEM_TABLE *MmSystemTable ) { - MM_CORE_PRIVATE_DATA *MmCorePrivate; - EFI_HOB_GUID_TYPE *GuidHob; - MM_CORE_DATA_HOB_DATA *DataInHob; VOID *HobStart; EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData; EFI_MMRAM_DESCRIPTOR *MmramRanges; @@ -858,35 +855,26 @@ MemoryAllocationLibConstructor ( DEBUG ((DEBUG_INFO, "StandaloneMmCoreMemoryAllocationLibConstructor - 0x%x\n", HobStart)); // - // Extract MM Core Private context from the Hob. If absent search for - // a Hob containing the MMRAM ranges + // Search for a Hob containing the MMRAM ranges // - GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart); - if (GuidHob == NULL) { - MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart); - if (MmramRangesHob == NULL) { - return EFI_UNSUPPORTED; - } + MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart); + if (MmramRangesHob == NULL) { + return EFI_UNSUPPORTED; + } - MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); - if (MmramRangesHobData == NULL) { - return EFI_UNSUPPORTED; - } + MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); + if (MmramRangesHobData == NULL) { + return EFI_UNSUPPORTED; + } - MmramRanges = MmramRangesHobData->Descriptor; - if (MmramRanges == NULL) { - return EFI_UNSUPPORTED; - } + MmramRanges = MmramRangesHobData->Descriptor; + if (MmramRanges == NULL) { + return EFI_UNSUPPORTED; + } - MmramRangeCount = (UINTN)MmramRangesHobData->NumberOfMmReservedRegions; - if (MmramRanges == NULL) { - return EFI_UNSUPPORTED; - } - } else { - DataInHob = GET_GUID_HOB_DATA (GuidHob); - MmCorePrivate = (MM_CORE_PRIVATE_DATA *)(UINTN)DataInHob->Address; - MmramRanges = (EFI_MMRAM_DESCRIPTOR *)(UINTN)MmCorePrivate->MmramRanges; - MmramRangeCount = (UINTN)MmCorePrivate->MmramRangeCount; + MmramRangeCount = (UINTN)MmramRangesHobData->NumberOfMmReservedRegions; + if (MmramRanges == NULL) { + return EFI_UNSUPPORTED; } { diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationServices.h b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationServices.h index 833ab0d177d8..1fd0478707e6 100644 --- a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationServices.h +++ b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationServices.h @@ -14,8 +14,6 @@ #ifndef _PI_MM_CORE_MEMORY_ALLOCATION_SERVICES_H_ #define _PI_MM_CORE_MEMORY_ALLOCATION_SERVICES_H_ -#include - /** Called to initialize the memory service. From 0f89005d71b79cb795adf5806845a9790df44839 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Tue, 14 May 2024 01:22:03 +0800 Subject: [PATCH 052/280] StandaloneMmMemLib: Drop MM_CORE_PRIVATE_DATA MM_CORE_PRIVATE_DATA is not used as shared structures between MM IPL and MM Core, therefore clean up the code related to gMmCorePrivate. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- .../StandaloneMmMemLib/StandaloneMmMemLib.inf | 1 - .../X86StandaloneMmMemLibInternal.c | 43 +++++-------------- 2 files changed, 11 insertions(+), 33 deletions(-) diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf index ed3cdf199452..696b8e06895d 100644 --- a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf +++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf @@ -51,5 +51,4 @@ MemoryAllocationLib [Guids] - gMmCoreDataHobGuid ## SOMETIMES_CONSUMES ## HOB gEfiMmPeiMmramMemoryReserveGuid ## SOMETIMES_CONSUMES ## HOB diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c b/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c index 0b4b1174de18..c8ffe43cd1af 100644 --- a/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c +++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c @@ -20,7 +20,6 @@ #include #include -#include #include // @@ -87,9 +86,6 @@ MmMemLibInternalPopulateMmramRanges ( ) { VOID *HobStart; - EFI_HOB_GUID_TYPE *GuidHob; - MM_CORE_DATA_HOB_DATA *DataInHob; - MM_CORE_PRIVATE_DATA *MmCorePrivateData; EFI_HOB_GUID_TYPE *MmramRangesHob; EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData; EFI_MMRAM_DESCRIPTOR *MmramDescriptors; @@ -98,38 +94,21 @@ MmMemLibInternalPopulateMmramRanges ( DEBUG ((DEBUG_INFO, "%a - 0x%x\n", __func__, HobStart)); // - // Extract MM Core Private context from the Hob. If absent search for - // a Hob containing the MMRAM ranges + // Search for a Hob containing the MMRAM ranges // - GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart); - if (GuidHob == NULL) { - MmramRangesHob = GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid); - if (MmramRangesHob == NULL) { - return EFI_UNSUPPORTED; - } - - MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); - if ((MmramRangesHobData == NULL) || (MmramRangesHobData->Descriptor == NULL)) { - return EFI_UNSUPPORTED; - } - - mMmMemLibInternalMmramCount = MmramRangesHobData->NumberOfMmReservedRegions; - MmramDescriptors = MmramRangesHobData->Descriptor; - } else { - DataInHob = GET_GUID_HOB_DATA (GuidHob); - if (DataInHob == NULL) { - return EFI_UNSUPPORTED; - } - - MmCorePrivateData = (MM_CORE_PRIVATE_DATA *)(UINTN)DataInHob->Address; - if ((MmCorePrivateData == NULL) || (MmCorePrivateData->MmramRanges == 0)) { - return EFI_UNSUPPORTED; - } + MmramRangesHob = GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid); + if (MmramRangesHob == NULL) { + return EFI_UNSUPPORTED; + } - mMmMemLibInternalMmramCount = (UINTN)MmCorePrivateData->MmramRangeCount; - MmramDescriptors = (EFI_MMRAM_DESCRIPTOR *)(UINTN)MmCorePrivateData->MmramRanges; + MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); + if ((MmramRangesHobData == NULL) || (MmramRangesHobData->Descriptor == NULL)) { + return EFI_UNSUPPORTED; } + mMmMemLibInternalMmramCount = MmramRangesHobData->NumberOfMmReservedRegions; + MmramDescriptors = MmramRangesHobData->Descriptor; + mMmMemLibInternalMmramRanges = AllocatePool (mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR)); if (mMmMemLibInternalMmramRanges) { CopyMem ( From f0254c9a1ca68c13f71da5424971b5617c5a1ca6 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Tue, 14 May 2024 02:34:12 +0800 Subject: [PATCH 053/280] StandaloneMmPkg: Remove definition for MM_CORE_PRIVATE_DATA MM_CORE_PRIVATE_DATA is not used as shared structures between MM IPL and MM Core, therefore clean up definition for MM_CORE_PRIVATE_DATA. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Include/Guid/MmCoreData.h | 126 ---------------------- StandaloneMmPkg/StandaloneMmPkg.dec | 3 - 2 files changed, 129 deletions(-) delete mode 100644 StandaloneMmPkg/Include/Guid/MmCoreData.h diff --git a/StandaloneMmPkg/Include/Guid/MmCoreData.h b/StandaloneMmPkg/Include/Guid/MmCoreData.h deleted file mode 100644 index b8be92c6abfd..000000000000 --- a/StandaloneMmPkg/Include/Guid/MmCoreData.h +++ /dev/null @@ -1,126 +0,0 @@ -/** @file - MM Core data. - -Copyright (c) 2015, Intel Corporation. All rights reserved.
-Copyright (c) 2018 - 2021, Arm Limited. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __MM_CORE_DATA_H__ -#define __MM_CORE_DATA_H__ - -#define MM_CORE_DATA_HOB_GUID \ - { 0xa160bf99, 0x2aa4, 0x4d7d, { 0x99, 0x93, 0x89, 0x9c, 0xb1, 0x2d, 0xf3, 0x76 }} - -extern EFI_GUID gMmCoreDataHobGuid; - -typedef struct { - // - // Address pointer to MM_CORE_PRIVATE_DATA - // - EFI_PHYSICAL_ADDRESS Address; -} MM_CORE_DATA_HOB_DATA; - -/// -/// Define values for the communications buffer used when gEfiEventDxeDispatchGuid is -/// event signaled. This event is signaled by the DXE Core each time the DXE Core -/// dispatcher has completed its work. When this event is signaled, the MM Core -/// if notified, so the MM Core can dispatch MM drivers. If COMM_BUFFER_MM_DISPATCH_ERROR -/// is returned in the communication buffer, then an error occurred dispatching MM -/// Drivers. If COMM_BUFFER_MM_DISPATCH_SUCCESS is returned, then the MM Core -/// dispatched all the drivers it could. If COMM_BUFFER_MM_DISPATCH_RESTART is -/// returned, then the MM Core just dispatched the MM Driver that registered -/// the MM Entry Point enabling the use of MM Mode. In this case, the MM Core -/// should be notified again to dispatch more MM Drivers using MM Mode. -/// -#define COMM_BUFFER_MM_DISPATCH_ERROR 0x00 -#define COMM_BUFFER_MM_DISPATCH_SUCCESS 0x01 -#define COMM_BUFFER_MM_DISPATCH_RESTART 0x02 - -/// -/// Signature for the private structure shared between the MM IPL and the MM Core -/// -#define MM_CORE_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('m', 'm', 'i', 'c') - -/// -/// Private structure that is used to share information between the MM IPL and -/// the MM Core. This structure is allocated from memory of type EfiRuntimeServicesData. -/// Since runtime memory types are converted to available memory when a legacy boot -/// is performed, the MM Core must not access any fields of this structure if a legacy -/// boot is performed. As a result, the MM IPL must create an event notification -/// for the Legacy Boot event and notify the MM Core that a legacy boot is being -/// performed. The MM Core can then use this information to filter accesses to -/// thos structure. -/// -typedef struct { - UINT64 Signature; - - /// - /// The number of MMRAM ranges passed from the MM IPL to the MM Core. The MM - /// Core uses these ranges of MMRAM to initialize the MM Core memory manager. - /// - UINT64 MmramRangeCount; - - /// - /// A table of MMRAM ranges passed from the MM IPL to the MM Core. The MM - /// Core uses these ranges of MMRAM to initialize the MM Core memory manager. - /// - EFI_PHYSICAL_ADDRESS MmramRanges; - - /// - /// The MM Foundation Entry Point. The MM Core fills in this field when the - /// MM Core is initialized. The MM IPL is responsbile for registering this entry - /// point with the MM Configuration Protocol. The MM Configuration Protocol may - /// not be available at the time the MM IPL and MM Core are started, so the MM IPL - /// sets up a protocol notification on the MM Configuration Protocol and registers - /// the MM Foundation Entry Point as soon as the MM Configuration Protocol is - /// available. - /// - EFI_PHYSICAL_ADDRESS MmEntryPoint; - - /// - /// Boolean flag set to TRUE while an MMI is being processed by the MM Core. - /// - BOOLEAN MmEntryPointRegistered; - - /// - /// Boolean flag set to TRUE while an MMI is being processed by the MM Core. - /// - BOOLEAN InMm; - - /// - /// This field is set by the MM Core then the MM Core is initialized. This field is - /// used by the MM Base 2 Protocol and MM Communication Protocol implementations in - /// the MM IPL. - /// - EFI_PHYSICAL_ADDRESS Mmst; - - /// - /// This field is used by the MM Communication Protocol to pass a buffer into - /// a software MMI handler and for the software MMI handler to pass a buffer back to - /// the caller of the MM Communication Protocol. - /// - EFI_PHYSICAL_ADDRESS CommunicationBuffer; - - /// - /// This field is used by the MM Communication Protocol to pass the size of a buffer, - /// in bytes, into a software MMI handler and for the software MMI handler to pass the - /// size, in bytes, of a buffer back to the caller of the MM Communication Protocol. - /// - UINT64 BufferSize; - - /// - /// This field is used by the MM Communication Protocol to pass the return status from - /// a software MMI handler back to the caller of the MM Communication Protocol. - /// - UINT64 ReturnStatus; - - EFI_PHYSICAL_ADDRESS MmCoreImageBase; - UINT64 MmCoreImageSize; - EFI_PHYSICAL_ADDRESS MmCoreEntryPoint; - - EFI_PHYSICAL_ADDRESS StandaloneBfvAddress; -} MM_CORE_PRIVATE_DATA; - -#endif diff --git a/StandaloneMmPkg/StandaloneMmPkg.dec b/StandaloneMmPkg/StandaloneMmPkg.dec index 25e660b2476d..8ba0a54706a5 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dec +++ b/StandaloneMmPkg/StandaloneMmPkg.dec @@ -43,9 +43,6 @@ gMpInformationHobGuid = { 0xba33f15d, 0x4000, 0x45c1, { 0x8e, 0x88, 0xf9, 0x16, 0x92, 0xd4, 0x57, 0xe3 }} gMmFvDispatchGuid = { 0xb65694cc, 0x09e3, 0x4c3b, { 0xb5, 0xcd, 0x05, 0xf4, 0x4d, 0x3c, 0xdb, 0xff }} - ## Include/Guid/MmCoreData.h - gMmCoreDataHobGuid = { 0xa160bf99, 0x2aa4, 0x4d7d, { 0x99, 0x93, 0x89, 0x9c, 0xb1, 0x2d, 0xf3, 0x76 }} - ## Include/Guid/MmramMemoryReserve.h gEfiMmPeiMmramMemoryReserveGuid = { 0x0703f912, 0xbf8d, 0x4e2a, { 0xbe, 0x07, 0xab, 0x27, 0x25, 0x25, 0xc5, 0x92 }} From 003a4d4ef4a2238c9cef83be36021861c6d949d2 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Tue, 14 May 2024 01:47:32 +0800 Subject: [PATCH 054/280] StandaloneMmPkg/Core: Remove unused mMmramRanges and mMmramRangeCount mMmramRanges and mMmramRangeCount are the global variables that are used to cache the MMRAM Ranges info, but they are not used in MM Core. Therefore, remove mMmramRanges and mMmramRangeCount. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Core/StandaloneMmCore.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c index 49d3e6d4076e..e5c28be4e0a9 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.c +++ b/StandaloneMmPkg/Core/StandaloneMmCore.c @@ -81,11 +81,9 @@ MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = { { NULL, NULL, NULL, FALSE }, }; -BOOLEAN mMmEntryPointRegistered = FALSE; -UINTN mMmramRangeCount; -EFI_MMRAM_DESCRIPTOR *mMmramRanges; -MM_COMM_BUFFER *mMmCommunicationBuffer; -VOID *mInternalCommBufferCopy; +BOOLEAN mMmEntryPointRegistered = FALSE; +MM_COMM_BUFFER *mMmCommunicationBuffer; +VOID *mInternalCommBufferCopy; /** Place holder function until all the MM System Table Service are available. @@ -696,16 +694,6 @@ StandaloneMmMain ( )); } - // - // Copy the MMRAM ranges into private MMRAM - // - mMmramRangeCount = MmramRangeCount; - DEBUG ((DEBUG_INFO, "mMmramRangeCount - 0x%x\n", mMmramRangeCount)); - mMmramRanges = AllocatePool (mMmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR)); - DEBUG ((DEBUG_INFO, "mMmramRanges - 0x%x\n", mMmramRanges)); - ASSERT (mMmramRanges != NULL); - CopyMem (mMmramRanges, (VOID *)(UINTN)MmramRanges, mMmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR)); - // // No need to initialize memory service. // It is done in the constructor of StandaloneMmCoreMemoryAllocationLib(), From 487fa274c48d5b77a25e13d6af1a9c7a4d3a7951 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Tue, 14 May 2024 02:11:22 +0800 Subject: [PATCH 055/280] StandaloneMmPkg/Core: Restart dispatcher once MmEntryPoint is registered Defer the dispatch of the remaining MM drivers once the CPU driver has been dispatched. In MmDispatcher, return immediately if the MM Entry Point was registered. Then the MM IPL will reinvoke the MM Core Dispatcher. This is required so MM Mode may be enabled as soon as all the dependent MM Drivers for MM Mode have been dispatched. Introduce a FeatureFlag PCD to control if MmDispatcher returns or not when MmEntryPointPoint is registered. Default value is FALSE. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Core/Dispatcher.c | 71 +++++++++++++++++++++++ StandaloneMmPkg/Core/StandaloneMmCore.c | 1 + StandaloneMmPkg/Core/StandaloneMmCore.h | 1 + StandaloneMmPkg/Core/StandaloneMmCore.inf | 3 +- StandaloneMmPkg/StandaloneMmPkg.dec | 7 +++ 5 files changed, 82 insertions(+), 1 deletion(-) diff --git a/StandaloneMmPkg/Core/Dispatcher.c b/StandaloneMmPkg/Core/Dispatcher.c index dd8f79a2d264..462a4abd8a52 100644 --- a/StandaloneMmPkg/Core/Dispatcher.c +++ b/StandaloneMmPkg/Core/Dispatcher.c @@ -384,6 +384,7 @@ MmDispatcher ( LIST_ENTRY *Link; EFI_MM_DRIVER_ENTRY *DriverEntry; BOOLEAN ReadyToRun; + BOOLEAN PreviousMmEntryPointRegistered; DEBUG ((DEBUG_INFO, "MmDispatcher\n")); @@ -447,6 +448,11 @@ MmDispatcher ( DriverEntry->Initialized = TRUE; RemoveEntryList (&DriverEntry->ScheduledLink); + // + // Cache state of MmEntryPointRegistered before calling entry point + // + PreviousMmEntryPointRegistered = mMmEntryPointRegistered; + // // For each MM driver, pass NULL as ImageHandle // @@ -463,6 +469,22 @@ MmDispatcher ( ); } } + + if (!PreviousMmEntryPointRegistered && mMmEntryPointRegistered) { + if (FeaturePcdGet (PcdRestartMmDispatcherOnceMmEntryRegistered)) { + // + // Return immediately if the MM Entry Point was registered by the MM + // Driver that was just dispatched. The MM IPL will reinvoke the MM + // Core Dispatcher. This is required so MM Mode may be enabled as soon + // as all the dependent MM Drivers for MM Mode have been dispatched. + // Once the MM Entry Point has been registered, then MM Mode will be + // used. + // + gRequestDispatch = TRUE; + gDispatcherRunning = FALSE; + return EFI_NOT_READY; + } + } } // @@ -693,6 +715,55 @@ MmAddToDriverList ( return EFI_SUCCESS; } +/** + Event notification that is fired MM IPL to dispatch the previously discovered MM drivers. + + @param[in] DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister(). + @param[in] Context Points to an optional handler context which was specified when the + handler was registered. + @param[in, out] CommBuffer A pointer to a collection of data in memory that will + be conveyed from a non-MM environment into an MM environment. + @param[in, out] CommBufferSize The size of the CommBuffer. + + @return EFI_SUCCESS Dispatcher is executed. + +**/ +EFI_STATUS +EFIAPI +MmDriverDispatchHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "MmDriverDispatchHandler\n")); + + // + // Execute the MM Dispatcher on MM drivers that have been discovered + // previously but not dispatched. + // + Status = MmDispatcher (); + + // + // Check to see if CommBuffer and CommBufferSize are valid + // + if ((CommBuffer != NULL) && (CommBufferSize != NULL)) { + if (*CommBufferSize > sizeof (EFI_STATUS)) { + // + // Set the status of MmDispatcher to CommBuffer + // + *(EFI_STATUS *)CommBuffer = Status; + } + } + + MmiHandlerUnRegister (DispatchHandle); + + return EFI_SUCCESS; +} + /** Traverse the discovered list for any drivers that were discovered but not loaded because the dependency expressions evaluated to false. diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c index e5c28be4e0a9..6bdb30f95471 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.c +++ b/StandaloneMmPkg/Core/StandaloneMmCore.c @@ -74,6 +74,7 @@ EFI_MM_SYSTEM_TABLE gMmCoreMmst = { // Table of MMI Handlers that are registered by the MM Core when it is initialized // MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = { + { MmDriverDispatchHandler, &gEventMmDispatchGuid, NULL, FALSE }, { MmReadyToLockHandler, &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE }, { MmEndOfDxeHandler, &gEfiEndOfDxeEventGroupGuid, NULL, FALSE }, { MmExitBootServiceHandler, &gEfiEventExitBootServicesGuid, NULL, FALSE }, diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.h b/StandaloneMmPkg/Core/StandaloneMmCore.h index 84d1632505dd..681b7ff61d1e 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.h +++ b/StandaloneMmPkg/Core/StandaloneMmCore.h @@ -177,6 +177,7 @@ typedef struct { // extern EFI_MM_SYSTEM_TABLE gMmCoreMmst; extern LIST_ENTRY gHandleList; +extern BOOLEAN mMmEntryPointRegistered; /** Called to initialize the memory service. diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf index dd9af16ca432..0073f5189473 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.inf +++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf @@ -63,7 +63,7 @@ [Guids] gAprioriGuid ## SOMETIMES_CONSUMES ## File - gEfiEventDxeDispatchGuid ## PRODUCES ## GUID # SmiHandlerRegister + gEventMmDispatchGuid ## PRODUCES ## GUID # SmiHandlerRegister gEfiEndOfDxeEventGroupGuid ## PRODUCES ## GUID # SmiHandlerRegister ## SOMETIMES_CONSUMES ## GUID # Locate protocol ## SOMETIMES_PRODUCES ## GUID # SmiHandlerRegister @@ -79,6 +79,7 @@ [Pcd] gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth ##CONSUMES + gStandaloneMmPkgTokenSpaceGuid.PcdRestartMmDispatcherOnceMmEntryRegistered ##CONSUMES # # This configuration fails for CLANGPDB, which does not support PIE in the GCC diff --git a/StandaloneMmPkg/StandaloneMmPkg.dec b/StandaloneMmPkg/StandaloneMmPkg.dec index 8ba0a54706a5..54fe59e99989 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dec +++ b/StandaloneMmPkg/StandaloneMmPkg.dec @@ -56,3 +56,10 @@ # in the MM phase. Minimum value is 1. Sections nested more deeply are rejected. # @Prompt Maximum permitted FwVol section nesting depth (exclusive) in MM. gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth|0x10|UINT32|0x00000001 + +[PcdsFeatureFlag] + ## Indicates if restart MM Dispatcher once MM Entry Point is registered.

+ # TRUE - Restart MM Dispatcher once MM Entry Point is registered.
+ # FALSE - Do not restart MM Dispatcher once MM Entry Point is registered.
+ # @Prompt Restart MM Dispatcher once MM Entry Point is registered. + gStandaloneMmPkgTokenSpaceGuid.PcdRestartMmDispatcherOnceMmEntryRegistered|FALSE|BOOLEAN|0x00000002 From c8df60801fa20e3e1dc85acdf37d73ca5cca8206 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Tue, 14 May 2024 02:54:44 +0800 Subject: [PATCH 056/280] StandaloneMmPkg: Support using gEfiSmmSmramMemoryGuid to get MMRAM range Add the support using gEfiSmmSmramMemoryGuid to get MMRAM ranges. If gEfiSmmSmramMemoryGuid HOB is not found, then try to get MMRAM ranges from gEfiMmPeiMmramMemoryReserveGuid HOB. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Core/StandaloneMmCore.c | 7 +++++-- StandaloneMmPkg/Core/StandaloneMmCore.inf | 1 + .../StandaloneMmCoreMemoryAllocationLib.c | 7 +++++-- .../StandaloneMmCoreMemoryAllocationLib.inf | 1 + .../Library/StandaloneMmMemLib/StandaloneMmMemLib.inf | 1 + .../StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c | 7 +++++-- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c index 6bdb30f95471..c1281ca8d499 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.c +++ b/StandaloneMmPkg/Core/StandaloneMmCore.c @@ -669,9 +669,12 @@ StandaloneMmMain ( // // Extract the MMRAM ranges from the MMRAM descriptor HOB // - MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart); + MmramRangesHob = GetNextGuidHob (&gEfiSmmSmramMemoryGuid, HobStart); if (MmramRangesHob == NULL) { - return EFI_UNSUPPORTED; + MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart); + if (MmramRangesHob == NULL) { + return EFI_UNSUPPORTED; + } } MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf index 0073f5189473..a6fafa569057 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.inf +++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf @@ -76,6 +76,7 @@ gEfiEventExitBootServicesGuid gEfiEventReadyToBootGuid gMmCommBufferHobGuid + gEfiSmmSmramMemoryGuid [Pcd] gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth ##CONSUMES diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c index afced78cdeb4..cd27fc59658c 100644 --- a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c +++ b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c @@ -857,9 +857,12 @@ MemoryAllocationLibConstructor ( // // Search for a Hob containing the MMRAM ranges // - MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart); + MmramRangesHob = GetNextGuidHob (&gEfiSmmSmramMemoryGuid, HobStart); if (MmramRangesHob == NULL) { - return EFI_UNSUPPORTED; + MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart); + if (MmramRangesHob == NULL) { + return EFI_UNSUPPORTED; + } } MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf index bf7530bb74c1..2848c4b0c7f6 100644 --- a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf +++ b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf @@ -42,3 +42,4 @@ [Guids] gEfiMmPeiMmramMemoryReserveGuid + gEfiSmmSmramMemoryGuid diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf index 696b8e06895d..a748af5ea539 100644 --- a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf +++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf @@ -52,3 +52,4 @@ [Guids] gEfiMmPeiMmramMemoryReserveGuid ## SOMETIMES_CONSUMES ## HOB + gEfiSmmSmramMemoryGuid ## SOMETIMES_CONSUMES ## HOB diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c b/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c index c8ffe43cd1af..19e1736ae174 100644 --- a/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c +++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c @@ -96,9 +96,12 @@ MmMemLibInternalPopulateMmramRanges ( // // Search for a Hob containing the MMRAM ranges // - MmramRangesHob = GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid); + MmramRangesHob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid); if (MmramRangesHob == NULL) { - return EFI_UNSUPPORTED; + MmramRangesHob = GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid); + if (MmramRangesHob == NULL) { + return EFI_UNSUPPORTED; + } } MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); From b7931cafea0052b4f3be66dc4f83ae63db4600c5 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Tue, 14 May 2024 10:20:06 +0800 Subject: [PATCH 057/280] StandaloneMmPkg/Core: Install protocol to notify MmEndOfPei event When the EndOfPei event is signaled, installs the MM EndOfPei Protocol so MM Drivers are informed that EndOfPei event is signaled. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Core/StandaloneMmCore.c | 41 +++++++++++++++++++++++ StandaloneMmPkg/Core/StandaloneMmCore.h | 23 +++++++++++++ StandaloneMmPkg/Core/StandaloneMmCore.inf | 1 + 3 files changed, 65 insertions(+) diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c index c1281ca8d499..352a067253ad 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.c +++ b/StandaloneMmPkg/Core/StandaloneMmCore.c @@ -76,6 +76,7 @@ EFI_MM_SYSTEM_TABLE gMmCoreMmst = { MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = { { MmDriverDispatchHandler, &gEventMmDispatchGuid, NULL, FALSE }, { MmReadyToLockHandler, &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE }, + { MmEndOfPeiHandler, &gEfiMmEndOfPeiProtocol, NULL, FALSE }, { MmEndOfDxeHandler, &gEfiEndOfDxeEventGroupGuid, NULL, FALSE }, { MmExitBootServiceHandler, &gEfiEventExitBootServicesGuid, NULL, FALSE }, { MmReadyToBootHandler, &gEfiEventReadyToBootGuid, NULL, FALSE }, @@ -274,6 +275,46 @@ MmReadyToLockHandler ( return Status; } +/** + Software MMI handler that is called when the EndOfPei event is signaled. + This function installs the MM EndOfPei Protocol so MM Drivers are informed that + EndOfPei event is signaled. + + @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister(). + @param Context Points to an optional handler context which was specified when the handler was registered. + @param CommBuffer A pointer to a collection of data in memory that will + be conveyed from a non-MM environment into an MM environment. + @param CommBufferSize The size of the CommBuffer. + + @return Status Code + +**/ +EFI_STATUS +EFIAPI +MmEndOfPeiHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_HANDLE MmHandle; + + DEBUG ((DEBUG_INFO, "MmEndOfPeiHandler\n")); + // + // Install MM EndOfDxe protocol + // + MmHandle = NULL; + Status = MmInstallProtocolInterface ( + &MmHandle, + &gEfiMmEndOfPeiProtocol, + EFI_NATIVE_INTERFACE, + NULL + ); + return Status; +} + /** Software MMI handler that is called when the EndOfDxe event is signaled. This function installs the MM EndOfDxe Protocol so MM Drivers are informed that diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.h b/StandaloneMmPkg/Core/StandaloneMmCore.h index 681b7ff61d1e..632ded9b27a0 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.h +++ b/StandaloneMmPkg/Core/StandaloneMmCore.h @@ -683,6 +683,29 @@ MmReadyToLockHandler ( IN OUT UINTN *CommBufferSize OPTIONAL ); +/** + Software MMI handler that is called when the EndOfPei event is signaled. + This function installs the MM EndOfPei Protocol so MM Drivers are informed that + EndOfPei event is signaled. + + @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister(). + @param Context Points to an optional handler context which was specified when the handler was registered. + @param CommBuffer A pointer to a collection of data in memory that will + be conveyed from a non-MM environment into an MM environment. + @param CommBufferSize The size of the CommBuffer. + + @return Status Code + +**/ +EFI_STATUS +EFIAPI +MmEndOfPeiHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ); + /** This function is the main entry point for an MM handler dispatch or communicate-based callback. diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf index a6fafa569057..58c3bdee0315 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.inf +++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf @@ -60,6 +60,7 @@ gEfiMmEndOfDxeProtocolGuid ## PRODUCES gEfiLoadedImageProtocolGuid ## PRODUCES gEfiMmConfigurationProtocolGuid ## CONSUMES + gEfiMmEndOfPeiProtocol ## PRODUCES [Guids] gAprioriGuid ## SOMETIMES_CONSUMES ## File From 6b69f564a949830fcc08c8bc19a2f27587034d37 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Tue, 14 May 2024 09:46:15 +0800 Subject: [PATCH 058/280] StandaloneMmPkg/Core: Add MemoryAttributes support The MM memory attribute table is ported from SMM Core. The new file StandaloneMmPkg/Core/MemoryAttributesTable.c, the new code in StandaloneMmPkg/Core/Page.c and StandaloneMmPkg/Core/Pool.c are almost identical to MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c, MdeModulePkg/Core/PiSmmCore/Page.c and MdeModulePkg/Core/PiSmmCore/Pool.c, but changing the word 'SMM' to 'MM'. Different from SMM Core, Standalone MM Core produces MM MemoryAttributes table at the end of MmDriverDispatchHandler() when all the drivers are dispatched, rather than at the MmEndOfDxe event. Then the MM CPU driver will consumes the table to set memory attribute in page table. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Core/Dispatcher.c | 2 + StandaloneMmPkg/Core/MemoryAttributesTable.c | 493 ++++++++++++++ StandaloneMmPkg/Core/Page.c | 648 ++++++++++++++++++- StandaloneMmPkg/Core/Pool.c | 25 + StandaloneMmPkg/Core/StandaloneMmCore.h | 88 ++- StandaloneMmPkg/Core/StandaloneMmCore.inf | 3 + StandaloneMmPkg/StandaloneMmPkg.dsc | 2 + 7 files changed, 1237 insertions(+), 24 deletions(-) create mode 100644 StandaloneMmPkg/Core/MemoryAttributesTable.c diff --git a/StandaloneMmPkg/Core/Dispatcher.c b/StandaloneMmPkg/Core/Dispatcher.c index 462a4abd8a52..b9fe3238465e 100644 --- a/StandaloneMmPkg/Core/Dispatcher.c +++ b/StandaloneMmPkg/Core/Dispatcher.c @@ -759,6 +759,8 @@ MmDriverDispatchHandler ( } } + MmCoreInitializeMemoryAttributesTable (); + MmiHandlerUnRegister (DispatchHandle); return EFI_SUCCESS; diff --git a/StandaloneMmPkg/Core/MemoryAttributesTable.c b/StandaloneMmPkg/Core/MemoryAttributesTable.c new file mode 100644 index 000000000000..bf001899aeca --- /dev/null +++ b/StandaloneMmPkg/Core/MemoryAttributesTable.c @@ -0,0 +1,493 @@ +/** @file + PI SMM MemoryAttributes support + +Copyright (c) 2024, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "StandaloneMmCore.h" + +#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ + ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size))) + +#define IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('I','P','P','D') + +typedef struct { + UINT32 Signature; + UINTN ImageRecordCount; + UINTN CodeSegmentCountMax; + LIST_ENTRY ImageRecordList; +} IMAGE_PROPERTIES_PRIVATE_DATA; + +IMAGE_PROPERTIES_PRIVATE_DATA mImagePropertiesPrivateData = { + IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE, + 0, + 0, + INITIALIZE_LIST_HEAD_VARIABLE (mImagePropertiesPrivateData.ImageRecordList) +}; + +#define EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA BIT0 + +UINT64 mMemoryProtectionAttribute = EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA; + +// +// Below functions are for MemoryMap +// + +/** + Merge continuous memory map entries whose have same attributes. + + @param[in, out] MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the current memory map. On output, + it is the size of new memory map after merge. + @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. +**/ +STATIC +VOID +MergeMemoryMap ( + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN OUT UINTN *MemoryMapSize, + IN UINTN DescriptorSize + ) +{ + EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; + UINT64 MemoryBlockLength; + EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; + + MemoryMapEntry = MemoryMap; + NewMemoryMapEntry = MemoryMap; + MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + *MemoryMapSize); + while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { + CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); + NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + + do { + MemoryBlockLength = LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT); + if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) && + (MemoryMapEntry->Type == NextMemoryMapEntry->Type) && + (MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) && + ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart)) + { + MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; + if (NewMemoryMapEntry != MemoryMapEntry) { + NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; + } + + NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); + continue; + } else { + MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); + break; + } + } while (TRUE); + + MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize); + } + + *MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap; + + return; +} + +/** + Enforce memory map attributes. + This function will set EfiRuntimeServicesData/EfiMemoryMappedIO/EfiMemoryMappedIOPortSpace to be EFI_MEMORY_XP. + + @param[in, out] MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param[in] MemoryMapSize Size, in bytes, of the MemoryMap buffer. + @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. +**/ +STATIC +VOID +EnforceMemoryMapAttribute ( + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize + ) +{ + EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; + + MemoryMapEntry = MemoryMap; + MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize); + while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { + if (MemoryMapEntry->Attribute != 0) { + // It is PE image, the attribute is already set. + } else { + switch (MemoryMapEntry->Type) { + case EfiRuntimeServicesCode: + MemoryMapEntry->Attribute = EFI_MEMORY_RO; + break; + case EfiRuntimeServicesData: + default: + MemoryMapEntry->Attribute |= EFI_MEMORY_XP; + break; + } + } + + MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + } + + return; +} + +/** + This function for GetMemoryMap() with memory attributes table. + + It calls original GetMemoryMap() to get the original memory map information. Then + plus the additional memory map entries for PE Code/Data separation. + + @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the buffer allocated by the caller. On output, + it is the size of the buffer returned by the + firmware if the buffer was large enough, or the + size of the buffer needed to contain the map if + the buffer was too small. + @param[in, out] MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param[out] MapKey A pointer to the location in which firmware + returns the key for the current memory map. + @param[out] DescriptorSize A pointer to the location in which firmware + returns the size, in bytes, of an individual + EFI_MEMORY_DESCRIPTOR. + @param[out] DescriptorVersion A pointer to the location in which firmware + returns the version number associated with the + EFI_MEMORY_DESCRIPTOR. + + @retval EFI_SUCCESS The memory map was returned in the MemoryMap + buffer. + @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current + buffer size needed to hold the memory map is + returned in MemoryMapSize. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +STATIC +EFI_STATUS +EFIAPI +MmCoreGetMemoryMapMemoryAttributesTable ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ) +{ + EFI_STATUS Status; + UINTN OldMemoryMapSize; + UINTN AdditionalRecordCount; + + // + // If PE code/data is not aligned, just return. + // + if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) { + return MmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion); + } + + if (MemoryMapSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 3) * mImagePropertiesPrivateData.ImageRecordCount; + + OldMemoryMapSize = *MemoryMapSize; + Status = MmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion); + if (Status == EFI_BUFFER_TOO_SMALL) { + *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount; + } else if (Status == EFI_SUCCESS) { + if (OldMemoryMapSize - *MemoryMapSize < (*DescriptorSize) * AdditionalRecordCount) { + *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount; + // + // Need update status to buffer too small + // + Status = EFI_BUFFER_TOO_SMALL; + } else { + // + // Split PE code/data + // + ASSERT (MemoryMap != NULL); + SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize, &mImagePropertiesPrivateData.ImageRecordList, AdditionalRecordCount); + + // + // Set RuntimeData to XP + // + EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, *DescriptorSize); + + // + // Merge same type to save entry size + // + MergeMemoryMap (MemoryMap, MemoryMapSize, *DescriptorSize); + } + } + + return Status; +} + +// +// Below functions are for ImageRecord +// + +/** + Insert image record. + + @param[in] DriverEntry Driver information +**/ +VOID +MmInsertImageRecord ( + IN EFI_MM_DRIVER_ENTRY *DriverEntry + ) +{ + EFI_STATUS Status; + IMAGE_PROPERTIES_RECORD *ImageRecord; + CHAR8 *PdbPointer; + UINT32 RequiredAlignment; + + DEBUG ((DEBUG_VERBOSE, "MM InsertImageRecord - 0x%x\n", DriverEntry)); + + ImageRecord = AllocatePool (sizeof (*ImageRecord)); + if (ImageRecord == NULL) { + return; + } + + InitializeListHead (&ImageRecord->Link); + InitializeListHead (&ImageRecord->CodeSegmentList); + + PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)DriverEntry->ImageBuffer); + if (PdbPointer != NULL) { + DEBUG ((DEBUG_VERBOSE, "MM Image - %a\n", PdbPointer)); + } + + RequiredAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY; + Status = CreateImagePropertiesRecord ( + (VOID *)(UINTN)DriverEntry->ImageBuffer, + LShiftU64 (DriverEntry->NumberOfPage, EFI_PAGE_SHIFT), + &RequiredAlignment, + ImageRecord + ); + + if (EFI_ERROR (Status)) { + if (Status == EFI_ABORTED) { + mMemoryProtectionAttribute &= + ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA); + } + + goto Finish; + } + + if (ImageRecord->CodeSegmentCount == 0) { + mMemoryProtectionAttribute &= + ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA); + DEBUG ((DEBUG_ERROR, "MM !!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n")); + if (PdbPointer != NULL) { + DEBUG ((DEBUG_ERROR, "MM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); + } + + Status = EFI_ABORTED; + goto Finish; + } + + // + // Check overlap all section in ImageBase/Size + // + if (!IsImageRecordCodeSectionValid (ImageRecord)) { + DEBUG ((DEBUG_ERROR, "MM IsImageRecordCodeSectionValid - FAIL\n")); + Status = EFI_ABORTED; + goto Finish; + } + + InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link); + mImagePropertiesPrivateData.ImageRecordCount++; + + if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) { + mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount; + } + + SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList); + +Finish: + if (EFI_ERROR (Status) && (ImageRecord != NULL)) { + DeleteImagePropertiesRecord (ImageRecord); + } + + return; +} + +/** + Publish MemoryAttributesTable to MM configuration table. +**/ +VOID +PublishMemoryAttributesTable ( + VOID + ) +{ + UINTN MemoryMapSize; + EFI_MEMORY_DESCRIPTOR *MemoryMap; + UINTN MapKey; + UINTN DescriptorSize; + UINT32 DescriptorVersion; + UINTN Index; + EFI_STATUS Status; + UINTN RuntimeEntryCount; + EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; + EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry; + UINTN MemoryAttributesTableSize; + + MemoryMapSize = 0; + MemoryMap = NULL; + Status = MmCoreGetMemoryMapMemoryAttributesTable ( + &MemoryMapSize, + MemoryMap, + &MapKey, + &DescriptorSize, + &DescriptorVersion + ); + ASSERT (Status == EFI_BUFFER_TOO_SMALL); + + do { + DEBUG ((DEBUG_VERBOSE, "MemoryMapSize - 0x%x\n", MemoryMapSize)); + MemoryMap = AllocatePool (MemoryMapSize); + ASSERT (MemoryMap != NULL); + DEBUG ((DEBUG_VERBOSE, "MemoryMap - 0x%x\n", MemoryMap)); + + Status = MmCoreGetMemoryMapMemoryAttributesTable ( + &MemoryMapSize, + MemoryMap, + &MapKey, + &DescriptorSize, + &DescriptorVersion + ); + if (EFI_ERROR (Status)) { + FreePool (MemoryMap); + } + } while (Status == EFI_BUFFER_TOO_SMALL); + + // + // Allocate MemoryAttributesTable + // + RuntimeEntryCount = MemoryMapSize/DescriptorSize; + MemoryAttributesTableSize = sizeof (EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE) + DescriptorSize * RuntimeEntryCount; + MemoryAttributesTable = AllocatePool (sizeof (EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE) + DescriptorSize * RuntimeEntryCount); + ASSERT (MemoryAttributesTable != NULL); + if (MemoryAttributesTable == NULL) { + return; + } + + MemoryAttributesTable->Version = EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE_VERSION; + MemoryAttributesTable->NumberOfEntries = (UINT32)RuntimeEntryCount; + MemoryAttributesTable->DescriptorSize = (UINT32)DescriptorSize; + MemoryAttributesTable->Reserved = 0; + DEBUG ((DEBUG_VERBOSE, "MemoryAttributesTable:\n")); + DEBUG ((DEBUG_VERBOSE, " Version - 0x%08x\n", MemoryAttributesTable->Version)); + DEBUG ((DEBUG_VERBOSE, " NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries)); + DEBUG ((DEBUG_VERBOSE, " DescriptorSize - 0x%08x\n", MemoryAttributesTable->DescriptorSize)); + MemoryAttributesEntry = (EFI_MEMORY_DESCRIPTOR *)(MemoryAttributesTable + 1); + for (Index = 0; Index < MemoryMapSize/DescriptorSize; Index++) { + CopyMem (MemoryAttributesEntry, MemoryMap, DescriptorSize); + DEBUG ((DEBUG_VERBOSE, "Entry (0x%x)\n", MemoryAttributesEntry)); + DEBUG ((DEBUG_VERBOSE, " Type - 0x%x\n", MemoryAttributesEntry->Type)); + DEBUG ((DEBUG_VERBOSE, " PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->PhysicalStart)); + DEBUG ((DEBUG_VERBOSE, " VirtualStart - 0x%016lx\n", MemoryAttributesEntry->VirtualStart)); + DEBUG ((DEBUG_VERBOSE, " NumberOfPages - 0x%016lx\n", MemoryAttributesEntry->NumberOfPages)); + DEBUG ((DEBUG_VERBOSE, " Attribute - 0x%016lx\n", MemoryAttributesEntry->Attribute)); + MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR (MemoryAttributesEntry, DescriptorSize); + + MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, DescriptorSize); + } + + Status = MmInstallConfigurationTable (&gMmCoreMmst, &gEdkiiPiSmmMemoryAttributesTableGuid, MemoryAttributesTable, MemoryAttributesTableSize); + ASSERT_EFI_ERROR (Status); +} + +/** + This function installs all MM image record information. +**/ +VOID +MmInstallImageRecord ( + VOID + ) +{ + EFI_STATUS Status; + UINTN NoHandles; + EFI_HANDLE *HandleBuffer; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + UINTN Index; + EFI_MM_DRIVER_ENTRY DriverEntry; + + Status = MmLocateHandleBuffer ( + ByProtocol, + &gEfiLoadedImageProtocolGuid, + NULL, + &NoHandles, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return; + } + + for (Index = 0; Index < NoHandles; Index++) { + Status = MmHandleProtocol ( + HandleBuffer[Index], + &gEfiLoadedImageProtocolGuid, + (VOID **)&LoadedImage + ); + if (EFI_ERROR (Status)) { + continue; + } + + DEBUG ((DEBUG_VERBOSE, "LoadedImage - 0x%x 0x%x ", LoadedImage->ImageBase, LoadedImage->ImageSize)); + { + VOID *PdbPointer; + PdbPointer = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase); + if (PdbPointer != NULL) { + DEBUG ((DEBUG_VERBOSE, "(%a) ", PdbPointer)); + } + } + DEBUG ((DEBUG_VERBOSE, "\n")); + ZeroMem (&DriverEntry, sizeof (DriverEntry)); + DriverEntry.ImageBuffer = (UINTN)LoadedImage->ImageBase; + DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)LoadedImage->ImageSize); + MmInsertImageRecord (&DriverEntry); + } + + FreePool (HandleBuffer); +} + +/** + Initialize MemoryAttributesTable support. + +**/ +VOID +EFIAPI +MmCoreInitializeMemoryAttributesTable ( + VOID + ) +{ + MmInstallImageRecord (); + + DEBUG ((DEBUG_VERBOSE, "MM MemoryProtectionAttribute - 0x%016lx\n", mMemoryProtectionAttribute)); + if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) { + return; + } + + DEBUG_CODE_BEGIN (); + if ( mImagePropertiesPrivateData.ImageRecordCount > 0) { + DEBUG ((DEBUG_INFO, "MM - Total Runtime Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount)); + DEBUG ((DEBUG_INFO, "MM - Dump Runtime Image Records:\n")); + DumpImageRecords (&mImagePropertiesPrivateData.ImageRecordList); + } + + DEBUG_CODE_END (); + + PublishMemoryAttributesTable (); + + return; +} diff --git a/StandaloneMmPkg/Core/Page.c b/StandaloneMmPkg/Core/Page.c index 8ee85d19dbac..5b94876b822d 100644 --- a/StandaloneMmPkg/Core/Page.c +++ b/StandaloneMmPkg/Core/Page.c @@ -9,15 +9,447 @@ #include "StandaloneMmCore.h" -#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ - ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size))) - #define TRUNCATE_TO_PAGES(a) ((a) >> EFI_PAGE_SHIFT) LIST_ENTRY mMmMemoryMap = INITIALIZE_LIST_HEAD_VARIABLE (mMmMemoryMap); UINTN mMapKey; +// +// For GetMemoryMap() +// + +#define MEMORY_MAP_SIGNATURE SIGNATURE_32('m','m','a','p') +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + BOOLEAN FromStack; + EFI_MEMORY_TYPE Type; + UINT64 Start; + UINT64 End; +} MEMORY_MAP; + +LIST_ENTRY gMemoryMap = INITIALIZE_LIST_HEAD_VARIABLE (gMemoryMap); + +#define MAX_MAP_DEPTH 6 + +/// +/// mMapDepth - depth of new descriptor stack +/// +UINTN mMapDepth = 0; +/// +/// mMapStack - space to use as temp storage to build new map descriptors +/// +MEMORY_MAP mMapStack[MAX_MAP_DEPTH]; +UINTN mFreeMapStack = 0; +/// +/// This list maintain the free memory map list +/// +LIST_ENTRY mFreeMemoryMapEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mFreeMemoryMapEntryList); + +/** + Allocates pages from the memory map. + + @param[in] Type The type of allocation to perform. + @param[in] MemoryType The type of memory to turn the allocated pages + into. + @param[in] NumberOfPages The number of pages to allocate. + @param[out] Memory A pointer to receive the base allocated memory + address. + @param[in] AddRegion If this memory is new added region. + + @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. + @retval EFI_NOT_FOUND Could not allocate pages match the requirement. + @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. + @retval EFI_SUCCESS Pages successfully allocated. + +**/ +EFI_STATUS +MmInternalAllocatePagesEx ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, + OUT EFI_PHYSICAL_ADDRESS *Memory, + IN BOOLEAN AddRegion + ); + +/** + Internal function. Deque a descriptor entry from the mFreeMemoryMapEntryList. + If the list is empty, then allocate a new page to refuel the list. + Please Note this algorithm to allocate the memory map descriptor has a property + that the memory allocated for memory entries always grows, and will never really be freed. + + @return The Memory map descriptor dequeued from the mFreeMemoryMapEntryList + +**/ +MEMORY_MAP * +AllocateMemoryMapEntry ( + VOID + ) +{ + EFI_PHYSICAL_ADDRESS Mem; + EFI_STATUS Status; + MEMORY_MAP *FreeDescriptorEntries; + MEMORY_MAP *Entry; + UINTN Index; + + // DEBUG((DEBUG_INFO, "AllocateMemoryMapEntry\n")); + + if (IsListEmpty (&mFreeMemoryMapEntryList)) { + // DEBUG((DEBUG_INFO, "mFreeMemoryMapEntryList is empty\n")); + // + // The list is empty, to allocate one page to refuel the list + // + Status = MmInternalAllocatePagesEx ( + AllocateAnyPages, + EfiRuntimeServicesData, + EFI_SIZE_TO_PAGES (RUNTIME_PAGE_ALLOCATION_GRANULARITY), + &Mem, + TRUE + ); + ASSERT_EFI_ERROR (Status); + if (!EFI_ERROR (Status)) { + FreeDescriptorEntries = (MEMORY_MAP *)(UINTN)Mem; + // DEBUG((DEBUG_INFO, "New FreeDescriptorEntries - 0x%x\n", FreeDescriptorEntries)); + // + // Enqueue the free memory map entries into the list + // + for (Index = 0; Index < RUNTIME_PAGE_ALLOCATION_GRANULARITY / sizeof (MEMORY_MAP); Index++) { + FreeDescriptorEntries[Index].Signature = MEMORY_MAP_SIGNATURE; + InsertTailList (&mFreeMemoryMapEntryList, &FreeDescriptorEntries[Index].Link); + } + } else { + return NULL; + } + } + + // + // dequeue the first descriptor from the list + // + Entry = CR (mFreeMemoryMapEntryList.ForwardLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); + RemoveEntryList (&Entry->Link); + + return Entry; +} + +/** + Internal function. Moves any memory descriptors that are on the + temporary descriptor stack to heap. + +**/ +VOID +CoreFreeMemoryMapStack ( + VOID + ) +{ + MEMORY_MAP *Entry; + + // + // If already freeing the map stack, then return + // + if (mFreeMapStack != 0) { + ASSERT (FALSE); + return; + } + + // + // Move the temporary memory descriptor stack into pool + // + mFreeMapStack += 1; + + while (mMapDepth != 0) { + // + // Deque an memory map entry from mFreeMemoryMapEntryList + // + Entry = AllocateMemoryMapEntry (); + ASSERT (Entry); + if (Entry == NULL) { + return; + } + + // + // Update to proper entry + // + mMapDepth -= 1; + + if (mMapStack[mMapDepth].Link.ForwardLink != NULL) { + CopyMem (Entry, &mMapStack[mMapDepth], sizeof (MEMORY_MAP)); + Entry->FromStack = FALSE; + + // + // Move this entry to general memory + // + InsertTailList (&mMapStack[mMapDepth].Link, &Entry->Link); + RemoveEntryList (&mMapStack[mMapDepth].Link); + mMapStack[mMapDepth].Link.ForwardLink = NULL; + } + } + + mFreeMapStack -= 1; +} + +/** + Insert new entry from memory map. + + @param[in] Link The old memory map entry to be linked. + @param[in] Start The start address of new memory map entry. + @param[in] End The end address of new memory map entry. + @param[in] Type The type of new memory map entry. + @param[in] Next If new entry is inserted to the next of old entry. + @param[in] AddRegion If this memory is new added region. +**/ +VOID +InsertNewEntry ( + IN LIST_ENTRY *Link, + IN UINT64 Start, + IN UINT64 End, + IN EFI_MEMORY_TYPE Type, + IN BOOLEAN Next, + IN BOOLEAN AddRegion + ) +{ + MEMORY_MAP *Entry; + + Entry = &mMapStack[mMapDepth]; + mMapDepth += 1; + ASSERT (mMapDepth < MAX_MAP_DEPTH); + Entry->FromStack = TRUE; + + Entry->Signature = MEMORY_MAP_SIGNATURE; + Entry->Type = Type; + Entry->Start = Start; + Entry->End = End; + if (Next) { + InsertHeadList (Link, &Entry->Link); + } else { + InsertTailList (Link, &Entry->Link); + } +} + +/** + Remove old entry from memory map. + + @param[in] Entry Memory map entry to be removed. +**/ +VOID +RemoveOldEntry ( + IN MEMORY_MAP *Entry + ) +{ + RemoveEntryList (&Entry->Link); + Entry->Link.ForwardLink = NULL; + + if (!Entry->FromStack) { + InsertTailList (&mFreeMemoryMapEntryList, &Entry->Link); + } +} + +/** + Update MM memory map entry. + + @param[in] Type The type of allocation to perform. + @param[in] Memory The base of memory address. + @param[in] NumberOfPages The number of pages to allocate. + @param[in] AddRegion If this memory is new added region. +**/ +VOID +ConvertMmMemoryMapEntry ( + IN EFI_MEMORY_TYPE Type, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages, + IN BOOLEAN AddRegion + ) +{ + LIST_ENTRY *Link; + MEMORY_MAP *Entry; + MEMORY_MAP *NextEntry; + LIST_ENTRY *NextLink; + MEMORY_MAP *PreviousEntry; + LIST_ENTRY *PreviousLink; + EFI_PHYSICAL_ADDRESS Start; + EFI_PHYSICAL_ADDRESS End; + + Start = Memory; + End = Memory + EFI_PAGES_TO_SIZE (NumberOfPages) - 1; + + // + // Exclude memory region + // + Link = gMemoryMap.ForwardLink; + while (Link != &gMemoryMap) { + Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); + Link = Link->ForwardLink; + + // + // --------------------------------------------------- + // | +----------+ +------+ +------+ +------+ | + // ---|gMemoryMep|---|Entry1|---|Entry2|---|Entry3|--- + // +----------+ ^ +------+ +------+ +------+ + // | + // +------+ + // |EntryX| + // +------+ + // + if (Entry->Start > End) { + if ((Entry->Start == End + 1) && (Entry->Type == Type)) { + Entry->Start = Start; + return; + } + + InsertNewEntry ( + &Entry->Link, + Start, + End, + Type, + FALSE, + AddRegion + ); + return; + } + + if ((Entry->Start <= Start) && (Entry->End >= End)) { + if (Entry->Type != Type) { + if (Entry->Start < Start) { + // + // --------------------------------------------------- + // | +----------+ +------+ +------+ +------+ | + // ---|gMemoryMep|---|Entry1|---|EntryX|---|Entry3|--- + // +----------+ +------+ ^ +------+ +------+ + // | + // +------+ + // |EntryA| + // +------+ + // + InsertNewEntry ( + &Entry->Link, + Entry->Start, + Start - 1, + Entry->Type, + FALSE, + AddRegion + ); + } + + if (Entry->End > End) { + // + // --------------------------------------------------- + // | +----------+ +------+ +------+ +------+ | + // ---|gMemoryMep|---|Entry1|---|EntryX|---|Entry3|--- + // +----------+ +------+ +------+ ^ +------+ + // | + // +------+ + // |EntryZ| + // +------+ + // + InsertNewEntry ( + &Entry->Link, + End + 1, + Entry->End, + Entry->Type, + TRUE, + AddRegion + ); + } + + // + // Update this node + // + Entry->Start = Start; + Entry->End = End; + Entry->Type = Type; + + // + // Check adjacent + // + NextLink = Entry->Link.ForwardLink; + if (NextLink != &gMemoryMap) { + NextEntry = CR (NextLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); + // + // --------------------------------------------------- + // | +----------+ +------+ +-----------------+ | + // ---|gMemoryMep|---|Entry1|---|EntryX Entry3|--- + // +----------+ +------+ +-----------------+ + // + if ((Entry->Type == NextEntry->Type) && (Entry->End + 1 == NextEntry->Start)) { + Entry->End = NextEntry->End; + RemoveOldEntry (NextEntry); + } + } + + PreviousLink = Entry->Link.BackLink; + if (PreviousLink != &gMemoryMap) { + PreviousEntry = CR (PreviousLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); + // + // --------------------------------------------------- + // | +----------+ +-----------------+ +------+ | + // ---|gMemoryMep|---|Entry1 EntryX|---|Entry3|--- + // +----------+ +-----------------+ +------+ + // + if ((PreviousEntry->Type == Entry->Type) && (PreviousEntry->End + 1 == Entry->Start)) { + PreviousEntry->End = Entry->End; + RemoveOldEntry (Entry); + } + } + } + + return; + } + } + + // + // --------------------------------------------------- + // | +----------+ +------+ +------+ +------+ | + // ---|gMemoryMep|---|Entry1|---|Entry2|---|Entry3|--- + // +----------+ +------+ +------+ +------+ ^ + // | + // +------+ + // |EntryX| + // +------+ + // + Link = gMemoryMap.BackLink; + if (Link != &gMemoryMap) { + Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); + if ((Entry->End + 1 == Start) && (Entry->Type == Type)) { + Entry->End = End; + return; + } + } + + InsertNewEntry ( + &gMemoryMap, + Start, + End, + Type, + FALSE, + AddRegion + ); + return; +} + +/** + Return the count of Mm memory map entry. + + @return The count of Mm memory map entry. +**/ +UINTN +GetMmMemoryMapEntryCount ( + VOID + ) +{ + LIST_ENTRY *Link; + UINTN Count; + + Count = 0; + Link = gMemoryMap.ForwardLink; + while (Link != &gMemoryMap) { + Link = Link->ForwardLink; + Count++; + } + + return Count; +} + /** Internal Function. Allocate n pages from given free page node. @@ -136,12 +568,13 @@ InternalAllocAddress ( /** Allocates pages from the memory map. - @param Type The type of allocation to perform. - @param MemoryType The type of memory to turn the allocated pages - into. - @param NumberOfPages The number of pages to allocate. - @param Memory A pointer to receive the base allocated memory - address. + @param[in] Type The type of allocation to perform. + @param[in] MemoryType The type of memory to turn the allocated pages + into. + @param[in] NumberOfPages The number of pages to allocate. + @param[out] Memory A pointer to receive the base allocated memory + address. + @param[in] AddRegion If this memory is new added region. @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. @retval EFI_NOT_FOUND Could not allocate pages match the requirement. @@ -150,12 +583,12 @@ InternalAllocAddress ( **/ EFI_STATUS -EFIAPI -MmInternalAllocatePages ( +MmInternalAllocatePagesEx ( IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN NumberOfPages, - OUT EFI_PHYSICAL_ADDRESS *Memory + OUT EFI_PHYSICAL_ADDRESS *Memory, + IN BOOLEAN AddRegion ) { UINTN RequestedAddress; @@ -203,9 +636,51 @@ MmInternalAllocatePages ( return EFI_INVALID_PARAMETER; } + // + // Update MmMemoryMap here. + // + ConvertMmMemoryMapEntry (MemoryType, *Memory, NumberOfPages, AddRegion); + if (!AddRegion) { + CoreFreeMemoryMapStack (); + } + return EFI_SUCCESS; } +/** + Allocates pages from the memory map. + + @param[in] Type The type of allocation to perform. + @param[in] MemoryType The type of memory to turn the allocated pages + into. + @param[in] NumberOfPages The number of pages to allocate. + @param[out] Memory A pointer to receive the base allocated memory + address. + + @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. + @retval EFI_NOT_FOUND Could not allocate pages match the requirement. + @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. + @retval EFI_SUCCESS Pages successfully allocated. + +**/ +EFI_STATUS +EFIAPI +MmInternalAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, + OUT EFI_PHYSICAL_ADDRESS *Memory + ) +{ + return MmInternalAllocatePagesEx ( + Type, + MemoryType, + NumberOfPages, + Memory, + FALSE + ); +} + /** Allocates pages from the memory map. @@ -269,19 +744,20 @@ InternalMergeNodes ( /** Frees previous allocated pages. - @param Memory Base address of memory being freed. - @param NumberOfPages The number of pages to free. + @param[in] Memory Base address of memory being freed. + @param[in] NumberOfPages The number of pages to free. + @param[in] AddRegion If this memory is new added region. @retval EFI_NOT_FOUND Could not find the entry that covers the range. - @retval EFI_INVALID_PARAMETER Address not aligned. + @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero. @return EFI_SUCCESS Pages successfully freed. **/ EFI_STATUS -EFIAPI -MmInternalFreePages ( +MmInternalFreePagesEx ( IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages + IN UINTN NumberOfPages, + IN BOOLEAN AddRegion ) { LIST_ENTRY *Node; @@ -329,9 +805,38 @@ MmInternalFreePages ( InternalMergeNodes (Pages); } + // + // Update MmMemoryMap here. + // + ConvertMmMemoryMapEntry (EfiConventionalMemory, Memory, NumberOfPages, AddRegion); + if (!AddRegion) { + CoreFreeMemoryMapStack (); + } + return EFI_SUCCESS; } +/** + Frees previous allocated pages. + + @param[in] Memory Base address of memory being freed. + @param[in] NumberOfPages The number of pages to free. + + @retval EFI_NOT_FOUND Could not find the entry that covers the range. + @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero. + @return EFI_SUCCESS Pages successfully freed. + +**/ +EFI_STATUS +EFIAPI +MmInternalFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ) +{ + return MmInternalFreePagesEx (Memory, NumberOfPages, FALSE); +} + /** Frees previous allocated pages. @@ -339,7 +844,7 @@ MmInternalFreePages ( @param NumberOfPages The number of pages to free. @retval EFI_NOT_FOUND Could not find the entry that covers the range. - @retval EFI_INVALID_PARAMETER Address not aligned. + @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero. @return EFI_SUCCESS Pages successfully freed. **/ @@ -376,10 +881,12 @@ MmAddMemoryRegion ( UINTN AlignedMemBase; // - // Do not add memory regions that is already allocated, needs testing, or needs ECC initialization + // Add EfiRuntimeServicesData for memory regions that is already allocated, needs testing, or needs ECC initialization // if ((Attributes & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) { - return; + Type = EfiRuntimeServicesData; + } else { + Type = EfiConventionalMemory; } // @@ -387,5 +894,102 @@ MmAddMemoryRegion ( // AlignedMemBase = (UINTN)(MemBase + EFI_PAGE_MASK) & ~EFI_PAGE_MASK; MemLength -= AlignedMemBase - MemBase; - MmFreePages (AlignedMemBase, TRUNCATE_TO_PAGES ((UINTN)MemLength)); + if (Type == EfiConventionalMemory) { + MmInternalFreePagesEx (AlignedMemBase, TRUNCATE_TO_PAGES ((UINTN)MemLength), TRUE); + } else { + ConvertMmMemoryMapEntry (EfiRuntimeServicesData, AlignedMemBase, TRUNCATE_TO_PAGES ((UINTN)MemLength), TRUE); + } + + CoreFreeMemoryMapStack (); +} + +/** + This function returns a copy of the current memory map. The map is an array of + memory descriptors, each of which describes a contiguous block of memory. + + @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the buffer allocated by the caller. On output, + it is the size of the buffer returned by the + firmware if the buffer was large enough, or the + size of the buffer needed to contain the map if + the buffer was too small. + @param[in, out] MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param[out] MapKey A pointer to the location in which firmware + returns the key for the current memory map. + @param[out] DescriptorSize A pointer to the location in which firmware + returns the size, in bytes, of an individual + EFI_MEMORY_DESCRIPTOR. + @param[out] DescriptorVersion A pointer to the location in which firmware + returns the version number associated with the + EFI_MEMORY_DESCRIPTOR. + + @retval EFI_SUCCESS The memory map was returned in the MemoryMap + buffer. + @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current + buffer size needed to hold the memory map is + returned in MemoryMapSize. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +MmCoreGetMemoryMap ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ) +{ + UINTN Count; + LIST_ENTRY *Link; + MEMORY_MAP *Entry; + UINTN Size; + UINTN BufferSize; + + Size = sizeof (EFI_MEMORY_DESCRIPTOR); + + // + // Make sure Size != sizeof(EFI_MEMORY_DESCRIPTOR). This will + // prevent people from having pointer math bugs in their code. + // now you have to use *DescriptorSize to make things work. + // + Size += sizeof (UINT64) - (Size % sizeof (UINT64)); + + if (DescriptorSize != NULL) { + *DescriptorSize = Size; + } + + if (DescriptorVersion != NULL) { + *DescriptorVersion = EFI_MEMORY_DESCRIPTOR_VERSION; + } + + Count = GetMmMemoryMapEntryCount (); + BufferSize = Size * Count; + if (*MemoryMapSize < BufferSize) { + *MemoryMapSize = BufferSize; + return EFI_BUFFER_TOO_SMALL; + } + + *MemoryMapSize = BufferSize; + if (MemoryMap == NULL) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (MemoryMap, BufferSize); + Link = gMemoryMap.ForwardLink; + while (Link != &gMemoryMap) { + Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); + Link = Link->ForwardLink; + + MemoryMap->Type = Entry->Type; + MemoryMap->PhysicalStart = Entry->Start; + MemoryMap->NumberOfPages = RShiftU64 (Entry->End - Entry->Start + 1, EFI_PAGE_SHIFT); + + MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, Size); + } + + return EFI_SUCCESS; } diff --git a/StandaloneMmPkg/Core/Pool.c b/StandaloneMmPkg/Core/Pool.c index 282caa9869ea..80a879c15b36 100644 --- a/StandaloneMmPkg/Core/Pool.c +++ b/StandaloneMmPkg/Core/Pool.c @@ -40,6 +40,7 @@ MmInitializeMemoryServices ( // // Initialize free MMRAM regions + // Need add Free memory at first, to let mMmMemoryMap record data // for (Index = 0; Index < MmramRangeCount; Index++) { // @@ -49,6 +50,10 @@ MmInitializeMemoryServices ( continue; } + if ((MmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) { + continue; + } + DEBUG (( DEBUG_INFO, "MmAddMemoryRegion %d : 0x%016lx - 0x%016lx\n", @@ -63,6 +68,26 @@ MmInitializeMemoryServices ( MmramRanges[Index].RegionState ); } + + for (Index = 0; Index < MmramRangeCount; Index++) { + // + // BUGBUG: Add legacy MMRAM region is buggy. + // + if (MmramRanges[Index].CpuStart < BASE_1MB) { + continue; + } + + if ((MmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) == 0) { + continue; + } + + MmAddMemoryRegion ( + MmramRanges[Index].CpuStart, + MmramRanges[Index].PhysicalSize, + EfiConventionalMemory, + MmramRanges[Index].RegionState + ); + } } /** diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.h b/StandaloneMmPkg/Core/StandaloneMmCore.h index 632ded9b27a0..093a35fb56be 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.h +++ b/StandaloneMmPkg/Core/StandaloneMmCore.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,8 @@ #include #include #include +#include +#include #include #include @@ -514,6 +517,38 @@ MmLocateHandle ( OUT EFI_HANDLE *Buffer ); +/** + Function returns an array of handles that support the requested protocol + in a buffer allocated from pool. This is a version of MmLocateHandle() + that allocates a buffer for the caller. + + @param SearchType Specifies which handle(s) are to be returned. + @param Protocol Provides the protocol to search by. This + parameter is only valid for SearchType + ByProtocol. + @param SearchKey Supplies the search key depending on the + SearchType. + @param NumberHandles The number of handles returned in Buffer. + @param Buffer A pointer to the buffer to return the requested + array of handles that support Protocol. + + @retval EFI_SUCCESS The result array of handles was returned. + @retval EFI_NOT_FOUND No handles match the search. + @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the + matching results. + @retval EFI_INVALID_PARAMETER One or more parameters are not valid. + +**/ +EFI_STATUS +EFIAPI +MmLocateHandleBuffer ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer + ); + /** Return the first Protocol Interface that matches the Protocol GUID. If Registration is passed in return a Protocol Instance that was just add @@ -895,7 +930,56 @@ MmCoreFfsFindMmDriver ( IN UINT32 Depth ); -extern UINTN mMmramRangeCount; -extern EFI_MMRAM_DESCRIPTOR *mMmramRanges; +#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ + ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size))) + +/** + Initialize MemoryAttributesTable support. +**/ +VOID +EFIAPI +MmCoreInitializeMemoryAttributesTable ( + VOID + ); + +/** + This function returns a copy of the current memory map. The map is an array of + memory descriptors, each of which describes a contiguous block of memory. + + @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the buffer allocated by the caller. On output, + it is the size of the buffer returned by the + firmware if the buffer was large enough, or the + size of the buffer needed to contain the map if + the buffer was too small. + @param[in, out] MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param[out] MapKey A pointer to the location in which firmware + returns the key for the current memory map. + @param[out] DescriptorSize A pointer to the location in which firmware + returns the size, in bytes, of an individual + EFI_MEMORY_DESCRIPTOR. + @param[out] DescriptorVersion A pointer to the location in which firmware + returns the version number associated with the + EFI_MEMORY_DESCRIPTOR. + + @retval EFI_SUCCESS The memory map was returned in the MemoryMap + buffer. + @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current + buffer size needed to hold the memory map is + returned in MemoryMapSize. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +MmCoreGetMemoryMap ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ); #endif diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf index 58c3bdee0315..f5ecda3a0692 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.inf +++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf @@ -33,6 +33,7 @@ Mmi.c InstallConfigurationTable.c FwVol.c + MemoryAttributesTable.c [Packages] MdePkg/MdePkg.dec @@ -53,6 +54,7 @@ ReportStatusCodeLib StandaloneMmCoreEntryPoint HobPrintLib + ImagePropertiesRecordLib [Protocols] gEfiDxeMmReadyToLockProtocolGuid ## UNDEFINED # SmiHandlerRegister @@ -78,6 +80,7 @@ gEfiEventReadyToBootGuid gMmCommBufferHobGuid gEfiSmmSmramMemoryGuid + gEdkiiPiSmmMemoryAttributesTableGuid [Pcd] gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth ##CONSUMES diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc index a2410f37d32f..02ab3d749e40 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -61,6 +61,8 @@ VariableMmDependency|StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf HobPrintLib|MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf MmPlatformHobProducerLib|StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf + ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf From cfaccc89a2bf734fcc20d1d97231bbeb344c0cf7 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Fri, 21 Jun 2024 15:04:57 +0800 Subject: [PATCH 059/280] StandaloneMmPkg/Core: Migrate Memory Allocation Hob into MMRAM If a Memory Allocation Hob with EfiBootServicesData memory type is reported into MM Hob List and it also has a non-zero GUID name, then the HOB is used by MM driver and needs to migrate the memory into MMRAM. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Core/StandaloneMmCore.c | 61 +++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c index 352a067253ad..f38d7d748343 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.c +++ b/StandaloneMmPkg/Core/StandaloneMmCore.c @@ -643,6 +643,66 @@ MmConfigurationMmNotify ( return EFI_SUCCESS; } +/** + Migrate MemoryBaseAddress in memory allocation HOBs with BootServiceData + type and non-zero GUID name from Boot Service memory to MMRAM. + + @param[in] HobStart Pointer to the start of the HOB list. + +**/ +VOID +MigrateMemoryAllocationHobs ( + IN VOID *HobStart + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob; + VOID *MemoryInMmram; + + MemoryAllocationHob = NULL; + Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, HobStart); + while (Hob.Raw != NULL) { + MemoryAllocationHob = (EFI_HOB_MEMORY_ALLOCATION *)Hob.Raw; + if ((MemoryAllocationHob->AllocDescriptor.MemoryType == EfiBootServicesData) && + (MmIsBufferOutsideMmValid ( + MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress, + MemoryAllocationHob->AllocDescriptor.MemoryLength + )) + ) + { + if (!IsZeroGuid (&MemoryAllocationHob->AllocDescriptor.Name)) { + MemoryInMmram = AllocatePages (EFI_SIZE_TO_PAGES (MemoryAllocationHob->AllocDescriptor.MemoryLength)); + if (MemoryInMmram != NULL) { + DEBUG (( + DEBUG_INFO, + "Migrate Memory Allocation Hob (%g) from %08x to %08p\n", + &MemoryAllocationHob->AllocDescriptor.Name, + MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress, + MemoryInMmram + )); + CopyMem ( + MemoryInMmram, + (VOID *)(UINTN)MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress, + MemoryAllocationHob->AllocDescriptor.MemoryLength + ); + MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryInMmram; + MemoryAllocationHob->AllocDescriptor.MemoryType = EfiRuntimeServicesData; + } + } else { + DEBUG (( + DEBUG_ERROR, + "Error - Memory Allocation Hob [%08x, %08x] doesn't have a GUID name specified\n", + MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress, + MemoryAllocationHob->AllocDescriptor.MemoryLength + )); + } + } + + Hob.Raw = GET_NEXT_HOB (Hob); + Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw); + } +} + /** Returns the HOB list size. @param [in] HobStart Pointer to the start of the HOB list. @@ -757,6 +817,7 @@ StandaloneMmMain ( CopyMem (MmHobStart, HobStart, HobSize); Status = MmInstallConfigurationTable (&gMmCoreMmst, &gEfiHobListGuid, MmHobStart, HobSize); ASSERT_EFI_ERROR (Status); + MigrateMemoryAllocationHobs (MmHobStart); gHobList = MmHobStart; // From 2a15750b79377a2e81deb6c5fb32abf9138a8839 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 24 Jun 2024 16:43:50 +0800 Subject: [PATCH 060/280] UefiCpuPkg/PiSmmCpuDxeSmm: Update gSmst to gMmst This patch update the gSmst to gMmst for SMM and MM common usage. No function impact. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c | 14 +++++++------- UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c | 8 ++++---- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 18 +++++++++--------- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 2 +- .../PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 8 ++++---- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 4 ++-- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c index caad70ac8455..4c6f31c16ac4 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c @@ -41,13 +41,13 @@ RestoreSmmConfigurationInS3 ( // if (mRestoreSmmConfigurationInS3) { // - // Need make sure gSmst is correct because below function may use them. + // Need make sure gMmst is correct because below function may use them. // - gSmst->SmmStartupThisAp = gSmmCpuPrivate->SmmCoreEntryContext.SmmStartupThisAp; - gSmst->CurrentlyExecutingCpu = gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu; - gSmst->NumberOfCpus = gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; - gSmst->CpuSaveStateSize = gSmmCpuPrivate->SmmCoreEntryContext.CpuSaveStateSize; - gSmst->CpuSaveState = gSmmCpuPrivate->SmmCoreEntryContext.CpuSaveState; + gMmst->MmStartupThisAp = gSmmCpuPrivate->SmmCoreEntryContext.SmmStartupThisAp; + gMmst->CurrentlyExecutingCpu = gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu; + gMmst->NumberOfCpus = gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; + gMmst->CpuSaveStateSize = gSmmCpuPrivate->SmmCoreEntryContext.CpuSaveStateSize; + gMmst->CpuSaveState = gSmmCpuPrivate->SmmCoreEntryContext.CpuSaveState; // // Configure SMM Code Access Check feature if available. @@ -220,7 +220,7 @@ InitSmmS3ResumeState ( ZeroMem (SmmS3ResumeState, sizeof (SMM_S3_RESUME_STATE)); mSmmS3ResumeState = SmmS3ResumeState; - SmmS3ResumeState->Smst = (EFI_PHYSICAL_ADDRESS)(UINTN)gSmst; + SmmS3ResumeState->Smst = (EFI_PHYSICAL_ADDRESS)(UINTN)gMmst; SmmS3ResumeState->SmmS3ResumeEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)SmmRestoreCpu; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c index c0485b0519db..3d1ea99400d5 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c @@ -1,7 +1,7 @@ /** @file Implementation of SMM CPU Services Protocol. -Copyright (c) 2011 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2011 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -98,7 +98,7 @@ SmmSwitchBsp ( } if ((gSmmCpuPrivate->Operation[ProcessorNumber] != SmmCpuNone) || - (gSmst->CurrentlyExecutingCpu == ProcessorNumber)) + (gMmst->CurrentlyExecutingCpu == ProcessorNumber)) { return EFI_UNSUPPORTED; } @@ -376,7 +376,7 @@ InitializeSmmCpuServices ( { EFI_STATUS Status; - Status = gSmst->SmmInstallProtocolInterface ( + Status = gMmst->MmInstallProtocolInterface ( &Handle, &gEfiSmmCpuServiceProtocolGuid, EFI_NATIVE_INTERFACE, @@ -387,7 +387,7 @@ InitializeSmmCpuServices ( return Status; } - Status = gSmst->SmmInstallProtocolInterface ( + Status = gMmst->MmInstallProtocolInterface ( &Handle, &gEdkiiSmmCpuRendezvousProtocolGuid, EFI_NATIVE_INTERFACE, diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index e7149ff7fd1a..71ff40b9ff77 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -232,7 +232,7 @@ SmmReadSaveState ( // // Retrieve pointer to the specified CPU's SMM Save State buffer // - if ((CpuIndex >= gSmst->NumberOfCpus) || (Buffer == NULL)) { + if ((CpuIndex >= gMmst->NumberOfCpus) || (Buffer == NULL)) { return EFI_INVALID_PARAMETER; } @@ -304,7 +304,7 @@ SmmWriteSaveState ( // // Retrieve pointer to the specified CPU's SMM Save State buffer // - if ((CpuIndex >= gSmst->NumberOfCpus) || (Buffer == NULL)) { + if ((CpuIndex >= gMmst->NumberOfCpus) || (Buffer == NULL)) { return EFI_INVALID_PARAMETER; } @@ -1289,7 +1289,7 @@ PiCpuSmmEntry ( // // Install the SMM CPU Protocol into SMM protocol database // - Status = gSmst->SmmInstallProtocolInterface ( + Status = gMmst->MmInstallProtocolInterface ( &mSmmCpuHandle, &gEfiSmmCpuProtocolGuid, EFI_NATIVE_INTERFACE, @@ -1300,7 +1300,7 @@ PiCpuSmmEntry ( // // Install the SMM Memory Attribute Protocol into SMM protocol database // - Status = gSmst->SmmInstallProtocolInterface ( + Status = gMmst->MmInstallProtocolInterface ( &mSmmCpuHandle, &gEdkiiSmmMemoryAttributeProtocolGuid, EFI_NATIVE_INTERFACE, @@ -1321,7 +1321,7 @@ PiCpuSmmEntry ( // // Install the SMM Mp Protocol into SMM protocol database // - Status = gSmst->SmmInstallProtocolInterface ( + Status = gMmst->MmInstallProtocolInterface ( &mSmmCpuHandle, &gEfiMmMpProtocolGuid, EFI_NATIVE_INTERFACE, @@ -1346,7 +1346,7 @@ PiCpuSmmEntry ( // // register SMM Ready To Lock Protocol notification // - Status = gSmst->SmmRegisterProtocolNotify ( + Status = gMmst->MmRegisterProtocolNotify ( &gEfiSmmReadyToLockProtocolGuid, SmmReadyToLockEventNotify, &Registration @@ -1591,7 +1591,7 @@ ConfigSmmCodeAccessCheck ( // // Enable SMM Code Access Check feature for the APs. // - for (Index = 0; Index < gSmst->NumberOfCpus; Index++) { + for (Index = 0; Index < gMmst->NumberOfCpus; Index++) { if (Index != gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu) { if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == INVALID_APIC_ID) { // @@ -1609,7 +1609,7 @@ ConfigSmmCodeAccessCheck ( // // Call SmmStartupThisAp() to enable SMM Code Access Check on an AP. // - Status = gSmst->SmmStartupThisAp (ConfigSmmCodeAccessCheckOnCurrentProcessor, Index, &Index); + Status = gMmst->MmStartupThisAp (ConfigSmmCodeAccessCheckOnCurrentProcessor, Index, &Index); ASSERT_EFI_ERROR (Status); // @@ -1648,7 +1648,7 @@ AllocateCodePages ( return NULL; } - Status = gSmst->SmmAllocatePages (AllocateAnyPages, EfiRuntimeServicesCode, Pages, &Memory); + Status = gMmst->MmAllocatePages (AllocateAnyPages, EfiRuntimeServicesCode, Pages, &Memory); if (EFI_ERROR (Status)) { return NULL; } diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h index abbdd79f0540..9d4775afda40 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h @@ -37,7 +37,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include +#include #include #include #include diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf index 2412f4caebd5..886a616a0c50 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -80,7 +80,7 @@ MtrrLib IoLib TimerLib - SmmServicesTableLib + MmServicesTableLib MemoryAllocationLib DebugAgentLib HobLib diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c index 6e0c251397dd..a66dd4ac4619 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -774,9 +774,9 @@ SmmGetSystemConfigurationTable ( ASSERT (Table != NULL); *Table = NULL; - for (Index = 0; Index < gSmst->NumberOfTableEntries; Index++) { - if (CompareGuid (TableGuid, &(gSmst->SmmConfigurationTable[Index].VendorGuid))) { - *Table = gSmst->SmmConfigurationTable[Index].VendorTable; + for (Index = 0; Index < gMmst->NumberOfTableEntries; Index++) { + if (CompareGuid (TableGuid, &(gMmst->MmConfigurationTable[Index].VendorGuid))) { + *Table = gMmst->MmConfigurationTable[Index].VendorTable; return EFI_SUCCESS; } } diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index 115d477fd0fe..bdfe05f851de 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -892,7 +892,7 @@ InitSmmProfileInternal ( // // Start SMM profile when SmmReadyToLock protocol is installed. // - Status = gSmst->SmmRegisterProtocolNotify ( + Status = gMmst->MmRegisterProtocolNotify ( &gEfiSmmReadyToLockProtocolGuid, InitSmmProfileCallBack, &Registration @@ -1374,7 +1374,7 @@ SmmProfilePFHandler ( // Indicate it is not software SMI // SmiCommand = 0xFFFFFFFFFFFFFFFFULL; - for (Index = 0; Index < gSmst->NumberOfCpus; Index++) { + for (Index = 0; Index < gMmst->NumberOfCpus; Index++) { Status = SmmReadSaveState (&mSmmCpu, sizeof (IoInfo), EFI_SMM_SAVE_STATE_REGISTER_IO, Index, &IoInfo); if (EFI_ERROR (Status)) { continue; From cd29383f77694ec47b0ac39647849572735657dc Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 24 Jun 2024 17:56:00 +0800 Subject: [PATCH 061/280] UefiCpuPkg/PiSmmCpuDxeSmm: Rename PiSmmCpuDxeSmm.h to PiSmmCpuCommon.h Rename the file PiSmmCpuDxeSmm.h to PiSmmCpuCommon.h to facilitate common usage in both SMM and MM. The renamed file PiSmmCpuCommon.h will be utilized for both modes in subsequent patches. No function impact. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 2 +- .../PiSmmCpuDxeSmm/{PiSmmCpuDxeSmm.h => PiSmmCpuCommon.h} | 0 UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.c | 4 ++-- UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c | 4 ++-- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c | 4 ++-- UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c | 2 +- 18 files changed, 20 insertions(+), 20 deletions(-) rename UefiCpuPkg/PiSmmCpuDxeSmm/{PiSmmCpuDxeSmm.h => PiSmmCpuCommon.h} (100%) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c index 4c6f31c16ac4..cb77c3b5ea39 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c @@ -6,7 +6,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" #include BOOLEAN mRestoreSmmConfigurationInS3 = FALSE; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c index 3d1ea99400d5..8a1c6ff8d791 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c @@ -6,7 +6,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" // // SMM CPU Service Protocol instance diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c index dfc9668dbc29..2fc55ea3c263 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c @@ -8,7 +8,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" /** Create PageTable for SMM use. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c index 0c1cc51adae9..2bcbd33563e1 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c @@ -6,7 +6,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" extern UINT64 gTaskGateDescriptor; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c index b279c8a09c57..b522a50c1e46 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c @@ -6,7 +6,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" #include "SmmProfileInternal.h" /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c index 570e99177f4d..dbcc5279a37f 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -8,7 +8,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" // // Slots for all MTRR( FIXED MTRR + VARIABLE MTRR + MTRR_LIB_IA32_MTRR_DEF_TYPE) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h similarity index 100% rename from UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h rename to UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index 71ff40b9ff77..7f3b2bc4a8fb 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -9,7 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" // // SMM CPU Private Data structure that contains SMM Configuration Protocol diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf index 886a616a0c50..e449880a58ee 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -30,7 +30,7 @@ [Sources] PiSmmCpuDxeSmm.c - PiSmmCpuDxeSmm.h + PiSmmCpuCommon.h MpService.c SyncTimer.c CpuS3.c diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c index a66dd4ac4619..4a1bab68ddce 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c @@ -5,7 +5,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" // // attributes for reserved memory before it is promoted to system memory diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.c index 6cc5f016cace..f839d1a3fd04 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.c @@ -1,13 +1,13 @@ /** @file SMM MP protocol implementation -Copyright (c) 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2019 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" #include "SmmMp.h" /// diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c index 6d5d2b2d632e..723d0dacb694 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c @@ -1,13 +1,13 @@ /** @file SMM MP perf-logging implementation -Copyright (c) 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2023 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" #define SMM_MP_PERF_PROCEDURE_NAME(procedure) # procedure GLOBAL_REMOVE_IF_UNREFERENCED diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index bdfe05f851de..a0ebaf5131df 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -8,7 +8,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" #include "SmmProfileInternal.h" UINT32 mSmmProfileCr3; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c index b9a62aeeb067..12fdf7463ff3 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c @@ -1,7 +1,7 @@ /** @file Provides services to access SMRAM Save State Map -Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.
Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -17,7 +17,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" typedef struct { UINT64 Signature; // Offset 0x00 diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c index 8d29ba7326f6..ad1531322483 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c @@ -6,7 +6,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" UINT64 mTimeoutTicker = 0; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index abaa3349f4a2..a5253e8167a4 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -8,7 +8,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" #define PAGE_TABLE_PAGES 8 #define ACC_MAX_BIT BIT3 diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c index ca706ee32c45..1be2de4162e0 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c @@ -6,7 +6,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" EFI_PHYSICAL_ADDRESS mGdtBuffer; UINTN mGdtBufferSize; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c index a95653ddbf0d..be9cd89b92b8 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c @@ -8,7 +8,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "PiSmmCpuDxeSmm.h" +#include "PiSmmCpuCommon.h" #include "SmmProfileInternal.h" // From cc5df45eb6bb1b514df6abd002c3663388efb814 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 24 Jun 2024 19:26:23 +0800 Subject: [PATCH 062/280] UefiCpuPkg/PiSmmCpuDxeSmm: Move common code into PiSmmCpuCommon.c Move common code into PiSmmCpuCommon.c to facilitate common usage in both SMM and MM. The PiSmmCpuCommon.h will be utilized for both modes in subsequent patches. No function impact. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c | 1633 +++++++++++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 26 + UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 1642 +----------------- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 1 + 4 files changed, 1681 insertions(+), 1621 deletions(-) create mode 100644 UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c new file mode 100644 index 000000000000..5d2b9eefd370 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c @@ -0,0 +1,1633 @@ +/** @file +Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU. + +Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
+Copyright (c) 2017, AMD Incorporated. All rights reserved.
+Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuCommon.h" + +// +// SMM CPU Private Data structure that contains SMM Configuration Protocol +// along its supporting fields. +// +SMM_CPU_PRIVATE_DATA mSmmCpuPrivateData = { + SMM_CPU_PRIVATE_DATA_SIGNATURE, // Signature + NULL, // SmmCpuHandle + NULL, // Pointer to ProcessorInfo array + NULL, // Pointer to Operation array + NULL, // Pointer to CpuSaveStateSize array + NULL, // Pointer to CpuSaveState array + { + { 0 } + }, // SmmReservedSmramRegion + { + SmmStartupThisAp, // SmmCoreEntryContext.SmmStartupThisAp + 0, // SmmCoreEntryContext.CurrentlyExecutingCpu + 0, // SmmCoreEntryContext.NumberOfCpus + NULL, // SmmCoreEntryContext.CpuSaveStateSize + NULL // SmmCoreEntryContext.CpuSaveState + }, + NULL, // SmmCoreEntry + { + mSmmCpuPrivateData.SmmReservedSmramRegion, // SmmConfiguration.SmramReservedRegions + RegisterSmmEntry // SmmConfiguration.RegisterSmmEntry + }, + NULL, // pointer to Ap Wrapper Func array + { NULL, NULL }, // List_Entry for Tokens. +}; + +CPU_HOT_PLUG_DATA mCpuHotPlugData = { + CPU_HOT_PLUG_DATA_REVISION_1, // Revision + 0, // Array Length of SmBase and APIC ID + NULL, // Pointer to APIC ID array + NULL, // Pointer to SMBASE array + 0, // Reserved + 0, // SmrrBase + 0 // SmrrSize +}; + +// +// Global pointer used to access mSmmCpuPrivateData from outside and inside SMM +// +SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate = &mSmmCpuPrivateData; + +/// +/// Handle for the SMM CPU Protocol +/// +EFI_HANDLE mSmmCpuHandle = NULL; + +/// +/// SMM CPU Protocol instance +/// +EFI_SMM_CPU_PROTOCOL mSmmCpu = { + SmmReadSaveState, + SmmWriteSaveState +}; + +/// +/// SMM Memory Attribute Protocol instance +/// +EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL mSmmMemoryAttribute = { + EdkiiSmmGetMemoryAttributes, + EdkiiSmmSetMemoryAttributes, + EdkiiSmmClearMemoryAttributes +}; + +EFI_CPU_INTERRUPT_HANDLER mExternalVectorTable[EXCEPTION_VECTOR_NUMBER]; + +volatile BOOLEAN *mSmmInitialized = NULL; +UINT32 mBspApicId = 0; + +// +// SMM stack information +// +UINTN mSmmStackArrayBase; +UINTN mSmmStackArrayEnd; +UINTN mSmmStackSize; + +UINTN mSmmShadowStackSize; +BOOLEAN mCetSupported = TRUE; + +UINTN mMaxNumberOfCpus = 0; +UINTN mNumberOfCpus = 0; + +// +// SMM ready to lock flag +// +BOOLEAN mSmmReadyToLock = FALSE; + +// +// Global used to cache PCD for SMM Code Access Check enable +// +BOOLEAN mSmmCodeAccessCheckEnable = FALSE; + +// +// Global used to cache SMM Debug Agent Supported ot not +// +BOOLEAN mSmmDebugAgentSupport = FALSE; + +// +// Global copy of the PcdPteMemoryEncryptionAddressOrMask +// +UINT64 mAddressEncMask = 0; + +// +// Spin lock used to serialize setting of SMM Code Access Check feature +// +SPIN_LOCK *mConfigSmmCodeAccessCheckLock = NULL; + +// +// Saved SMM ranges information +// +EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges; +UINTN mSmmCpuSmramRangeCount; + +UINT8 mPhysicalAddressBits; + +/** + Initialize IDT to setup exception handlers for SMM. + +**/ +VOID +InitializeSmmIdt ( + VOID + ) +{ + EFI_STATUS Status; + BOOLEAN InterruptState; + IA32_DESCRIPTOR DxeIdtr; + + // + // There are 32 (not 255) entries in it since only processor + // generated exceptions will be handled. + // + gcSmiIdtr.Limit = (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 32) - 1; + // + // Allocate page aligned IDT, because it might be set as read only. + // + gcSmiIdtr.Base = (UINTN)AllocateCodePages (EFI_SIZE_TO_PAGES (gcSmiIdtr.Limit + 1)); + ASSERT (gcSmiIdtr.Base != 0); + ZeroMem ((VOID *)gcSmiIdtr.Base, gcSmiIdtr.Limit + 1); + + // + // Disable Interrupt and save DXE IDT table + // + InterruptState = SaveAndDisableInterrupts (); + AsmReadIdtr (&DxeIdtr); + // + // Load SMM temporary IDT table + // + AsmWriteIdtr (&gcSmiIdtr); + // + // Setup SMM default exception handlers, SMM IDT table + // will be updated and saved in gcSmiIdtr + // + Status = InitializeCpuExceptionHandlers (NULL); + ASSERT_EFI_ERROR (Status); + // + // Restore DXE IDT table and CPU interrupt + // + AsmWriteIdtr ((IA32_DESCRIPTOR *)&DxeIdtr); + SetInterruptState (InterruptState); +} + +/** + Search module name by input IP address and output it. + + @param CallerIpAddress Caller instruction pointer. + +**/ +VOID +DumpModuleInfoByIp ( + IN UINTN CallerIpAddress + ) +{ + UINTN Pe32Data; + VOID *PdbPointer; + + // + // Find Image Base + // + Pe32Data = PeCoffSearchImageBase (CallerIpAddress); + if (Pe32Data != 0) { + DEBUG ((DEBUG_ERROR, "It is invoked from the instruction before IP(0x%p)", (VOID *)CallerIpAddress)); + PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)Pe32Data); + if (PdbPointer != NULL) { + DEBUG ((DEBUG_ERROR, " in module (%a)\n", PdbPointer)); + } + } +} + +/** + Read information from the CPU save state. + + @param This EFI_SMM_CPU_PROTOCOL instance + @param Width The number of bytes to read from the CPU save state. + @param Register Specifies the CPU register to read form the save state. + @param CpuIndex Specifies the zero-based index of the CPU save state. + @param Buffer Upon return, this holds the CPU register value read from the save state. + + @retval EFI_SUCCESS The register was read from Save State + @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor + @retval EFI_INVALID_PARAMETER This or Buffer is NULL. + +**/ +EFI_STATUS +EFIAPI +SmmReadSaveState ( + IN CONST EFI_SMM_CPU_PROTOCOL *This, + IN UINTN Width, + IN EFI_SMM_SAVE_STATE_REGISTER Register, + IN UINTN CpuIndex, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + + // + // Retrieve pointer to the specified CPU's SMM Save State buffer + // + if ((CpuIndex >= gMmst->NumberOfCpus) || (Buffer == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // The SpeculationBarrier() call here is to ensure the above check for the + // CpuIndex has been completed before the execution of subsequent codes. + // + SpeculationBarrier (); + + // + // Check for special EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID + // + if (Register == EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID) { + // + // The pseudo-register only supports the 64-bit size specified by Width. + // + if (Width != sizeof (UINT64)) { + return EFI_INVALID_PARAMETER; + } + + // + // If the processor is in SMM at the time the SMI occurred, + // the pseudo register value for EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID is returned in Buffer. + // Otherwise, EFI_NOT_FOUND is returned. + // + if (*(mSmmMpSyncData->CpuData[CpuIndex].Present)) { + *(UINT64 *)Buffer = gSmmCpuPrivate->ProcessorInfo[CpuIndex].ProcessorId; + return EFI_SUCCESS; + } else { + return EFI_NOT_FOUND; + } + } + + if (!(*(mSmmMpSyncData->CpuData[CpuIndex].Present))) { + return EFI_INVALID_PARAMETER; + } + + Status = MmSaveStateReadRegister (CpuIndex, Register, Width, Buffer); + + return Status; +} + +/** + Write data to the CPU save state. + + @param This EFI_SMM_CPU_PROTOCOL instance + @param Width The number of bytes to read from the CPU save state. + @param Register Specifies the CPU register to write to the save state. + @param CpuIndex Specifies the zero-based index of the CPU save state + @param Buffer Upon entry, this holds the new CPU register value. + + @retval EFI_SUCCESS The register was written from Save State + @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor + @retval EFI_INVALID_PARAMETER ProcessorIndex or Width is not correct + +**/ +EFI_STATUS +EFIAPI +SmmWriteSaveState ( + IN CONST EFI_SMM_CPU_PROTOCOL *This, + IN UINTN Width, + IN EFI_SMM_SAVE_STATE_REGISTER Register, + IN UINTN CpuIndex, + IN CONST VOID *Buffer + ) +{ + EFI_STATUS Status; + + // + // Retrieve pointer to the specified CPU's SMM Save State buffer + // + if ((CpuIndex >= gMmst->NumberOfCpus) || (Buffer == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Writes to EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID are ignored + // + if (Register == EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID) { + return EFI_SUCCESS; + } + + if (!mSmmMpSyncData->CpuData[CpuIndex].Present) { + return EFI_INVALID_PARAMETER; + } + + Status = MmSaveStateWriteRegister (CpuIndex, Register, Width, Buffer); + + return Status; +} + +/** + Initialize SMM environment. + +**/ +VOID +InitializeSmm ( + VOID + ) +{ + UINT32 ApicId; + UINTN Index; + BOOLEAN IsBsp; + + ApicId = GetApicId (); + + IsBsp = (BOOLEAN)(mBspApicId == ApicId); + + ASSERT (mNumberOfCpus <= mMaxNumberOfCpus); + + for (Index = 0; Index < mNumberOfCpus; Index++) { + if (ApicId == (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId) { + PERF_CODE ( + MpPerfBegin (Index, SMM_MP_PERF_PROCEDURE_ID (InitializeSmm)); + ); + // + // Initialize SMM specific features on the currently executing CPU + // + SmmCpuFeaturesInitializeProcessor ( + Index, + IsBsp, + gSmmCpuPrivate->ProcessorInfo, + &mCpuHotPlugData + ); + + if (!mSmmS3Flag) { + // + // Check XD and BTS features on each processor on normal boot + // + CheckFeatureSupported (); + } else if (IsBsp) { + // + // BSP rebase is already done above. + // Initialize private data during S3 resume + // + InitializeMpSyncData (); + } + + PERF_CODE ( + MpPerfEnd (Index, SMM_MP_PERF_PROCEDURE_ID (InitializeSmm)); + ); + + return; + } + } + + ASSERT (FALSE); +} + +/** + Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init. + +**/ +VOID +ExecuteFirstSmiInit ( + VOID + ) +{ + UINTN Index; + + PERF_FUNCTION_BEGIN (); + + if (mSmmInitialized == NULL) { + mSmmInitialized = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) * mMaxNumberOfCpus); + } + + ASSERT (mSmmInitialized != NULL); + if (mSmmInitialized == NULL) { + PERF_FUNCTION_END (); + return; + } + + // + // Reset the mSmmInitialized to false. + // + ZeroMem ((VOID *)mSmmInitialized, sizeof (BOOLEAN) * mMaxNumberOfCpus); + + // + // Get the BSP ApicId. + // + mBspApicId = GetApicId (); + + // + // Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) for SMM init + // + SendSmiIpi (mBspApicId); + SendSmiIpiAllExcludingSelf (); + + // + // Wait for all processors to finish its 1st SMI + // + for (Index = 0; Index < mNumberOfCpus; Index++) { + while (!(BOOLEAN)mSmmInitialized[Index]) { + } + } + + PERF_FUNCTION_END (); +} + +/** + SMM Ready To Lock event notification handler. + + mSmmReadyToLock is set to perform additional lock actions that must be + performed from SMM on the next SMI. + + @param[in] Protocol Points to the protocol's unique identifier. + @param[in] Interface Points to the interface instance. + @param[in] Handle The handle on which the interface was installed. + + @retval EFI_SUCCESS Notification handler runs successfully. + **/ +EFI_STATUS +EFIAPI +SmmReadyToLockEventNotify ( + IN CONST EFI_GUID *Protocol, + IN VOID *Interface, + IN EFI_HANDLE Handle + ) +{ + // + // Cache a copy of UEFI memory map before we start profiling feature. + // + GetUefiMemoryMap (); + + // + // Set SMM ready to lock flag and return + // + mSmmReadyToLock = TRUE; + return EFI_SUCCESS; +} + +/** + Function to compare 2 SMM_BASE_HOB_DATA pointer based on ProcessorIndex. + + @param[in] Buffer1 pointer to SMM_BASE_HOB_DATA poiner to compare + @param[in] Buffer2 pointer to second SMM_BASE_HOB_DATA pointer to compare + + @retval 0 Buffer1 equal to Buffer2 + @retval <0 Buffer1 is less than Buffer2 + @retval >0 Buffer1 is greater than Buffer2 +**/ +INTN +EFIAPI +SmBaseHobCompare ( + IN CONST VOID *Buffer1, + IN CONST VOID *Buffer2 + ) +{ + if ((*(SMM_BASE_HOB_DATA **)Buffer1)->ProcessorIndex > (*(SMM_BASE_HOB_DATA **)Buffer2)->ProcessorIndex) { + return 1; + } else if ((*(SMM_BASE_HOB_DATA **)Buffer1)->ProcessorIndex < (*(SMM_BASE_HOB_DATA **)Buffer2)->ProcessorIndex) { + return -1; + } + + return 0; +} + +/** + Extract SmBase for all CPU from SmmBase HOB. + + @param[in] MaxNumberOfCpus Max NumberOfCpus. + + @param[out] AllocatedSmBaseBuffer Pointer to SmBase Buffer allocated + by this function. Only set if the + function returns EFI_SUCCESS. + + @retval EFI_SUCCESS SmBase Buffer output successfully. + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. + @retval EFI_NOT_FOUND gSmmBaseHobGuid was never created. +**/ +STATIC +EFI_STATUS +GetSmBase ( + IN UINTN MaxNumberOfCpus, + OUT UINTN **AllocatedSmBaseBuffer + ) +{ + UINTN HobCount; + EFI_HOB_GUID_TYPE *GuidHob; + SMM_BASE_HOB_DATA *SmmBaseHobData; + UINTN NumberOfProcessors; + SMM_BASE_HOB_DATA **SmBaseHobs; + UINTN *SmBaseBuffer; + UINTN HobIndex; + UINTN SortBuffer; + UINTN ProcessorIndex; + UINT64 PrevProcessorIndex; + EFI_HOB_GUID_TYPE *FirstSmmBaseGuidHob; + + SmmBaseHobData = NULL; + HobIndex = 0; + ProcessorIndex = 0; + HobCount = 0; + NumberOfProcessors = 0; + + FirstSmmBaseGuidHob = GetFirstGuidHob (&gSmmBaseHobGuid); + if (FirstSmmBaseGuidHob == NULL) { + return EFI_NOT_FOUND; + } + + GuidHob = FirstSmmBaseGuidHob; + while (GuidHob != NULL) { + HobCount++; + SmmBaseHobData = GET_GUID_HOB_DATA (GuidHob); + NumberOfProcessors += SmmBaseHobData->NumberOfProcessors; + + if (NumberOfProcessors >= MaxNumberOfCpus) { + break; + } + + GuidHob = GetNextGuidHob (&gSmmBaseHobGuid, GET_NEXT_HOB (GuidHob)); + } + + ASSERT (NumberOfProcessors == MaxNumberOfCpus); + if (NumberOfProcessors != MaxNumberOfCpus) { + CpuDeadLoop (); + } + + SmBaseHobs = AllocatePool (sizeof (SMM_BASE_HOB_DATA *) * HobCount); + if (SmBaseHobs == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Record each SmmBaseHob pointer in the SmBaseHobs. + // The FirstSmmBaseGuidHob is to speed up this while-loop + // without needing to look for SmBaseHob from beginning. + // + GuidHob = FirstSmmBaseGuidHob; + while (HobIndex < HobCount) { + SmBaseHobs[HobIndex++] = GET_GUID_HOB_DATA (GuidHob); + GuidHob = GetNextGuidHob (&gSmmBaseHobGuid, GET_NEXT_HOB (GuidHob)); + } + + SmBaseBuffer = (UINTN *)AllocatePool (sizeof (UINTN) * (MaxNumberOfCpus)); + ASSERT (SmBaseBuffer != NULL); + if (SmBaseBuffer == NULL) { + FreePool (SmBaseHobs); + return EFI_OUT_OF_RESOURCES; + } + + QuickSort (SmBaseHobs, HobCount, sizeof (SMM_BASE_HOB_DATA *), (BASE_SORT_COMPARE)SmBaseHobCompare, &SortBuffer); + PrevProcessorIndex = 0; + for (HobIndex = 0; HobIndex < HobCount; HobIndex++) { + // + // Make sure no overlap and no gap in the CPU range covered by each HOB + // + ASSERT (SmBaseHobs[HobIndex]->ProcessorIndex == PrevProcessorIndex); + + // + // Cache each SmBase in order. + // + for (ProcessorIndex = 0; ProcessorIndex < SmBaseHobs[HobIndex]->NumberOfProcessors; ProcessorIndex++) { + SmBaseBuffer[PrevProcessorIndex + ProcessorIndex] = (UINTN)SmBaseHobs[HobIndex]->SmBase[ProcessorIndex]; + } + + PrevProcessorIndex += SmBaseHobs[HobIndex]->NumberOfProcessors; + } + + FreePool (SmBaseHobs); + *AllocatedSmBaseBuffer = SmBaseBuffer; + return EFI_SUCCESS; +} + +/** + Function to compare 2 MP_INFORMATION2_HOB_DATA pointer based on ProcessorIndex. + + @param[in] Buffer1 pointer to MP_INFORMATION2_HOB_DATA poiner to compare + @param[in] Buffer2 pointer to second MP_INFORMATION2_HOB_DATA pointer to compare + + @retval 0 Buffer1 equal to Buffer2 + @retval <0 Buffer1 is less than Buffer2 + @retval >0 Buffer1 is greater than Buffer2 +**/ +INTN +EFIAPI +MpInformation2HobCompare ( + IN CONST VOID *Buffer1, + IN CONST VOID *Buffer2 + ) +{ + if ((*(MP_INFORMATION2_HOB_DATA **)Buffer1)->ProcessorIndex > (*(MP_INFORMATION2_HOB_DATA **)Buffer2)->ProcessorIndex) { + return 1; + } else if ((*(MP_INFORMATION2_HOB_DATA **)Buffer1)->ProcessorIndex < (*(MP_INFORMATION2_HOB_DATA **)Buffer2)->ProcessorIndex) { + return -1; + } + + return 0; +} + +/** + Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from MpInformation2 HOB. + + @param[out] NumberOfCpus Pointer to NumberOfCpus. + @param[out] MaxNumberOfCpus Pointer to MaxNumberOfCpus. + + @retval ProcessorInfo Pointer to EFI_PROCESSOR_INFORMATION buffer. +**/ +EFI_PROCESSOR_INFORMATION * +GetMpInformation ( + OUT UINTN *NumberOfCpus, + OUT UINTN *MaxNumberOfCpus + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + EFI_HOB_GUID_TYPE *FirstMpInfo2Hob; + MP_INFORMATION2_HOB_DATA *MpInformation2HobData; + UINTN HobCount; + UINTN HobIndex; + MP_INFORMATION2_HOB_DATA **MpInfo2Hobs; + UINTN SortBuffer; + UINTN ProcessorIndex; + UINT64 PrevProcessorIndex; + MP_INFORMATION2_ENTRY *MpInformation2Entry; + EFI_PROCESSOR_INFORMATION *ProcessorInfo; + + GuidHob = NULL; + MpInformation2HobData = NULL; + FirstMpInfo2Hob = NULL; + MpInfo2Hobs = NULL; + HobIndex = 0; + HobCount = 0; + + FirstMpInfo2Hob = GetFirstGuidHob (&gMpInformation2HobGuid); + if (FirstMpInfo2Hob == NULL) { + DEBUG ((DEBUG_INFO, "%a: [INFO] gMpInformation2HobGuid HOB not found.\n", __func__)); + return GetMpInformationFromMpServices (NumberOfCpus, MaxNumberOfCpus); + } + + GuidHob = FirstMpInfo2Hob; + while (GuidHob != NULL) { + MpInformation2HobData = GET_GUID_HOB_DATA (GuidHob); + + // + // This is the last MpInformationHob in the HOB list. + // + if (MpInformation2HobData->NumberOfProcessors == 0) { + ASSERT (HobCount != 0); + break; + } + + HobCount++; + *NumberOfCpus += MpInformation2HobData->NumberOfProcessors; + GuidHob = GetNextGuidHob (&gMpInformation2HobGuid, GET_NEXT_HOB (GuidHob)); + } + + ASSERT (*NumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + + // + // If support CPU hot plug, we need to allocate resources for possibly hot-added processors + // + if (FeaturePcdGet (PcdCpuHotPlugSupport)) { + *MaxNumberOfCpus = PcdGet32 (PcdCpuMaxLogicalProcessorNumber); + } else { + *MaxNumberOfCpus = *NumberOfCpus; + } + + MpInfo2Hobs = AllocatePool (sizeof (MP_INFORMATION2_HOB_DATA *) * HobCount); + ASSERT (MpInfo2Hobs != NULL); + if (MpInfo2Hobs == NULL) { + return NULL; + } + + // + // Record each MpInformation2Hob pointer in the MpInfo2Hobs. + // The FirstMpInfo2Hob is to speed up this while-loop without + // needing to look for MpInfo2Hob from beginning. + // + GuidHob = FirstMpInfo2Hob; + while (HobIndex < HobCount) { + MpInfo2Hobs[HobIndex++] = GET_GUID_HOB_DATA (GuidHob); + GuidHob = GetNextGuidHob (&gMpInformation2HobGuid, GET_NEXT_HOB (GuidHob)); + } + + ProcessorInfo = (EFI_PROCESSOR_INFORMATION *)AllocatePool (sizeof (EFI_PROCESSOR_INFORMATION) * (*MaxNumberOfCpus)); + ASSERT (ProcessorInfo != NULL); + if (ProcessorInfo == NULL) { + FreePool (MpInfo2Hobs); + return NULL; + } + + QuickSort (MpInfo2Hobs, HobCount, sizeof (MP_INFORMATION2_HOB_DATA *), (BASE_SORT_COMPARE)MpInformation2HobCompare, &SortBuffer); + PrevProcessorIndex = 0; + for (HobIndex = 0; HobIndex < HobCount; HobIndex++) { + // + // Make sure no overlap and no gap in the CPU range covered by each HOB + // + ASSERT (MpInfo2Hobs[HobIndex]->ProcessorIndex == PrevProcessorIndex); + + // + // Cache each EFI_PROCESSOR_INFORMATION in order. + // + for (ProcessorIndex = 0; ProcessorIndex < MpInfo2Hobs[HobIndex]->NumberOfProcessors; ProcessorIndex++) { + MpInformation2Entry = GET_MP_INFORMATION_ENTRY (MpInfo2Hobs[HobIndex], ProcessorIndex); + CopyMem ( + &ProcessorInfo[PrevProcessorIndex + ProcessorIndex], + &MpInformation2Entry->ProcessorInfo, + sizeof (EFI_PROCESSOR_INFORMATION) + ); + } + + PrevProcessorIndex += MpInfo2Hobs[HobIndex]->NumberOfProcessors; + } + + FreePool (MpInfo2Hobs); + return ProcessorInfo; +} + +/** + The module Entry Point of the CPU SMM driver. + + @retval EFI_SUCCESS The common entry point is executed successfully. + @retval Other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +PiSmmCpuEntryCommon ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Index; + UINTN TileCodeSize; + UINTN TileDataSize; + UINTN TileSize; + UINT8 *Stacks; + VOID *Registration; + UINT32 RegEax; + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; + UINTN FamilyId; + UINTN ModelId; + UINT32 Cr3; + + PERF_FUNCTION_BEGIN (); + + // + // Initialize address fixup + // + PiSmmCpuSmiEntryFixupAddress (); + + // + // Initialize Debug Agent to support source level debug in SMM code + // + InitializeDebugAgent (DEBUG_AGENT_INIT_SMM, &mSmmDebugAgentSupport, NULL); + + // + // Report the start of CPU SMM initialization. + // + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT + ); + + // + // Find out SMRR Base and SMRR Size + // + FindSmramInfo (&mCpuHotPlugData.SmrrBase, &mCpuHotPlugData.SmrrSize); + + // + // Retrieve NumberOfProcessors, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from MpInformation2 HOB. + // + gSmmCpuPrivate->ProcessorInfo = GetMpInformation (&mNumberOfCpus, &mMaxNumberOfCpus); + ASSERT (gSmmCpuPrivate->ProcessorInfo != NULL); + + // + // If support CPU hot plug, PcdCpuSmmEnableBspElection should be set to TRUE. + // A constant BSP index makes no sense because it may be hot removed. + // + DEBUG_CODE_BEGIN (); + if (FeaturePcdGet (PcdCpuHotPlugSupport)) { + ASSERT (FeaturePcdGet (PcdCpuSmmEnableBspElection)); + } + + DEBUG_CODE_END (); + + // + // Save the PcdCpuSmmCodeAccessCheckEnable value into a global variable. + // + mSmmCodeAccessCheckEnable = PcdGetBool (PcdCpuSmmCodeAccessCheckEnable); + DEBUG ((DEBUG_INFO, "PcdCpuSmmCodeAccessCheckEnable = %d\n", mSmmCodeAccessCheckEnable)); + + gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus = mMaxNumberOfCpus; + + PERF_CODE ( + InitializeMpPerf (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus); + ); + + // + // The CPU save state and code for the SMI entry point are tiled within an SMRAM + // allocated buffer. The minimum size of this buffer for a uniprocessor system + // is 32 KB, because the entry point is SMBASE + 32KB, and CPU save state area + // just below SMBASE + 64KB. If more than one CPU is present in the platform, + // then the SMI entry point and the CPU save state areas can be tiles to minimize + // the total amount SMRAM required for all the CPUs. The tile size can be computed + // by adding the // CPU save state size, any extra CPU specific context, and + // the size of code that must be placed at the SMI entry point to transfer + // control to a C function in the native SMM execution mode. This size is + // rounded up to the nearest power of 2 to give the tile size for a each CPU. + // The total amount of memory required is the maximum number of CPUs that + // platform supports times the tile size. The picture below shows the tiling, + // where m is the number of tiles that fit in 32KB. + // + // +-----------------------------+ <-- 2^n offset from Base of allocated buffer + // | CPU m+1 Save State | + // +-----------------------------+ + // | CPU m+1 Extra Data | + // +-----------------------------+ + // | Padding | + // +-----------------------------+ + // | CPU 2m SMI Entry | + // +#############################+ <-- Base of allocated buffer + 64 KB + // | CPU m-1 Save State | + // +-----------------------------+ + // | CPU m-1 Extra Data | + // +-----------------------------+ + // | Padding | + // +-----------------------------+ + // | CPU 2m-1 SMI Entry | + // +=============================+ <-- 2^n offset from Base of allocated buffer + // | . . . . . . . . . . . . | + // +=============================+ <-- 2^n offset from Base of allocated buffer + // | CPU 2 Save State | + // +-----------------------------+ + // | CPU 2 Extra Data | + // +-----------------------------+ + // | Padding | + // +-----------------------------+ + // | CPU m+1 SMI Entry | + // +=============================+ <-- Base of allocated buffer + 32 KB + // | CPU 1 Save State | + // +-----------------------------+ + // | CPU 1 Extra Data | + // +-----------------------------+ + // | Padding | + // +-----------------------------+ + // | CPU m SMI Entry | + // +#############################+ <-- Base of allocated buffer + 32 KB == CPU 0 SMBASE + 64 KB + // | CPU 0 Save State | + // +-----------------------------+ + // | CPU 0 Extra Data | + // +-----------------------------+ + // | Padding | + // +-----------------------------+ + // | CPU m-1 SMI Entry | + // +=============================+ <-- 2^n offset from Base of allocated buffer + // | . . . . . . . . . . . . | + // +=============================+ <-- 2^n offset from Base of allocated buffer + // | Padding | + // +-----------------------------+ + // | CPU 1 SMI Entry | + // +=============================+ <-- 2^n offset from Base of allocated buffer + // | Padding | + // +-----------------------------+ + // | CPU 0 SMI Entry | + // +#############################+ <-- Base of allocated buffer == CPU 0 SMBASE + 32 KB + // + + // + // Retrieve CPU Family + // + AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL); + FamilyId = (RegEax >> 8) & 0xf; + ModelId = (RegEax >> 4) & 0xf; + if ((FamilyId == 0x06) || (FamilyId == 0x0f)) { + ModelId = ModelId | ((RegEax >> 12) & 0xf0); + } + + RegEdx = 0; + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); + if (RegEax >= CPUID_EXTENDED_CPU_SIG) { + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx); + } + + // + // Determine the mode of the CPU at the time an SMI occurs + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual + // Volume 3C, Section 34.4.1.1 + // + mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT; + if ((RegEdx & BIT29) != 0) { + mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT; + } + + if (FamilyId == 0x06) { + if ((ModelId == 0x17) || (ModelId == 0x0f) || (ModelId == 0x1c)) { + mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT; + } + } + + DEBUG ((DEBUG_INFO, "PcdControlFlowEnforcementPropertyMask = %d\n", PcdGet32 (PcdControlFlowEnforcementPropertyMask))); + if (PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) { + AsmCpuid (CPUID_SIGNATURE, &RegEax, NULL, NULL, NULL); + if (RegEax >= CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS) { + AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, NULL, NULL, &RegEcx, &RegEdx); + DEBUG ((DEBUG_INFO, "CPUID[7/0] ECX - 0x%08x\n", RegEcx)); + DEBUG ((DEBUG_INFO, " CET_SS - 0x%08x\n", RegEcx & CPUID_CET_SS)); + DEBUG ((DEBUG_INFO, " CET_IBT - 0x%08x\n", RegEdx & CPUID_CET_IBT)); + if ((RegEcx & CPUID_CET_SS) == 0) { + mCetSupported = FALSE; + PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); + } + + if (mCetSupported) { + AsmCpuidEx (CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF, NULL, &RegEbx, &RegEcx, NULL); + DEBUG ((DEBUG_INFO, "CPUID[D/1] EBX - 0x%08x, ECX - 0x%08x\n", RegEbx, RegEcx)); + AsmCpuidEx (CPUID_EXTENDED_STATE, 11, &RegEax, NULL, &RegEcx, NULL); + DEBUG ((DEBUG_INFO, "CPUID[D/11] EAX - 0x%08x, ECX - 0x%08x\n", RegEax, RegEcx)); + AsmCpuidEx (CPUID_EXTENDED_STATE, 12, &RegEax, NULL, &RegEcx, NULL); + DEBUG ((DEBUG_INFO, "CPUID[D/12] EAX - 0x%08x, ECX - 0x%08x\n", RegEax, RegEcx)); + } + } else { + mCetSupported = FALSE; + PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); + } + } else { + mCetSupported = FALSE; + PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); + } + + // + // Compute tile size of buffer required to hold the CPU SMRAM Save State Map, extra CPU + // specific context start starts at SMBASE + SMM_PSD_OFFSET, and the SMI entry point. + // This size is rounded up to nearest power of 2. + // + TileCodeSize = GetSmiHandlerSize (); + TileCodeSize = ALIGN_VALUE (TileCodeSize, SIZE_4KB); + TileDataSize = (SMRAM_SAVE_STATE_MAP_OFFSET - SMM_PSD_OFFSET) + sizeof (SMRAM_SAVE_STATE_MAP); + TileDataSize = ALIGN_VALUE (TileDataSize, SIZE_4KB); + TileSize = TileDataSize + TileCodeSize - 1; + TileSize = 2 * GetPowerOfTwo32 ((UINT32)TileSize); + DEBUG ((DEBUG_INFO, "SMRAM TileSize = 0x%08x (0x%08x, 0x%08x)\n", TileSize, TileCodeSize, TileDataSize)); + + // + // If the TileSize is larger than space available for the SMI Handler of + // CPU[i], the extra CPU specific context of CPU[i+1], and the SMRAM Save + // State Map of CPU[i+1], then ASSERT(). If this ASSERT() is triggered, then + // the SMI Handler size must be reduced or the size of the extra CPU specific + // context must be reduced. + // + ASSERT (TileSize <= (SMRAM_SAVE_STATE_MAP_OFFSET + sizeof (SMRAM_SAVE_STATE_MAP) - SMM_HANDLER_OFFSET)); + + // + // Check whether the Required TileSize is enough. + // + if (TileSize > SIZE_8KB) { + DEBUG ((DEBUG_ERROR, "The Range of Smbase in SMRAM is not enough -- Required TileSize = 0x%08x, Actual TileSize = 0x%08x\n", TileSize, SIZE_8KB)); + FreePool (gSmmCpuPrivate->ProcessorInfo); + CpuDeadLoop (); + return RETURN_BUFFER_TOO_SMALL; + } + + // + // Retrieve the allocated SmmBase from gSmmBaseHobGuid. If found, + // means the SmBase relocation has been done. + // + mCpuHotPlugData.SmBase = NULL; + Status = GetSmBase (mMaxNumberOfCpus, &mCpuHotPlugData.SmBase); + ASSERT (!EFI_ERROR (Status)); + if (EFI_ERROR (Status)) { + CpuDeadLoop (); + } + + // + // ASSERT SmBase has been relocated. + // + ASSERT (mCpuHotPlugData.SmBase != NULL); + + // + // Allocate buffer for pointers to array in SMM_CPU_PRIVATE_DATA. + // + gSmmCpuPrivate->Operation = (SMM_CPU_OPERATION *)AllocatePool (sizeof (SMM_CPU_OPERATION) * mMaxNumberOfCpus); + ASSERT (gSmmCpuPrivate->Operation != NULL); + + gSmmCpuPrivate->CpuSaveStateSize = (UINTN *)AllocatePool (sizeof (UINTN) * mMaxNumberOfCpus); + ASSERT (gSmmCpuPrivate->CpuSaveStateSize != NULL); + + gSmmCpuPrivate->CpuSaveState = (VOID **)AllocatePool (sizeof (VOID *) * mMaxNumberOfCpus); + ASSERT (gSmmCpuPrivate->CpuSaveState != NULL); + + mSmmCpuPrivateData.SmmCoreEntryContext.CpuSaveStateSize = gSmmCpuPrivate->CpuSaveStateSize; + mSmmCpuPrivateData.SmmCoreEntryContext.CpuSaveState = gSmmCpuPrivate->CpuSaveState; + + // + // Allocate buffer for pointers to array in CPU_HOT_PLUG_DATA. + // + mCpuHotPlugData.ApicId = (UINT64 *)AllocatePool (sizeof (UINT64) * mMaxNumberOfCpus); + ASSERT (mCpuHotPlugData.ApicId != NULL); + mCpuHotPlugData.ArrayLength = (UINT32)mMaxNumberOfCpus; + + // + // Retrieve APIC ID of each enabled processor from the MP Services protocol. + // Also compute the SMBASE address, CPU Save State address, and CPU Save state + // size for each CPU in the platform + // + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + gSmmCpuPrivate->CpuSaveStateSize[Index] = sizeof (SMRAM_SAVE_STATE_MAP); + gSmmCpuPrivate->CpuSaveState[Index] = (VOID *)(mCpuHotPlugData.SmBase[Index] + SMRAM_SAVE_STATE_MAP_OFFSET); + gSmmCpuPrivate->Operation[Index] = SmmCpuNone; + + if (Index < mNumberOfCpus) { + mCpuHotPlugData.ApicId[Index] = gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId; + + DEBUG (( + DEBUG_INFO, + "CPU[%03x] APIC ID=%04x SMBASE=%08x SaveState=%08x Size=%08x\n", + Index, + (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId, + mCpuHotPlugData.SmBase[Index], + gSmmCpuPrivate->CpuSaveState[Index], + gSmmCpuPrivate->CpuSaveStateSize[Index] + )); + } else { + gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId = INVALID_APIC_ID; + mCpuHotPlugData.ApicId[Index] = INVALID_APIC_ID; + } + } + + // + // Allocate SMI stacks for all processors. + // + mSmmStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmStackSize))); + if (FeaturePcdGet (PcdCpuSmmStackGuard)) { + // + // SMM Stack Guard Enabled + // 2 more pages is allocated for each processor, one is guard page and the other is known good stack. + // + // +--------------------------------------------------+-----+--------------------------------------------------+ + // | Known Good Stack | Guard Page | SMM Stack | ... | Known Good Stack | Guard Page | SMM Stack | + // +--------------------------------------------------+-----+--------------------------------------------------+ + // | 4K | 4K PcdCpuSmmStackSize| | 4K | 4K PcdCpuSmmStackSize| + // |<---------------- mSmmStackSize ----------------->| |<---------------- mSmmStackSize ----------------->| + // | | | | + // |<------------------ Processor 0 ----------------->| |<------------------ Processor n ----------------->| + // + mSmmStackSize += EFI_PAGES_TO_SIZE (2); + } + + mSmmShadowStackSize = 0; + if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) { + mSmmShadowStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmShadowStackSize))); + + if (FeaturePcdGet (PcdCpuSmmStackGuard)) { + // + // SMM Stack Guard Enabled + // Append Shadow Stack after normal stack + // 2 more pages is allocated for each processor, one is guard page and the other is known good shadow stack. + // + // |= Stacks + // +--------------------------------------------------+---------------------------------------------------------------+ + // | Known Good Stack | Guard Page | SMM Stack | Known Good Shadow Stack | Guard Page | SMM Shadow Stack | + // +--------------------------------------------------+---------------------------------------------------------------+ + // | 4K | 4K |PcdCpuSmmStackSize| 4K | 4K |PcdCpuSmmShadowStackSize| + // |<---------------- mSmmStackSize ----------------->|<--------------------- mSmmShadowStackSize ------------------->| + // | | + // |<-------------------------------------------- Processor N ------------------------------------------------------->| + // + mSmmShadowStackSize += EFI_PAGES_TO_SIZE (2); + } else { + // + // SMM Stack Guard Disabled (Known Good Stack is still required for potential stack switch.) + // Append Shadow Stack after normal stack with 1 more page as known good shadow stack. + // 1 more pages is allocated for each processor, it is known good stack. + // + // + // |= Stacks + // +-------------------------------------+--------------------------------------------------+ + // | Known Good Stack | SMM Stack | Known Good Shadow Stack | SMM Shadow Stack | + // +-------------------------------------+--------------------------------------------------+ + // | 4K |PcdCpuSmmStackSize| 4K |PcdCpuSmmShadowStackSize| + // |<---------- mSmmStackSize ---------->|<--------------- mSmmShadowStackSize ------------>| + // | | + // |<-------------------------------- Processor N ----------------------------------------->| + // + mSmmShadowStackSize += EFI_PAGES_TO_SIZE (1); + mSmmStackSize += EFI_PAGES_TO_SIZE (1); + } + } + + Stacks = (UINT8 *)AllocatePages (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * (EFI_SIZE_TO_PAGES (mSmmStackSize + mSmmShadowStackSize))); + ASSERT (Stacks != NULL); + mSmmStackArrayBase = (UINTN)Stacks; + mSmmStackArrayEnd = mSmmStackArrayBase + gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * (mSmmStackSize + mSmmShadowStackSize) - 1; + + DEBUG ((DEBUG_INFO, "Stacks - 0x%x\n", Stacks)); + DEBUG ((DEBUG_INFO, "mSmmStackSize - 0x%x\n", mSmmStackSize)); + DEBUG ((DEBUG_INFO, "PcdCpuSmmStackGuard - 0x%x\n", FeaturePcdGet (PcdCpuSmmStackGuard))); + if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) { + DEBUG ((DEBUG_INFO, "mSmmShadowStackSize - 0x%x\n", mSmmShadowStackSize)); + } + + // + // Initialize IDT + // + InitializeSmmIdt (); + + // + // SMM Time initialization + // + InitializeSmmTimer (); + + // + // Initialize MP globals + // + Cr3 = InitializeMpServiceData (Stacks, mSmmStackSize, mSmmShadowStackSize); + + if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) { + for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) { + SetShadowStack ( + Cr3, + (EFI_PHYSICAL_ADDRESS)(UINTN)Stacks + mSmmStackSize + (mSmmStackSize + mSmmShadowStackSize) * Index, + mSmmShadowStackSize + ); + if (FeaturePcdGet (PcdCpuSmmStackGuard)) { + ConvertMemoryPageAttributes ( + Cr3, + mPagingMode, + (EFI_PHYSICAL_ADDRESS)(UINTN)Stacks + mSmmStackSize + EFI_PAGES_TO_SIZE (1) + (mSmmStackSize + mSmmShadowStackSize) * Index, + EFI_PAGES_TO_SIZE (1), + EFI_MEMORY_RP, + TRUE, + NULL + ); + } + } + } + + // + // For relocated SMBASE, some MSRs & CSRs are still required to be configured in SMM Mode for SMM Initialization. + // Those MSRs & CSRs must be configured before normal SMI sources happen. + // So, here is to issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init. + // + ExecuteFirstSmiInit (); + + // + // Call hook for BSP to perform extra actions in normal mode after all + // SMM base addresses have been relocated on all CPUs + // + SmmCpuFeaturesSmmRelocationComplete (); + + DEBUG ((DEBUG_INFO, "mXdSupported - 0x%x\n", mXdSupported)); + + // + // Fill in SMM Reserved Regions + // + gSmmCpuPrivate->SmmReservedSmramRegion[0].SmramReservedStart = 0; + gSmmCpuPrivate->SmmReservedSmramRegion[0].SmramReservedSize = 0; + + // + // Install the SMM CPU Protocol into SMM protocol database + // + Status = gMmst->MmInstallProtocolInterface ( + &mSmmCpuHandle, + &gEfiSmmCpuProtocolGuid, + EFI_NATIVE_INTERFACE, + &mSmmCpu + ); + ASSERT_EFI_ERROR (Status); + + // + // Install the SMM Memory Attribute Protocol into SMM protocol database + // + Status = gMmst->MmInstallProtocolInterface ( + &mSmmCpuHandle, + &gEdkiiSmmMemoryAttributeProtocolGuid, + EFI_NATIVE_INTERFACE, + &mSmmMemoryAttribute + ); + ASSERT_EFI_ERROR (Status); + + // + // Initialize global buffer for MM MP. + // + InitializeDataForMmMp (); + + // + // Initialize Package First Thread Index Info. + // + InitPackageFirstThreadIndexInfo (); + + // + // Install the SMM Mp Protocol into SMM protocol database + // + Status = gMmst->MmInstallProtocolInterface ( + &mSmmCpuHandle, + &gEfiMmMpProtocolGuid, + EFI_NATIVE_INTERFACE, + &mSmmMp + ); + ASSERT_EFI_ERROR (Status); + + // + // Initialize SMM CPU Services Support + // + Status = InitializeSmmCpuServices (mSmmCpuHandle); + ASSERT_EFI_ERROR (Status); + + // + // register SMM Ready To Lock Protocol notification + // + Status = gMmst->MmRegisterProtocolNotify ( + &gEfiSmmReadyToLockProtocolGuid, + SmmReadyToLockEventNotify, + &Registration + ); + ASSERT_EFI_ERROR (Status); + + // + // Initialize SMM Profile feature + // + InitSmmProfile (Cr3); + + GetAcpiS3EnableFlag (); + InitSmmS3ResumeState (); + + DEBUG ((DEBUG_INFO, "SMM CPU Module exit from SMRAM with EFI_SUCCESS\n")); + + PERF_FUNCTION_END (); + return EFI_SUCCESS; +} + +/** + Function to compare 2 EFI_SMRAM_DESCRIPTOR based on CpuStart. + + @param[in] Buffer1 pointer to Device Path poiner to compare + @param[in] Buffer2 pointer to second DevicePath pointer to compare + + @retval 0 Buffer1 equal to Buffer2 + @retval <0 Buffer1 is less than Buffer2 + @retval >0 Buffer1 is greater than Buffer2 +**/ +INTN +EFIAPI +CpuSmramRangeCompare ( + IN CONST VOID *Buffer1, + IN CONST VOID *Buffer2 + ) +{ + if (((EFI_SMRAM_DESCRIPTOR *)Buffer1)->CpuStart > ((EFI_SMRAM_DESCRIPTOR *)Buffer2)->CpuStart) { + return 1; + } else if (((EFI_SMRAM_DESCRIPTOR *)Buffer1)->CpuStart < ((EFI_SMRAM_DESCRIPTOR *)Buffer2)->CpuStart) { + return -1; + } + + return 0; +} + +/** + + Find out SMRAM information including SMRR base and SMRR size. + + @param SmrrBase SMRR base + @param SmrrSize SMRR size + +**/ +VOID +FindSmramInfo ( + OUT UINT32 *SmrrBase, + OUT UINT32 *SmrrSize + ) +{ + EFI_STATUS Status; + UINTN Size; + EFI_SMM_ACCESS2_PROTOCOL *SmmAccess; + EFI_SMRAM_DESCRIPTOR *CurrentSmramRange; + UINTN Index; + UINT64 MaxSize; + BOOLEAN Found; + EFI_SMRAM_DESCRIPTOR SmramDescriptor; + + // + // Get SMM Access Protocol + // + Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess); + ASSERT_EFI_ERROR (Status); + + // + // Get SMRAM information + // + Size = 0; + Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL); + ASSERT (Status == EFI_BUFFER_TOO_SMALL); + + mSmmCpuSmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocatePool (Size); + ASSERT (mSmmCpuSmramRanges != NULL); + + Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmmCpuSmramRanges); + ASSERT_EFI_ERROR (Status); + + mSmmCpuSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR); + + // + // Sort the mSmmCpuSmramRanges + // + QuickSort (mSmmCpuSmramRanges, mSmmCpuSmramRangeCount, sizeof (EFI_SMRAM_DESCRIPTOR), (BASE_SORT_COMPARE)CpuSmramRangeCompare, &SmramDescriptor); + + // + // Find the largest SMRAM range between 1MB and 4GB that is at least 256K - 4K in size + // + CurrentSmramRange = NULL; + for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < mSmmCpuSmramRangeCount; Index++) { + // + // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization + // + if ((mSmmCpuSmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) { + continue; + } + + if (mSmmCpuSmramRanges[Index].CpuStart >= BASE_1MB) { + if ((mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize) <= SMRR_MAX_ADDRESS) { + if (mSmmCpuSmramRanges[Index].PhysicalSize >= MaxSize) { + MaxSize = mSmmCpuSmramRanges[Index].PhysicalSize; + CurrentSmramRange = &mSmmCpuSmramRanges[Index]; + } + } + } + } + + ASSERT (CurrentSmramRange != NULL); + + *SmrrBase = (UINT32)CurrentSmramRange->CpuStart; + *SmrrSize = (UINT32)CurrentSmramRange->PhysicalSize; + + do { + Found = FALSE; + for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) { + if ((mSmmCpuSmramRanges[Index].CpuStart < *SmrrBase) && + (*SmrrBase == (mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize))) + { + *SmrrBase = (UINT32)mSmmCpuSmramRanges[Index].CpuStart; + *SmrrSize = (UINT32)(*SmrrSize + mSmmCpuSmramRanges[Index].PhysicalSize); + Found = TRUE; + } else if (((*SmrrBase + *SmrrSize) == mSmmCpuSmramRanges[Index].CpuStart) && (mSmmCpuSmramRanges[Index].PhysicalSize > 0)) { + *SmrrSize = (UINT32)(*SmrrSize + mSmmCpuSmramRanges[Index].PhysicalSize); + Found = TRUE; + } + } + } while (Found); + + DEBUG ((DEBUG_INFO, "SMRR Base: 0x%x, SMRR Size: 0x%x\n", *SmrrBase, *SmrrSize)); +} + +/** +Configure SMM Code Access Check feature on an AP. +SMM Feature Control MSR will be locked after configuration. + +@param[in,out] Buffer Pointer to private data buffer. +**/ +VOID +EFIAPI +ConfigSmmCodeAccessCheckOnCurrentProcessor ( + IN OUT VOID *Buffer + ) +{ + UINTN CpuIndex; + UINT64 SmmFeatureControlMsr; + UINT64 NewSmmFeatureControlMsr; + + // + // Retrieve the CPU Index from the context passed in + // + CpuIndex = *(UINTN *)Buffer; + + // + // Get the current SMM Feature Control MSR value + // + SmmFeatureControlMsr = SmmCpuFeaturesGetSmmRegister (CpuIndex, SmmRegFeatureControl); + + // + // Compute the new SMM Feature Control MSR value + // + NewSmmFeatureControlMsr = SmmFeatureControlMsr; + if (mSmmCodeAccessCheckEnable) { + NewSmmFeatureControlMsr |= SMM_CODE_CHK_EN_BIT; + if (FeaturePcdGet (PcdCpuSmmFeatureControlMsrLock)) { + NewSmmFeatureControlMsr |= SMM_FEATURE_CONTROL_LOCK_BIT; + } + } + + // + // Only set the SMM Feature Control MSR value if the new value is different than the current value + // + if (NewSmmFeatureControlMsr != SmmFeatureControlMsr) { + SmmCpuFeaturesSetSmmRegister (CpuIndex, SmmRegFeatureControl, NewSmmFeatureControlMsr); + } + + // + // Release the spin lock user to serialize the updates to the SMM Feature Control MSR + // + ReleaseSpinLock (mConfigSmmCodeAccessCheckLock); +} + +/** +Configure SMM Code Access Check feature for all processors. +SMM Feature Control MSR will be locked after configuration. +**/ +VOID +ConfigSmmCodeAccessCheck ( + VOID + ) +{ + UINTN Index; + EFI_STATUS Status; + + PERF_FUNCTION_BEGIN (); + + // + // Check to see if the Feature Control MSR is supported on this CPU + // + Index = gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu; + if (!SmmCpuFeaturesIsSmmRegisterSupported (Index, SmmRegFeatureControl)) { + mSmmCodeAccessCheckEnable = FALSE; + PERF_FUNCTION_END (); + return; + } + + // + // Check to see if the CPU supports the SMM Code Access Check feature + // Do not access this MSR unless the CPU supports the SmmRegFeatureControl + // + if ((AsmReadMsr64 (EFI_MSR_SMM_MCA_CAP) & SMM_CODE_ACCESS_CHK_BIT) == 0) { + mSmmCodeAccessCheckEnable = FALSE; + PERF_FUNCTION_END (); + return; + } + + // + // Initialize the lock used to serialize the MSR programming in BSP and all APs + // + InitializeSpinLock (mConfigSmmCodeAccessCheckLock); + + // + // Acquire Config SMM Code Access Check spin lock. The BSP will release the + // spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor(). + // + AcquireSpinLock (mConfigSmmCodeAccessCheckLock); + + // + // Enable SMM Code Access Check feature on the BSP. + // + ConfigSmmCodeAccessCheckOnCurrentProcessor (&Index); + + // + // Enable SMM Code Access Check feature for the APs. + // + for (Index = 0; Index < gMmst->NumberOfCpus; Index++) { + if (Index != gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu) { + if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == INVALID_APIC_ID) { + // + // If this processor does not exist + // + continue; + } + + // + // Acquire Config SMM Code Access Check spin lock. The AP will release the + // spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor(). + // + AcquireSpinLock (mConfigSmmCodeAccessCheckLock); + + // + // Call SmmStartupThisAp() to enable SMM Code Access Check on an AP. + // + Status = gMmst->MmStartupThisAp (ConfigSmmCodeAccessCheckOnCurrentProcessor, Index, &Index); + ASSERT_EFI_ERROR (Status); + + // + // Wait for the AP to release the Config SMM Code Access Check spin lock. + // + while (!AcquireSpinLockOrFail (mConfigSmmCodeAccessCheckLock)) { + CpuPause (); + } + + // + // Release the Config SMM Code Access Check spin lock. + // + ReleaseSpinLock (mConfigSmmCodeAccessCheckLock); + } + } + + PERF_FUNCTION_END (); +} + +/** + Allocate pages for code. + + @param[in] Pages Number of pages to be allocated. + + @return Allocated memory. +**/ +VOID * +AllocateCodePages ( + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + + if (Pages == 0) { + return NULL; + } + + Status = gMmst->MmAllocatePages (AllocateAnyPages, EfiRuntimeServicesCode, Pages, &Memory); + if (EFI_ERROR (Status)) { + return NULL; + } + + return (VOID *)(UINTN)Memory; +} + +/** + Perform the remaining tasks. + +**/ +VOID +PerformRemainingTasks ( + VOID + ) +{ + if (mSmmReadyToLock) { + PERF_FUNCTION_BEGIN (); + + // + // Check if all Aps enter SMM. In Relaxed-AP Sync Mode, BSP will not wait for + // all Aps arrive. However,PerformRemainingTasks() needs to wait all Aps arrive before calling + // SetMemMapAttributes() and ConfigSmmCodeAccessCheck() when mSmmReadyToLock + // is true. In SetMemMapAttributes(), SmmSetMemoryAttributesEx() will call + // FlushTlbForAll() that need to start up the aps. So it need to let all + // aps arrive. Same as SetMemMapAttributes(), ConfigSmmCodeAccessCheck() + // also will start up the aps. + // + if (EFI_ERROR (SmmCpuRendezvous (NULL, TRUE))) { + DEBUG ((DEBUG_ERROR, "PerformRemainingTasks: fail to wait for all AP check in SMM!\n")); + } + + // + // Start SMM Profile feature + // + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + SmmProfileStart (); + } + + // + // Create a mix of 2MB and 4KB page table. Update some memory ranges absent and execute-disable. + // + InitPaging (); + + // + // Mark critical region to be read-only in page table + // + SetMemMapAttributes (); + + if (IsRestrictedMemoryAccess ()) { + // + // For outside SMRAM, we only map SMM communication buffer or MMIO. + // + SetUefiMemMapAttributes (); + + // + // Set page table itself to be read-only + // + SetPageTableAttributes (); + } + + // + // Configure SMM Code Access Check feature if available. + // + ConfigSmmCodeAccessCheck (); + + // + // Measure performance of SmmCpuFeaturesCompleteSmmReadyToLock() from caller side + // as the implementation is provided by platform. + // + PERF_START (NULL, "SmmCompleteReadyToLock", NULL, 0); + SmmCpuFeaturesCompleteSmmReadyToLock (); + PERF_END (NULL, "SmmCompleteReadyToLock", NULL, 0); + + // + // Clean SMM ready to lock flag + // + mSmmReadyToLock = FALSE; + + PERF_FUNCTION_END (); + } +} + +/** + Perform the pre tasks. + +**/ +VOID +PerformPreTasks ( + VOID + ) +{ + RestoreSmmConfigurationInS3 (); +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index 9d4775afda40..87fd7d9ba155 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -1490,4 +1490,30 @@ SmmWriteProtectReadOnlyPage ( } \ } while (FALSE) +/** + Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from gEfiMpServiceProtocolGuid. + + @param[out] NumberOfCpus Pointer to NumberOfCpus. + @param[out] MaxNumberOfCpus Pointer to MaxNumberOfCpus. + + @retval ProcessorInfo Pointer to EFI_PROCESSOR_INFORMATION buffer. +**/ +EFI_PROCESSOR_INFORMATION * +GetMpInformationFromMpServices ( + OUT UINTN *NumberOfCpus, + OUT UINTN *MaxNumberOfCpus + ); + +/** + The common Entry Point of the SMM CPU driver. + + @retval EFI_SUCCESS The common entry point is executed successfully. + @retval Other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +PiSmmCpuEntryCommon ( + VOID + ); + #endif diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index 7f3b2bc4a8fb..29cba42e7a09 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -11,618 +11,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PiSmmCpuCommon.h" -// -// SMM CPU Private Data structure that contains SMM Configuration Protocol -// along its supporting fields. -// -SMM_CPU_PRIVATE_DATA mSmmCpuPrivateData = { - SMM_CPU_PRIVATE_DATA_SIGNATURE, // Signature - NULL, // SmmCpuHandle - NULL, // Pointer to ProcessorInfo array - NULL, // Pointer to Operation array - NULL, // Pointer to CpuSaveStateSize array - NULL, // Pointer to CpuSaveState array - { - { 0 } - }, // SmmReservedSmramRegion - { - SmmStartupThisAp, // SmmCoreEntryContext.SmmStartupThisAp - 0, // SmmCoreEntryContext.CurrentlyExecutingCpu - 0, // SmmCoreEntryContext.NumberOfCpus - NULL, // SmmCoreEntryContext.CpuSaveStateSize - NULL // SmmCoreEntryContext.CpuSaveState - }, - NULL, // SmmCoreEntry - { - mSmmCpuPrivateData.SmmReservedSmramRegion, // SmmConfiguration.SmramReservedRegions - RegisterSmmEntry // SmmConfiguration.RegisterSmmEntry - }, - NULL, // pointer to Ap Wrapper Func array - { NULL, NULL }, // List_Entry for Tokens. -}; - -CPU_HOT_PLUG_DATA mCpuHotPlugData = { - CPU_HOT_PLUG_DATA_REVISION_1, // Revision - 0, // Array Length of SmBase and APIC ID - NULL, // Pointer to APIC ID array - NULL, // Pointer to SMBASE array - 0, // Reserved - 0, // SmrrBase - 0 // SmrrSize -}; - -// -// Global pointer used to access mSmmCpuPrivateData from outside and inside SMM -// -SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate = &mSmmCpuPrivateData; - -/// -/// Handle for the SMM CPU Protocol -/// -EFI_HANDLE mSmmCpuHandle = NULL; - -/// -/// SMM CPU Protocol instance -/// -EFI_SMM_CPU_PROTOCOL mSmmCpu = { - SmmReadSaveState, - SmmWriteSaveState -}; - -/// -/// SMM Memory Attribute Protocol instance -/// -EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL mSmmMemoryAttribute = { - EdkiiSmmGetMemoryAttributes, - EdkiiSmmSetMemoryAttributes, - EdkiiSmmClearMemoryAttributes -}; - -EFI_CPU_INTERRUPT_HANDLER mExternalVectorTable[EXCEPTION_VECTOR_NUMBER]; - -volatile BOOLEAN *mSmmInitialized = NULL; -UINT32 mBspApicId = 0; - -// -// SMM stack information -// -UINTN mSmmStackArrayBase; -UINTN mSmmStackArrayEnd; -UINTN mSmmStackSize; - -UINTN mSmmShadowStackSize; -BOOLEAN mCetSupported = TRUE; - -UINTN mMaxNumberOfCpus = 0; -UINTN mNumberOfCpus = 0; - -// -// SMM ready to lock flag -// -BOOLEAN mSmmReadyToLock = FALSE; - -// -// Global used to cache PCD for SMM Code Access Check enable -// -BOOLEAN mSmmCodeAccessCheckEnable = FALSE; - -// -// Global used to cache SMM Debug Agent Supported ot not -// -BOOLEAN mSmmDebugAgentSupport = FALSE; - -// -// Global copy of the PcdPteMemoryEncryptionAddressOrMask -// -UINT64 mAddressEncMask = 0; - -// -// Spin lock used to serialize setting of SMM Code Access Check feature -// -SPIN_LOCK *mConfigSmmCodeAccessCheckLock = NULL; - -// -// Saved SMM ranges information -// -EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges; -UINTN mSmmCpuSmramRangeCount; - -UINT8 mPhysicalAddressBits; - -/** - Initialize IDT to setup exception handlers for SMM. - -**/ -VOID -InitializeSmmIdt ( - VOID - ) -{ - EFI_STATUS Status; - BOOLEAN InterruptState; - IA32_DESCRIPTOR DxeIdtr; - - // - // There are 32 (not 255) entries in it since only processor - // generated exceptions will be handled. - // - gcSmiIdtr.Limit = (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 32) - 1; - // - // Allocate page aligned IDT, because it might be set as read only. - // - gcSmiIdtr.Base = (UINTN)AllocateCodePages (EFI_SIZE_TO_PAGES (gcSmiIdtr.Limit + 1)); - ASSERT (gcSmiIdtr.Base != 0); - ZeroMem ((VOID *)gcSmiIdtr.Base, gcSmiIdtr.Limit + 1); - - // - // Disable Interrupt and save DXE IDT table - // - InterruptState = SaveAndDisableInterrupts (); - AsmReadIdtr (&DxeIdtr); - // - // Load SMM temporary IDT table - // - AsmWriteIdtr (&gcSmiIdtr); - // - // Setup SMM default exception handlers, SMM IDT table - // will be updated and saved in gcSmiIdtr - // - Status = InitializeCpuExceptionHandlers (NULL); - ASSERT_EFI_ERROR (Status); - // - // Restore DXE IDT table and CPU interrupt - // - AsmWriteIdtr ((IA32_DESCRIPTOR *)&DxeIdtr); - SetInterruptState (InterruptState); -} - -/** - Search module name by input IP address and output it. - - @param CallerIpAddress Caller instruction pointer. - -**/ -VOID -DumpModuleInfoByIp ( - IN UINTN CallerIpAddress - ) -{ - UINTN Pe32Data; - VOID *PdbPointer; - - // - // Find Image Base - // - Pe32Data = PeCoffSearchImageBase (CallerIpAddress); - if (Pe32Data != 0) { - DEBUG ((DEBUG_ERROR, "It is invoked from the instruction before IP(0x%p)", (VOID *)CallerIpAddress)); - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)Pe32Data); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_ERROR, " in module (%a)\n", PdbPointer)); - } - } -} - -/** - Read information from the CPU save state. - - @param This EFI_SMM_CPU_PROTOCOL instance - @param Width The number of bytes to read from the CPU save state. - @param Register Specifies the CPU register to read form the save state. - @param CpuIndex Specifies the zero-based index of the CPU save state. - @param Buffer Upon return, this holds the CPU register value read from the save state. - - @retval EFI_SUCCESS The register was read from Save State - @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor - @retval EFI_INVALID_PARAMETER This or Buffer is NULL. - -**/ -EFI_STATUS -EFIAPI -SmmReadSaveState ( - IN CONST EFI_SMM_CPU_PROTOCOL *This, - IN UINTN Width, - IN EFI_SMM_SAVE_STATE_REGISTER Register, - IN UINTN CpuIndex, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - - // - // Retrieve pointer to the specified CPU's SMM Save State buffer - // - if ((CpuIndex >= gMmst->NumberOfCpus) || (Buffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - // - // The SpeculationBarrier() call here is to ensure the above check for the - // CpuIndex has been completed before the execution of subsequent codes. - // - SpeculationBarrier (); - - // - // Check for special EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID - // - if (Register == EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID) { - // - // The pseudo-register only supports the 64-bit size specified by Width. - // - if (Width != sizeof (UINT64)) { - return EFI_INVALID_PARAMETER; - } - - // - // If the processor is in SMM at the time the SMI occurred, - // the pseudo register value for EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID is returned in Buffer. - // Otherwise, EFI_NOT_FOUND is returned. - // - if (*(mSmmMpSyncData->CpuData[CpuIndex].Present)) { - *(UINT64 *)Buffer = gSmmCpuPrivate->ProcessorInfo[CpuIndex].ProcessorId; - return EFI_SUCCESS; - } else { - return EFI_NOT_FOUND; - } - } - - if (!(*(mSmmMpSyncData->CpuData[CpuIndex].Present))) { - return EFI_INVALID_PARAMETER; - } - - Status = MmSaveStateReadRegister (CpuIndex, Register, Width, Buffer); - - return Status; -} - -/** - Write data to the CPU save state. - - @param This EFI_SMM_CPU_PROTOCOL instance - @param Width The number of bytes to read from the CPU save state. - @param Register Specifies the CPU register to write to the save state. - @param CpuIndex Specifies the zero-based index of the CPU save state - @param Buffer Upon entry, this holds the new CPU register value. - - @retval EFI_SUCCESS The register was written from Save State - @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor - @retval EFI_INVALID_PARAMETER ProcessorIndex or Width is not correct - -**/ -EFI_STATUS -EFIAPI -SmmWriteSaveState ( - IN CONST EFI_SMM_CPU_PROTOCOL *This, - IN UINTN Width, - IN EFI_SMM_SAVE_STATE_REGISTER Register, - IN UINTN CpuIndex, - IN CONST VOID *Buffer - ) -{ - EFI_STATUS Status; - - // - // Retrieve pointer to the specified CPU's SMM Save State buffer - // - if ((CpuIndex >= gMmst->NumberOfCpus) || (Buffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - // - // Writes to EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID are ignored - // - if (Register == EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID) { - return EFI_SUCCESS; - } - - if (!mSmmMpSyncData->CpuData[CpuIndex].Present) { - return EFI_INVALID_PARAMETER; - } - - Status = MmSaveStateWriteRegister (CpuIndex, Register, Width, Buffer); - - return Status; -} - -/** - Initialize SMM environment. - -**/ -VOID -InitializeSmm ( - VOID - ) -{ - UINT32 ApicId; - UINTN Index; - BOOLEAN IsBsp; - - ApicId = GetApicId (); - - IsBsp = (BOOLEAN)(mBspApicId == ApicId); - - ASSERT (mNumberOfCpus <= mMaxNumberOfCpus); - - for (Index = 0; Index < mNumberOfCpus; Index++) { - if (ApicId == (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId) { - PERF_CODE ( - MpPerfBegin (Index, SMM_MP_PERF_PROCEDURE_ID (InitializeSmm)); - ); - // - // Initialize SMM specific features on the currently executing CPU - // - SmmCpuFeaturesInitializeProcessor ( - Index, - IsBsp, - gSmmCpuPrivate->ProcessorInfo, - &mCpuHotPlugData - ); - - if (!mSmmS3Flag) { - // - // Check XD and BTS features on each processor on normal boot - // - CheckFeatureSupported (); - } else if (IsBsp) { - // - // BSP rebase is already done above. - // Initialize private data during S3 resume - // - InitializeMpSyncData (); - } - - PERF_CODE ( - MpPerfEnd (Index, SMM_MP_PERF_PROCEDURE_ID (InitializeSmm)); - ); - - return; - } - } - - ASSERT (FALSE); -} - -/** - Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init. - -**/ -VOID -ExecuteFirstSmiInit ( - VOID - ) -{ - UINTN Index; - - PERF_FUNCTION_BEGIN (); - - if (mSmmInitialized == NULL) { - mSmmInitialized = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) * mMaxNumberOfCpus); - } - - ASSERT (mSmmInitialized != NULL); - if (mSmmInitialized == NULL) { - PERF_FUNCTION_END (); - return; - } - - // - // Reset the mSmmInitialized to false. - // - ZeroMem ((VOID *)mSmmInitialized, sizeof (BOOLEAN) * mMaxNumberOfCpus); - - // - // Get the BSP ApicId. - // - mBspApicId = GetApicId (); - - // - // Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) for SMM init - // - SendSmiIpi (mBspApicId); - SendSmiIpiAllExcludingSelf (); - - // - // Wait for all processors to finish its 1st SMI - // - for (Index = 0; Index < mNumberOfCpus; Index++) { - while (!(BOOLEAN)mSmmInitialized[Index]) { - } - } - - PERF_FUNCTION_END (); -} - -/** - SMM Ready To Lock event notification handler. - - mSmmReadyToLock is set to perform additional lock actions that must be - performed from SMM on the next SMI. - - @param[in] Protocol Points to the protocol's unique identifier. - @param[in] Interface Points to the interface instance. - @param[in] Handle The handle on which the interface was installed. - - @retval EFI_SUCCESS Notification handler runs successfully. - **/ -EFI_STATUS -EFIAPI -SmmReadyToLockEventNotify ( - IN CONST EFI_GUID *Protocol, - IN VOID *Interface, - IN EFI_HANDLE Handle - ) -{ - // - // Cache a copy of UEFI memory map before we start profiling feature. - // - GetUefiMemoryMap (); - - // - // Set SMM ready to lock flag and return - // - mSmmReadyToLock = TRUE; - return EFI_SUCCESS; -} - -/** - Function to compare 2 SMM_BASE_HOB_DATA pointer based on ProcessorIndex. - - @param[in] Buffer1 pointer to SMM_BASE_HOB_DATA poiner to compare - @param[in] Buffer2 pointer to second SMM_BASE_HOB_DATA pointer to compare - - @retval 0 Buffer1 equal to Buffer2 - @retval <0 Buffer1 is less than Buffer2 - @retval >0 Buffer1 is greater than Buffer2 -**/ -INTN -EFIAPI -SmBaseHobCompare ( - IN CONST VOID *Buffer1, - IN CONST VOID *Buffer2 - ) -{ - if ((*(SMM_BASE_HOB_DATA **)Buffer1)->ProcessorIndex > (*(SMM_BASE_HOB_DATA **)Buffer2)->ProcessorIndex) { - return 1; - } else if ((*(SMM_BASE_HOB_DATA **)Buffer1)->ProcessorIndex < (*(SMM_BASE_HOB_DATA **)Buffer2)->ProcessorIndex) { - return -1; - } - - return 0; -} - -/** - Extract SmBase for all CPU from SmmBase HOB. - - @param[in] MaxNumberOfCpus Max NumberOfCpus. - - @param[out] AllocatedSmBaseBuffer Pointer to SmBase Buffer allocated - by this function. Only set if the - function returns EFI_SUCCESS. - - @retval EFI_SUCCESS SmBase Buffer output successfully. - @retval EFI_OUT_OF_RESOURCES Memory allocation failed. - @retval EFI_NOT_FOUND gSmmBaseHobGuid was never created. -**/ -STATIC -EFI_STATUS -GetSmBase ( - IN UINTN MaxNumberOfCpus, - OUT UINTN **AllocatedSmBaseBuffer - ) -{ - UINTN HobCount; - EFI_HOB_GUID_TYPE *GuidHob; - SMM_BASE_HOB_DATA *SmmBaseHobData; - UINTN NumberOfProcessors; - SMM_BASE_HOB_DATA **SmBaseHobs; - UINTN *SmBaseBuffer; - UINTN HobIndex; - UINTN SortBuffer; - UINTN ProcessorIndex; - UINT64 PrevProcessorIndex; - EFI_HOB_GUID_TYPE *FirstSmmBaseGuidHob; - - SmmBaseHobData = NULL; - HobIndex = 0; - ProcessorIndex = 0; - HobCount = 0; - NumberOfProcessors = 0; - - FirstSmmBaseGuidHob = GetFirstGuidHob (&gSmmBaseHobGuid); - if (FirstSmmBaseGuidHob == NULL) { - return EFI_NOT_FOUND; - } - - GuidHob = FirstSmmBaseGuidHob; - while (GuidHob != NULL) { - HobCount++; - SmmBaseHobData = GET_GUID_HOB_DATA (GuidHob); - NumberOfProcessors += SmmBaseHobData->NumberOfProcessors; - - if (NumberOfProcessors >= MaxNumberOfCpus) { - break; - } - - GuidHob = GetNextGuidHob (&gSmmBaseHobGuid, GET_NEXT_HOB (GuidHob)); - } - - ASSERT (NumberOfProcessors == MaxNumberOfCpus); - if (NumberOfProcessors != MaxNumberOfCpus) { - CpuDeadLoop (); - } - - SmBaseHobs = AllocatePool (sizeof (SMM_BASE_HOB_DATA *) * HobCount); - if (SmBaseHobs == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Record each SmmBaseHob pointer in the SmBaseHobs. - // The FirstSmmBaseGuidHob is to speed up this while-loop - // without needing to look for SmBaseHob from beginning. - // - GuidHob = FirstSmmBaseGuidHob; - while (HobIndex < HobCount) { - SmBaseHobs[HobIndex++] = GET_GUID_HOB_DATA (GuidHob); - GuidHob = GetNextGuidHob (&gSmmBaseHobGuid, GET_NEXT_HOB (GuidHob)); - } - - SmBaseBuffer = (UINTN *)AllocatePool (sizeof (UINTN) * (MaxNumberOfCpus)); - ASSERT (SmBaseBuffer != NULL); - if (SmBaseBuffer == NULL) { - FreePool (SmBaseHobs); - return EFI_OUT_OF_RESOURCES; - } - - QuickSort (SmBaseHobs, HobCount, sizeof (SMM_BASE_HOB_DATA *), (BASE_SORT_COMPARE)SmBaseHobCompare, &SortBuffer); - PrevProcessorIndex = 0; - for (HobIndex = 0; HobIndex < HobCount; HobIndex++) { - // - // Make sure no overlap and no gap in the CPU range covered by each HOB - // - ASSERT (SmBaseHobs[HobIndex]->ProcessorIndex == PrevProcessorIndex); - - // - // Cache each SmBase in order. - // - for (ProcessorIndex = 0; ProcessorIndex < SmBaseHobs[HobIndex]->NumberOfProcessors; ProcessorIndex++) { - SmBaseBuffer[PrevProcessorIndex + ProcessorIndex] = (UINTN)SmBaseHobs[HobIndex]->SmBase[ProcessorIndex]; - } - - PrevProcessorIndex += SmBaseHobs[HobIndex]->NumberOfProcessors; - } - - FreePool (SmBaseHobs); - *AllocatedSmBaseBuffer = SmBaseBuffer; - return EFI_SUCCESS; -} - -/** - Function to compare 2 MP_INFORMATION2_HOB_DATA pointer based on ProcessorIndex. - - @param[in] Buffer1 pointer to MP_INFORMATION2_HOB_DATA poiner to compare - @param[in] Buffer2 pointer to second MP_INFORMATION2_HOB_DATA pointer to compare - - @retval 0 Buffer1 equal to Buffer2 - @retval <0 Buffer1 is less than Buffer2 - @retval >0 Buffer1 is greater than Buffer2 -**/ -INTN -EFIAPI -MpInformation2HobCompare ( - IN CONST VOID *Buffer1, - IN CONST VOID *Buffer2 - ) -{ - if ((*(MP_INFORMATION2_HOB_DATA **)Buffer1)->ProcessorIndex > (*(MP_INFORMATION2_HOB_DATA **)Buffer2)->ProcessorIndex) { - return 1; - } else if ((*(MP_INFORMATION2_HOB_DATA **)Buffer1)->ProcessorIndex < (*(MP_INFORMATION2_HOB_DATA **)Buffer2)->ProcessorIndex) { - return -1; - } - - return 0; -} - /** Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from gEfiMpServiceProtocolGuid. @@ -703,575 +91,34 @@ GetMpInformationFromMpServices ( } /** - Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from MpInformation2 HOB. + The module Entry Point of the CPU SMM driver. - @param[out] NumberOfCpus Pointer to NumberOfCpus. - @param[out] MaxNumberOfCpus Pointer to MaxNumberOfCpus. + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval Other Some error occurs when executing this entry point. - @retval ProcessorInfo Pointer to EFI_PROCESSOR_INFORMATION buffer. **/ -EFI_PROCESSOR_INFORMATION * -GetMpInformation ( - OUT UINTN *NumberOfCpus, - OUT UINTN *MaxNumberOfCpus +EFI_STATUS +EFIAPI +PiCpuSmmEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_HOB_GUID_TYPE *GuidHob; - EFI_HOB_GUID_TYPE *FirstMpInfo2Hob; - MP_INFORMATION2_HOB_DATA *MpInformation2HobData; - UINTN HobCount; - UINTN HobIndex; - MP_INFORMATION2_HOB_DATA **MpInfo2Hobs; - UINTN SortBuffer; - UINTN ProcessorIndex; - UINT64 PrevProcessorIndex; - MP_INFORMATION2_ENTRY *MpInformation2Entry; - EFI_PROCESSOR_INFORMATION *ProcessorInfo; - - GuidHob = NULL; - MpInformation2HobData = NULL; - FirstMpInfo2Hob = NULL; - MpInfo2Hobs = NULL; - HobIndex = 0; - HobCount = 0; - - FirstMpInfo2Hob = GetFirstGuidHob (&gMpInformation2HobGuid); - if (FirstMpInfo2Hob == NULL) { - DEBUG ((DEBUG_INFO, "%a: [INFO] gMpInformation2HobGuid HOB not found.\n", __func__)); - return GetMpInformationFromMpServices (NumberOfCpus, MaxNumberOfCpus); - } + EFI_STATUS Status; - GuidHob = FirstMpInfo2Hob; - while (GuidHob != NULL) { - MpInformation2HobData = GET_GUID_HOB_DATA (GuidHob); + // + // Save the PcdPteMemoryEncryptionAddressOrMask value into a global variable. + // Make sure AddressEncMask is contained to smallest supported address field. + // + mAddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; + DEBUG ((DEBUG_INFO, "mAddressEncMask = 0x%lx\n", mAddressEncMask)); - // - // This is the last MpInformationHob in the HOB list. - // - if (MpInformation2HobData->NumberOfProcessors == 0) { - ASSERT (HobCount != 0); - break; - } + Status = PiSmmCpuEntryCommon (); - HobCount++; - *NumberOfCpus += MpInformation2HobData->NumberOfProcessors; - GuidHob = GetNextGuidHob (&gMpInformation2HobGuid, GET_NEXT_HOB (GuidHob)); - } - - ASSERT (*NumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); - - // - // If support CPU hot plug, we need to allocate resources for possibly hot-added processors - // - if (FeaturePcdGet (PcdCpuHotPlugSupport)) { - *MaxNumberOfCpus = PcdGet32 (PcdCpuMaxLogicalProcessorNumber); - } else { - *MaxNumberOfCpus = *NumberOfCpus; - } - - MpInfo2Hobs = AllocatePool (sizeof (MP_INFORMATION2_HOB_DATA *) * HobCount); - ASSERT (MpInfo2Hobs != NULL); - if (MpInfo2Hobs == NULL) { - return NULL; - } - - // - // Record each MpInformation2Hob pointer in the MpInfo2Hobs. - // The FirstMpInfo2Hob is to speed up this while-loop without - // needing to look for MpInfo2Hob from beginning. - // - GuidHob = FirstMpInfo2Hob; - while (HobIndex < HobCount) { - MpInfo2Hobs[HobIndex++] = GET_GUID_HOB_DATA (GuidHob); - GuidHob = GetNextGuidHob (&gMpInformation2HobGuid, GET_NEXT_HOB (GuidHob)); - } - - ProcessorInfo = (EFI_PROCESSOR_INFORMATION *)AllocatePool (sizeof (EFI_PROCESSOR_INFORMATION) * (*MaxNumberOfCpus)); - ASSERT (ProcessorInfo != NULL); - if (ProcessorInfo == NULL) { - FreePool (MpInfo2Hobs); - return NULL; - } - - QuickSort (MpInfo2Hobs, HobCount, sizeof (MP_INFORMATION2_HOB_DATA *), (BASE_SORT_COMPARE)MpInformation2HobCompare, &SortBuffer); - PrevProcessorIndex = 0; - for (HobIndex = 0; HobIndex < HobCount; HobIndex++) { - // - // Make sure no overlap and no gap in the CPU range covered by each HOB - // - ASSERT (MpInfo2Hobs[HobIndex]->ProcessorIndex == PrevProcessorIndex); - - // - // Cache each EFI_PROCESSOR_INFORMATION in order. - // - for (ProcessorIndex = 0; ProcessorIndex < MpInfo2Hobs[HobIndex]->NumberOfProcessors; ProcessorIndex++) { - MpInformation2Entry = GET_MP_INFORMATION_ENTRY (MpInfo2Hobs[HobIndex], ProcessorIndex); - CopyMem ( - &ProcessorInfo[PrevProcessorIndex + ProcessorIndex], - &MpInformation2Entry->ProcessorInfo, - sizeof (EFI_PROCESSOR_INFORMATION) - ); - } - - PrevProcessorIndex += MpInfo2Hobs[HobIndex]->NumberOfProcessors; - } - - FreePool (MpInfo2Hobs); - return ProcessorInfo; -} - -/** - The module Entry Point of the CPU SMM driver. - - @param ImageHandle The firmware allocated handle for the EFI image. - @param SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The entry point is executed successfully. - @retval Other Some error occurs when executing this entry point. - -**/ -EFI_STATUS -EFIAPI -PiCpuSmmEntry ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - UINTN Index; - UINTN TileCodeSize; - UINTN TileDataSize; - UINTN TileSize; - UINT8 *Stacks; - VOID *Registration; - UINT32 RegEax; - UINT32 RegEbx; - UINT32 RegEcx; - UINT32 RegEdx; - UINTN FamilyId; - UINTN ModelId; - UINT32 Cr3; - - PERF_FUNCTION_BEGIN (); - - // - // Initialize address fixup - // - PiSmmCpuSmiEntryFixupAddress (); - - // - // Initialize Debug Agent to support source level debug in SMM code - // - InitializeDebugAgent (DEBUG_AGENT_INIT_SMM, &mSmmDebugAgentSupport, NULL); - - // - // Report the start of CPU SMM initialization. - // - REPORT_STATUS_CODE ( - EFI_PROGRESS_CODE, - EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT - ); - - // - // Find out SMRR Base and SMRR Size - // - FindSmramInfo (&mCpuHotPlugData.SmrrBase, &mCpuHotPlugData.SmrrSize); - - // - // Retrive NumberOfProcessors, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from MpInformation2 HOB. - // - gSmmCpuPrivate->ProcessorInfo = GetMpInformation (&mNumberOfCpus, &mMaxNumberOfCpus); - ASSERT (gSmmCpuPrivate->ProcessorInfo != NULL); - - // - // If support CPU hot plug, PcdCpuSmmEnableBspElection should be set to TRUE. - // A constant BSP index makes no sense because it may be hot removed. - // - DEBUG_CODE_BEGIN (); - if (FeaturePcdGet (PcdCpuHotPlugSupport)) { - ASSERT (FeaturePcdGet (PcdCpuSmmEnableBspElection)); - } - - DEBUG_CODE_END (); - - // - // Save the PcdCpuSmmCodeAccessCheckEnable value into a global variable. - // - mSmmCodeAccessCheckEnable = PcdGetBool (PcdCpuSmmCodeAccessCheckEnable); - DEBUG ((DEBUG_INFO, "PcdCpuSmmCodeAccessCheckEnable = %d\n", mSmmCodeAccessCheckEnable)); - - // - // Save the PcdPteMemoryEncryptionAddressOrMask value into a global variable. - // Make sure AddressEncMask is contained to smallest supported address field. - // - mAddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; - DEBUG ((DEBUG_INFO, "mAddressEncMask = 0x%lx\n", mAddressEncMask)); - - gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus = mMaxNumberOfCpus; - - PERF_CODE ( - InitializeMpPerf (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus); - ); - - // - // The CPU save state and code for the SMI entry point are tiled within an SMRAM - // allocated buffer. The minimum size of this buffer for a uniprocessor system - // is 32 KB, because the entry point is SMBASE + 32KB, and CPU save state area - // just below SMBASE + 64KB. If more than one CPU is present in the platform, - // then the SMI entry point and the CPU save state areas can be tiles to minimize - // the total amount SMRAM required for all the CPUs. The tile size can be computed - // by adding the // CPU save state size, any extra CPU specific context, and - // the size of code that must be placed at the SMI entry point to transfer - // control to a C function in the native SMM execution mode. This size is - // rounded up to the nearest power of 2 to give the tile size for a each CPU. - // The total amount of memory required is the maximum number of CPUs that - // platform supports times the tile size. The picture below shows the tiling, - // where m is the number of tiles that fit in 32KB. - // - // +-----------------------------+ <-- 2^n offset from Base of allocated buffer - // | CPU m+1 Save State | - // +-----------------------------+ - // | CPU m+1 Extra Data | - // +-----------------------------+ - // | Padding | - // +-----------------------------+ - // | CPU 2m SMI Entry | - // +#############################+ <-- Base of allocated buffer + 64 KB - // | CPU m-1 Save State | - // +-----------------------------+ - // | CPU m-1 Extra Data | - // +-----------------------------+ - // | Padding | - // +-----------------------------+ - // | CPU 2m-1 SMI Entry | - // +=============================+ <-- 2^n offset from Base of allocated buffer - // | . . . . . . . . . . . . | - // +=============================+ <-- 2^n offset from Base of allocated buffer - // | CPU 2 Save State | - // +-----------------------------+ - // | CPU 2 Extra Data | - // +-----------------------------+ - // | Padding | - // +-----------------------------+ - // | CPU m+1 SMI Entry | - // +=============================+ <-- Base of allocated buffer + 32 KB - // | CPU 1 Save State | - // +-----------------------------+ - // | CPU 1 Extra Data | - // +-----------------------------+ - // | Padding | - // +-----------------------------+ - // | CPU m SMI Entry | - // +#############################+ <-- Base of allocated buffer + 32 KB == CPU 0 SMBASE + 64 KB - // | CPU 0 Save State | - // +-----------------------------+ - // | CPU 0 Extra Data | - // +-----------------------------+ - // | Padding | - // +-----------------------------+ - // | CPU m-1 SMI Entry | - // +=============================+ <-- 2^n offset from Base of allocated buffer - // | . . . . . . . . . . . . | - // +=============================+ <-- 2^n offset from Base of allocated buffer - // | Padding | - // +-----------------------------+ - // | CPU 1 SMI Entry | - // +=============================+ <-- 2^n offset from Base of allocated buffer - // | Padding | - // +-----------------------------+ - // | CPU 0 SMI Entry | - // +#############################+ <-- Base of allocated buffer == CPU 0 SMBASE + 32 KB - // - - // - // Retrieve CPU Family - // - AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL); - FamilyId = (RegEax >> 8) & 0xf; - ModelId = (RegEax >> 4) & 0xf; - if ((FamilyId == 0x06) || (FamilyId == 0x0f)) { - ModelId = ModelId | ((RegEax >> 12) & 0xf0); - } - - RegEdx = 0; - AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); - if (RegEax >= CPUID_EXTENDED_CPU_SIG) { - AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx); - } - - // - // Determine the mode of the CPU at the time an SMI occurs - // Intel(R) 64 and IA-32 Architectures Software Developer's Manual - // Volume 3C, Section 34.4.1.1 - // - mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT; - if ((RegEdx & BIT29) != 0) { - mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT; - } - - if (FamilyId == 0x06) { - if ((ModelId == 0x17) || (ModelId == 0x0f) || (ModelId == 0x1c)) { - mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT; - } - } - - DEBUG ((DEBUG_INFO, "PcdControlFlowEnforcementPropertyMask = %d\n", PcdGet32 (PcdControlFlowEnforcementPropertyMask))); - if (PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) { - AsmCpuid (CPUID_SIGNATURE, &RegEax, NULL, NULL, NULL); - if (RegEax >= CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS) { - AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, NULL, NULL, &RegEcx, &RegEdx); - DEBUG ((DEBUG_INFO, "CPUID[7/0] ECX - 0x%08x\n", RegEcx)); - DEBUG ((DEBUG_INFO, " CET_SS - 0x%08x\n", RegEcx & CPUID_CET_SS)); - DEBUG ((DEBUG_INFO, " CET_IBT - 0x%08x\n", RegEdx & CPUID_CET_IBT)); - if ((RegEcx & CPUID_CET_SS) == 0) { - mCetSupported = FALSE; - PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); - } - - if (mCetSupported) { - AsmCpuidEx (CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF, NULL, &RegEbx, &RegEcx, NULL); - DEBUG ((DEBUG_INFO, "CPUID[D/1] EBX - 0x%08x, ECX - 0x%08x\n", RegEbx, RegEcx)); - AsmCpuidEx (CPUID_EXTENDED_STATE, 11, &RegEax, NULL, &RegEcx, NULL); - DEBUG ((DEBUG_INFO, "CPUID[D/11] EAX - 0x%08x, ECX - 0x%08x\n", RegEax, RegEcx)); - AsmCpuidEx (CPUID_EXTENDED_STATE, 12, &RegEax, NULL, &RegEcx, NULL); - DEBUG ((DEBUG_INFO, "CPUID[D/12] EAX - 0x%08x, ECX - 0x%08x\n", RegEax, RegEcx)); - } - } else { - mCetSupported = FALSE; - PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); - } - } else { - mCetSupported = FALSE; - PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); - } - - // - // Compute tile size of buffer required to hold the CPU SMRAM Save State Map, extra CPU - // specific context start starts at SMBASE + SMM_PSD_OFFSET, and the SMI entry point. - // This size is rounded up to nearest power of 2. - // - TileCodeSize = GetSmiHandlerSize (); - TileCodeSize = ALIGN_VALUE (TileCodeSize, SIZE_4KB); - TileDataSize = (SMRAM_SAVE_STATE_MAP_OFFSET - SMM_PSD_OFFSET) + sizeof (SMRAM_SAVE_STATE_MAP); - TileDataSize = ALIGN_VALUE (TileDataSize, SIZE_4KB); - TileSize = TileDataSize + TileCodeSize - 1; - TileSize = 2 * GetPowerOfTwo32 ((UINT32)TileSize); - DEBUG ((DEBUG_INFO, "SMRAM TileSize = 0x%08x (0x%08x, 0x%08x)\n", TileSize, TileCodeSize, TileDataSize)); - - // - // If the TileSize is larger than space available for the SMI Handler of - // CPU[i], the extra CPU specific context of CPU[i+1], and the SMRAM Save - // State Map of CPU[i+1], then ASSERT(). If this ASSERT() is triggered, then - // the SMI Handler size must be reduced or the size of the extra CPU specific - // context must be reduced. - // - ASSERT (TileSize <= (SMRAM_SAVE_STATE_MAP_OFFSET + sizeof (SMRAM_SAVE_STATE_MAP) - SMM_HANDLER_OFFSET)); - - // - // Check whether the Required TileSize is enough. - // - if (TileSize > SIZE_8KB) { - DEBUG ((DEBUG_ERROR, "The Range of Smbase in SMRAM is not enough -- Required TileSize = 0x%08x, Actual TileSize = 0x%08x\n", TileSize, SIZE_8KB)); - FreePool (gSmmCpuPrivate->ProcessorInfo); - CpuDeadLoop (); - return RETURN_BUFFER_TOO_SMALL; - } - - // - // Retrieve the allocated SmmBase from gSmmBaseHobGuid. If found, - // means the SmBase relocation has been done. - // - mCpuHotPlugData.SmBase = NULL; - Status = GetSmBase (mMaxNumberOfCpus, &mCpuHotPlugData.SmBase); - ASSERT (!EFI_ERROR (Status)); - if (EFI_ERROR (Status)) { - CpuDeadLoop (); - } - - // - // ASSERT SmBase has been relocated. - // - ASSERT (mCpuHotPlugData.SmBase != NULL); - - // - // Allocate buffer for pointers to array in SMM_CPU_PRIVATE_DATA. - // - gSmmCpuPrivate->Operation = (SMM_CPU_OPERATION *)AllocatePool (sizeof (SMM_CPU_OPERATION) * mMaxNumberOfCpus); - ASSERT (gSmmCpuPrivate->Operation != NULL); - - gSmmCpuPrivate->CpuSaveStateSize = (UINTN *)AllocatePool (sizeof (UINTN) * mMaxNumberOfCpus); - ASSERT (gSmmCpuPrivate->CpuSaveStateSize != NULL); - - gSmmCpuPrivate->CpuSaveState = (VOID **)AllocatePool (sizeof (VOID *) * mMaxNumberOfCpus); - ASSERT (gSmmCpuPrivate->CpuSaveState != NULL); - - mSmmCpuPrivateData.SmmCoreEntryContext.CpuSaveStateSize = gSmmCpuPrivate->CpuSaveStateSize; - mSmmCpuPrivateData.SmmCoreEntryContext.CpuSaveState = gSmmCpuPrivate->CpuSaveState; - - // - // Allocate buffer for pointers to array in CPU_HOT_PLUG_DATA. - // - mCpuHotPlugData.ApicId = (UINT64 *)AllocatePool (sizeof (UINT64) * mMaxNumberOfCpus); - ASSERT (mCpuHotPlugData.ApicId != NULL); - mCpuHotPlugData.ArrayLength = (UINT32)mMaxNumberOfCpus; - - // - // Retrieve APIC ID of each enabled processor from the MP Services protocol. - // Also compute the SMBASE address, CPU Save State address, and CPU Save state - // size for each CPU in the platform - // - for (Index = 0; Index < mMaxNumberOfCpus; Index++) { - gSmmCpuPrivate->CpuSaveStateSize[Index] = sizeof (SMRAM_SAVE_STATE_MAP); - gSmmCpuPrivate->CpuSaveState[Index] = (VOID *)(mCpuHotPlugData.SmBase[Index] + SMRAM_SAVE_STATE_MAP_OFFSET); - gSmmCpuPrivate->Operation[Index] = SmmCpuNone; - - if (Index < mNumberOfCpus) { - mCpuHotPlugData.ApicId[Index] = gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId; - - DEBUG (( - DEBUG_INFO, - "CPU[%03x] APIC ID=%04x SMBASE=%08x SaveState=%08x Size=%08x\n", - Index, - (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId, - mCpuHotPlugData.SmBase[Index], - gSmmCpuPrivate->CpuSaveState[Index], - gSmmCpuPrivate->CpuSaveStateSize[Index] - )); - } else { - gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId = INVALID_APIC_ID; - mCpuHotPlugData.ApicId[Index] = INVALID_APIC_ID; - } - } - - // - // Allocate SMI stacks for all processors. - // - mSmmStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmStackSize))); - if (FeaturePcdGet (PcdCpuSmmStackGuard)) { - // - // SMM Stack Guard Enabled - // 2 more pages is allocated for each processor, one is guard page and the other is known good stack. - // - // +--------------------------------------------------+-----+--------------------------------------------------+ - // | Known Good Stack | Guard Page | SMM Stack | ... | Known Good Stack | Guard Page | SMM Stack | - // +--------------------------------------------------+-----+--------------------------------------------------+ - // | 4K | 4K PcdCpuSmmStackSize| | 4K | 4K PcdCpuSmmStackSize| - // |<---------------- mSmmStackSize ----------------->| |<---------------- mSmmStackSize ----------------->| - // | | | | - // |<------------------ Processor 0 ----------------->| |<------------------ Processor n ----------------->| - // - mSmmStackSize += EFI_PAGES_TO_SIZE (2); - } - - mSmmShadowStackSize = 0; - if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) { - mSmmShadowStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmShadowStackSize))); - - if (FeaturePcdGet (PcdCpuSmmStackGuard)) { - // - // SMM Stack Guard Enabled - // Append Shadow Stack after normal stack - // 2 more pages is allocated for each processor, one is guard page and the other is known good shadow stack. - // - // |= Stacks - // +--------------------------------------------------+---------------------------------------------------------------+ - // | Known Good Stack | Guard Page | SMM Stack | Known Good Shadow Stack | Guard Page | SMM Shadow Stack | - // +--------------------------------------------------+---------------------------------------------------------------+ - // | 4K | 4K |PcdCpuSmmStackSize| 4K | 4K |PcdCpuSmmShadowStackSize| - // |<---------------- mSmmStackSize ----------------->|<--------------------- mSmmShadowStackSize ------------------->| - // | | - // |<-------------------------------------------- Processor N ------------------------------------------------------->| - // - mSmmShadowStackSize += EFI_PAGES_TO_SIZE (2); - } else { - // - // SMM Stack Guard Disabled (Known Good Stack is still required for potential stack switch.) - // Append Shadow Stack after normal stack with 1 more page as known good shadow stack. - // 1 more pages is allocated for each processor, it is known good stack. - // - // - // |= Stacks - // +-------------------------------------+--------------------------------------------------+ - // | Known Good Stack | SMM Stack | Known Good Shadow Stack | SMM Shadow Stack | - // +-------------------------------------+--------------------------------------------------+ - // | 4K |PcdCpuSmmStackSize| 4K |PcdCpuSmmShadowStackSize| - // |<---------- mSmmStackSize ---------->|<--------------- mSmmShadowStackSize ------------>| - // | | - // |<-------------------------------- Processor N ----------------------------------------->| - // - mSmmShadowStackSize += EFI_PAGES_TO_SIZE (1); - mSmmStackSize += EFI_PAGES_TO_SIZE (1); - } - } - - Stacks = (UINT8 *)AllocatePages (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * (EFI_SIZE_TO_PAGES (mSmmStackSize + mSmmShadowStackSize))); - ASSERT (Stacks != NULL); - mSmmStackArrayBase = (UINTN)Stacks; - mSmmStackArrayEnd = mSmmStackArrayBase + gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * (mSmmStackSize + mSmmShadowStackSize) - 1; - - DEBUG ((DEBUG_INFO, "Stacks - 0x%x\n", Stacks)); - DEBUG ((DEBUG_INFO, "mSmmStackSize - 0x%x\n", mSmmStackSize)); - DEBUG ((DEBUG_INFO, "PcdCpuSmmStackGuard - 0x%x\n", FeaturePcdGet (PcdCpuSmmStackGuard))); - if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) { - DEBUG ((DEBUG_INFO, "mSmmShadowStackSize - 0x%x\n", mSmmShadowStackSize)); - } - - // - // Initialize IDT - // - InitializeSmmIdt (); - - // - // SMM Time initialization - // - InitializeSmmTimer (); - - // - // Initialize MP globals - // - Cr3 = InitializeMpServiceData (Stacks, mSmmStackSize, mSmmShadowStackSize); - - if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) { - for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) { - SetShadowStack ( - Cr3, - (EFI_PHYSICAL_ADDRESS)(UINTN)Stacks + mSmmStackSize + (mSmmStackSize + mSmmShadowStackSize) * Index, - mSmmShadowStackSize - ); - if (FeaturePcdGet (PcdCpuSmmStackGuard)) { - ConvertMemoryPageAttributes ( - Cr3, - mPagingMode, - (EFI_PHYSICAL_ADDRESS)(UINTN)Stacks + mSmmStackSize + EFI_PAGES_TO_SIZE (1) + (mSmmStackSize + mSmmShadowStackSize) * Index, - EFI_PAGES_TO_SIZE (1), - EFI_MEMORY_RP, - TRUE, - NULL - ); - } - } - } - - // - // For relocated SMBASE, some MSRs & CSRs are still required to be configured in SMM Mode for SMM Initialization. - // Those MSRs & CSRs must be configured before normal SMI sources happen. - // So, here is to issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init. - // - ExecuteFirstSmiInit (); - - // - // Call hook for BSP to perform extra actions in normal mode after all - // SMM base addresses have been relocated on all CPUs - // - SmmCpuFeaturesSmmRelocationComplete (); - - DEBUG ((DEBUG_INFO, "mXdSupported - 0x%x\n", mXdSupported)); - - // - // Fill in SMM Reserved Regions - // - gSmmCpuPrivate->SmmReservedSmramRegion[0].SmramReservedStart = 0; - gSmmCpuPrivate->SmmReservedSmramRegion[0].SmramReservedSize = 0; + ASSERT_EFI_ERROR (Status); // // Install the SMM Configuration Protocol onto a new handle on the handle database. @@ -1286,49 +133,6 @@ PiCpuSmmEntry ( ); ASSERT_EFI_ERROR (Status); - // - // Install the SMM CPU Protocol into SMM protocol database - // - Status = gMmst->MmInstallProtocolInterface ( - &mSmmCpuHandle, - &gEfiSmmCpuProtocolGuid, - EFI_NATIVE_INTERFACE, - &mSmmCpu - ); - ASSERT_EFI_ERROR (Status); - - // - // Install the SMM Memory Attribute Protocol into SMM protocol database - // - Status = gMmst->MmInstallProtocolInterface ( - &mSmmCpuHandle, - &gEdkiiSmmMemoryAttributeProtocolGuid, - EFI_NATIVE_INTERFACE, - &mSmmMemoryAttribute - ); - ASSERT_EFI_ERROR (Status); - - // - // Initialize global buffer for MM MP. - // - InitializeDataForMmMp (); - - // - // Initialize Package First Thread Index Info. - // - InitPackageFirstThreadIndexInfo (); - - // - // Install the SMM Mp Protocol into SMM protocol database - // - Status = gMmst->MmInstallProtocolInterface ( - &mSmmCpuHandle, - &gEfiMmMpProtocolGuid, - EFI_NATIVE_INTERFACE, - &mSmmMp - ); - ASSERT_EFI_ERROR (Status); - // // Expose address of CPU Hot Plug Data structure if CPU hot plug is supported. // @@ -1337,409 +141,5 @@ PiCpuSmmEntry ( ASSERT_EFI_ERROR (Status); } - // - // Initialize SMM CPU Services Support - // - Status = InitializeSmmCpuServices (mSmmCpuHandle); - ASSERT_EFI_ERROR (Status); - - // - // register SMM Ready To Lock Protocol notification - // - Status = gMmst->MmRegisterProtocolNotify ( - &gEfiSmmReadyToLockProtocolGuid, - SmmReadyToLockEventNotify, - &Registration - ); - ASSERT_EFI_ERROR (Status); - - // - // Initialize SMM Profile feature - // - InitSmmProfile (Cr3); - - GetAcpiS3EnableFlag (); - InitSmmS3ResumeState (); - - DEBUG ((DEBUG_INFO, "SMM CPU Module exit from SMRAM with EFI_SUCCESS\n")); - - PERF_FUNCTION_END (); - return EFI_SUCCESS; -} - -/** - Function to compare 2 EFI_SMRAM_DESCRIPTOR based on CpuStart. - - @param[in] Buffer1 pointer to Device Path poiner to compare - @param[in] Buffer2 pointer to second DevicePath pointer to compare - - @retval 0 Buffer1 equal to Buffer2 - @retval <0 Buffer1 is less than Buffer2 - @retval >0 Buffer1 is greater than Buffer2 -**/ -INTN -EFIAPI -CpuSmramRangeCompare ( - IN CONST VOID *Buffer1, - IN CONST VOID *Buffer2 - ) -{ - if (((EFI_SMRAM_DESCRIPTOR *)Buffer1)->CpuStart > ((EFI_SMRAM_DESCRIPTOR *)Buffer2)->CpuStart) { - return 1; - } else if (((EFI_SMRAM_DESCRIPTOR *)Buffer1)->CpuStart < ((EFI_SMRAM_DESCRIPTOR *)Buffer2)->CpuStart) { - return -1; - } - - return 0; -} - -/** - - Find out SMRAM information including SMRR base and SMRR size. - - @param SmrrBase SMRR base - @param SmrrSize SMRR size - -**/ -VOID -FindSmramInfo ( - OUT UINT32 *SmrrBase, - OUT UINT32 *SmrrSize - ) -{ - EFI_STATUS Status; - UINTN Size; - EFI_SMM_ACCESS2_PROTOCOL *SmmAccess; - EFI_SMRAM_DESCRIPTOR *CurrentSmramRange; - UINTN Index; - UINT64 MaxSize; - BOOLEAN Found; - EFI_SMRAM_DESCRIPTOR SmramDescriptor; - - // - // Get SMM Access Protocol - // - Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess); - ASSERT_EFI_ERROR (Status); - - // - // Get SMRAM information - // - Size = 0; - Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); - - mSmmCpuSmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocatePool (Size); - ASSERT (mSmmCpuSmramRanges != NULL); - - Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmmCpuSmramRanges); - ASSERT_EFI_ERROR (Status); - - mSmmCpuSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR); - - // - // Sort the mSmmCpuSmramRanges - // - QuickSort (mSmmCpuSmramRanges, mSmmCpuSmramRangeCount, sizeof (EFI_SMRAM_DESCRIPTOR), (BASE_SORT_COMPARE)CpuSmramRangeCompare, &SmramDescriptor); - - // - // Find the largest SMRAM range between 1MB and 4GB that is at least 256K - 4K in size - // - CurrentSmramRange = NULL; - for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < mSmmCpuSmramRangeCount; Index++) { - // - // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization - // - if ((mSmmCpuSmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) { - continue; - } - - if (mSmmCpuSmramRanges[Index].CpuStart >= BASE_1MB) { - if ((mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize) <= SMRR_MAX_ADDRESS) { - if (mSmmCpuSmramRanges[Index].PhysicalSize >= MaxSize) { - MaxSize = mSmmCpuSmramRanges[Index].PhysicalSize; - CurrentSmramRange = &mSmmCpuSmramRanges[Index]; - } - } - } - } - - ASSERT (CurrentSmramRange != NULL); - - *SmrrBase = (UINT32)CurrentSmramRange->CpuStart; - *SmrrSize = (UINT32)CurrentSmramRange->PhysicalSize; - - do { - Found = FALSE; - for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) { - if ((mSmmCpuSmramRanges[Index].CpuStart < *SmrrBase) && - (*SmrrBase == (mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize))) - { - *SmrrBase = (UINT32)mSmmCpuSmramRanges[Index].CpuStart; - *SmrrSize = (UINT32)(*SmrrSize + mSmmCpuSmramRanges[Index].PhysicalSize); - Found = TRUE; - } else if (((*SmrrBase + *SmrrSize) == mSmmCpuSmramRanges[Index].CpuStart) && (mSmmCpuSmramRanges[Index].PhysicalSize > 0)) { - *SmrrSize = (UINT32)(*SmrrSize + mSmmCpuSmramRanges[Index].PhysicalSize); - Found = TRUE; - } - } - } while (Found); - - DEBUG ((DEBUG_INFO, "SMRR Base: 0x%x, SMRR Size: 0x%x\n", *SmrrBase, *SmrrSize)); -} - -/** -Configure SMM Code Access Check feature on an AP. -SMM Feature Control MSR will be locked after configuration. - -@param[in,out] Buffer Pointer to private data buffer. -**/ -VOID -EFIAPI -ConfigSmmCodeAccessCheckOnCurrentProcessor ( - IN OUT VOID *Buffer - ) -{ - UINTN CpuIndex; - UINT64 SmmFeatureControlMsr; - UINT64 NewSmmFeatureControlMsr; - - // - // Retrieve the CPU Index from the context passed in - // - CpuIndex = *(UINTN *)Buffer; - - // - // Get the current SMM Feature Control MSR value - // - SmmFeatureControlMsr = SmmCpuFeaturesGetSmmRegister (CpuIndex, SmmRegFeatureControl); - - // - // Compute the new SMM Feature Control MSR value - // - NewSmmFeatureControlMsr = SmmFeatureControlMsr; - if (mSmmCodeAccessCheckEnable) { - NewSmmFeatureControlMsr |= SMM_CODE_CHK_EN_BIT; - if (FeaturePcdGet (PcdCpuSmmFeatureControlMsrLock)) { - NewSmmFeatureControlMsr |= SMM_FEATURE_CONTROL_LOCK_BIT; - } - } - - // - // Only set the SMM Feature Control MSR value if the new value is different than the current value - // - if (NewSmmFeatureControlMsr != SmmFeatureControlMsr) { - SmmCpuFeaturesSetSmmRegister (CpuIndex, SmmRegFeatureControl, NewSmmFeatureControlMsr); - } - - // - // Release the spin lock user to serialize the updates to the SMM Feature Control MSR - // - ReleaseSpinLock (mConfigSmmCodeAccessCheckLock); -} - -/** -Configure SMM Code Access Check feature for all processors. -SMM Feature Control MSR will be locked after configuration. -**/ -VOID -ConfigSmmCodeAccessCheck ( - VOID - ) -{ - UINTN Index; - EFI_STATUS Status; - - PERF_FUNCTION_BEGIN (); - - // - // Check to see if the Feature Control MSR is supported on this CPU - // - Index = gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu; - if (!SmmCpuFeaturesIsSmmRegisterSupported (Index, SmmRegFeatureControl)) { - mSmmCodeAccessCheckEnable = FALSE; - PERF_FUNCTION_END (); - return; - } - - // - // Check to see if the CPU supports the SMM Code Access Check feature - // Do not access this MSR unless the CPU supports the SmmRegFeatureControl - // - if ((AsmReadMsr64 (EFI_MSR_SMM_MCA_CAP) & SMM_CODE_ACCESS_CHK_BIT) == 0) { - mSmmCodeAccessCheckEnable = FALSE; - PERF_FUNCTION_END (); - return; - } - - // - // Initialize the lock used to serialize the MSR programming in BSP and all APs - // - InitializeSpinLock (mConfigSmmCodeAccessCheckLock); - - // - // Acquire Config SMM Code Access Check spin lock. The BSP will release the - // spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor(). - // - AcquireSpinLock (mConfigSmmCodeAccessCheckLock); - - // - // Enable SMM Code Access Check feature on the BSP. - // - ConfigSmmCodeAccessCheckOnCurrentProcessor (&Index); - - // - // Enable SMM Code Access Check feature for the APs. - // - for (Index = 0; Index < gMmst->NumberOfCpus; Index++) { - if (Index != gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu) { - if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == INVALID_APIC_ID) { - // - // If this processor does not exist - // - continue; - } - - // - // Acquire Config SMM Code Access Check spin lock. The AP will release the - // spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor(). - // - AcquireSpinLock (mConfigSmmCodeAccessCheckLock); - - // - // Call SmmStartupThisAp() to enable SMM Code Access Check on an AP. - // - Status = gMmst->MmStartupThisAp (ConfigSmmCodeAccessCheckOnCurrentProcessor, Index, &Index); - ASSERT_EFI_ERROR (Status); - - // - // Wait for the AP to release the Config SMM Code Access Check spin lock. - // - while (!AcquireSpinLockOrFail (mConfigSmmCodeAccessCheckLock)) { - CpuPause (); - } - - // - // Release the Config SMM Code Access Check spin lock. - // - ReleaseSpinLock (mConfigSmmCodeAccessCheckLock); - } - } - - PERF_FUNCTION_END (); -} - -/** - Allocate pages for code. - - @param[in] Pages Number of pages to be allocated. - - @return Allocated memory. -**/ -VOID * -AllocateCodePages ( - IN UINTN Pages - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - - if (Pages == 0) { - return NULL; - } - - Status = gMmst->MmAllocatePages (AllocateAnyPages, EfiRuntimeServicesCode, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - -/** - Perform the remaining tasks. - -**/ -VOID -PerformRemainingTasks ( - VOID - ) -{ - if (mSmmReadyToLock) { - PERF_FUNCTION_BEGIN (); - - // - // Check if all Aps enter SMM. In Relaxed-AP Sync Mode, BSP will not wait for - // all Aps arrive. However,PerformRemainingTasks() needs to wait all Aps arrive before calling - // SetMemMapAttributes() and ConfigSmmCodeAccessCheck() when mSmmReadyToLock - // is true. In SetMemMapAttributes(), SmmSetMemoryAttributesEx() will call - // FlushTlbForAll() that need to start up the aps. So it need to let all - // aps arrive. Same as SetMemMapAttributes(), ConfigSmmCodeAccessCheck() - // also will start up the aps. - // - if (EFI_ERROR (SmmCpuRendezvous (NULL, TRUE))) { - DEBUG ((DEBUG_ERROR, "PerformRemainingTasks: fail to wait for all AP check in SMM!\n")); - } - - // - // Start SMM Profile feature - // - if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { - SmmProfileStart (); - } - - // - // Create a mix of 2MB and 4KB page table. Update some memory ranges absent and execute-disable. - // - InitPaging (); - - // - // Mark critical region to be read-only in page table - // - SetMemMapAttributes (); - - if (IsRestrictedMemoryAccess ()) { - // - // For outside SMRAM, we only map SMM communication buffer or MMIO. - // - SetUefiMemMapAttributes (); - - // - // Set page table itself to be read-only - // - SetPageTableAttributes (); - } - - // - // Configure SMM Code Access Check feature if available. - // - ConfigSmmCodeAccessCheck (); - - // - // Measure performance of SmmCpuFeaturesCompleteSmmReadyToLock() from caller side - // as the implementation is provided by platform. - // - PERF_START (NULL, "SmmCompleteReadyToLock", NULL, 0); - SmmCpuFeaturesCompleteSmmReadyToLock (); - PERF_END (NULL, "SmmCompleteReadyToLock", NULL, 0); - - // - // Clean SMM ready to lock flag - // - mSmmReadyToLock = FALSE; - - PERF_FUNCTION_END (); - } -} - -/** - Perform the pre tasks. - -**/ -VOID -PerformPreTasks ( - VOID - ) -{ - RestoreSmmConfigurationInS3 (); + return Status; } diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf index e449880a58ee..56349a771e0c 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -30,6 +30,7 @@ [Sources] PiSmmCpuDxeSmm.c + PiSmmCpuCommon.c PiSmmCpuCommon.h MpService.c SyncTimer.c From 8ccf7f65e5e3276e2bad06419134759c02107e75 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 24 Jun 2024 20:24:30 +0800 Subject: [PATCH 063/280] UefiCpuPkg/PiSmmCpuDxeSmm: Centralize Non-Mmram Mem Management Code Centralize the SMM Non-Mmram Memory Management related code into the NonMmramMapDxeSmm.c. The file SmmCpuMemoryManagement.c will be target to use for both SMM and MM in subsequent patches. No function impact. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c | 488 ++++++++++++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 1 + .../PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 477 ----------------- 3 files changed, 489 insertions(+), 477 deletions(-) create mode 100644 UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c new file mode 100644 index 000000000000..d188b11a9679 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c @@ -0,0 +1,488 @@ +/** @file + +Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuCommon.h" +#include +#include +#include + +// +// attributes for reserved memory before it is promoted to system memory +// +#define EFI_MEMORY_PRESENT 0x0100000000000000ULL +#define EFI_MEMORY_INITIALIZED 0x0200000000000000ULL +#define EFI_MEMORY_TESTED 0x0400000000000000ULL + +#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ + ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size))) + +EFI_MEMORY_DESCRIPTOR *mUefiMemoryMap; +UINTN mUefiMemoryMapSize; +UINTN mUefiDescriptorSize; + +EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mGcdMemSpace = NULL; +UINTN mGcdMemNumberOfDesc = 0; + +EFI_MEMORY_ATTRIBUTES_TABLE *mUefiMemoryAttributesTable = NULL; + +/** + Sort memory map entries based upon PhysicalStart, from low to high. + + @param MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param MemoryMapSize Size, in bytes, of the MemoryMap buffer. + @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. +**/ +STATIC +VOID +SortMemoryMap ( + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize + ) +{ + EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; + EFI_MEMORY_DESCRIPTOR TempMemoryMap; + + MemoryMapEntry = MemoryMap; + NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize); + while (MemoryMapEntry < MemoryMapEnd) { + while (NextMemoryMapEntry < MemoryMapEnd) { + if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) { + CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); + CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); + CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DESCRIPTOR)); + } + + NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); + } + + MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + } +} + +/** + Return if a UEFI memory page should be marked as not present in SMM page table. + If the memory map entries type is + EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory, + EfiUnusableMemory, EfiACPIReclaimMemory, return TRUE. + Or return FALSE. + + @param[in] MemoryMap A pointer to the memory descriptor. + + @return TRUE The memory described will be marked as not present in SMM page table. + @return FALSE The memory described will not be marked as not present in SMM page table. +**/ +BOOLEAN +IsUefiPageNotPresent ( + IN EFI_MEMORY_DESCRIPTOR *MemoryMap + ) +{ + switch (MemoryMap->Type) { + case EfiLoaderCode: + case EfiLoaderData: + case EfiBootServicesCode: + case EfiBootServicesData: + case EfiConventionalMemory: + case EfiUnusableMemory: + case EfiACPIReclaimMemory: + return TRUE; + default: + return FALSE; + } +} + +/** + Merge continuous memory map entries whose type is + EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory, + EfiUnusableMemory, EfiACPIReclaimMemory, because the memory described by + these entries will be set as NOT present in SMM page table. + + @param[in, out] MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the current memory map. On output, + it is the size of new memory map after merge. + @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. +**/ +STATIC +VOID +MergeMemoryMapForNotPresentEntry ( + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN OUT UINTN *MemoryMapSize, + IN UINTN DescriptorSize + ) +{ + EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; + UINT64 MemoryBlockLength; + EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; + + MemoryMapEntry = MemoryMap; + NewMemoryMapEntry = MemoryMap; + MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + *MemoryMapSize); + while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { + CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); + NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + + do { + MemoryBlockLength = (UINT64)(EFI_PAGES_TO_SIZE ((UINTN)MemoryMapEntry->NumberOfPages)); + if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) && + IsUefiPageNotPresent (MemoryMapEntry) && IsUefiPageNotPresent (NextMemoryMapEntry) && + ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart)) + { + MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; + if (NewMemoryMapEntry != MemoryMapEntry) { + NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; + } + + NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); + continue; + } else { + MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); + break; + } + } while (TRUE); + + MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize); + } + + *MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap; + + return; +} + +/** + This function caches the GCD memory map information. +**/ +VOID +GetGcdMemoryMap ( + VOID + ) +{ + UINTN NumberOfDescriptors; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemSpaceMap; + EFI_STATUS Status; + UINTN Index; + + Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap); + if (EFI_ERROR (Status)) { + return; + } + + mGcdMemNumberOfDesc = 0; + for (Index = 0; Index < NumberOfDescriptors; Index++) { + if ((MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved) && + ((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) == + (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)) + ) + { + mGcdMemNumberOfDesc++; + } + } + + mGcdMemSpace = AllocateZeroPool (mGcdMemNumberOfDesc * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR)); + ASSERT (mGcdMemSpace != NULL); + if (mGcdMemSpace == NULL) { + mGcdMemNumberOfDesc = 0; + gBS->FreePool (MemSpaceMap); + return; + } + + mGcdMemNumberOfDesc = 0; + for (Index = 0; Index < NumberOfDescriptors; Index++) { + if ((MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved) && + ((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) == + (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)) + ) + { + CopyMem ( + &mGcdMemSpace[mGcdMemNumberOfDesc], + &MemSpaceMap[Index], + sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR) + ); + mGcdMemNumberOfDesc++; + } + } + + gBS->FreePool (MemSpaceMap); +} + +/** + Get UEFI MemoryAttributesTable. +**/ +VOID +GetUefiMemoryAttributesTable ( + VOID + ) +{ + EFI_STATUS Status; + EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; + UINTN MemoryAttributesTableSize; + + Status = EfiGetSystemConfigurationTable (&gEfiMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable); + if (!EFI_ERROR (Status) && (MemoryAttributesTable != NULL)) { + MemoryAttributesTableSize = sizeof (EFI_MEMORY_ATTRIBUTES_TABLE) + MemoryAttributesTable->DescriptorSize * MemoryAttributesTable->NumberOfEntries; + mUefiMemoryAttributesTable = AllocateCopyPool (MemoryAttributesTableSize, MemoryAttributesTable); + ASSERT (mUefiMemoryAttributesTable != NULL); + } +} + +/** + This function caches the UEFI memory map information. +**/ +VOID +GetUefiMemoryMap ( + VOID + ) +{ + EFI_STATUS Status; + UINTN MapKey; + UINT32 DescriptorVersion; + EFI_MEMORY_DESCRIPTOR *MemoryMap; + UINTN UefiMemoryMapSize; + + DEBUG ((DEBUG_INFO, "GetUefiMemoryMap\n")); + + UefiMemoryMapSize = 0; + MemoryMap = NULL; + Status = gBS->GetMemoryMap ( + &UefiMemoryMapSize, + MemoryMap, + &MapKey, + &mUefiDescriptorSize, + &DescriptorVersion + ); + ASSERT (Status == EFI_BUFFER_TOO_SMALL); + + do { + Status = gBS->AllocatePool (EfiBootServicesData, UefiMemoryMapSize, (VOID **)&MemoryMap); + ASSERT (MemoryMap != NULL); + if (MemoryMap == NULL) { + return; + } + + Status = gBS->GetMemoryMap ( + &UefiMemoryMapSize, + MemoryMap, + &MapKey, + &mUefiDescriptorSize, + &DescriptorVersion + ); + if (EFI_ERROR (Status)) { + gBS->FreePool (MemoryMap); + MemoryMap = NULL; + } + } while (Status == EFI_BUFFER_TOO_SMALL); + + if (MemoryMap == NULL) { + return; + } + + SortMemoryMap (MemoryMap, UefiMemoryMapSize, mUefiDescriptorSize); + MergeMemoryMapForNotPresentEntry (MemoryMap, &UefiMemoryMapSize, mUefiDescriptorSize); + + mUefiMemoryMapSize = UefiMemoryMapSize; + mUefiMemoryMap = AllocateCopyPool (UefiMemoryMapSize, MemoryMap); + ASSERT (mUefiMemoryMap != NULL); + + gBS->FreePool (MemoryMap); + + // + // Get additional information from GCD memory map. + // + GetGcdMemoryMap (); + + // + // Get UEFI memory attributes table. + // + GetUefiMemoryAttributesTable (); +} + +/** + This function sets UEFI memory attribute according to UEFI memory map. + + The normal memory region is marked as not present, such as + EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory, + EfiUnusableMemory, EfiACPIReclaimMemory. +**/ +VOID +SetUefiMemMapAttributes ( + VOID + ) +{ + EFI_STATUS Status; + EFI_MEMORY_DESCRIPTOR *MemoryMap; + UINTN MemoryMapEntryCount; + UINTN Index; + EFI_MEMORY_DESCRIPTOR *Entry; + BOOLEAN WriteProtect; + BOOLEAN CetEnabled; + + PERF_FUNCTION_BEGIN (); + + DEBUG ((DEBUG_INFO, "SetUefiMemMapAttributes\n")); + + WRITE_UNPROTECT_RO_PAGES (WriteProtect, CetEnabled); + + if (mUefiMemoryMap != NULL) { + MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize; + MemoryMap = mUefiMemoryMap; + for (Index = 0; Index < MemoryMapEntryCount; Index++) { + if (IsUefiPageNotPresent (MemoryMap)) { + Status = SmmSetMemoryAttributes ( + MemoryMap->PhysicalStart, + EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages), + EFI_MEMORY_RP + ); + DEBUG (( + DEBUG_INFO, + "UefiMemory protection: 0x%lx - 0x%lx %r\n", + MemoryMap->PhysicalStart, + MemoryMap->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages), + Status + )); + } + + MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize); + } + } + + // + // Do not free mUefiMemoryMap, it will be checked in IsSmmCommBufferForbiddenAddress(). + // + + // + // Set untested memory as not present. + // + if (mGcdMemSpace != NULL) { + for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) { + Status = SmmSetMemoryAttributes ( + mGcdMemSpace[Index].BaseAddress, + mGcdMemSpace[Index].Length, + EFI_MEMORY_RP + ); + DEBUG (( + DEBUG_INFO, + "GcdMemory protection: 0x%lx - 0x%lx %r\n", + mGcdMemSpace[Index].BaseAddress, + mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length, + Status + )); + } + } + + // + // Do not free mGcdMemSpace, it will be checked in IsSmmCommBufferForbiddenAddress(). + // + + // + // Set UEFI runtime memory with EFI_MEMORY_RO as not present. + // + if (mUefiMemoryAttributesTable != NULL) { + Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1); + for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) { + if ((Entry->Type == EfiRuntimeServicesCode) || (Entry->Type == EfiRuntimeServicesData)) { + if ((Entry->Attribute & EFI_MEMORY_RO) != 0) { + Status = SmmSetMemoryAttributes ( + Entry->PhysicalStart, + EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages), + EFI_MEMORY_RP + ); + DEBUG (( + DEBUG_INFO, + "UefiMemoryAttribute protection: 0x%lx - 0x%lx %r\n", + Entry->PhysicalStart, + Entry->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages), + Status + )); + } + } + + Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize); + } + } + + WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled); + + // + // Do not free mUefiMemoryAttributesTable, it will be checked in IsSmmCommBufferForbiddenAddress(). + // + + PERF_FUNCTION_END (); +} + +/** + Return if the Address is forbidden as SMM communication buffer. + + @param[in] Address the address to be checked + + @return TRUE The address is forbidden as SMM communication buffer. + @return FALSE The address is allowed as SMM communication buffer. +**/ +BOOLEAN +IsSmmCommBufferForbiddenAddress ( + IN UINT64 Address + ) +{ + EFI_MEMORY_DESCRIPTOR *MemoryMap; + UINTN MemoryMapEntryCount; + UINTN Index; + EFI_MEMORY_DESCRIPTOR *Entry; + + if (mUefiMemoryMap != NULL) { + MemoryMap = mUefiMemoryMap; + MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize; + for (Index = 0; Index < MemoryMapEntryCount; Index++) { + if (IsUefiPageNotPresent (MemoryMap)) { + if ((Address >= MemoryMap->PhysicalStart) && + (Address < MemoryMap->PhysicalStart + EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages))) + { + return TRUE; + } + } + + MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize); + } + } + + if (mGcdMemSpace != NULL) { + for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) { + if ((Address >= mGcdMemSpace[Index].BaseAddress) && + (Address < mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length)) + { + return TRUE; + } + } + } + + if (mUefiMemoryAttributesTable != NULL) { + Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1); + for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) { + if ((Entry->Type == EfiRuntimeServicesCode) || (Entry->Type == EfiRuntimeServicesData)) { + if ((Entry->Attribute & EFI_MEMORY_RO) != 0) { + if ((Address >= Entry->PhysicalStart) && + (Address < Entry->PhysicalStart + LShiftU64 (Entry->NumberOfPages, EFI_PAGE_SHIFT))) + { + return TRUE; + } + + Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize); + } + } + } + } + + return FALSE; +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf index 56349a771e0c..d18e9e85f800 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -46,6 +46,7 @@ SmmMp.c SmmMpPerf.h SmmMpPerf.c + NonMmramMapDxeSmm.c [Sources.Ia32] Ia32/PageTbl.c diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c index 4a1bab68ddce..76eaaec98161 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c @@ -7,25 +7,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PiSmmCpuCommon.h" -// -// attributes for reserved memory before it is promoted to system memory -// -#define EFI_MEMORY_PRESENT 0x0100000000000000ULL -#define EFI_MEMORY_INITIALIZED 0x0200000000000000ULL -#define EFI_MEMORY_TESTED 0x0400000000000000ULL - -#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ - ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size))) - -EFI_MEMORY_DESCRIPTOR *mUefiMemoryMap; -UINTN mUefiMemoryMapSize; -UINTN mUefiDescriptorSize; - -EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mGcdMemSpace = NULL; -UINTN mGcdMemNumberOfDesc = 0; - -EFI_MEMORY_ATTRIBUTES_TABLE *mUefiMemoryAttributesTable = NULL; - BOOLEAN mIsShadowStack = FALSE; BOOLEAN m5LevelPagingNeeded = FALSE; PAGING_MODE mPagingMode = PagingModeMax; @@ -1118,464 +1099,6 @@ SetMemMapAttributes ( PERF_FUNCTION_END (); } -/** - Sort memory map entries based upon PhysicalStart, from low to high. - - @param MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param MemoryMapSize Size, in bytes, of the MemoryMap buffer. - @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -STATIC -VOID -SortMemoryMap ( - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; - EFI_MEMORY_DESCRIPTOR TempMemoryMap; - - MemoryMapEntry = MemoryMap; - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize); - while (MemoryMapEntry < MemoryMapEnd) { - while (NextMemoryMapEntry < MemoryMapEnd) { - if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) { - CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); - CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); - CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DESCRIPTOR)); - } - - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); - } - - MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - } -} - -/** - Return if a UEFI memory page should be marked as not present in SMM page table. - If the memory map entries type is - EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory, - EfiUnusableMemory, EfiACPIReclaimMemory, return TRUE. - Or return FALSE. - - @param[in] MemoryMap A pointer to the memory descriptor. - - @return TRUE The memory described will be marked as not present in SMM page table. - @return FALSE The memory described will not be marked as not present in SMM page table. -**/ -BOOLEAN -IsUefiPageNotPresent ( - IN EFI_MEMORY_DESCRIPTOR *MemoryMap - ) -{ - switch (MemoryMap->Type) { - case EfiLoaderCode: - case EfiLoaderData: - case EfiBootServicesCode: - case EfiBootServicesData: - case EfiConventionalMemory: - case EfiUnusableMemory: - case EfiACPIReclaimMemory: - return TRUE; - default: - return FALSE; - } -} - -/** - Merge continuous memory map entries whose type is - EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory, - EfiUnusableMemory, EfiACPIReclaimMemory, because the memory described by - these entries will be set as NOT present in SMM page table. - - @param[in, out] MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - the current memory map. On output, - it is the size of new memory map after merge. - @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -STATIC -VOID -MergeMemoryMapForNotPresentEntry ( - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN OUT UINTN *MemoryMapSize, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; - UINT64 MemoryBlockLength; - EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; - - MemoryMapEntry = MemoryMap; - NewMemoryMapEntry = MemoryMap; - MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + *MemoryMapSize); - while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { - CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - - do { - MemoryBlockLength = (UINT64)(EFI_PAGES_TO_SIZE ((UINTN)MemoryMapEntry->NumberOfPages)); - if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) && - IsUefiPageNotPresent (MemoryMapEntry) && IsUefiPageNotPresent (NextMemoryMapEntry) && - ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart)) - { - MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; - if (NewMemoryMapEntry != MemoryMapEntry) { - NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; - } - - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); - continue; - } else { - MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); - break; - } - } while (TRUE); - - MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize); - } - - *MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap; - - return; -} - -/** - This function caches the GCD memory map information. -**/ -VOID -GetGcdMemoryMap ( - VOID - ) -{ - UINTN NumberOfDescriptors; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemSpaceMap; - EFI_STATUS Status; - UINTN Index; - - Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap); - if (EFI_ERROR (Status)) { - return; - } - - mGcdMemNumberOfDesc = 0; - for (Index = 0; Index < NumberOfDescriptors; Index++) { - if ((MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved) && - ((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) == - (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)) - ) - { - mGcdMemNumberOfDesc++; - } - } - - mGcdMemSpace = AllocateZeroPool (mGcdMemNumberOfDesc * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR)); - ASSERT (mGcdMemSpace != NULL); - if (mGcdMemSpace == NULL) { - mGcdMemNumberOfDesc = 0; - gBS->FreePool (MemSpaceMap); - return; - } - - mGcdMemNumberOfDesc = 0; - for (Index = 0; Index < NumberOfDescriptors; Index++) { - if ((MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved) && - ((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) == - (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)) - ) - { - CopyMem ( - &mGcdMemSpace[mGcdMemNumberOfDesc], - &MemSpaceMap[Index], - sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR) - ); - mGcdMemNumberOfDesc++; - } - } - - gBS->FreePool (MemSpaceMap); -} - -/** - Get UEFI MemoryAttributesTable. -**/ -VOID -GetUefiMemoryAttributesTable ( - VOID - ) -{ - EFI_STATUS Status; - EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; - UINTN MemoryAttributesTableSize; - - Status = EfiGetSystemConfigurationTable (&gEfiMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable); - if (!EFI_ERROR (Status) && (MemoryAttributesTable != NULL)) { - MemoryAttributesTableSize = sizeof (EFI_MEMORY_ATTRIBUTES_TABLE) + MemoryAttributesTable->DescriptorSize * MemoryAttributesTable->NumberOfEntries; - mUefiMemoryAttributesTable = AllocateCopyPool (MemoryAttributesTableSize, MemoryAttributesTable); - ASSERT (mUefiMemoryAttributesTable != NULL); - } -} - -/** - This function caches the UEFI memory map information. -**/ -VOID -GetUefiMemoryMap ( - VOID - ) -{ - EFI_STATUS Status; - UINTN MapKey; - UINT32 DescriptorVersion; - EFI_MEMORY_DESCRIPTOR *MemoryMap; - UINTN UefiMemoryMapSize; - - DEBUG ((DEBUG_INFO, "GetUefiMemoryMap\n")); - - UefiMemoryMapSize = 0; - MemoryMap = NULL; - Status = gBS->GetMemoryMap ( - &UefiMemoryMapSize, - MemoryMap, - &MapKey, - &mUefiDescriptorSize, - &DescriptorVersion - ); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); - - do { - Status = gBS->AllocatePool (EfiBootServicesData, UefiMemoryMapSize, (VOID **)&MemoryMap); - ASSERT (MemoryMap != NULL); - if (MemoryMap == NULL) { - return; - } - - Status = gBS->GetMemoryMap ( - &UefiMemoryMapSize, - MemoryMap, - &MapKey, - &mUefiDescriptorSize, - &DescriptorVersion - ); - if (EFI_ERROR (Status)) { - gBS->FreePool (MemoryMap); - MemoryMap = NULL; - } - } while (Status == EFI_BUFFER_TOO_SMALL); - - if (MemoryMap == NULL) { - return; - } - - SortMemoryMap (MemoryMap, UefiMemoryMapSize, mUefiDescriptorSize); - MergeMemoryMapForNotPresentEntry (MemoryMap, &UefiMemoryMapSize, mUefiDescriptorSize); - - mUefiMemoryMapSize = UefiMemoryMapSize; - mUefiMemoryMap = AllocateCopyPool (UefiMemoryMapSize, MemoryMap); - ASSERT (mUefiMemoryMap != NULL); - - gBS->FreePool (MemoryMap); - - // - // Get additional information from GCD memory map. - // - GetGcdMemoryMap (); - - // - // Get UEFI memory attributes table. - // - GetUefiMemoryAttributesTable (); -} - -/** - This function sets UEFI memory attribute according to UEFI memory map. - - The normal memory region is marked as not present, such as - EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory, - EfiUnusableMemory, EfiACPIReclaimMemory. -**/ -VOID -SetUefiMemMapAttributes ( - VOID - ) -{ - EFI_STATUS Status; - EFI_MEMORY_DESCRIPTOR *MemoryMap; - UINTN MemoryMapEntryCount; - UINTN Index; - EFI_MEMORY_DESCRIPTOR *Entry; - BOOLEAN WriteProtect; - BOOLEAN CetEnabled; - - PERF_FUNCTION_BEGIN (); - - DEBUG ((DEBUG_INFO, "SetUefiMemMapAttributes\n")); - - WRITE_UNPROTECT_RO_PAGES (WriteProtect, CetEnabled); - - if (mUefiMemoryMap != NULL) { - MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize; - MemoryMap = mUefiMemoryMap; - for (Index = 0; Index < MemoryMapEntryCount; Index++) { - if (IsUefiPageNotPresent (MemoryMap)) { - Status = SmmSetMemoryAttributes ( - MemoryMap->PhysicalStart, - EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages), - EFI_MEMORY_RP - ); - DEBUG (( - DEBUG_INFO, - "UefiMemory protection: 0x%lx - 0x%lx %r\n", - MemoryMap->PhysicalStart, - MemoryMap->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages), - Status - )); - } - - MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize); - } - } - - // - // Do not free mUefiMemoryMap, it will be checked in IsSmmCommBufferForbiddenAddress(). - // - - // - // Set untested memory as not present. - // - if (mGcdMemSpace != NULL) { - for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) { - Status = SmmSetMemoryAttributes ( - mGcdMemSpace[Index].BaseAddress, - mGcdMemSpace[Index].Length, - EFI_MEMORY_RP - ); - DEBUG (( - DEBUG_INFO, - "GcdMemory protection: 0x%lx - 0x%lx %r\n", - mGcdMemSpace[Index].BaseAddress, - mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length, - Status - )); - } - } - - // - // Do not free mGcdMemSpace, it will be checked in IsSmmCommBufferForbiddenAddress(). - // - - // - // Set UEFI runtime memory with EFI_MEMORY_RO as not present. - // - if (mUefiMemoryAttributesTable != NULL) { - Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1); - for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) { - if ((Entry->Type == EfiRuntimeServicesCode) || (Entry->Type == EfiRuntimeServicesData)) { - if ((Entry->Attribute & EFI_MEMORY_RO) != 0) { - Status = SmmSetMemoryAttributes ( - Entry->PhysicalStart, - EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages), - EFI_MEMORY_RP - ); - DEBUG (( - DEBUG_INFO, - "UefiMemoryAttribute protection: 0x%lx - 0x%lx %r\n", - Entry->PhysicalStart, - Entry->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages), - Status - )); - } - } - - Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize); - } - } - - WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled); - - // - // Do not free mUefiMemoryAttributesTable, it will be checked in IsSmmCommBufferForbiddenAddress(). - // - - PERF_FUNCTION_END (); -} - -/** - Return if the Address is forbidden as SMM communication buffer. - - @param[in] Address the address to be checked - - @return TRUE The address is forbidden as SMM communication buffer. - @return FALSE The address is allowed as SMM communication buffer. -**/ -BOOLEAN -IsSmmCommBufferForbiddenAddress ( - IN UINT64 Address - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMap; - UINTN MemoryMapEntryCount; - UINTN Index; - EFI_MEMORY_DESCRIPTOR *Entry; - - if (mUefiMemoryMap != NULL) { - MemoryMap = mUefiMemoryMap; - MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize; - for (Index = 0; Index < MemoryMapEntryCount; Index++) { - if (IsUefiPageNotPresent (MemoryMap)) { - if ((Address >= MemoryMap->PhysicalStart) && - (Address < MemoryMap->PhysicalStart + EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages))) - { - return TRUE; - } - } - - MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize); - } - } - - if (mGcdMemSpace != NULL) { - for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) { - if ((Address >= mGcdMemSpace[Index].BaseAddress) && - (Address < mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length)) - { - return TRUE; - } - } - } - - if (mUefiMemoryAttributesTable != NULL) { - Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1); - for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) { - if ((Entry->Type == EfiRuntimeServicesCode) || (Entry->Type == EfiRuntimeServicesData)) { - if ((Entry->Attribute & EFI_MEMORY_RO) != 0) { - if ((Address >= Entry->PhysicalStart) && - (Address < Entry->PhysicalStart + LShiftU64 (Entry->NumberOfPages, EFI_PAGE_SHIFT))) - { - return TRUE; - } - - Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize); - } - } - } - } - - return FALSE; -} - /** This function set given attributes of the memory region specified by BaseAddress and Length. From c8a1295d3e98490b4e18522cb1752200ae73d324 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 24 Jun 2024 20:49:23 +0800 Subject: [PATCH 064/280] UefiCpuPkg/PiSmmCpuDxeSmm: Get SMRAM info from gEfiSmmSmramMemoryGuid MM can not use the SMM Access Protocol, so get SMRAM info from gEfiSmmSmramMemoryGuid instead of via SMM Access Protocol for both SMM and MM. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c | 40 +++++++------------- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 2 +- 3 files changed, 16 insertions(+), 28 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c index 5d2b9eefd370..1ba5967fd60b 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c @@ -1282,7 +1282,6 @@ CpuSmramRangeCompare ( } /** - Find out SMRAM information including SMRR base and SMRR size. @param SmrrBase SMRR base @@ -1295,35 +1294,24 @@ FindSmramInfo ( OUT UINT32 *SmrrSize ) { - EFI_STATUS Status; - UINTN Size; - EFI_SMM_ACCESS2_PROTOCOL *SmmAccess; - EFI_SMRAM_DESCRIPTOR *CurrentSmramRange; - UINTN Index; - UINT64 MaxSize; - BOOLEAN Found; - EFI_SMRAM_DESCRIPTOR SmramDescriptor; + VOID *GuidHob; + EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *DescriptorBlock; + EFI_SMRAM_DESCRIPTOR *CurrentSmramRange; + UINTN Index; + UINT64 MaxSize; + BOOLEAN Found; + EFI_SMRAM_DESCRIPTOR SmramDescriptor; - // - // Get SMM Access Protocol - // - Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess); - ASSERT_EFI_ERROR (Status); + ASSERT (SmrrBase != NULL && SmrrSize != NULL); // // Get SMRAM information // - Size = 0; - Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); - - mSmmCpuSmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocatePool (Size); - ASSERT (mSmmCpuSmramRanges != NULL); - - Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmmCpuSmramRanges); - ASSERT_EFI_ERROR (Status); - - mSmmCpuSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR); + GuidHob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid); + ASSERT (GuidHob != NULL); + DescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)GET_GUID_HOB_DATA (GuidHob); + mSmmCpuSmramRangeCount = DescriptorBlock->NumberOfSmmReservedRegions; + mSmmCpuSmramRanges = DescriptorBlock->Descriptor; // // Sort the mSmmCpuSmramRanges @@ -1373,7 +1361,7 @@ FindSmramInfo ( } } while (Found); - DEBUG ((DEBUG_INFO, "SMRR Base: 0x%x, SMRR Size: 0x%x\n", *SmrrBase, *SmrrSize)); + DEBUG ((DEBUG_INFO, "%a: SMRR Base = 0x%x, SMRR Size = 0x%x\n", __func__, *SmrrBase, *SmrrSize)); } /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index 87fd7d9ba155..c75f0ea9d645 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -16,7 +16,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include #include #include #include @@ -25,6 +24,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf index d18e9e85f800..2705ca69ea4c 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -102,7 +102,6 @@ SmmCpuSyncLib [Protocols] - gEfiSmmAccess2ProtocolGuid ## CONSUMES gEfiSmmConfigurationProtocolGuid ## PRODUCES gEfiSmmCpuProtocolGuid ## PRODUCES gEfiSmmReadyToLockProtocolGuid ## NOTIFY @@ -118,6 +117,7 @@ gEfiMemoryAttributesTableGuid ## CONSUMES ## SystemTable gSmmBaseHobGuid ## CONSUMES gMpInformation2HobGuid ## CONSUMES # Assume the HOB must has been created + gEfiSmmSmramMemoryGuid [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug ## CONSUMES From 89fe9c5d794327fb4b36f8f656f9336a91b95510 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 24 Jun 2024 23:14:50 +0800 Subject: [PATCH 065/280] UefiCpuPkg/PiSmmCpuDxeSmm: Use SMM Variable to set SmmProfileBase MM can not use the gRT service, so use SMM Variable protocol to set SmmProfileBase instead of gRT->SetVariable for both SMM and MM. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 1 + UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 1 + UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 23 ++++++++++++++------ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index c75f0ea9d645..cc1fceb837a5 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -20,6 +20,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf index 2705ca69ea4c..d8eda7825ff2 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -110,6 +110,7 @@ gEfiMmMpProtocolGuid ## PRODUCES gEdkiiSmmCpuRendezvousProtocolGuid ## PRODUCES gEfiMpServiceProtocolGuid ## CONSUMES + gEfiSmmVariableProtocolGuid ## CONSUMES [Guids] gEfiAcpiVariableGuid ## SOMETIMES_CONSUMES ## HOB # it is used for S3 boot. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index a0ebaf5131df..19f3ba7000b6 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -753,16 +753,25 @@ InitSmmProfileCallBack ( IN EFI_HANDLE Handle ) { + EFI_STATUS Status; + EFI_SMM_VARIABLE_PROTOCOL *SmmProfileVariable; + + // + // Locate SmmVariableProtocol. + // + Status = gMmst->MmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&SmmProfileVariable); + ASSERT_EFI_ERROR (Status); + // // Save to variable so that SMM profile data can be found. // - gRT->SetVariable ( - SMM_PROFILE_NAME, - &gEfiCallerIdGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - sizeof (mSmmProfileBase), - &mSmmProfileBase - ); + SmmProfileVariable->SmmSetVariable ( + SMM_PROFILE_NAME, + &gEfiCallerIdGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (mSmmProfileBase), + &mSmmProfileBase + ); // // Get Software SMI from FADT From 5547d1487c630fd66c99fd529dddf8d09c075681 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 24 Jun 2024 23:34:45 +0800 Subject: [PATCH 066/280] UefiCpuPkg/PiSmmCpuDxeSmm: Move SMM profile data allocation into func MM can not use the gBS service, so move SMM profile data allocation into function. This can make InitSmmProfileInternal() to a common function for both SMM and MM. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c | 37 ++++++++++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 16 +++++++ UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 43 ++++++------------- 3 files changed, 67 insertions(+), 29 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c index d188b11a9679..4f6f040bc81b 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c @@ -423,6 +423,43 @@ SetUefiMemMapAttributes ( PERF_FUNCTION_END (); } +/** + Get SmmProfileData. + + @param[in, out] Size Return Size of SmmProfileData. + + @return Address of SmmProfileData + +**/ +EFI_PHYSICAL_ADDRESS +GetSmmProfileData ( + IN OUT UINT64 *Size + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Base; + + ASSERT (Size != NULL); + + if (mBtsSupported) { + *Size = PcdGet32 (PcdCpuSmmProfileSize) + mMsrDsAreaSize; + } else { + *Size = PcdGet32 (PcdCpuSmmProfileSize); + } + + Base = 0xFFFFFFFF; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiReservedMemoryType, + (UINTN)EFI_SIZE_TO_PAGES (*Size), + &Base + ); + ASSERT_EFI_ERROR (Status); + ZeroMem ((VOID *)(UINTN)Base, (UINTN)*Size); + + return Base; +} + /** Return if the Address is forbidden as SMM communication buffer. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index cc1fceb837a5..da59b074604b 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -267,6 +267,9 @@ extern UINTN mSmmShadowStackSize; /// extern UINT8 mSmmSaveStateRegisterLma; +extern BOOLEAN mBtsSupported; +extern UINTN mMsrDsAreaSize; + #define PAGE_TABLE_POOL_ALIGNMENT BASE_128KB #define PAGE_TABLE_POOL_UNIT_SIZE BASE_128KB #define PAGE_TABLE_POOL_UNIT_PAGES EFI_SIZE_TO_PAGES (PAGE_TABLE_POOL_UNIT_SIZE) @@ -910,6 +913,19 @@ SetUefiMemMapAttributes ( VOID ); +/** + Get SmmProfileData. + + @param[in, out] Size Return Size of SmmProfileData. + + @return Address of SmmProfileData + +**/ +EFI_PHYSICAL_ADDRESS +GetSmmProfileData ( + IN OUT UINT64 *Size + ); + /** Return if the Address is forbidden as SMM communication buffer. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index 19f3ba7000b6..e775b7d7eff0 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -795,12 +795,11 @@ InitSmmProfileInternal ( VOID ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Base; - VOID *Registration; - UINTN Index; - UINTN MsrDsAreaSizePerCpu; - UINTN TotalSize; + EFI_STATUS Status; + VOID *Registration; + UINTN Index; + UINTN MsrDsAreaSizePerCpu; + UINT64 SmmProfileSize; mPFEntryCount = (UINTN *)AllocateZeroPool (sizeof (UINTN) * mMaxNumberOfCpus); ASSERT (mPFEntryCount != NULL); @@ -813,29 +812,15 @@ InitSmmProfileInternal ( ); ASSERT (mLastPFEntryPointer != NULL); - // - // Allocate memory for SmmProfile below 4GB. - // The base address - // - mSmmProfileSize = PcdGet32 (PcdCpuSmmProfileSize); + mSmmProfileSize = FixedPcdGet32 (PcdCpuSmmProfileSize); ASSERT ((mSmmProfileSize & 0xFFF) == 0); - if (mBtsSupported) { - TotalSize = mSmmProfileSize + mMsrDsAreaSize; - } else { - TotalSize = mSmmProfileSize; - } - - Base = 0xFFFFFFFF; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiReservedMemoryType, - EFI_SIZE_TO_PAGES (TotalSize), - &Base - ); - ASSERT_EFI_ERROR (Status); - ZeroMem ((VOID *)(UINTN)Base, TotalSize); - mSmmProfileBase = (SMM_PROFILE_HEADER *)(UINTN)Base; + // + // Get Smm Profile Base + // + mSmmProfileBase = (SMM_PROFILE_HEADER *)(UINTN)GetSmmProfileData (&SmmProfileSize); + DEBUG ((DEBUG_ERROR, "SmmProfileBase = 0x%016x.\n", (UINTN)mSmmProfileBase)); + DEBUG ((DEBUG_ERROR, "SmmProfileSize = 0x%016x.\n", (UINTN)SmmProfileSize)); // // Initialize SMM profile data header. @@ -858,7 +843,7 @@ InitSmmProfileInternal ( mMsrPEBSRecord = (PEBS_RECORD **)AllocateZeroPool (sizeof (PEBS_RECORD *) * mMaxNumberOfCpus); ASSERT (mMsrPEBSRecord != NULL); - mMsrDsAreaBase = (MSR_DS_AREA_STRUCT *)((UINTN)Base + mSmmProfileSize); + mMsrDsAreaBase = (MSR_DS_AREA_STRUCT *)((UINTN)mSmmProfileBase + mSmmProfileSize); MsrDsAreaSizePerCpu = mMsrDsAreaSize / mMaxNumberOfCpus; mBTSRecordNumber = (MsrDsAreaSizePerCpu - sizeof (PEBS_RECORD) * PEBS_RECORD_NUMBER - sizeof (MSR_DS_AREA_STRUCT)) / sizeof (BRANCH_TRACE_RECORD); for (Index = 0; Index < mMaxNumberOfCpus; Index++) { @@ -891,7 +876,7 @@ InitSmmProfileInternal ( // Update SMM profile entry. // mProtectionMemRange[1].Range.Base = (EFI_PHYSICAL_ADDRESS)(UINTN)mSmmProfileBase; - mProtectionMemRange[1].Range.Top = (EFI_PHYSICAL_ADDRESS)(UINTN)mSmmProfileBase + TotalSize; + mProtectionMemRange[1].Range.Top = (EFI_PHYSICAL_ADDRESS)(UINTN)mSmmProfileBase + SmmProfileSize; // // Allocate memory reserved for creating 4KB pages. From 23c5ee6e23b96cdceb5813bfc7d27e2c54a332a5 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Tue, 25 Jun 2024 00:18:14 +0800 Subject: [PATCH 067/280] UefiCpuPkg/PiSmmCpuDxeSmm: Move GetAcpiS3EnableFlag into DxeSmm code MM can not use the dynamic PCD, so, Move GetAcpiS3EnableFlag into DxeSmm code. This can make PiSmmCpuEntryCommon to be a function for SMM and MM. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c | 12 ------------ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 1 + UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 12 ++++++++++++ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c index cb77c3b5ea39..f3b7d44ab87a 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c @@ -248,15 +248,3 @@ InitSmmS3ResumeState ( InitSmmS3Cr3 ((UINTN *)&SmmS3ResumeState->SmmS3Cr3); } } - -/** - Get ACPI S3 enable flag. - -**/ -VOID -GetAcpiS3EnableFlag ( - VOID - ) -{ - mAcpiS3Enable = PcdGetBool (PcdAcpiS3Enable); -} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index da59b074604b..821c0b94884b 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -269,6 +269,7 @@ extern UINT8 mSmmSaveStateRegisterLma; extern BOOLEAN mBtsSupported; extern UINTN mMsrDsAreaSize; +extern BOOLEAN mAcpiS3Enable; #define PAGE_TABLE_POOL_ALIGNMENT BASE_128KB #define PAGE_TABLE_POOL_UNIT_SIZE BASE_128KB diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index 29cba42e7a09..d1280db49014 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -11,6 +11,18 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PiSmmCpuCommon.h" +/** + Get ACPI S3 enable flag. + +**/ +VOID +GetAcpiS3EnableFlag ( + VOID + ) +{ + mAcpiS3Enable = PcdGetBool (PcdAcpiS3Enable); +} + /** Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from gEfiMpServiceProtocolGuid. From d480f106a6c1ac15d14b0dc803b03c945c71a09e Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Tue, 25 Jun 2024 00:25:21 +0800 Subject: [PATCH 068/280] UefiCpuPkg/PiSmmCpuDxeSmm: Get SmmCpuSyncConfig data from func MM can not use the dynamic PCD (PcdCpuSmmSyncMode & PcdCpuSmmApSyncTimeout & PcdCpuSmmApSyncTimeout2), so, move to DxeSmm code and implement in GetSmmCpuSyncConfigData function. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 6 ++++- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 16 ++++++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 29 ++++++++++++++++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c | 10 ++++++-- 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c index dbcc5279a37f..aae283e79bdc 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -1924,6 +1924,7 @@ InitializeMpServiceData ( CPUID_VERSION_INFO_EDX RegEdx; UINT32 MaxExtendedFunction; CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize; + BOOLEAN RelaxedMode; // // Determine if this CPU supports machine check @@ -1943,7 +1944,10 @@ InitializeMpServiceData ( (sizeof (SMM_CPU_DATA_BLOCK) + sizeof (BOOLEAN)) * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; mSmmMpSyncData = (SMM_DISPATCHER_MP_SYNC_DATA *)AllocatePages (EFI_SIZE_TO_PAGES (mSmmMpSyncDataSize)); ASSERT (mSmmMpSyncData != NULL); - mCpuSmmSyncMode = (SMM_CPU_SYNC_MODE)PcdGet8 (PcdCpuSmmSyncMode); + + RelaxedMode = FALSE; + GetSmmCpuSyncConfigData (&RelaxedMode, NULL, NULL); + mCpuSmmSyncMode = RelaxedMode ? SmmCpuSyncModeRelaxedAp : SmmCpuSyncModeTradition; InitializeMpSyncData (); // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index 821c0b94884b..a5b40f864e77 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -1078,6 +1078,22 @@ RestoreSmmConfigurationInS3 ( VOID ); +/** + Get SmmCpuSyncConfig data: RelaxedMode, SyncTimeout, SyncTimeout2. + + @param[in,out] RelaxedMode It indicates if Relaxed CPU synchronization method or + traditional CPU synchronization method is used when processing an SMI. + @param[in,out] SyncTimeout It indicates the 1st BSP/AP synchronization timeout value in SMM. + @param[in,out] SyncTimeout2 It indicates the 2nd BSP/AP synchronization timeout value in SMM. + + **/ +VOID +GetSmmCpuSyncConfigData ( + IN OUT BOOLEAN *RelaxedMode, OPTIONAL + IN OUT UINT64 *SyncTimeout, OPTIONAL + IN OUT UINT64 *SyncTimeout2 OPTIONAL + ); + /** Get ACPI S3 enable flag. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index d1280db49014..5f126a5f23ad 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -11,6 +11,35 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PiSmmCpuCommon.h" +/** + Get SmmCpuSyncConfig data: RelaxedMode, SyncTimeout, SyncTimeout2. + + @param[in,out] RelaxedMode It indicates if Relaxed CPU synchronization method or + traditional CPU synchronization method is used when processing an SMI. + @param[in,out] SyncTimeout It indicates the 1st BSP/AP synchronization timeout value in SMM. + @param[in,out] SyncTimeout2 It indicates the 2nd BSP/AP synchronization timeout value in SMM. + + **/ +VOID +GetSmmCpuSyncConfigData ( + IN OUT BOOLEAN *RelaxedMode, OPTIONAL + IN OUT UINT64 *SyncTimeout, OPTIONAL + IN OUT UINT64 *SyncTimeout2 OPTIONAL + ) +{ + if (RelaxedMode != NULL) { + *RelaxedMode = (BOOLEAN)(PcdGet8 (PcdCpuSmmSyncMode) == SmmCpuSyncModeRelaxedAp); + } + + if (SyncTimeout != NULL) { + *SyncTimeout = PcdGet64 (PcdCpuSmmApSyncTimeout); + } + + if (SyncTimeout2 != NULL) { + *SyncTimeout2 = PcdGet64 (PcdCpuSmmApSyncTimeout2); + } +} + /** Get ACPI S3 enable flag. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c index ad1531322483..fcf002c5e3d8 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c @@ -31,16 +31,22 @@ InitializeSmmTimer ( ) { UINT64 TimerFrequency; + UINT64 SyncTimeout; + UINT64 SyncTimeout2; UINT64 Start; UINT64 End; + SyncTimeout = 0; + SyncTimeout2 = 0; + GetSmmCpuSyncConfigData (NULL, &SyncTimeout, &SyncTimeout2); + TimerFrequency = GetPerformanceCounterProperties (&Start, &End); mTimeoutTicker = DivU64x32 ( - MultU64x64 (TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout)), + MultU64x64 (TimerFrequency, SyncTimeout), 1000 * 1000 ); mTimeoutTicker2 = DivU64x32 ( - MultU64x64 (TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout2)), + MultU64x64 (TimerFrequency, SyncTimeout2), 1000 * 1000 ); if (End < Start) { From 0c037b5fa7d14bc40294b4fa4edd42b4a5111f64 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 24 Jun 2024 23:53:34 +0800 Subject: [PATCH 069/280] UefiCpuPkg/PiSmmCpuDxeSmm: Create extended protection MemRegion in func MM can not use the gDS service, so move the extended protection MemRegion creation into function. This can make InitProtectedMemRange() to be a common function for both SMM and MM. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c | 78 ++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 30 +++ UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 174 ++++++++---------- 3 files changed, 187 insertions(+), 95 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c index 4f6f040bc81b..be5b333cd18c 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c @@ -523,3 +523,81 @@ IsSmmCommBufferForbiddenAddress ( return FALSE; } + +/** + Create extended protection MemoryRegion. + Return all MMIO ranges that are reported in GCD service at EndOfDxe. + + The caller is responsible for freeing MemoryRegion via FreePool(). + + @param[out] MemoryRegion Returned Non-Mmram Memory regions. + @param[out] MemoryRegionCount A pointer to the number of Memory regions. +**/ +VOID +CreateExtendedProtectionRange ( + OUT MM_CPU_MEMORY_REGION **MemoryRegion, + OUT UINTN *MemoryRegionCount + ) +{ + UINTN Index; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap; + UINTN NumberOfSpaceDescriptors; + UINTN MemoryRegionIndex; + UINTN Count; + + MemorySpaceMap = NULL; + NumberOfSpaceDescriptors = 0; + Count = 0; + + ASSERT (MemoryRegion != NULL && MemoryRegionCount != NULL); + + *MemoryRegion = NULL; + *MemoryRegionCount = 0; + + // + // Get MMIO ranges from GCD. + // + gDS->GetMemorySpaceMap ( + &NumberOfSpaceDescriptors, + &MemorySpaceMap + ); + for (Index = 0; Index < NumberOfSpaceDescriptors; Index++) { + if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo)) { + if (ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) && + (MemorySpaceMap[Index].Length % SIZE_4KB == 0)) + { + Count++; + } else { + // + // Skip the MMIO range that BaseAddress and Length are not 4k aligned since + // the minimum granularity of the page table is 4k + // + DEBUG (( + DEBUG_WARN, + "MMIO range [0x%lx, 0x%lx] is skipped since it is not 4k aligned.\n", + MemorySpaceMap[Index].BaseAddress, + MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length + )); + } + } + } + + *MemoryRegionCount = Count; + + *MemoryRegion = (MM_CPU_MEMORY_REGION *)AllocateZeroPool (sizeof (MM_CPU_MEMORY_REGION) * Count); + ASSERT (*MemoryRegion != NULL); + + MemoryRegionIndex = 0; + for (Index = 0; Index < NumberOfSpaceDescriptors; Index++) { + if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) && + ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) && + (MemorySpaceMap[Index].Length % SIZE_4KB == 0)) + { + (*MemoryRegion)[MemoryRegionIndex].Base = MemorySpaceMap[Index].BaseAddress; + (*MemoryRegion)[MemoryRegionIndex].Length = MemorySpaceMap[Index].Length; + MemoryRegionIndex++; + } + } + + return; +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index a5b40f864e77..ed0badf4314b 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -479,6 +479,21 @@ extern UINT64 mAddressEncMask; extern UINT64 mTimeoutTicker; extern UINT64 mTimeoutTicker2; +typedef struct { + /// + /// Address of the first byte in the memory region. + /// + EFI_PHYSICAL_ADDRESS Base; + /// + /// Length in bytes of the memory region. + /// + UINT64 Length; + /// + /// Attributes of the memory region + /// + UINT64 Attribute; +} MM_CPU_MEMORY_REGION; + /** Create 4G PageTable in SMRAM. @@ -940,6 +955,21 @@ IsSmmCommBufferForbiddenAddress ( IN UINT64 Address ); +/* + Build extended protection MemoryRegion. + + The caller is responsible for freeing MemoryRegion via FreePool(). + + @param[out] MemoryRegion Returned Non-Mmram Memory regions. + @param[out] MemoryRegionCount A pointer to the number of Memory regions. + +*/ +VOID +CreateExtendedProtectionRange ( + OUT MM_CPU_MEMORY_REGION **MemoryRegion, + OUT UINTN *MemoryRegionCount + ); + /** This function caches the UEFI memory map information. **/ diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index e775b7d7eff0..a6f7697c6338 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -404,116 +404,100 @@ InitProtectedMemRange ( VOID ) { - UINTN Index; - UINTN NumberOfDescriptors; - UINTN NumberOfAddedDescriptors; - UINTN NumberOfProtectRange; - UINTN NumberOfSpliteRange; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap; - UINTN TotalSize; - EFI_PHYSICAL_ADDRESS ProtectBaseAddress; - EFI_PHYSICAL_ADDRESS ProtectEndAddress; - EFI_PHYSICAL_ADDRESS Top2MBAlignedAddress; - EFI_PHYSICAL_ADDRESS Base2MBAlignedAddress; - UINT64 High4KBPageSize; - UINT64 Low4KBPageSize; - MEMORY_PROTECTION_RANGE MemProtectionRange; - - NumberOfDescriptors = 0; + UINTN Index; + MM_CPU_MEMORY_REGION *MemoryRegion; + UINTN MemoryRegionCount; + UINTN NumberOfAddedDescriptors; + UINTN NumberOfProtectRange; + UINTN NumberOfSpliteRange; + UINTN TotalSize; + EFI_PHYSICAL_ADDRESS ProtectBaseAddress; + EFI_PHYSICAL_ADDRESS ProtectEndAddress; + EFI_PHYSICAL_ADDRESS Top2MBAlignedAddress; + EFI_PHYSICAL_ADDRESS Base2MBAlignedAddress; + UINT64 High4KBPageSize; + UINT64 Low4KBPageSize; + MEMORY_PROTECTION_RANGE MemProtectionRange; + + MemoryRegion = NULL; + MemoryRegionCount = 0; NumberOfAddedDescriptors = mSmmCpuSmramRangeCount; NumberOfSpliteRange = 0; - MemorySpaceMap = NULL; // - // Get MMIO ranges from GCD and add them into protected memory ranges. + // Create extended protection MemoryRegion and add them into protected memory ranges. + // Retrieve the accessible regions when SMM profile is enabled. + // In SMM: only MMIO is accessible. // - gDS->GetMemorySpaceMap ( - &NumberOfDescriptors, - &MemorySpaceMap - ); - for (Index = 0; Index < NumberOfDescriptors; Index++) { - if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo)) { - if (ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) && - (MemorySpaceMap[Index].Length % SIZE_4KB == 0)) - { - NumberOfAddedDescriptors++; - } else { - // - // Skip the MMIO range that BaseAddress and Length are not 4k aligned since - // the minimum granularity of the page table is 4k - // - DEBUG (( - DEBUG_WARN, - "MMIO range [0x%lx, 0x%lx] is skipped since it is not 4k aligned.\n", - MemorySpaceMap[Index].BaseAddress, - MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - )); - } - } - } + CreateExtendedProtectionRange (&MemoryRegion, &MemoryRegionCount); + ASSERT (MemoryRegion != NULL); - if (NumberOfAddedDescriptors != 0) { - TotalSize = NumberOfAddedDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate); - mProtectionMemRange = (MEMORY_PROTECTION_RANGE *)AllocateZeroPool (TotalSize); - ASSERT (mProtectionMemRange != NULL); - mProtectionMemRangeCount = TotalSize / sizeof (MEMORY_PROTECTION_RANGE); + NumberOfAddedDescriptors += MemoryRegionCount; - // - // Copy existing ranges. - // - CopyMem (mProtectionMemRange, mProtectionMemRangeTemplate, sizeof (mProtectionMemRangeTemplate)); + ASSERT (NumberOfAddedDescriptors != 0); - // - // Create split ranges which come from protected ranges. - // - TotalSize = (TotalSize / sizeof (MEMORY_PROTECTION_RANGE)) * sizeof (MEMORY_RANGE); - mSplitMemRange = (MEMORY_RANGE *)AllocateZeroPool (TotalSize); - ASSERT (mSplitMemRange != NULL); + TotalSize = NumberOfAddedDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate); + mProtectionMemRange = (MEMORY_PROTECTION_RANGE *)AllocateZeroPool (TotalSize); + ASSERT (mProtectionMemRange != NULL); + mProtectionMemRangeCount = TotalSize / sizeof (MEMORY_PROTECTION_RANGE); - // - // Create SMM ranges which are set to present and execution-enable. - // - NumberOfProtectRange = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE); - for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) { - if ((mSmmCpuSmramRanges[Index].CpuStart >= mProtectionMemRange[0].Range.Base) && - (mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize < mProtectionMemRange[0].Range.Top)) - { - // - // If the address have been already covered by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz - // - break; - } + // + // Copy existing ranges. + // + CopyMem (mProtectionMemRange, mProtectionMemRangeTemplate, sizeof (mProtectionMemRangeTemplate)); - mProtectionMemRange[NumberOfProtectRange].Range.Base = mSmmCpuSmramRanges[Index].CpuStart; - mProtectionMemRange[NumberOfProtectRange].Range.Top = mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize; - mProtectionMemRange[NumberOfProtectRange].Present = TRUE; - mProtectionMemRange[NumberOfProtectRange].Nx = FALSE; - NumberOfProtectRange++; - } + // + // Create split ranges which come from protected ranges. + // + TotalSize = (TotalSize / sizeof (MEMORY_PROTECTION_RANGE)) * sizeof (MEMORY_RANGE); + mSplitMemRange = (MEMORY_RANGE *)AllocateZeroPool (TotalSize); + ASSERT (mSplitMemRange != NULL); - // - // Create MMIO ranges which are set to present and execution-disable. - // - for (Index = 0; Index < NumberOfDescriptors; Index++) { - if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) && - ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) && - (MemorySpaceMap[Index].Length % SIZE_4KB == 0)) - { - mProtectionMemRange[NumberOfProtectRange].Range.Base = MemorySpaceMap[Index].BaseAddress; - mProtectionMemRange[NumberOfProtectRange].Range.Top = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length; - mProtectionMemRange[NumberOfProtectRange].Present = TRUE; - mProtectionMemRange[NumberOfProtectRange].Nx = TRUE; - NumberOfProtectRange++; - } + // + // Create SMM ranges which are set to present and execution-enable. + // + NumberOfProtectRange = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE); + for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) { + if ((mSmmCpuSmramRanges[Index].CpuStart >= mProtectionMemRange[0].Range.Base) && + (mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize < mProtectionMemRange[0].Range.Top)) + { + // + // If the address have been already covered by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz + // + break; } - // - // Check and updated actual protected memory ranges count - // - ASSERT (NumberOfProtectRange <= mProtectionMemRangeCount); - mProtectionMemRangeCount = NumberOfProtectRange; + mProtectionMemRange[NumberOfProtectRange].Range.Base = mSmmCpuSmramRanges[Index].CpuStart; + mProtectionMemRange[NumberOfProtectRange].Range.Top = mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize; + mProtectionMemRange[NumberOfProtectRange].Present = TRUE; + mProtectionMemRange[NumberOfProtectRange].Nx = FALSE; + NumberOfProtectRange++; } + // + // Create MMIO ranges which are set to present and execution-disable. + // + for (Index = 0; Index < MemoryRegionCount; Index++) { + mProtectionMemRange[NumberOfProtectRange].Range.Base = MemoryRegion[Index].Base; + mProtectionMemRange[NumberOfProtectRange].Range.Top = MemoryRegion[Index].Base + MemoryRegion[Index].Length; + mProtectionMemRange[NumberOfProtectRange].Present = TRUE; + mProtectionMemRange[NumberOfProtectRange].Nx = TRUE; + NumberOfProtectRange++; + } + + // + // Free the MemoryRegion + // + if (MemoryRegion != NULL) { + FreePool (MemoryRegion); + } + + // + // Check and updated actual protected memory ranges count + // + ASSERT (NumberOfProtectRange <= mProtectionMemRangeCount); + mProtectionMemRangeCount = NumberOfProtectRange; + // // According to protected ranges, create the ranges which will be mapped by 2KB page. // From abc2f595235d0b87f1d15f1a75a345b22ff86c75 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Tue, 25 Jun 2024 00:40:32 +0800 Subject: [PATCH 070/280] UefiCpuPkg/PiSmmCpuDxeSmm: Move GetUefiMemoryMap into DxeSmm code MM can not call GetUefiMemoryMap() function, so, move it into DxeSmm code. Define a SmmReadyToLockEventNotify to handler the logic. This will make PiSmmCpuEntryCommon to be common function for SMM and MM. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c | 43 ---------------------- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 1 + UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 43 ++++++++++++++++++++++ 3 files changed, 44 insertions(+), 43 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c index 1ba5967fd60b..78bfc8a3e776 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c @@ -432,38 +432,6 @@ ExecuteFirstSmiInit ( PERF_FUNCTION_END (); } -/** - SMM Ready To Lock event notification handler. - - mSmmReadyToLock is set to perform additional lock actions that must be - performed from SMM on the next SMI. - - @param[in] Protocol Points to the protocol's unique identifier. - @param[in] Interface Points to the interface instance. - @param[in] Handle The handle on which the interface was installed. - - @retval EFI_SUCCESS Notification handler runs successfully. - **/ -EFI_STATUS -EFIAPI -SmmReadyToLockEventNotify ( - IN CONST EFI_GUID *Protocol, - IN VOID *Interface, - IN EFI_HANDLE Handle - ) -{ - // - // Cache a copy of UEFI memory map before we start profiling feature. - // - GetUefiMemoryMap (); - - // - // Set SMM ready to lock flag and return - // - mSmmReadyToLock = TRUE; - return EFI_SUCCESS; -} - /** Function to compare 2 SMM_BASE_HOB_DATA pointer based on ProcessorIndex. @@ -759,7 +727,6 @@ PiSmmCpuEntryCommon ( UINTN TileDataSize; UINTN TileSize; UINT8 *Stacks; - VOID *Registration; UINT32 RegEax; UINT32 RegEbx; UINT32 RegEcx; @@ -1231,16 +1198,6 @@ PiSmmCpuEntryCommon ( Status = InitializeSmmCpuServices (mSmmCpuHandle); ASSERT_EFI_ERROR (Status); - // - // register SMM Ready To Lock Protocol notification - // - Status = gMmst->MmRegisterProtocolNotify ( - &gEfiSmmReadyToLockProtocolGuid, - SmmReadyToLockEventNotify, - &Registration - ); - ASSERT_EFI_ERROR (Status); - // // Initialize SMM Profile feature // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index ed0badf4314b..e662f2dc45ea 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -270,6 +270,7 @@ extern UINT8 mSmmSaveStateRegisterLma; extern BOOLEAN mBtsSupported; extern UINTN mMsrDsAreaSize; extern BOOLEAN mAcpiS3Enable; +extern BOOLEAN mSmmReadyToLock; #define PAGE_TABLE_POOL_ALIGNMENT BASE_128KB #define PAGE_TABLE_POOL_UNIT_SIZE BASE_128KB diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index 5f126a5f23ad..22b0de13c7db 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -11,6 +11,38 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PiSmmCpuCommon.h" +/** + SMM Ready To Lock event notification handler. + + mSmmReadyToLock is set to perform additional lock actions that must be + performed from SMM on the next SMI. + + @param[in] Protocol Points to the protocol's unique identifier. + @param[in] Interface Points to the interface instance. + @param[in] Handle The handle on which the interface was installed. + + @retval EFI_SUCCESS Notification handler runs successfully. + **/ +EFI_STATUS +EFIAPI +SmmReadyToLockEventNotify ( + IN CONST EFI_GUID *Protocol, + IN VOID *Interface, + IN EFI_HANDLE Handle + ) +{ + // + // Cache a copy of UEFI memory map before we start profiling feature. + // + GetUefiMemoryMap (); + + // + // Set SMM ready to lock flag and return + // + mSmmReadyToLock = TRUE; + return EFI_SUCCESS; +} + /** Get SmmCpuSyncConfig data: RelaxedMode, SyncTimeout, SyncTimeout2. @@ -149,6 +181,7 @@ PiCpuSmmEntry ( ) { EFI_STATUS Status; + VOID *Registration; // // Save the PcdPteMemoryEncryptionAddressOrMask value into a global variable. @@ -182,5 +215,15 @@ PiCpuSmmEntry ( ASSERT_EFI_ERROR (Status); } + // + // Register SMM Ready To Lock Protocol notification + // + Status = gMmst->MmRegisterProtocolNotify ( + &gEfiSmmReadyToLockProtocolGuid, + SmmReadyToLockEventNotify, + &Registration + ); + ASSERT_EFI_ERROR (Status); + return Status; } From 9d9bbb6f5f44cfccaf8a7aadf89cbe22edea58e5 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Tue, 25 Jun 2024 01:00:26 +0800 Subject: [PATCH 071/280] UefiCpuPkg/PiSmmCpuDxeSmm: Move GetSmiCommandPort into DxeSmm Code MM can not call the EfiLocateFirstAcpiTable(), so, move the function into DxeSmm Code. This will make InitSmmProfileCallBack() to be common function for both SMM and MM. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 2 -- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 31 +++++++++++++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 25 --------------- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h | 4 +++ .../PiSmmCpuDxeSmm/SmmProfileInternal.h | 2 -- 5 files changed, 35 insertions(+), 29 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index e662f2dc45ea..4b0d5fb08b86 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -40,8 +40,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include -#include #include #include #include diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index 22b0de13c7db..8995b54226fe 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -10,6 +10,27 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "PiSmmCpuCommon.h" +#include + +/** + To get system port address of the SMI Command Port in FADT table. + +**/ +VOID +GetSmiCommandPort ( + VOID + ) +{ + EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt; + + Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)EfiLocateFirstAcpiTable ( + EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE + ); + ASSERT (Fadt != NULL); + + mSmiCommandPort = Fadt->SmiCmd; + DEBUG ((DEBUG_INFO, "mSmiCommandPort = %x\n", mSmiCommandPort)); +} /** SMM Ready To Lock event notification handler. @@ -36,6 +57,16 @@ SmmReadyToLockEventNotify ( // GetUefiMemoryMap (); + // + // Skip SMM profile initialization if feature is disabled + // + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + // + // Get Software SMI from FADT + // + GetSmiCommandPort (); + } + // // Set SMM ready to lock flag and return // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index a6f7697c6338..f38e8e8e404a 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -678,26 +678,6 @@ InitPaging ( PERF_FUNCTION_END (); } -/** - To get system port address of the SMI Command Port in FADT table. - -**/ -VOID -GetSmiCommandPort ( - VOID - ) -{ - EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt; - - Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)EfiLocateFirstAcpiTable ( - EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE - ); - ASSERT (Fadt != NULL); - - mSmiCommandPort = Fadt->SmiCmd; - DEBUG ((DEBUG_INFO, "mSmiCommandPort = %x\n", mSmiCommandPort)); -} - /** Updates page table to make some memory ranges (like system memory) absent and make some memory ranges (like MMIO) present and execute disable. It also @@ -757,11 +737,6 @@ InitSmmProfileCallBack ( &mSmmProfileBase ); - // - // Get Software SMI from FADT - // - GetSmiCommandPort (); - // // Initialize protected memory range for patching page table later. // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h index 1a82ac05ce92..7a0f006d778b 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h @@ -130,5 +130,9 @@ extern BOOLEAN mXdEnabled; // The flag indicates if #DB will be setup in #PF handler. // extern BOOLEAN mSetupDebugTrap; +// +// SMI command port. +// +extern UINT32 mSmiCommandPort; #endif // _SMM_PROFILE_H_ diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h index 42a6effe5284..2edfd7a8b220 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h @@ -11,8 +11,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define _SMM_PROFILE_INTERNAL_H_ #include -#include -#include #include #include From cc996831bd518d71e9b68626ca8250f57fc2d911 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 11:58:49 +0800 Subject: [PATCH 072/280] UefiCpuPkg/PiSmmCpuDxeSmm: Add empty .c for MM CPU specific impl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds the empty .c for MM CPU specific implementation: NonMmramMapStandaloneMm.c PiSmmCpuStandaloneMm.c Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c | 8 ++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c | 10 ++++++++++ 2 files changed, 18 insertions(+) create mode 100644 UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c create mode 100644 UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c new file mode 100644 index 000000000000..68f63f3c64c4 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c @@ -0,0 +1,8 @@ +/** @file + +Copyright (c) 2024, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuCommon.h" diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c new file mode 100644 index 000000000000..3471d40cb272 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c @@ -0,0 +1,10 @@ +/** @file +Agent Module to load other modules to deploy MM Entry Vector for X86 CPU. + +Copyright (c) 2024, Intel Corporation. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuCommon.h" From 502a9122a427f3f54def77c046c23214ba3c34b6 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 12:10:38 +0800 Subject: [PATCH 073/280] UefiCpuPkg/PiSmmCpuDxeSmm: Impl GetSmmProfileData for MM MM CPU can not use the dynamic PCD (PcdCpuSmmProfileSize), so it consumes the gMmProfileDataHobGuid memory allocation hob for SmmProfile base address & size. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- .../PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c | 39 +++++++++++++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 1 + 2 files changed, 40 insertions(+) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c index 68f63f3c64c4..1dc610d697b7 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c @@ -6,3 +6,42 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "PiSmmCpuCommon.h" + +/** + Get SmmProfileData. + + @param[in, out] Size Return Size of SmmProfileData. + + @return Address of SmmProfileData + +**/ +EFI_PHYSICAL_ADDRESS +GetSmmProfileData ( + IN OUT UINT64 *Size + ) +{ + EFI_PEI_HOB_POINTERS SmmProfileDataHob; + + ASSERT (Size != NULL); + + // + // Get Smm Profile Base from Memory Allocation HOB + // + SmmProfileDataHob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION); + while (SmmProfileDataHob.Raw != NULL) { + // + // Find gMmProfileDataHobGuid + // + if (CompareGuid (&SmmProfileDataHob.MemoryAllocation->AllocDescriptor.Name, &gMmProfileDataHobGuid)) { + break; + } + + SmmProfileDataHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (SmmProfileDataHob)); + } + + ASSERT (SmmProfileDataHob.Raw != NULL); + + *Size = SmmProfileDataHob.MemoryAllocation->AllocDescriptor.MemoryLength; + + return SmmProfileDataHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress; +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index 4b0d5fb08b86..7f11429e50f3 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -28,6 +28,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include From 1f22b96b11cec64c11ef2681566c7fd50ee9c0cf Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 12:43:51 +0800 Subject: [PATCH 074/280] UefiCpuPkg/PiSmmCpuDxeSmm: Impl GetAcpiS3EnableFlag for MM MM CPU can not use the dynamic PCD (PcdAcpiS3Enable), so, it consumes the gMmAcpiS3EnableHobGuid to get ACPI S3 enable flag. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 1 + .../PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index 7f11429e50f3..1769af2fa616 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -29,6 +29,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c index 3471d40cb272..35657a3b574f 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c @@ -8,3 +8,31 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "PiSmmCpuCommon.h" + +/** + Get ACPI S3 enable flag. + +**/ +VOID +GetAcpiS3EnableFlag ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + MM_ACPI_S3_ENABLE *MmAcpiS3EnableHob; + + MmAcpiS3EnableHob = NULL; + + // + // Get MM_ACPI_S3_ENABLE for Standalone MM init. + // + GuidHob = GetFirstGuidHob (&gMmAcpiS3EnableHobGuid); + ASSERT (GuidHob != NULL); + if (GuidHob != NULL) { + MmAcpiS3EnableHob = GET_GUID_HOB_DATA (GuidHob); + } + + if (MmAcpiS3EnableHob != NULL) { + mAcpiS3Enable = MmAcpiS3EnableHob->AcpiS3Enable; + } +} From 614d6c91bf8ede620afeb76baf352689288e56ed Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 12:47:46 +0800 Subject: [PATCH 075/280] UefiCpuPkg/PiSmmCpuDxeSmm: Impl GetSmmCpuSyncConfigData for MM MM CPU can not use the dynamic PCD (PcdCpuSmmSyncMode & PcdCpuSmmApSyncTimeout & PcdCpuSmmApSyncTimeout2), so, it consumes the gMmCpuSyncConfigHobGuid for RelaxedApMode & Timeout & Timeout2. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 1 + .../PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index 1769af2fa616..9272b9df3d2e 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -30,6 +30,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c index 35657a3b574f..80ce1af4e65b 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c @@ -9,6 +9,51 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PiSmmCpuCommon.h" +/** + Get SmmCpuSyncConfig data: RelaxedMode, SyncTimeout, SyncTimeout2. + + @param[in,out] RelaxedMode It indicates if Relaxed CPU synchronization method or + traditional CPU synchronization method is used when processing an SMI. + @param[in,out] SyncTimeout It indicates the 1st BSP/AP synchronization timeout value in SMM. + @param[in,out] SyncTimeout2 It indicates the 2nd BSP/AP synchronization timeout value in SMM. + + **/ +VOID +GetSmmCpuSyncConfigData ( + IN OUT BOOLEAN *RelaxedMode, OPTIONAL + IN OUT UINT64 *SyncTimeout, OPTIONAL + IN OUT UINT64 *SyncTimeout2 OPTIONAL + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + MM_CPU_SYNC_CONFIG *MmCpuSyncConfigHob; + + MmCpuSyncConfigHob = NULL; + + // + // Get MM_CPU_SYNC_CONFIG for Standalone MM init. + // + GuidHob = GetFirstGuidHob (&gMmCpuSyncConfigHobGuid); + ASSERT (GuidHob != NULL); + if (GuidHob != NULL) { + MmCpuSyncConfigHob = GET_GUID_HOB_DATA (GuidHob); + } + + if (MmCpuSyncConfigHob != NULL) { + if (RelaxedMode != NULL) { + *RelaxedMode = ((MmCpuSyncConfigHob->RelaxedApMode == MmCpuSyncModeRelaxedAp) ? TRUE : FALSE); + } + + if (SyncTimeout != NULL) { + *SyncTimeout = MmCpuSyncConfigHob->Timeout; + } + + if (SyncTimeout2 != NULL) { + *SyncTimeout2 = MmCpuSyncConfigHob->Timeout2; + } + } +} + /** Get ACPI S3 enable flag. From ee54bda382641499443a12805ac986f8d8621c77 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 13:04:57 +0800 Subject: [PATCH 076/280] UefiCpuPkg/PiSmmCpuDxeSmm: Impl CreateExtendedProtectionRange for MM According Standalone MM design, all accessible NON-MMRAM memory shall be in ResourceDescriptor HOBs. So, This patch consumes the Resource HOBs to create extended protection MemoryRegion and add them into protected memory ranges. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- .../PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c | 83 +++++++++++++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 5 +- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c index 1dc610d697b7..3c86c6b28a45 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c @@ -45,3 +45,86 @@ GetSmmProfileData ( return SmmProfileDataHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress; } + +/** + Build Memory Region from ResourceDescriptor HOBs by excluding Logging attribute range. + + @param[out] MemoryRegion Returned Non-Mmram Memory regions. + @param[out] MemoryRegionCount A pointer to the number of Memory regions. +**/ +VOID +BuildMemoryMapFromResDescHobs ( + OUT MM_CPU_MEMORY_REGION **MemoryRegion, + OUT UINTN *MemoryRegionCount + ) +{ + EFI_PEI_HOB_POINTERS Hob; + UINTN Count; + UINTN Index; + + ASSERT (MemoryRegion != NULL && MemoryRegionCount != NULL); + + *MemoryRegion = NULL; + *MemoryRegionCount = 0; + + // + // Get the count. + // + Count = 0; + Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR); + while (Hob.Raw != NULL) { + if ((Hob.ResourceDescriptor->ResourceAttribute & MM_RESOURCE_ATTRIBUTE_LOGGING) == 0) { + // + // Resource HOBs describe all accessible non-smram regions. + // Logging attribute range is treated as not present. Not-present ranges are not included in this memory map. + // + Count++; + } + + Hob.Raw = GET_NEXT_HOB (Hob); + Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw); + } + + *MemoryRegionCount = Count; + + *MemoryRegion = (MM_CPU_MEMORY_REGION *)AllocateZeroPool (sizeof (MM_CPU_MEMORY_REGION) * Count); + ASSERT (*MemoryRegion != NULL); + + Index = 0; + Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR); + while (Hob.Raw != NULL) { + if ((Hob.ResourceDescriptor->ResourceAttribute & MM_RESOURCE_ATTRIBUTE_LOGGING) == 0) { + ASSERT (Index < Count); + (*MemoryRegion)[Index].Base = Hob.ResourceDescriptor->PhysicalStart; + (*MemoryRegion)[Index].Length = Hob.ResourceDescriptor->ResourceLength; + (*MemoryRegion)[Index].Attribute = EFI_MEMORY_XP; + if (Hob.ResourceDescriptor->ResourceAttribute == EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED) { + (*MemoryRegion)[Index].Attribute |= EFI_MEMORY_RO; + } + + Index++; + } + + Hob.Raw = GET_NEXT_HOB (Hob); + Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw); + } + + return; +} + +/** + Build extended protection MemoryRegion. + + The caller is responsible for freeing MemoryRegion via FreePool(). + + @param[out] MemoryRegion Returned Non-Mmram Memory regions. + @param[out] MemoryRegionCount A pointer to the number of Memory regions. +**/ +VOID +CreateExtendedProtectionRange ( + OUT MM_CPU_MEMORY_REGION **MemoryRegion, + OUT UINTN *MemoryRegionCount + ) +{ + BuildMemoryMapFromResDescHobs (MemoryRegion, MemoryRegionCount); +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index f38e8e8e404a..f3ef4df0b097 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -428,6 +428,7 @@ InitProtectedMemRange ( // Create extended protection MemoryRegion and add them into protected memory ranges. // Retrieve the accessible regions when SMM profile is enabled. // In SMM: only MMIO is accessible. + // In MM: all regions described by resource HOBs are accessible. // CreateExtendedProtectionRange (&MemoryRegion, &MemoryRegionCount); ASSERT (MemoryRegion != NULL); @@ -475,7 +476,7 @@ InitProtectedMemRange ( } // - // Create MMIO ranges which are set to present and execution-disable. + // Create protection ranges which are set to present and execution-disable. // for (Index = 0; Index < MemoryRegionCount; Index++) { mProtectionMemRange[NumberOfProtectRange].Range.Base = MemoryRegion[Index].Base; @@ -505,7 +506,7 @@ InitProtectedMemRange ( NumberOfProtectRange = mProtectionMemRangeCount; for (Index = 0; Index < NumberOfProtectRange; Index++) { // - // If MMIO base address is not 2MB alignment, make 2MB alignment for create 4KB page in page table. + // If base address is not 2MB alignment, make 2MB alignment for create 4KB page in page table. // ProtectBaseAddress = mProtectionMemRange[Index].Range.Base; ProtectEndAddress = mProtectionMemRange[Index].Range.Top; From 5f88a4463779054d48e5647c22bf0f64af9a6658 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 13:19:21 +0800 Subject: [PATCH 077/280] UefiCpuPkg/PiSmmCpuDxeSmm: Impl GetSmiCommandPort for MM MM CPU can not call EfiLocateFirstAcpiTable to get the system port address of the SMI Command Port. This patch just hard-code to 0xB2 for MM CPU. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c index 80ce1af4e65b..c0378f5bd22e 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c @@ -9,6 +9,19 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PiSmmCpuCommon.h" +/** + To get system port address of the SMI Command Port. + +**/ +VOID +GetSmiCommandPort ( + VOID + ) +{ + mSmiCommandPort = 0xB2; + DEBUG ((DEBUG_INFO, "mSmiCommandPort = %x\n", mSmiCommandPort)); +} + /** Get SmmCpuSyncConfig data: RelaxedMode, SyncTimeout, SyncTimeout2. From 9ee533479651d29a254a184a56d01809353f0bcc Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 13:28:56 +0800 Subject: [PATCH 078/280] UefiCpuPkg/PiSmmCpuDxeSmm: Define mIsStandaloneMm to indicate SMM or MM Define the mIsStandaloneMm to indicate it's the MM_STANDALONE MM CPU driver or DXE_SMM_DRIVER SMM CPU driver execution. With mIsStandaloneMm, GetMpInformationFromMpServices() can be skipped for the MM CPU since it can not call the GetMpInformationFromMpServices() due to the NON-SMM MP Services usage for the MP Information. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c | 11 +++++--- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 2 ++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 6 +++++ .../PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c | 25 +++++++++++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c index 78bfc8a3e776..48b6fe62c449 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c @@ -625,9 +625,14 @@ GetMpInformation ( HobCount = 0; FirstMpInfo2Hob = GetFirstGuidHob (&gMpInformation2HobGuid); - if (FirstMpInfo2Hob == NULL) { - DEBUG ((DEBUG_INFO, "%a: [INFO] gMpInformation2HobGuid HOB not found.\n", __func__)); - return GetMpInformationFromMpServices (NumberOfCpus, MaxNumberOfCpus); + + if (mIsStandaloneMm) { + ASSERT (FirstMpInfo2Hob != NULL); + } else { + if (FirstMpInfo2Hob == NULL) { + DEBUG ((DEBUG_INFO, "%a: [INFO] gMpInformation2HobGuid HOB not found.\n", __func__)); + return GetMpInformationFromMpServices (NumberOfCpus, MaxNumberOfCpus); + } } GuidHob = FirstMpInfo2Hob; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index 9272b9df3d2e..828080946e9c 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -253,6 +253,8 @@ typedef struct { LIST_ENTRY *FirstFreeToken; } SMM_CPU_PRIVATE_DATA; +extern const BOOLEAN mIsStandaloneMm; + extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate; extern CPU_HOT_PLUG_DATA mCpuHotPlugData; extern UINTN mMaxNumberOfCpus; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index 8995b54226fe..97b2bc6efb17 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -12,6 +12,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PiSmmCpuCommon.h" #include +// +// TRUE to indicate it's the MM_STANDALONE MM CPU driver. +// FALSE to indicate it's the DXE_SMM_DRIVER SMM CPU driver. +// +const BOOLEAN mIsStandaloneMm = FALSE; + /** To get system port address of the SMI Command Port in FADT table. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c index c0378f5bd22e..235e53cde5ab 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c @@ -9,6 +9,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PiSmmCpuCommon.h" +// +// TRUE to indicate it's the MM_STANDALONE MM CPU driver. +// FALSE to indicate it's the DXE_SMM_DRIVER SMM CPU driver. +// +const BOOLEAN mIsStandaloneMm = TRUE; + /** To get system port address of the SMI Command Port. @@ -94,3 +100,22 @@ GetAcpiS3EnableFlag ( mAcpiS3Enable = MmAcpiS3EnableHob->AcpiS3Enable; } } + +/** + Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION. + + @param[out] NumberOfCpus Pointer to NumberOfCpus. + @param[out] MaxNumberOfCpus Pointer to MaxNumberOfCpus. + + @retval ProcessorInfo Pointer to EFI_PROCESSOR_INFORMATION buffer. +**/ +EFI_PROCESSOR_INFORMATION * +GetMpInformationFromMpServices ( + OUT UINTN *NumberOfCpus, + OUT UINTN *MaxNumberOfCpus + ) +{ + ASSERT (FALSE); + + return NULL; +} From 167e902624c9ccdf28920c099ee2d5e74d9c85a3 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 13:41:45 +0800 Subject: [PATCH 079/280] UefiCpuPkg/PiSmmCpuDxeSmm: Impl IsSmmCommBufferForbiddenAddress for MM Since all accessible NON-MMRAM memory shall be in ResourceDescriptor HOBs, check the ResourceDescriptor HOBs to return if the Address is forbidden or not for MM CPU. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- .../PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c index 3c86c6b28a45..3ae074c63df1 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c @@ -46,6 +46,34 @@ GetSmmProfileData ( return SmmProfileDataHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress; } +/** + Return if the Address is forbidden as SMM communication buffer. + + @param[in] Address the address to be checked + + @return TRUE The address is forbidden as SMM communication buffer. + @return FALSE The address is allowed as SMM communication buffer. +**/ +BOOLEAN +IsSmmCommBufferForbiddenAddress ( + IN UINT64 Address + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR); + while (Hob.Raw != NULL) { + if ((Address >= Hob.ResourceDescriptor->PhysicalStart) && (Address < Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength)) { + return FALSE; + } + + Hob.Raw = GET_NEXT_HOB (Hob); + Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw); + } + + return TRUE; +} + /** Build Memory Region from ResourceDescriptor HOBs by excluding Logging attribute range. From 7b9b4ed57fac9c5339071ce7672fbbc8d7dd2eca Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 1 Jul 2024 16:14:51 +0800 Subject: [PATCH 080/280] UefiCpuPkg/PiSmmCpuDxeSmm: Add GetSupportedMaxLogicalProcessorNumber MM CPU can not use the dynamic PCD (PcdCpuMaxLogicalProcessorNumber), so move the PCD usage to DxeSmm. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c | 18 +++++++++-------- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 11 ++++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 20 ++++++++++++++++--- .../PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c | 16 +++++++++++++++ 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c index 48b6fe62c449..ecb16454ca54 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c @@ -652,15 +652,17 @@ GetMpInformation ( GuidHob = GetNextGuidHob (&gMpInformation2HobGuid, GET_NEXT_HOB (GuidHob)); } - ASSERT (*NumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + *MaxNumberOfCpus = *NumberOfCpus; - // - // If support CPU hot plug, we need to allocate resources for possibly hot-added processors - // - if (FeaturePcdGet (PcdCpuHotPlugSupport)) { - *MaxNumberOfCpus = PcdGet32 (PcdCpuMaxLogicalProcessorNumber); - } else { - *MaxNumberOfCpus = *NumberOfCpus; + if (!mIsStandaloneMm) { + ASSERT (*NumberOfCpus <= GetSupportedMaxLogicalProcessorNumber ()); + + // + // If support CPU hot plug, we need to allocate resources for possibly hot-added processors + // + if (FeaturePcdGet (PcdCpuHotPlugSupport)) { + *MaxNumberOfCpus = GetSupportedMaxLogicalProcessorNumber (); + } } MpInfo2Hobs = AllocatePool (sizeof (MP_INFORMATION2_HOB_DATA *) * HobCount); diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index 828080946e9c..475da8f1d744 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -1558,6 +1558,17 @@ SmmWriteProtectReadOnlyPage ( } \ } while (FALSE) +/** + Get the maximum number of logical processors supported by the system. + + @retval The maximum number of logical processors supported by the system + is indicated by the return value. +**/ +UINTN +GetSupportedMaxLogicalProcessorNumber ( + VOID + ); + /** Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from gEfiMpServiceProtocolGuid. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index 97b2bc6efb17..c5e7f4363b6e 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -121,6 +121,20 @@ GetAcpiS3EnableFlag ( mAcpiS3Enable = PcdGetBool (PcdAcpiS3Enable); } +/** + Get the maximum number of logical processors supported by the system. + + @retval The maximum number of logical processors supported by the system + is indicated by the return value. +**/ +UINTN +GetSupportedMaxLogicalProcessorNumber ( + VOID + ) +{ + return PcdGet32 (PcdCpuMaxLogicalProcessorNumber); +} + /** Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from gEfiMpServiceProtocolGuid. @@ -165,7 +179,7 @@ GetMpInformationFromMpServices ( return NULL; } - ASSERT (NumberOfProcessors <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + ASSERT (NumberOfProcessors <= GetSupportedMaxLogicalProcessorNumber ()); /// Allocate buffer for processor information ProcessorInfo = AllocateZeroPool (sizeof (EFI_PROCESSOR_INFORMATION) * NumberOfProcessors); @@ -187,12 +201,12 @@ GetMpInformationFromMpServices ( *NumberOfCpus = NumberOfEnabledProcessors; - ASSERT (*NumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + ASSERT (*NumberOfCpus <= GetSupportedMaxLogicalProcessorNumber ()); // // If support CPU hot plug, we need to allocate resources for possibly hot-added processors // if (FeaturePcdGet (PcdCpuHotPlugSupport)) { - *MaxNumberOfCpus = PcdGet32 (PcdCpuMaxLogicalProcessorNumber); + *MaxNumberOfCpus = GetSupportedMaxLogicalProcessorNumber (); } else { *MaxNumberOfCpus = *NumberOfCpus; } diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c index 235e53cde5ab..ed5466a74d23 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c @@ -101,6 +101,22 @@ GetAcpiS3EnableFlag ( } } +/** + Get the maximum number of logical processors supported by the system. + + @retval The maximum number of logical processors supported by the system + is indicated by the return value. +**/ +UINTN +GetSupportedMaxLogicalProcessorNumber ( + VOID + ) +{ + ASSERT (FALSE); + + return 0; +} + /** Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION. From 14cb36685bdc260d67c119a81f55e49a1f8e0ca3 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 13:46:20 +0800 Subject: [PATCH 081/280] UefiCpuPkg/PiSmmCpuDxeSmm: Add PiCpuStandaloneMmEntry for MM This patch adds the PiCpuStandaloneMmEntry for MM, which is the module Entry Point of the CPU StandaloneMm driver. In the Entry Point: 1. Init the mIsStandaloneMm flag 2. Call PiSmmCpuEntryCommon 3. Init SmiCommandPort 4. Install the SMM Configuration Protocol. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- .../PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c index ed5466a74d23..7d143e78ebc1 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c @@ -135,3 +135,49 @@ GetMpInformationFromMpServices ( return NULL; } + +/** + The module Entry Point of the CPU StandaloneMm driver. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the MM System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval Other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +PiCpuStandaloneMmEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_MM_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = PiSmmCpuEntryCommon (); + + ASSERT_EFI_ERROR (Status); + + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + // + // Get Software SMI + // + GetSmiCommandPort (); + } + + // + // Install the SMM Configuration Protocol onto a new handle on the handle database. + // The entire SMM Configuration Protocol is allocated from SMRAM, so only a pointer + // to an SMRAM address will be present in the handle database + // + Status = gMmst->MmInstallProtocolInterface ( + &gSmmCpuPrivate->SmmCpuHandle, + &gEfiSmmConfigurationProtocolGuid, + EFI_NATIVE_INTERFACE, + &gSmmCpuPrivate->SmmConfiguration + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} From 1c19ccd5103b918efef9c4076e92d175cfba8d81 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 14:49:01 +0800 Subject: [PATCH 082/280] UefiCpuPkg/PiSmmCpuDxeSmm: Refactor code to create default Page Table For MM: Since all accessible NON-MMRAM memory and attribute shall be in ResourceDescriptor HOBs for MM, the page table for MM can be finalized and created in the default Page. For SMM: There are still 2 steps for the finalized default Page: 1. Create default Page 2. update the page table in the first SMI when SMM ready to lock happen This patch to refactor the GenSmmPageTable() function to create the default Page Table for Both SMM and MM: 1. Create NonMmram MemoryRegion 2. Gen NonMmram MemoryRegion PageTable 3. Gen MMRAM Range PageTable 4. Consider PcdCpuSmmStackGuard & PcdNullPointerDetectionPropertyMask cases. Meanwhile, mXdSupported needs to be initialized before GenSmmPageTable since it's required by GenSmmPageTable function. So, move the mXdSupported init from CheckFeatureSupported to the common EntryPoint function. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c | 67 +++++++ .../PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c | 20 +++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c | 57 ++++-- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 21 ++- .../PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 166 +++++++++++++++--- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 27 --- .../PiSmmCpuDxeSmm/SmmProfileInternal.h | 5 +- 7 files changed, 289 insertions(+), 74 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c index be5b333cd18c..8dbcd8d95091 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c @@ -601,3 +601,70 @@ CreateExtendedProtectionRange ( return; } + +/** + Create the Non-Mmram Memory Region. + Build MemoryRegion to cover [0, 2^PhysicalAddressBits) by excluding all Smram range. + The memory attribute is all-allowed (read/write/executable). + + The caller is responsible for freeing MemoryRegion via FreePool(). + + @param[in] PhysicalAddressBits The bits of physical address to map. + @param[out] MemoryRegion Returned Non-Mmram Memory regions. + @param[out] MemoryRegionCount A pointer to the number of Memory regions. +**/ +VOID +CreateNonMmramMemMap ( + IN UINT8 PhysicalAddressBits, + OUT MM_CPU_MEMORY_REGION **MemoryRegion, + OUT UINTN *MemoryRegionCount + ) +{ + UINT64 MaxLength; + UINTN Count; + UINTN Index; + UINT64 PreviousAddress; + UINT64 Base; + UINT64 Length; + + ASSERT (MemoryRegion != NULL && MemoryRegionCount != NULL); + + *MemoryRegion = NULL; + *MemoryRegionCount = 0; + + MaxLength = LShiftU64 (1, PhysicalAddressBits); + + // + // Build MemoryRegion to cover [0, 2^PhysicalAddressBits) by excluding all Smram range + // + Count = mSmmCpuSmramRangeCount + 1; + + *MemoryRegionCount = Count; + + *MemoryRegion = (MM_CPU_MEMORY_REGION *)AllocateZeroPool (sizeof (MM_CPU_MEMORY_REGION) * Count); + ASSERT (*MemoryRegion != NULL); + + PreviousAddress = 0; + for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) { + Base = mSmmCpuSmramRanges[Index].CpuStart; + Length = mSmmCpuSmramRanges[Index].PhysicalSize; + + ASSERT (MaxLength > Base + Length); + + if (Base > PreviousAddress) { + (*MemoryRegion)[Index].Base = PreviousAddress; + (*MemoryRegion)[Index].Length = Base - PreviousAddress; + (*MemoryRegion)[Index].Attribute = 0; + } + + PreviousAddress = Base + Length; + } + + // + // Set the last remaining range + // + if (PreviousAddress < MaxLength) { + (*MemoryRegion)[Index].Base = PreviousAddress; + (*MemoryRegion)[Index].Length = MaxLength - PreviousAddress; + } +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c index 3ae074c63df1..8c5286b74472 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c @@ -156,3 +156,23 @@ CreateExtendedProtectionRange ( { BuildMemoryMapFromResDescHobs (MemoryRegion, MemoryRegionCount); } + +/** + Create the Non-Mmram Memory Region within the ResourceDescriptor HOBs + without Logging attribute. + + The caller is responsible for freeing MemoryRegion via FreePool(). + + @param[in] PhysicalAddressBits The bits of physical address to map. + @param[out] MemoryRegion Returned Non-Mmram Memory regions. + @param[out] MemoryRegionCount A pointer to the number of Memory regions. +**/ +VOID +CreateNonMmramMemMap ( + IN UINT8 PhysicalAddressBits, + OUT MM_CPU_MEMORY_REGION **MemoryRegion, + OUT UINTN *MemoryRegionCount + ) +{ + BuildMemoryMapFromResDescHobs (MemoryRegion, MemoryRegionCount); +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c index ecb16454ca54..ba559afae6c2 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c @@ -728,19 +728,20 @@ PiSmmCpuEntryCommon ( VOID ) { - EFI_STATUS Status; - UINTN Index; - UINTN TileCodeSize; - UINTN TileDataSize; - UINTN TileSize; - UINT8 *Stacks; - UINT32 RegEax; - UINT32 RegEbx; - UINT32 RegEcx; - UINT32 RegEdx; - UINTN FamilyId; - UINTN ModelId; - UINT32 Cr3; + EFI_STATUS Status; + UINTN Index; + UINTN TileCodeSize; + UINTN TileDataSize; + UINTN TileSize; + UINT8 *Stacks; + UINT32 RegEax; + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; + CPUID_EXTENDED_CPU_SIG_EDX ExtendedRegEdx; + UINTN FamilyId; + UINTN ModelId; + UINT32 Cr3; PERF_FUNCTION_BEGIN (); @@ -928,6 +929,36 @@ PiSmmCpuEntryCommon ( PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); } + // + // Check XD supported or not. + // + RegEax = 0; + ExtendedRegEdx.Uint32 = 0; + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); + if (RegEax <= CPUID_EXTENDED_FUNCTION) { + // + // Extended CPUID functions are not supported on this processor. + // + mXdSupported = FALSE; + PatchInstructionX86 (gPatchXdSupported, mXdSupported, 1); + } + + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &ExtendedRegEdx.Uint32); + if (ExtendedRegEdx.Bits.NX == 0) { + // + // Execute Disable Bit feature is not supported on this processor. + // + mXdSupported = FALSE; + PatchInstructionX86 (gPatchXdSupported, mXdSupported, 1); + } + + if (StandardSignatureIsAuthenticAMD ()) { + // + // AMD processors do not support MSR_IA32_MISC_ENABLE + // + PatchInstructionX86 (gPatchMsrIa32MiscEnableSupported, FALSE, 1); + } + // // Compute tile size of buffer required to hold the CPU SMRAM Save State Map, extra CPU // specific context start starts at SMBASE + SMM_PSD_OFFSET, and the SMI entry point. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index 475da8f1d744..5b2202490e97 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -959,7 +959,7 @@ IsSmmCommBufferForbiddenAddress ( IN UINT64 Address ); -/* +/** Build extended protection MemoryRegion. The caller is responsible for freeing MemoryRegion via FreePool(). @@ -967,13 +967,30 @@ IsSmmCommBufferForbiddenAddress ( @param[out] MemoryRegion Returned Non-Mmram Memory regions. @param[out] MemoryRegionCount A pointer to the number of Memory regions. -*/ +**/ VOID CreateExtendedProtectionRange ( OUT MM_CPU_MEMORY_REGION **MemoryRegion, OUT UINTN *MemoryRegionCount ); +/** + Create the Non-Mmram Memory Region. + + The caller is responsible for freeing MemoryRegion via FreePool(). + + @param[in] PhysicalAddressBits The bits of physical address to map. + @param[out] MemoryRegion Returned Non-Mmram Memory regions. + @param[out] MemoryRegionCount A pointer to the number of Memory regions. + +**/ +VOID +CreateNonMmramMemMap ( + IN UINT8 PhysicalAddressBits, + OUT MM_CPU_MEMORY_REGION **MemoryRegion, + OUT UINTN *MemoryRegionCount + ); + /** This function caches the UEFI memory map information. **/ diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c index 76eaaec98161..cf1e49d89b29 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c @@ -1169,6 +1169,64 @@ EdkiiSmmClearMemoryAttributes ( return SmmClearMemoryAttributes (BaseAddress, Length, Attributes); } +/** + Create page table based on input PagingMode, LinearAddress and Length. + + @param[in, out] PageTable The pointer to the page table. + @param[in] PagingMode The paging mode. + @param[in] LinearAddress The start of the linear address range. + @param[in] Length The length of the linear address range. + @param[in] MapAttribute The MapAttribute of the linear address range + @param[in] MapMask The MapMask used for attribute. The corresponding field in Attribute is ignored if that in MapMask is 0. + +**/ +VOID +GenPageTable ( + IN OUT UINTN *PageTable, + IN PAGING_MODE PagingMode, + IN UINT64 LinearAddress, + IN UINT64 Length, + IN IA32_MAP_ATTRIBUTE MapAttribute, + IN IA32_MAP_ATTRIBUTE MapMask + ) +{ + RETURN_STATUS Status; + UINTN PageTableBufferSize; + VOID *PageTableBuffer; + + PageTableBufferSize = 0; + + Status = PageTableMap ( + PageTable, + PagingMode, + NULL, + &PageTableBufferSize, + LinearAddress, + Length, + &MapAttribute, + &MapMask, + NULL + ); + if (Status == RETURN_BUFFER_TOO_SMALL) { + PageTableBuffer = AllocatePageTableMemory (EFI_SIZE_TO_PAGES (PageTableBufferSize)); + ASSERT (PageTableBuffer != NULL); + Status = PageTableMap ( + PageTable, + PagingMode, + PageTableBuffer, + &PageTableBufferSize, + LinearAddress, + Length, + &MapAttribute, + &MapMask, + NULL + ); + } + + ASSERT (Status == RETURN_SUCCESS); + ASSERT (PageTableBufferSize == 0); +} + /** Create page table based on input PagingMode and PhysicalAddressBits in smm. @@ -1184,35 +1242,85 @@ GenSmmPageTable ( IN UINT8 PhysicalAddressBits ) { - UINTN PageTableBufferSize; - UINTN PageTable; - VOID *PageTableBuffer; - IA32_MAP_ATTRIBUTE MapAttribute; - IA32_MAP_ATTRIBUTE MapMask; - RETURN_STATUS Status; - UINTN GuardPage; - UINTN Index; - UINT64 Length; - - Length = LShiftU64 (1, PhysicalAddressBits); - PageTable = 0; - PageTableBufferSize = 0; - MapMask.Uint64 = MAX_UINT64; - MapAttribute.Uint64 = mAddressEncMask; - MapAttribute.Bits.Present = 1; - MapAttribute.Bits.ReadWrite = 1; - MapAttribute.Bits.UserSupervisor = 1; - MapAttribute.Bits.Accessed = 1; - MapAttribute.Bits.Dirty = 1; - - Status = PageTableMap (&PageTable, PagingMode, NULL, &PageTableBufferSize, 0, Length, &MapAttribute, &MapMask, NULL); - ASSERT (Status == RETURN_BUFFER_TOO_SMALL); - DEBUG ((DEBUG_INFO, "GenSMMPageTable: 0x%x bytes needed for initial SMM page table\n", PageTableBufferSize)); - PageTableBuffer = AllocatePageTableMemory (EFI_SIZE_TO_PAGES (PageTableBufferSize)); - ASSERT (PageTableBuffer != NULL); - Status = PageTableMap (&PageTable, PagingMode, PageTableBuffer, &PageTableBufferSize, 0, Length, &MapAttribute, &MapMask, NULL); - ASSERT (Status == RETURN_SUCCESS); - ASSERT (PageTableBufferSize == 0); + UINTN PageTable; + UINTN Index; + MM_CPU_MEMORY_REGION *MemoryRegion; + UINTN MemoryRegionCount; + IA32_MAP_ATTRIBUTE MapAttribute; + IA32_MAP_ATTRIBUTE MapMask; + RETURN_STATUS Status; + UINTN GuardPage; + + PageTable = 0; + MemoryRegion = NULL; + MemoryRegionCount = 0; + MapMask.Uint64 = MAX_UINT64; + + // + // 1. Create NonMmram MemoryRegion + // + CreateNonMmramMemMap (PhysicalAddressBits, &MemoryRegion, &MemoryRegionCount); + ASSERT (MemoryRegion != NULL && MemoryRegionCount != 0); + + // + // 2. Gen NonMmram MemoryRegion PageTable + // + for (Index = 0; Index < MemoryRegionCount; Index++) { + ASSERT (MemoryRegion[Index].Base % SIZE_4KB == 0); + ASSERT (MemoryRegion[Index].Length % EFI_PAGE_SIZE == 0); + + // + // Set the MapAttribute + // + MapAttribute.Uint64 = mAddressEncMask|MemoryRegion[Index].Base; + MapAttribute.Bits.Present = 1; + MapAttribute.Bits.ReadWrite = 1; + MapAttribute.Bits.UserSupervisor = 1; + MapAttribute.Bits.Accessed = 1; + MapAttribute.Bits.Dirty = 1; + + // + // Update the MapAttribute according MemoryRegion[Index].Attribute + // + if ((MemoryRegion[Index].Attribute & EFI_MEMORY_RO) != 0) { + MapAttribute.Bits.ReadWrite = 0; + } + + if ((MemoryRegion[Index].Attribute & EFI_MEMORY_XP) != 0) { + if (mXdSupported) { + MapAttribute.Bits.Nx = 1; + } + } + + GenPageTable (&PageTable, PagingMode, MemoryRegion[Index].Base, (UINTN)MemoryRegion[Index].Length, MapAttribute, MapMask); + } + + // + // Free the MemoryRegion after usage + // + if (MemoryRegion != NULL) { + FreePool (MemoryRegion); + } + + // + // 3. Gen MMRAM Range PageTable + // + for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) { + ASSERT (mSmmCpuSmramRanges[Index].CpuStart % SIZE_4KB == 0); + ASSERT (mSmmCpuSmramRanges[Index].PhysicalSize % EFI_PAGE_SIZE == 0); + + // + // Set the MapAttribute + // + MapAttribute.Uint64 = mAddressEncMask|mSmmCpuSmramRanges[Index].CpuStart; + MapAttribute.Bits.Present = 1; + MapAttribute.Bits.ReadWrite = 1; + MapAttribute.Bits.UserSupervisor = 1; + MapAttribute.Bits.Accessed = 1; + MapAttribute.Bits.Dirty = 1; + + GenPageTable (&PageTable, PagingMode, mSmmCpuSmramRanges[Index].CpuStart, mSmmCpuSmramRanges[Index].PhysicalSize, MapAttribute, MapMask); + } if (FeaturePcdGet (PcdCpuSmmStackGuard)) { // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index f3ef4df0b097..ba83c37cbf9c 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -884,33 +884,6 @@ CheckFeatureSupported ( } } - if (mXdSupported) { - AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); - if (RegEax <= CPUID_EXTENDED_FUNCTION) { - // - // Extended CPUID functions are not supported on this processor. - // - mXdSupported = FALSE; - PatchInstructionX86 (gPatchXdSupported, mXdSupported, 1); - } - - AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx); - if ((RegEdx & CPUID1_EDX_XD_SUPPORT) == 0) { - // - // Execute Disable Bit feature is not supported on this processor. - // - mXdSupported = FALSE; - PatchInstructionX86 (gPatchXdSupported, mXdSupported, 1); - } - - if (StandardSignatureIsAuthenticAMD ()) { - // - // AMD processors do not support MSR_IA32_MISC_ENABLE - // - PatchInstructionX86 (gPatchMsrIa32MiscEnableSupported, FALSE, 1); - } - } - if (mBtsSupported) { AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx); if ((RegEdx & CPUID1_EDX_BTS_AVAILABLE) != 0) { diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h index 2edfd7a8b220..e8f3f6492f80 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h @@ -39,9 +39,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent // // CPU generic definition // -#define CPUID1_EDX_XD_SUPPORT 0x100000 -#define MSR_EFER 0xc0000080 -#define MSR_EFER_XD 0x800 +#define MSR_EFER 0xc0000080 +#define MSR_EFER_XD 0x800 #define CPUID1_EDX_BTS_AVAILABLE 0x200000 From 268397a8923173330b473b8a1d6b21000bc3b7d1 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 15:28:36 +0800 Subject: [PATCH 083/280] UefiCpuPkg/PiSmmCpuDxeSmm: Enable CodeAccessCheck in MM Entry Point For MM: CodeAccessCheck is designed to enable in the MM CPU Driver Entry Point. For SMM: CodeAccessCheck is still enabled in the first SMI when SMM ready to lock happen. This patch enables the CodeAccessCheck in MM CPU Driver Entry Point for MM support. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c | 40 ++++++++++------------ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 13 +++++++ UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 17 ++++++++- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h | 3 +- 4 files changed, 50 insertions(+), 23 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c index ba559afae6c2..cd43619d1735 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c @@ -362,7 +362,20 @@ InitializeSmm ( // // Check XD and BTS features on each processor on normal boot // - CheckFeatureSupported (); + CheckFeatureSupported (Index); + + if (mIsStandaloneMm) { + AcquireSpinLock (mConfigSmmCodeAccessCheckLock); + + // + // Standalone MM does not allow call out to DXE at anytime. + // Code Access check can be enabled in the first SMI. + // While SMM needs to defer the enabling to EndOfDxe. + // + // Enable SMM Code Access Check feature. + // + ConfigSmmCodeAccessCheckOnCurrentProcessor (&Index); + } } else if (IsBsp) { // // BSP rebase is already done above. @@ -410,6 +423,11 @@ ExecuteFirstSmiInit ( // ZeroMem ((VOID *)mSmmInitialized, sizeof (BOOLEAN) * mMaxNumberOfCpus); + // + // Initialize the lock used to serialize the MSR programming in BSP and all APs + // + InitializeSpinLock (mConfigSmmCodeAccessCheckLock); + // // Get the BSP ApicId. // @@ -1427,26 +1445,6 @@ ConfigSmmCodeAccessCheck ( // Check to see if the Feature Control MSR is supported on this CPU // Index = gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu; - if (!SmmCpuFeaturesIsSmmRegisterSupported (Index, SmmRegFeatureControl)) { - mSmmCodeAccessCheckEnable = FALSE; - PERF_FUNCTION_END (); - return; - } - - // - // Check to see if the CPU supports the SMM Code Access Check feature - // Do not access this MSR unless the CPU supports the SmmRegFeatureControl - // - if ((AsmReadMsr64 (EFI_MSR_SMM_MCA_CAP) & SMM_CODE_ACCESS_CHK_BIT) == 0) { - mSmmCodeAccessCheckEnable = FALSE; - PERF_FUNCTION_END (); - return; - } - - // - // Initialize the lock used to serialize the MSR programming in BSP and all APs - // - InitializeSpinLock (mConfigSmmCodeAccessCheckLock); // // Acquire Config SMM Code Access Check spin lock. The BSP will release the diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index 5b2202490e97..a0b5e6fafb71 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -474,6 +474,7 @@ extern EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges; extern UINTN mSmmCpuSmramRangeCount; extern UINT8 mPhysicalAddressBits; extern BOOLEAN mSmmDebugAgentSupport; +extern BOOLEAN mSmmCodeAccessCheckEnable; // // Copy of the PcdPteMemoryEncryptionAddressOrMask @@ -847,6 +848,18 @@ InitMsrSpinLockByIndex ( IN UINT32 MsrIndex ); +/** +Configure SMM Code Access Check feature on an AP. +SMM Feature Control MSR will be locked after configuration. + +@param[in,out] Buffer Pointer to private data buffer. +**/ +VOID +EFIAPI +ConfigSmmCodeAccessCheckOnCurrentProcessor ( + IN OUT VOID *Buffer + ); + /** Configure SMM Code Access Check feature for all processors. SMM Feature Control MSR will be locked after configuration. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index ba83c37cbf9c..bbac6064e23d 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -859,10 +859,11 @@ InitSmmProfileInternal ( /** Check if feature is supported by a processor. + @param CpuIndex The index of the CPU. **/ VOID CheckFeatureSupported ( - VOID + IN UINTN CpuIndex ) { UINT32 RegEax; @@ -904,6 +905,20 @@ CheckFeatureSupported ( } } } + + if (mSmmCodeAccessCheckEnable) { + if (!SmmCpuFeaturesIsSmmRegisterSupported (CpuIndex, SmmRegFeatureControl)) { + mSmmCodeAccessCheckEnable = FALSE; + } + + // + // Check to see if the CPU supports the SMM Code Access Check feature + // Do not access this MSR unless the CPU supports the SmmRegFeatureControl + // + if ((AsmReadMsr64 (EFI_MSR_SMM_MCA_CAP) & SMM_CODE_ACCESS_CHK_BIT) == 0) { + mSmmCodeAccessCheckEnable = FALSE; + } + } } /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h index 7a0f006d778b..b34aab41efcb 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h @@ -83,10 +83,11 @@ PageFaultIdtHandlerSmmProfile ( /** Check if feature is supported by a processor. + @param CpuIndex The index of the CPU. **/ VOID CheckFeatureSupported ( - VOID + IN UINTN CpuIndex ); /** From 79468b58c31e9fcbc6bd7aa1955876fc516bebc4 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 15:43:52 +0800 Subject: [PATCH 084/280] UefiCpuPkg/PiSmmCpuDxeSmm: Differentiate PerformRemainingTasks For MM: SMRAM & PageTable itself & SMM Paging State shall be configured once the gEdkiiPiMmMemoryAttributesTableGuid is installed by SMM core. It will happen after MmIpl.Entrypoint. PerformRemainingTasks will be called before MmIpl.Entrypoint exit. For SMM: SMRAM & PageTable itself & SMM Paging State are still configured in the first SMI when SMM ready to lock happen. So, this patch is to differentiate PerformRemainingTasks for MM and SMM. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c | 81 ---------------- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 24 ++++- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 92 +++++++++++++++++++ .../PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c | 57 ++++++++++++ .../PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 38 ++++---- 5 files changed, 189 insertions(+), 103 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c index cd43619d1735..c5921a6de838 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c @@ -96,11 +96,6 @@ BOOLEAN mCetSupported = TRUE; UINTN mMaxNumberOfCpus = 0; UINTN mNumberOfCpus = 0; -// -// SMM ready to lock flag -// -BOOLEAN mSmmReadyToLock = FALSE; - // // Global used to cache PCD for SMM Code Access Check enable // @@ -1525,82 +1520,6 @@ AllocateCodePages ( return (VOID *)(UINTN)Memory; } -/** - Perform the remaining tasks. - -**/ -VOID -PerformRemainingTasks ( - VOID - ) -{ - if (mSmmReadyToLock) { - PERF_FUNCTION_BEGIN (); - - // - // Check if all Aps enter SMM. In Relaxed-AP Sync Mode, BSP will not wait for - // all Aps arrive. However,PerformRemainingTasks() needs to wait all Aps arrive before calling - // SetMemMapAttributes() and ConfigSmmCodeAccessCheck() when mSmmReadyToLock - // is true. In SetMemMapAttributes(), SmmSetMemoryAttributesEx() will call - // FlushTlbForAll() that need to start up the aps. So it need to let all - // aps arrive. Same as SetMemMapAttributes(), ConfigSmmCodeAccessCheck() - // also will start up the aps. - // - if (EFI_ERROR (SmmCpuRendezvous (NULL, TRUE))) { - DEBUG ((DEBUG_ERROR, "PerformRemainingTasks: fail to wait for all AP check in SMM!\n")); - } - - // - // Start SMM Profile feature - // - if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { - SmmProfileStart (); - } - - // - // Create a mix of 2MB and 4KB page table. Update some memory ranges absent and execute-disable. - // - InitPaging (); - - // - // Mark critical region to be read-only in page table - // - SetMemMapAttributes (); - - if (IsRestrictedMemoryAccess ()) { - // - // For outside SMRAM, we only map SMM communication buffer or MMIO. - // - SetUefiMemMapAttributes (); - - // - // Set page table itself to be read-only - // - SetPageTableAttributes (); - } - - // - // Configure SMM Code Access Check feature if available. - // - ConfigSmmCodeAccessCheck (); - - // - // Measure performance of SmmCpuFeaturesCompleteSmmReadyToLock() from caller side - // as the implementation is provided by platform. - // - PERF_START (NULL, "SmmCompleteReadyToLock", NULL, 0); - SmmCpuFeaturesCompleteSmmReadyToLock (); - PERF_END (NULL, "SmmCompleteReadyToLock", NULL, 0); - - // - // Clean SMM ready to lock flag - // - mSmmReadyToLock = FALSE; - - PERF_FUNCTION_END (); - } -} - /** Perform the pre tasks. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index a0b5e6fafb71..44bf3f3aba4f 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -273,7 +273,6 @@ extern UINT8 mSmmSaveStateRegisterLma; extern BOOLEAN mBtsSupported; extern UINTN mMsrDsAreaSize; extern BOOLEAN mAcpiS3Enable; -extern BOOLEAN mSmmReadyToLock; #define PAGE_TABLE_POOL_ALIGNMENT BASE_128KB #define PAGE_TABLE_POOL_UNIT_SIZE BASE_128KB @@ -780,6 +779,24 @@ SmmClearMemoryAttributes ( IN UINT64 Attributes ); +/** + Retrieves a pointer to the system configuration table from the SMM System Table + based on a specified GUID. + + @param[in] TableGuid The pointer to table's GUID type. + @param[out] Table The pointer to the table associated with TableGuid in the EFI System Table. + + @retval EFI_SUCCESS A configuration table matching TableGuid was found. + @retval EFI_NOT_FOUND A configuration table matching TableGuid could not be found. + +**/ +EFI_STATUS +EFIAPI +SmmGetSystemConfigurationTable ( + IN EFI_GUID *TableGuid, + OUT VOID **Table + ); + /** Initialize MP synchronization data. @@ -932,10 +949,13 @@ DumpModuleInfoByIp ( /** This function sets memory attribute according to MemoryAttributesTable. + + @param MemoryAttributesTable A pointer to the buffer of SmmMemoryAttributesTable. + **/ VOID SetMemMapAttributes ( - VOID + EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable ); /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index c5e7f4363b6e..959e993bda33 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -18,6 +18,98 @@ SPDX-License-Identifier: BSD-2-Clause-Patent // const BOOLEAN mIsStandaloneMm = FALSE; +// +// SMM ready to lock flag +// +BOOLEAN mSmmReadyToLock = FALSE; + +/** + Perform the remaining tasks. + +**/ +VOID +PerformRemainingTasks ( + VOID + ) +{ + EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; + + if (mSmmReadyToLock) { + PERF_FUNCTION_BEGIN (); + + // + // Start SMM Profile feature + // + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + SmmProfileStart (); + } + + // + // Check if all Aps enter SMM. In Relaxed-AP Sync Mode, BSP will not wait for + // all Aps arrive. However,PerformRemainingTasks() needs to wait all Aps arrive before calling + // SetMemMapAttributes() and ConfigSmmCodeAccessCheck() when mSmmReadyToLock + // is true. In SetMemMapAttributes(), SmmSetMemoryAttributesEx() will call + // FlushTlbForAll() that need to start up the aps. So it need to let all + // aps arrive. Same as SetMemMapAttributes(), ConfigSmmCodeAccessCheck() + // also will start up the aps. + // + if (EFI_ERROR (SmmCpuRendezvous (NULL, TRUE))) { + DEBUG ((DEBUG_ERROR, "PerformRemainingTasks: fail to wait for all AP check in SMM!\n")); + } + + // + // Create a mix of 2MB and 4KB page table. Update some memory ranges absent and execute-disable. + // + InitPaging (); + + // + // gEdkiiPiSmmMemoryAttributesTableGuid should have been published at EndOfDxe by SmmCore + // Note: gEdkiiPiSmmMemoryAttributesTableGuid is not always installed since it depends on + // the memory protection attribute setting in MM Core. + // + SmmGetSystemConfigurationTable (&gEdkiiPiSmmMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable); + + // + // Set critical region attribute in page table according to the MemoryAttributesTable + // + if (MemoryAttributesTable != NULL) { + SetMemMapAttributes (MemoryAttributesTable); + } + + if (IsRestrictedMemoryAccess ()) { + // + // For outside SMRAM, we only map SMM communication buffer or MMIO. + // + SetUefiMemMapAttributes (); + + // + // Set page table itself to be read-only + // + SetPageTableAttributes (); + } + + // + // Configure SMM Code Access Check feature if available. + // + ConfigSmmCodeAccessCheck (); + + // + // Measure performance of SmmCpuFeaturesCompleteSmmReadyToLock() from caller side + // as the implementation is provided by platform. + // + PERF_START (NULL, "SmmCompleteReadyToLock", NULL, 0); + SmmCpuFeaturesCompleteSmmReadyToLock (); + PERF_END (NULL, "SmmCompleteReadyToLock", NULL, 0); + + // + // Clean SMM ready to lock flag + // + mSmmReadyToLock = FALSE; + + PERF_FUNCTION_END (); + } +} + /** To get system port address of the SMI Command Port in FADT table. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c index 7d143e78ebc1..005fbcd96872 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c @@ -15,6 +15,63 @@ SPDX-License-Identifier: BSD-2-Clause-Patent // const BOOLEAN mIsStandaloneMm = TRUE; +// +// RemainingTasks Done flag +// +BOOLEAN mRemainingTasksDone = FALSE; + +/** + Perform the remaining tasks. + +**/ +VOID +PerformRemainingTasks ( + VOID + ) +{ + EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; + + if (!mRemainingTasksDone) { + PERF_FUNCTION_BEGIN (); + + // + // gEdkiiPiSmmMemoryAttributesTableGuid should have been published after SmmCore dispatched all MM drivers (MmDriverDispatchHandler). + // Note: gEdkiiPiSmmMemoryAttributesTableGuid is not always installed since it depends on + // the memory protection attribute setting in MM Core. + // + SmmGetSystemConfigurationTable (&gEdkiiPiSmmMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable); + + // + // Set critical region attribute in page table according to the MemoryAttributesTable + // + if (MemoryAttributesTable != NULL) { + SetMemMapAttributes (MemoryAttributesTable); + } + + if (IsRestrictedMemoryAccess ()) { + // + // Set page table itself to be read-only + // + SetPageTableAttributes (); + } + + // + // Measure performance of SmmCpuFeaturesCompleteSmmReadyToLock() from caller side + // as the implementation is provided by platform. + // + PERF_START (NULL, "SmmCompleteReadyToLock", NULL, 0); + SmmCpuFeaturesCompleteSmmReadyToLock (); + PERF_END (NULL, "SmmCompleteReadyToLock", NULL, 0); + + // + // Mark RemainingTasks Done flag to TRUE + // + mRemainingTasksDone = TRUE; + + PERF_FUNCTION_END (); + } +} + /** To get system port address of the SMI Command Port. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c index cf1e49d89b29..4022c4506599 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c @@ -993,31 +993,29 @@ SetMemMapWithNonPresentRange ( /** This function sets memory attribute according to MemoryAttributesTable. + + @param MemoryAttributesTable A pointer to the buffer of SmmMemoryAttributesTable. + **/ VOID SetMemMapAttributes ( - VOID + EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable ) { - EFI_MEMORY_DESCRIPTOR *MemoryMap; - EFI_MEMORY_DESCRIPTOR *MemoryMapStart; - UINTN MemoryMapEntryCount; - UINTN DescriptorSize; - UINTN Index; - EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; - UINTN PageTable; - EFI_STATUS Status; - IA32_MAP_ENTRY *Map; - UINTN Count; - UINT64 MemoryAttribute; - BOOLEAN WriteProtect; - BOOLEAN CetEnabled; - - SmmGetSystemConfigurationTable (&gEdkiiPiSmmMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable); - if (MemoryAttributesTable == NULL) { - DEBUG ((DEBUG_INFO, "MemoryAttributesTable - NULL\n")); - return; - } + EFI_MEMORY_DESCRIPTOR *MemoryMap; + EFI_MEMORY_DESCRIPTOR *MemoryMapStart; + UINTN MemoryMapEntryCount; + UINTN DescriptorSize; + UINTN Index; + UINTN PageTable; + EFI_STATUS Status; + IA32_MAP_ENTRY *Map; + UINTN Count; + UINT64 MemoryAttribute; + BOOLEAN WriteProtect; + BOOLEAN CetEnabled; + + ASSERT (MemoryAttributesTable != NULL); PERF_FUNCTION_BEGIN (); From 0593183d764e63ffd07807213300bbfe1702d079 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 15:54:22 +0800 Subject: [PATCH 085/280] UefiCpuPkg/PiSmmCpuDxeSmm: Start SMM Profile early for MM SMM Profile start can be started early in SMM CPU EntryPoint since page table for SMM profile is ready. No need wait smm ready to lock. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 5 +++++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c | 10 ++++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 5 ----- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h | 9 +++++++++ 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index 959e993bda33..93bb67ce7aa8 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -163,6 +163,11 @@ SmmReadyToLockEventNotify ( // Get Software SMI from FADT // GetSmiCommandPort (); + + // + // Initialize protected memory range for patching page table later. + // + InitProtectedMemRange (); } // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c index 005fbcd96872..d8aaff811c5b 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c @@ -221,6 +221,16 @@ PiCpuStandaloneMmEntry ( // Get Software SMI // GetSmiCommandPort (); + + // + // Initialize protected memory range for patching page table later. + // + InitProtectedMemRange (); + + // + // Start SMM Profile feature + // + SmmProfileStart (); } // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index bbac6064e23d..0e95fc0eb308 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -738,11 +738,6 @@ InitSmmProfileCallBack ( &mSmmProfileBase ); - // - // Initialize protected memory range for patching page table later. - // - InitProtectedMemRange (); - return EFI_SUCCESS; } diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h index b34aab41efcb..fc4c2731a0c6 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h @@ -90,6 +90,15 @@ CheckFeatureSupported ( IN UINTN CpuIndex ); +/** + Initialize the protected memory ranges and the 4KB-page mapped memory ranges. + +**/ +VOID +InitProtectedMemRange ( + VOID + ); + /** Update page table according to protected memory ranges and the 4KB-page mapped memory ranges. From 3690d30a6e3cdc4f159bae74a88d6e201e3d69f6 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 16:04:50 +0800 Subject: [PATCH 086/280] UefiCpuPkg/PiSmmCpuDxeSmm: Check logging PF address for MM This patch is to make sure only logging PF address for MM can run into the SmmProfilePFHandler. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c | 18 +++++++++++ .../PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c | 32 +++++++++++++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 13 ++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 7 ++++ 4 files changed, 70 insertions(+) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c index 8dbcd8d95091..27f159b98c1e 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c @@ -460,6 +460,24 @@ GetSmmProfileData ( return Base; } +/** + Return if the Address is the NonMmram logging Address. + + @param[in] Address the address to be checked + + @return TRUE The address is the NonMmram logging Address. + @return FALSE The address is not the NonMmram logging Address. +**/ +BOOLEAN +IsNonMmramLoggingAddress ( + IN UINT64 Address + ) +{ + ASSERT (FALSE); + + return TRUE; +} + /** Return if the Address is forbidden as SMM communication buffer. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c index 8c5286b74472..70e94a6b76fb 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c @@ -46,6 +46,38 @@ GetSmmProfileData ( return SmmProfileDataHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress; } +/** + Return if the Address is the NonMmram logging Address. + + @param[in] Address the address to be checked + + @return TRUE The address is the NonMmram logging Address. + @return FALSE The address is not the NonMmram logging Address. +**/ +BOOLEAN +IsNonMmramLoggingAddress ( + IN UINT64 Address + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR); + while (Hob.Raw != NULL) { + if ((Address >= Hob.ResourceDescriptor->PhysicalStart) && (Address < Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength)) { + if ((Hob.ResourceDescriptor->ResourceAttribute & MM_RESOURCE_ATTRIBUTE_LOGGING) != 0) { + return TRUE; + } + + return FALSE; + } + + Hob.Raw = GET_NEXT_HOB (Hob); + Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw); + } + + return FALSE; +} + /** Return if the Address is forbidden as SMM communication buffer. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index 44bf3f3aba4f..73ace4efa4fd 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -979,6 +979,19 @@ GetSmmProfileData ( IN OUT UINT64 *Size ); +/** + Return if the Address is the NonMmram logging Address. + + @param[in] Address the address to be checked + + @return TRUE The address is the NonMmram logging Address. + @return FALSE The address is not the NonMmram logging Address. +**/ +BOOLEAN +IsNonMmramLoggingAddress ( + IN UINT64 Address + ); + /** Return if the Address is forbidden as SMM communication buffer. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index a5253e8167a4..f56d2849de0c 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -821,6 +821,13 @@ SmiPFHandler ( } if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + if (mIsStandaloneMm) { + // + // Only logging ranges shall run here in MM env. + // + ASSERT (IsNonMmramLoggingAddress (PFAddress)); + } + SmmProfilePFHandler ( SystemContext.SystemContextX64->Rip, SystemContext.SystemContextX64->ExceptionData From 5bcf6049f2f09f52f837d9b37607ed52c0153cd3 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 26 Jun 2024 16:10:20 +0800 Subject: [PATCH 087/280] UefiCpuPkg/PiSmmCpuDxeSmm: Add PiSmmCpuStandaloneMm.inf This patch is to add PiSmmCpuStandaloneMm.inf for MM CPU support. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- .../PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf new file mode 100644 index 000000000000..13b8ce17bd95 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf @@ -0,0 +1,136 @@ +## @file +# PiSmmCpuStandaloneMm driver. +# This Standalone MM driver performs SMM initialization, deploy SMM Entry Vector, +# provides CPU specific services in SMM. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PiSmmCpuStandaloneMm + FILE_GUID = d88f894b-9287-4706-8b28-f716ae4d35c7 + MODULE_TYPE = MM_STANDALONE + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x00010032 + ENTRY_POINT = PiCpuStandaloneMmEntry + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = X64 +# + +[Sources] + PiSmmCpuStandaloneMm.c + PiSmmCpuCommon.c + PiSmmCpuCommon.h + MpService.c + SyncTimer.c + CpuS3.c + CpuService.c + CpuService.h + SmmProfile.c + SmmProfile.h + SmmProfileInternal.h + SmramSaveState.c + SmmCpuMemoryManagement.c + SmmMp.h + SmmMp.c + SmmMpPerf.h + SmmMpPerf.c + NonMmramMapStandaloneMm.c + +[Sources.X64] + X64/PageTbl.c + X64/SmmFuncsArch.c + X64/SmmProfileArch.c + X64/SmmProfileArch.h + X64/SmiEntry.nasm + X64/SmiException.nasm + X64/Cet.nasm + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + StandaloneMmDriverEntryPoint + PcdLib + DebugLib + BaseLib + SynchronizationLib + BaseMemoryLib + MtrrLib + IoLib + TimerLib + MmServicesTableLib + MemoryAllocationLib + DebugAgentLib + HobLib + PciLib + LocalApicLib + SmmCpuPlatformHookLib + CpuExceptionHandlerLib + CpuLib + ReportStatusCodeLib + SmmCpuFeaturesLib + PeCoffGetEntryPointLib + PerformanceLib + CpuPageTableLib + MmSaveStateLib + SmmCpuSyncLib + +[Protocols] + gEfiSmmConfigurationProtocolGuid ## PRODUCES + gEfiSmmCpuProtocolGuid ## PRODUCES + gEfiSmmReadyToLockProtocolGuid ## NOTIFY + gEfiSmmCpuServiceProtocolGuid ## PRODUCES + gEdkiiSmmMemoryAttributeProtocolGuid ## PRODUCES + gEfiMmMpProtocolGuid ## PRODUCES + gEdkiiSmmCpuRendezvousProtocolGuid ## PRODUCES + gEfiSmmVariableProtocolGuid ## CONSUMES + +[Guids] + gEfiAcpiVariableGuid ## SOMETIMES_CONSUMES ## HOB # it is used for S3 boot. + gEdkiiPiSmmMemoryAttributesTableGuid ## CONSUMES ## SystemTable + gSmmBaseHobGuid ## CONSUMES + gMpInformation2HobGuid ## CONSUMES # Assume the HOB must has been created + gEfiSmmSmramMemoryGuid + gMmProfileDataHobGuid + gMmAcpiS3EnableHobGuid + gMmCpuSyncConfigHobGuid + +[FeaturePcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmBlockStartupThisAp ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugSupport ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileEnable ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileRingBuffer ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmFeatureControlMsrLock ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdSmmApPerfLogEnable ## CONSUMES + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmShadowStackSize ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask ## CONSUMES + +[FixedPcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmMpTokenCountPerChunk ## CONSUMES + +[Depex] + TRUE + +[Pcd.X64] + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmRestrictedMemoryAccess ## CONSUMES From 1816c78f43f5d2d309a2a2d91bf5e7412bab19b5 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 8 Jul 2024 09:59:03 +0800 Subject: [PATCH 088/280] UefiCpuPkg/PiSmmCpuDxeSmm: Refine DxeSmm PageTable update logic This patch is to refine the updatePageTable logic for DxeSmm. For DxeSmm, PageTable will be updated in the first SMI when SMM ready to lock happen: IF SMM Profile is TRUE: 1. Mark mProtectionMemRange attribute: SmrrBase:Present, SMM profile base:Present&Nx, MMRAM ranges:Present, MMIO ranges: Present&Nx. 2. Mark the ranges not in mProtectionMemRange as RP (non-present). IF SMM Profile is FALSE: 1. Mark Non-MMRAM ranges as NX. 2. IF RestrictedMemoryAccess is TRUE: Forbidden Address mark as RP (IsUefiPageNotPresent is TRUE). Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c | 192 +++++++++++------- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 17 +- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 13 +- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 92 ++++----- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h | 4 +- 5 files changed, 174 insertions(+), 144 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c index 27f159b98c1e..51f0edd296cb 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c @@ -311,116 +311,170 @@ GetUefiMemoryMap ( } /** - This function sets UEFI memory attribute according to UEFI memory map. + This function updates UEFI memory attribute according to UEFI memory map. - The normal memory region is marked as not present, such as - EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory, - EfiUnusableMemory, EfiACPIReclaimMemory. **/ VOID -SetUefiMemMapAttributes ( +UpdateUefiMemMapAttributes ( VOID ) { + BOOLEAN WriteProtect; + BOOLEAN CetEnabled; EFI_STATUS Status; + UINTN Index; + UINT64 Limit; + UINT64 PreviousAddress; + UINTN PageTable; + UINT64 Base; EFI_MEMORY_DESCRIPTOR *MemoryMap; UINTN MemoryMapEntryCount; - UINTN Index; EFI_MEMORY_DESCRIPTOR *Entry; - BOOLEAN WriteProtect; - BOOLEAN CetEnabled; - PERF_FUNCTION_BEGIN (); - - DEBUG ((DEBUG_INFO, "SetUefiMemMapAttributes\n")); + DEBUG ((DEBUG_INFO, "UpdateUefiMemMapAttributes Start...\n")); WRITE_UNPROTECT_RO_PAGES (WriteProtect, CetEnabled); - if (mUefiMemoryMap != NULL) { - MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize; - MemoryMap = mUefiMemoryMap; - for (Index = 0; Index < MemoryMapEntryCount; Index++) { - if (IsUefiPageNotPresent (MemoryMap)) { - Status = SmmSetMemoryAttributes ( - MemoryMap->PhysicalStart, - EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages), - EFI_MEMORY_RP - ); - DEBUG (( - DEBUG_INFO, - "UefiMemory protection: 0x%lx - 0x%lx %r\n", - MemoryMap->PhysicalStart, - MemoryMap->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages), - Status - )); - } - - MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize); - } - } + PageTable = AsmReadCr3 (); + Limit = LShiftU64 (1, mPhysicalAddressBits); // - // Do not free mUefiMemoryMap, it will be checked in IsSmmCommBufferForbiddenAddress(). + // [0, 4k] may be non-present. // + PreviousAddress = ((FixedPcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0) ? BASE_4KB : 0; // - // Set untested memory as not present. + // NonMmram shall be non-executable after the SmmReadyToLock event occurs, regardless of whether + // RestrictedMemoryAccess is enabled, since all MM drivers located in NonMmram have already been dispatched and executed. // - if (mGcdMemSpace != NULL) { - for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) { - Status = SmmSetMemoryAttributes ( - mGcdMemSpace[Index].BaseAddress, - mGcdMemSpace[Index].Length, - EFI_MEMORY_RP - ); - DEBUG (( - DEBUG_INFO, - "GcdMemory protection: 0x%lx - 0x%lx %r\n", - mGcdMemSpace[Index].BaseAddress, - mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length, - Status - )); + for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) { + Base = mSmmCpuSmramRanges[Index].CpuStart; + if (Base > PreviousAddress) { + Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, PreviousAddress, Base - PreviousAddress, EFI_MEMORY_XP, TRUE, NULL); + ASSERT_RETURN_ERROR (Status); } + + PreviousAddress = mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize; } - // - // Do not free mGcdMemSpace, it will be checked in IsSmmCommBufferForbiddenAddress(). - // + if (PreviousAddress < Limit) { + Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, PreviousAddress, Limit - PreviousAddress, EFI_MEMORY_XP, TRUE, NULL); + ASSERT_RETURN_ERROR (Status); + } // - // Set UEFI runtime memory with EFI_MEMORY_RO as not present. + // Set NonMmram to not-present by excluding "RT, Reserved and NVS" memory type when RestrictedMemoryAccess is enabled. // - if (mUefiMemoryAttributesTable != NULL) { - Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1); - for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) { - if ((Entry->Type == EfiRuntimeServicesCode) || (Entry->Type == EfiRuntimeServicesData)) { - if ((Entry->Attribute & EFI_MEMORY_RO) != 0) { - Status = SmmSetMemoryAttributes ( - Entry->PhysicalStart, - EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages), - EFI_MEMORY_RP + if (IsRestrictedMemoryAccess ()) { + if (mUefiMemoryMap != NULL) { + MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize; + MemoryMap = mUefiMemoryMap; + for (Index = 0; Index < MemoryMapEntryCount; Index++) { + if (IsUefiPageNotPresent (MemoryMap)) { + Status = ConvertMemoryPageAttributes ( + PageTable, + mPagingMode, + MemoryMap->PhysicalStart, + EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages), + EFI_MEMORY_RP, + TRUE, + NULL ); DEBUG (( DEBUG_INFO, - "UefiMemoryAttribute protection: 0x%lx - 0x%lx %r\n", - Entry->PhysicalStart, - Entry->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages), + "UefiMemory protection: 0x%lx - 0x%lx %r\n", + MemoryMap->PhysicalStart, + MemoryMap->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages), Status )); } + + MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize); + } + } + + // + // Do not free mUefiMemoryMap, it will be checked in IsSmmCommBufferForbiddenAddress(). + // + + // + // Set untested NonMmram memory as not present. + // + if (mGcdMemSpace != NULL) { + for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) { + Status = ConvertMemoryPageAttributes ( + PageTable, + mPagingMode, + mGcdMemSpace[Index].BaseAddress, + mGcdMemSpace[Index].Length, + EFI_MEMORY_RP, + TRUE, + NULL + ); + DEBUG (( + DEBUG_INFO, + "GcdMemory protection: 0x%lx - 0x%lx %r\n", + mGcdMemSpace[Index].BaseAddress, + mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length, + Status + )); } + } + + // + // Do not free mGcdMemSpace, it will be checked in IsSmmCommBufferForbiddenAddress(). + // + + // + // Above logic sets the whole RT memory as present. + // Below logic is to set the RT code as not present. + // + if (mUefiMemoryAttributesTable != NULL) { + Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1); + for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) { + if ((Entry->Type == EfiRuntimeServicesCode) || (Entry->Type == EfiRuntimeServicesData)) { + if ((Entry->Attribute & EFI_MEMORY_RO) != 0) { + Status = ConvertMemoryPageAttributes ( + PageTable, + mPagingMode, + Entry->PhysicalStart, + EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages), + EFI_MEMORY_RP, + TRUE, + NULL + ); + DEBUG (( + DEBUG_INFO, + "UefiMemoryAttribute protection: 0x%lx - 0x%lx %r\n", + Entry->PhysicalStart, + Entry->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages), + Status + )); + } + } - Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize); + Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize); + } } + + // + // Do not free mUefiMemoryAttributesTable, it will be checked in IsSmmCommBufferForbiddenAddress(). + // } - WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled); + // + // Flush TLB + // + CpuFlushTlb (); // - // Do not free mUefiMemoryAttributesTable, it will be checked in IsSmmCommBufferForbiddenAddress(). + // Set execute-disable flag // + mXdEnabled = TRUE; + + WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled); - PERF_FUNCTION_END (); + DEBUG ((DEBUG_INFO, "UpdateUefiMemMapAttributes Done.\n")); } /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index 73ace4efa4fd..ec3f32e38192 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -958,14 +958,6 @@ SetMemMapAttributes ( EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable ); -/** - This function sets UEFI memory attribute according to UEFI memory map. -**/ -VOID -SetUefiMemMapAttributes ( - VOID - ); - /** Get SmmProfileData. @@ -1037,6 +1029,15 @@ CreateNonMmramMemMap ( OUT UINTN *MemoryRegionCount ); +/** + This function updates UEFI memory attribute according to UEFI memory map. + +**/ +VOID +UpdateUefiMemMapAttributes ( + VOID + ); + /** This function caches the UEFI memory map information. **/ diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index 93bb67ce7aa8..579f5bd985bc 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -58,9 +58,13 @@ PerformRemainingTasks ( } // - // Create a mix of 2MB and 4KB page table. Update some memory ranges absent and execute-disable. + // Update Page Table for outside SMRAM. // - InitPaging (); + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + SmmProfileUpdateMemoryAttributes (); + } else { + UpdateUefiMemMapAttributes (); + } // // gEdkiiPiSmmMemoryAttributesTableGuid should have been published at EndOfDxe by SmmCore @@ -77,11 +81,6 @@ PerformRemainingTasks ( } if (IsRestrictedMemoryAccess ()) { - // - // For outside SMRAM, we only map SMM communication buffer or MMIO. - // - SetUefiMemMapAttributes (); - // // Set page table itself to be read-only // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index 0e95fc0eb308..44f67cc38bc5 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -573,11 +573,11 @@ InitProtectedMemRange ( } /** - Update page table according to protected memory ranges and the 4KB-page mapped memory ranges. + This function updates memory attribute according to mProtectionMemRangeCount. **/ VOID -InitPaging ( +SmmProfileUpdateMemoryAttributes ( VOID ) { @@ -592,91 +592,67 @@ InitPaging ( BOOLEAN WriteProtect; BOOLEAN CetEnabled; - PERF_FUNCTION_BEGIN (); + DEBUG ((DEBUG_INFO, "SmmProfileUpdateMemoryAttributes Start...\n")); + + WRITE_UNPROTECT_RO_PAGES (WriteProtect, CetEnabled); PageTable = AsmReadCr3 (); Limit = LShiftU64 (1, mPhysicalAddressBits); - WRITE_UNPROTECT_RO_PAGES (WriteProtect, CetEnabled); - // // [0, 4k] may be non-present. // PreviousAddress = ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0) ? BASE_4KB : 0; - DEBUG ((DEBUG_INFO, "Patch page table start ...\n")); - if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { - for (Index = 0; Index < mProtectionMemRangeCount; Index++) { - MemoryAttrMask = 0; - if (mProtectionMemRange[Index].Nx == TRUE) { - MemoryAttrMask |= EFI_MEMORY_XP; - } - - if (mProtectionMemRange[Index].Present == FALSE) { - MemoryAttrMask = EFI_MEMORY_RP; - } - - Base = mProtectionMemRange[Index].Range.Base; - Length = mProtectionMemRange[Index].Range.Top - Base; - if (MemoryAttrMask != 0) { - Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, Base, Length, MemoryAttrMask, TRUE, NULL); - ASSERT_RETURN_ERROR (Status); - } - - if (Base > PreviousAddress) { - // - // Mark the ranges not in mProtectionMemRange as non-present. - // - MemoryAttrMask = EFI_MEMORY_RP; - Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, PreviousAddress, Base - PreviousAddress, MemoryAttrMask, TRUE, NULL); - ASSERT_RETURN_ERROR (Status); - } + for (Index = 0; Index < mProtectionMemRangeCount; Index++) { + MemoryAttrMask = 0; + if (mProtectionMemRange[Index].Nx == TRUE) { + MemoryAttrMask = EFI_MEMORY_XP; + } - PreviousAddress = Base + Length; + if (mProtectionMemRange[Index].Present == FALSE) { + MemoryAttrMask = EFI_MEMORY_RP; } - // - // This assignment is for setting the last remaining range - // - MemoryAttrMask = EFI_MEMORY_RP; - } else { - MemoryAttrMask = EFI_MEMORY_XP; - for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) { - Base = mSmmCpuSmramRanges[Index].CpuStart; - if (Base > PreviousAddress) { - // - // Mark the ranges not in mSmmCpuSmramRanges as NX. - // - Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, PreviousAddress, Base - PreviousAddress, MemoryAttrMask, TRUE, NULL); - ASSERT_RETURN_ERROR (Status); - } + Base = mProtectionMemRange[Index].Range.Base; + Length = mProtectionMemRange[Index].Range.Top - Base; + if (MemoryAttrMask != 0) { + Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, Base, Length, MemoryAttrMask, TRUE, NULL); + ASSERT_RETURN_ERROR (Status); + } - PreviousAddress = mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize; + if (Base > PreviousAddress) { + // + // Mark the ranges not in mProtectionMemRange as non-present. + // + Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, PreviousAddress, Base - PreviousAddress, EFI_MEMORY_RP, TRUE, NULL); + ASSERT_RETURN_ERROR (Status); } + + PreviousAddress = Base + Length; } + // + // Set the last remaining range + // if (PreviousAddress < Limit) { - // - // Set the last remaining range to EFI_MEMORY_RP/EFI_MEMORY_XP. - // This path applies to both SmmProfile enable/disable case. - // - Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, PreviousAddress, Limit - PreviousAddress, MemoryAttrMask, TRUE, NULL); + Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, PreviousAddress, Limit - PreviousAddress, EFI_MEMORY_RP, TRUE, NULL); ASSERT_RETURN_ERROR (Status); } - WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled); - // // Flush TLB // CpuFlushTlb (); - DEBUG ((DEBUG_INFO, "Patch page table done!\n")); + // // Set execute-disable flag // mXdEnabled = TRUE; - PERF_FUNCTION_END (); + WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled); + + DEBUG ((DEBUG_INFO, "SmmProfileUpdateMemoryAttributes Done.\n")); } /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h index fc4c2731a0c6..feddf6eec362 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h @@ -100,11 +100,11 @@ InitProtectedMemRange ( ); /** - Update page table according to protected memory ranges and the 4KB-page mapped memory ranges. + This function updates memory attribute according to mProtectionMemRangeCount. **/ VOID -InitPaging ( +SmmProfileUpdateMemoryAttributes ( VOID ); From ae0d54cd4362b1a2788226a2fecf4cff6bfb453d Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 8 Jul 2024 11:23:09 +0800 Subject: [PATCH 089/280] UefiCpuPkg/PiSmmCpuDxeSmm: Cleanup SMM_CPU_SYNC_MODE Use MM_CPU_SYNC_MODE instead of SMM_CPU_SYNC_MODE. Cleanup the duplicate definition. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 22 ++++++++--------- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 28 +++++++++------------- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 2 +- 4 files changed, 24 insertions(+), 30 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c index 8a1c6ff8d791..72ffb5a50d60 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c @@ -431,7 +431,7 @@ SmmCpuRendezvous ( goto ON_EXIT; } - if ((mSmmMpSyncData->EffectiveSyncMode != SmmCpuSyncModeTradition) && !SmmCpuFeaturesNeedConfigureMtrrs ()) { + if ((mSmmMpSyncData->EffectiveSyncMode != MmCpuSyncModeTradition) && !SmmCpuFeaturesNeedConfigureMtrrs ()) { // // There are some APs outside SMM, Wait for all avaiable APs to arrive. // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c index aae283e79bdc..819b35a35d79 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -20,7 +20,7 @@ UINTN mSmmMpSyncDataSize; SMM_CPU_SEMAPHORES mSmmCpuSemaphores; UINTN mSemaphoreSize; SPIN_LOCK *mPFLock = NULL; -SMM_CPU_SYNC_MODE mCpuSmmSyncMode; +MM_CPU_SYNC_MODE mCpuSmmSyncMode; BOOLEAN mMachineCheckSupported = FALSE; MM_COMPLETION mSmmStartupThisApToken; @@ -454,8 +454,8 @@ ResetTokens ( **/ VOID BSPHandler ( - IN UINTN CpuIndex, - IN SMM_CPU_SYNC_MODE SyncMode + IN UINTN CpuIndex, + IN MM_CPU_SYNC_MODE SyncMode ) { UINTN CpuCount; @@ -504,7 +504,7 @@ BSPHandler ( // // If Traditional Sync Mode or need to configure MTRRs: gather all available APs. // - if ((SyncMode == SmmCpuSyncModeTradition) || SmmCpuFeaturesNeedConfigureMtrrs ()) { + if ((SyncMode == MmCpuSyncModeTradition) || SmmCpuFeaturesNeedConfigureMtrrs ()) { // // Wait for APs to arrive // @@ -594,7 +594,7 @@ BSPHandler ( // make those APs to exit SMI synchronously. APs which arrive later will be excluded and // will run through freely. // - if ((SyncMode != SmmCpuSyncModeTradition) && !SmmCpuFeaturesNeedConfigureMtrrs ()) { + if ((SyncMode != MmCpuSyncModeTradition) && !SmmCpuFeaturesNeedConfigureMtrrs ()) { // // Lock door for late coming CPU checkin and retrieve the Arrived number of APs // @@ -722,9 +722,9 @@ BSPHandler ( **/ VOID APHandler ( - IN UINTN CpuIndex, - IN BOOLEAN ValidSmi, - IN SMM_CPU_SYNC_MODE SyncMode + IN UINTN CpuIndex, + IN BOOLEAN ValidSmi, + IN MM_CPU_SYNC_MODE SyncMode ) { UINT64 Timer; @@ -801,7 +801,7 @@ APHandler ( // *(mSmmMpSyncData->CpuData[CpuIndex].Present) = TRUE; - if ((SyncMode == SmmCpuSyncModeTradition) || SmmCpuFeaturesNeedConfigureMtrrs ()) { + if ((SyncMode == MmCpuSyncModeTradition) || SmmCpuFeaturesNeedConfigureMtrrs ()) { // // Notify BSP of arrival at this point // @@ -1131,7 +1131,7 @@ InternalSmmStartupThisAp ( } if (!(*(mSmmMpSyncData->CpuData[CpuIndex].Present))) { - if (mSmmMpSyncData->EffectiveSyncMode == SmmCpuSyncModeTradition) { + if (mSmmMpSyncData->EffectiveSyncMode == MmCpuSyncModeTradition) { DEBUG ((DEBUG_ERROR, "!mSmmMpSyncData->CpuData[%d].Present\n", CpuIndex)); } @@ -1947,7 +1947,7 @@ InitializeMpServiceData ( RelaxedMode = FALSE; GetSmmCpuSyncConfigData (&RelaxedMode, NULL, NULL); - mCpuSmmSyncMode = RelaxedMode ? SmmCpuSyncModeRelaxedAp : SmmCpuSyncModeTradition; + mCpuSmmSyncMode = RelaxedMode ? MmCpuSyncModeRelaxedAp : MmCpuSyncModeTradition; InitializeMpSyncData (); // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index ec3f32e38192..d7a645fb5bf0 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -401,28 +401,22 @@ typedef struct { EFI_STATUS *Status; } SMM_CPU_DATA_BLOCK; -typedef enum { - SmmCpuSyncModeTradition, - SmmCpuSyncModeRelaxedAp, - SmmCpuSyncModeMax -} SMM_CPU_SYNC_MODE; - typedef struct { // // Pointer to an array. The array should be located immediately after this structure // so that UC cache-ability can be set together. // - SMM_CPU_DATA_BLOCK *CpuData; - volatile UINT32 BspIndex; - volatile BOOLEAN *InsideSmm; - volatile BOOLEAN *AllCpusInSync; - volatile SMM_CPU_SYNC_MODE EffectiveSyncMode; - volatile BOOLEAN SwitchBsp; - volatile BOOLEAN *CandidateBsp; - volatile BOOLEAN AllApArrivedWithException; - EFI_AP_PROCEDURE StartupProcedure; - VOID *StartupProcArgs; - SMM_CPU_SYNC_CONTEXT *SyncContext; + SMM_CPU_DATA_BLOCK *CpuData; + volatile UINT32 BspIndex; + volatile BOOLEAN *InsideSmm; + volatile BOOLEAN *AllCpusInSync; + volatile MM_CPU_SYNC_MODE EffectiveSyncMode; + volatile BOOLEAN SwitchBsp; + volatile BOOLEAN *CandidateBsp; + volatile BOOLEAN AllApArrivedWithException; + EFI_AP_PROCEDURE StartupProcedure; + VOID *StartupProcArgs; + SMM_CPU_SYNC_CONTEXT *SyncContext; } SMM_DISPATCHER_MP_SYNC_DATA; #define SMM_PSD_OFFSET 0xfb00 diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index 579f5bd985bc..f544858c19b5 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -193,7 +193,7 @@ GetSmmCpuSyncConfigData ( ) { if (RelaxedMode != NULL) { - *RelaxedMode = (BOOLEAN)(PcdGet8 (PcdCpuSmmSyncMode) == SmmCpuSyncModeRelaxedAp); + *RelaxedMode = (BOOLEAN)(PcdGet8 (PcdCpuSmmSyncMode) == MmCpuSyncModeRelaxedAp); } if (SyncTimeout != NULL) { From 2e6ca59e332f691195be869e87a8737c20bc25a8 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 8 Jul 2024 12:48:32 +0800 Subject: [PATCH 090/280] UefiCpuPkg/PiSmmCpuDxeSmm: Avoid PcdCpuSmmProfileEnable check in MM For MM, gMmProfileDataHobGuid Memory Allocation HOB is defined to indicate SMM profile feature enabled or not. If the HOB exist, SMM profile base address and size will be returned in the HOB, so no need to consume the PcdCpuSmmProfileEnable feature PCD to check enable or disable. To achieve above purpose, Add the IsSmmProfileEnabled () function. With this change, Both MM and SMM can use the new function for SMM profile feature check. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 4 ++-- .../PiSmmCpuDxeSmm/Ia32/SmiException.nasm | 1 - UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 4 ++-- .../PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c | 6 ++++- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c | 5 ++++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 12 ++++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 21 +++++++++++++--- .../PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c | 24 ++++++++++++++++++- .../PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 4 ++-- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 9 +++++-- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h | 4 ++++ UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 6 ++--- 12 files changed, 83 insertions(+), 17 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c index 2fc55ea3c263..1294485c60ae 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c @@ -33,7 +33,7 @@ SmmInitPageTable ( mPhysicalAddressBits = 32; mPagingMode = PagingPae; - if (FeaturePcdGet (PcdCpuSmmProfileEnable) || + if (mSmmProfileEnabled || HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) { @@ -187,7 +187,7 @@ SmiPFHandler ( } } - if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + if (mSmmProfileEnabled) { SmmProfilePFHandler ( SystemContext.SystemContextIa32->Eip, SystemContext.SystemContextIa32->ExceptionData diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.nasm index e7b85a994982..208d6bc2ee77 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.nasm +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.nasm @@ -12,7 +12,6 @@ ; ;------------------------------------------------------------------------------- -extern ASM_PFX(FeaturePcdGet (PcdCpuSmmProfileEnable)) extern ASM_PFX(SmiPFHandler) extern ASM_PFX(mSetupDebugTrap) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c index 819b35a35d79..210b23af21d8 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -1616,7 +1616,7 @@ SmiRendezvous ( InitializeSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy); } - if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + if (mSmmProfileEnabled) { ActivateSmmProfile (CpuIndex); } @@ -1677,7 +1677,7 @@ SmiRendezvous ( } } - if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + if (mSmmProfileEnabled) { SmmProfileRecordSmiNum (); } diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c index 70e94a6b76fb..dba7db0d0099 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c @@ -11,6 +11,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent Get SmmProfileData. @param[in, out] Size Return Size of SmmProfileData. + 0 means the gMmProfileDataHobGuid does not exist. @return Address of SmmProfileData @@ -39,7 +40,10 @@ GetSmmProfileData ( SmmProfileDataHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (SmmProfileDataHob)); } - ASSERT (SmmProfileDataHob.Raw != NULL); + if (SmmProfileDataHob.Raw == NULL) { + *Size = 0; + return 0; + } *Size = SmmProfileDataHob.MemoryAllocation->AllocDescriptor.MemoryLength; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c index c5921a6de838..c6df9358ebdb 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c @@ -1153,6 +1153,11 @@ PiSmmCpuEntryCommon ( // InitializeSmmTimer (); + // + // Initialize mSmmProfileEnabled + // + mSmmProfileEnabled = IsSmmProfileEnabled (); + // // Initialize MP globals // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index d7a645fb5bf0..0dccf7ca656b 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -830,6 +830,18 @@ SmiPFHandler ( IN EFI_SYSTEM_CONTEXT SystemContext ); +/** + Check SmmProfile is enabled or not. + + @return TRUE SmmProfile is enabled. + FALSE SmmProfile is not enabled. + +**/ +BOOLEAN +IsSmmProfileEnabled ( + VOID + ); + /** Perform the remaining tasks. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index f544858c19b5..50aeefb9484e 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -23,6 +23,21 @@ const BOOLEAN mIsStandaloneMm = FALSE; // BOOLEAN mSmmReadyToLock = FALSE; +/** + Check SmmProfile is enabled or not. + + @return TRUE SmmProfile is enabled. + FALSE SmmProfile is not enabled. + +**/ +BOOLEAN +IsSmmProfileEnabled ( + VOID + ) +{ + return FeaturePcdGet (PcdCpuSmmProfileEnable); +} + /** Perform the remaining tasks. @@ -40,7 +55,7 @@ PerformRemainingTasks ( // // Start SMM Profile feature // - if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + if (mSmmProfileEnabled) { SmmProfileStart (); } @@ -60,7 +75,7 @@ PerformRemainingTasks ( // // Update Page Table for outside SMRAM. // - if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + if (mSmmProfileEnabled) { SmmProfileUpdateMemoryAttributes (); } else { UpdateUefiMemMapAttributes (); @@ -157,7 +172,7 @@ SmmReadyToLockEventNotify ( // // Skip SMM profile initialization if feature is disabled // - if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + if (mSmmProfileEnabled) { // // Get Software SMI from FADT // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c index d8aaff811c5b..f81389463fc7 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c @@ -20,6 +20,28 @@ const BOOLEAN mIsStandaloneMm = TRUE; // BOOLEAN mRemainingTasksDone = FALSE; +/** + Check SmmProfile is enabled or not. + + @return TRUE SmmProfile is enabled. + FALSE SmmProfile is not enabled. + +**/ +BOOLEAN +IsSmmProfileEnabled ( + VOID + ) +{ + UINT64 SmmProfileSize; + + GetSmmProfileData (&SmmProfileSize); + if (SmmProfileSize == 0) { + return FALSE; + } + + return TRUE; +} + /** Perform the remaining tasks. @@ -216,7 +238,7 @@ PiCpuStandaloneMmEntry ( ASSERT_EFI_ERROR (Status); - if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + if (mSmmProfileEnabled) { // // Get Software SMI // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c index 4022c4506599..d1cfd72106c0 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c @@ -1494,7 +1494,7 @@ IfReadOnlyPageTableNeeded ( // if (!IsRestrictedMemoryAccess () || ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) || - FeaturePcdGet (PcdCpuSmmProfileEnable)) + mSmmProfileEnabled) { if (sizeof (UINTN) == sizeof (UINT64)) { // @@ -1508,7 +1508,7 @@ IfReadOnlyPageTableNeeded ( // // Restriction on access to non-SMRAM memory and SMM profile could not be enabled at the same time. // - ASSERT (!(IsRestrictedMemoryAccess () && FeaturePcdGet (PcdCpuSmmProfileEnable))); + ASSERT (!(IsRestrictedMemoryAccess () && mSmmProfileEnabled)); } return FALSE; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index 44f67cc38bc5..164af20a4cd7 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -40,6 +40,11 @@ BOOLEAN mXdEnabled = FALSE; // BOOLEAN mBtsSupported = TRUE; +// +// The flag indicates if SMM profile is enabled. +// +BOOLEAN mSmmProfileEnabled = FALSE; + // // The flag indicates if SMM profile starts to record data. // @@ -342,7 +347,7 @@ IsAddressSplit ( { UINTN Index; - if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + if (mSmmProfileEnabled) { // // Check configuration // @@ -1018,7 +1023,7 @@ InitSmmProfile ( // // Skip SMM profile initialization if feature is disabled // - if (!FeaturePcdGet (PcdCpuSmmProfileEnable) && + if (!mSmmProfileEnabled && !HEAP_GUARD_NONSTOP_MODE && !NULL_DETECTION_NONSTOP_MODE) { diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h index feddf6eec362..2726840c0e38 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h @@ -137,6 +137,10 @@ extern BOOLEAN mXdSupported; // extern BOOLEAN mXdEnabled; // +// The flag indicates if SMM profile is enabled. +// +extern BOOLEAN mSmmProfileEnabled; +// // The flag indicates if #DB will be setup in #PF handler. // extern BOOLEAN mSetupDebugTrap; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index f56d2849de0c..15d53b14114e 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -228,7 +228,7 @@ SmmInitPageTable ( // PageTable = GenSmmPageTable (mPagingMode, mPhysicalAddressBits); - if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + if (mSmmProfileEnabled) { if (m5LevelPagingNeeded) { Pml5Entry = (UINT64 *)PageTable; // @@ -264,7 +264,7 @@ SmmInitPageTable ( } } - if (FeaturePcdGet (PcdCpuSmmProfileEnable) || + if (mSmmProfileEnabled || HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) { @@ -820,7 +820,7 @@ SmiPFHandler ( } } - if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + if (mSmmProfileEnabled) { if (mIsStandaloneMm) { // // Only logging ranges shall run here in MM env. From 0de7882b46f31618f60bec65005af9a1d085b051 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 8 Jul 2024 13:24:55 +0800 Subject: [PATCH 091/280] UefiCpuPkg/PiSmmCpuDxeSmm: Simplify SMM Profile Size Calculation The motivation of this change is to simplify the logic in StandaloneMmIpl when allocating the memory for SMM profile data. IPL does not need to detect the CPU feature regarding MSR DS Area. That change requires the PCD value contains the MSR DS Area. So, the size of SmmProfileData will be simplified to the PcdCpuSmmProfileSize directly. mMsrDsAreaSize will be within the PcdCpuSmmProfileSize if mBtsSupported is TRUE. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c | 6 +----- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 2 -- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 12 +++++++++--- UefiCpuPkg/UefiCpuPkg.dec | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c index 51f0edd296cb..a98013b7d01e 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c @@ -495,11 +495,7 @@ GetSmmProfileData ( ASSERT (Size != NULL); - if (mBtsSupported) { - *Size = PcdGet32 (PcdCpuSmmProfileSize) + mMsrDsAreaSize; - } else { - *Size = PcdGet32 (PcdCpuSmmProfileSize); - } + *Size = PcdGet32 (PcdCpuSmmProfileSize); Base = 0xFFFFFFFF; Status = gBS->AllocatePages ( diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index 0dccf7ca656b..bc08f03640e8 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -270,8 +270,6 @@ extern UINTN mSmmShadowStackSize; /// extern UINT8 mSmmSaveStateRegisterLma; -extern BOOLEAN mBtsSupported; -extern UINTN mMsrDsAreaSize; extern BOOLEAN mAcpiS3Enable; #define PAGE_TABLE_POOL_ALIGNMENT BASE_128KB diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index 164af20a4cd7..c152dccea4bc 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -748,9 +748,6 @@ InitSmmProfileInternal ( ); ASSERT (mLastPFEntryPointer != NULL); - mSmmProfileSize = FixedPcdGet32 (PcdCpuSmmProfileSize); - ASSERT ((mSmmProfileSize & 0xFFF) == 0); - // // Get Smm Profile Base // @@ -758,6 +755,15 @@ InitSmmProfileInternal ( DEBUG ((DEBUG_ERROR, "SmmProfileBase = 0x%016x.\n", (UINTN)mSmmProfileBase)); DEBUG ((DEBUG_ERROR, "SmmProfileSize = 0x%016x.\n", (UINTN)SmmProfileSize)); + if (mBtsSupported) { + ASSERT (SmmProfileSize > mMsrDsAreaSize); + mSmmProfileSize = (UINTN)SmmProfileSize - mMsrDsAreaSize; + } else { + mSmmProfileSize = (UINTN)SmmProfileSize; + } + + ASSERT ((mSmmProfileSize & 0xFFF) == 0); + // // Initialize SMM profile data header. // diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 2cabf5fc0333..33ac8cf91c4a 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -281,7 +281,7 @@ ## Specifies buffer size in bytes to save SMM profile data. The value should be a multiple of 4KB. # @Prompt SMM profile data buffer size. - gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize|0x200000|UINT32|0x32132107 + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize|0x600000|UINT32|0x32132107 ## Specifies stack size in bytes for each processor in SMM. # @Prompt Processor stack size in SMM. From 84e7b74c8c643c59ee32d4da769f48a3c8c277a4 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Thu, 20 Jun 2024 15:59:18 +0800 Subject: [PATCH 092/280] UefiCpuPkg/UefiCpuPkg.dsc: Include PiSmmCpuStandaloneMm and required Libs Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/UefiCpuPkg.dsc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 34d0d45bf624..6459ba8f1ab2 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -69,6 +69,8 @@ UnitTestPersistenceLib|UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf + HobLib|MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf + MemoryAllocationLib|MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf [LibraryClasses.common.SEC] PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf @@ -102,11 +104,14 @@ MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf - CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf - MmSaveStateLib|UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf [LibraryClasses.common.MM_STANDALONE] MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf + SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf + +[LibraryClasses.common.MM_STANDALONE, LibraryClasses.common.DXE_SMM_DRIVER] + CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf + MmSaveStateLib|UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf [LibraryClasses.common.UEFI_APPLICATION] UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf @@ -207,6 +212,7 @@ UefiCpuPkg/Library/SmmRelocationLib/AmdSmmRelocationLib.inf [Components.X64] + UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerLibUnitTest.inf [Components.RISCV64] From 94f68d0b56a36d84e038751f9cd907c2cf637626 Mon Sep 17 00:00:00 2001 From: Ray Ni Date: Fri, 14 Apr 2023 17:19:37 +0800 Subject: [PATCH 093/280] UefiCpuPkg/MpInitLib: Separate X2APIC enabling to subfunction It's very confusing that auto X2 APIC enabling and APIC ID sorting are all performed inside CollectProcessorCount(). The change is to separate the X2 APIC enabling to AutoEnableX2Apic() and call that from MpInitLibInitialize(). SortApicId() is called from MpInitLibInitialize() as well. Signed-off-by: Ray Ni Cc: Eric Dong Cc: Rahul Kumar Cc: Gerd Hoffmann --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 65 ++++++++++++++++++---------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 4088e76f4583..e708b3fef4fa 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -502,33 +502,20 @@ GetProcessorNumber ( } /** - This function will get CPU count in the system. + Enable x2APIC mode if + 1. Number of CPU is greater than 255; or + 2. There are any logical processors reporting an Initial APIC ID of 255 or greater. @param[in] CpuMpData Pointer to PEI CPU MP Data - - @return CPU count detected **/ -UINTN -CollectProcessorCount ( +VOID +AutoEnableX2Apic ( IN CPU_MP_DATA *CpuMpData ) { + BOOLEAN X2Apic; UINTN Index; CPU_INFO_IN_HOB *CpuInfoInHob; - BOOLEAN X2Apic; - - // - // Send 1st broadcast IPI to APs to wakeup APs - // - CpuMpData->InitFlag = ApInitConfig; - WakeUpAP (CpuMpData, TRUE, 0, NULL, NULL, TRUE); - CpuMpData->InitFlag = ApInitDone; - // - // When InitFlag == ApInitConfig, WakeUpAP () guarantees all APs are checked in. - // FinishedCount is the number of check-in APs. - // - CpuMpData->CpuCount = CpuMpData->FinishedCount + 1; - ASSERT (CpuMpData->CpuCount <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); // // Enable x2APIC mode if @@ -577,12 +564,32 @@ CollectProcessorCount ( } DEBUG ((DEBUG_INFO, "APIC MODE is %d\n", GetApicMode ())); +} + +/** + This function will get CPU count in the system. + + @param[in] CpuMpData Pointer to PEI CPU MP Data + + @return CPU count detected +**/ +UINTN +CollectProcessorCount ( + IN CPU_MP_DATA *CpuMpData + ) +{ // - // Sort BSP/Aps by CPU APIC ID in ascending order + // Send 1st broadcast IPI to APs to wakeup APs // - SortApicId (CpuMpData); - - DEBUG ((DEBUG_INFO, "MpInitLib: Find %d processors in system.\n", CpuMpData->CpuCount)); + CpuMpData->InitFlag = ApInitConfig; + WakeUpAP (CpuMpData, TRUE, 0, NULL, NULL, TRUE); + CpuMpData->InitFlag = ApInitDone; + // + // When InitFlag == ApInitConfig, WakeUpAP () guarantees all APs are checked in. + // FinishedCount is the number of check-in APs. + // + CpuMpData->CpuCount = CpuMpData->FinishedCount + 1; + ASSERT (CpuMpData->CpuCount <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); return CpuMpData->CpuCount; } @@ -2226,6 +2233,18 @@ MpInitLibInitialize ( // Wakeup all APs and calculate the processor count in system // CollectProcessorCount (CpuMpData); + + // + // Enable X2APIC if needed. + // + AutoEnableX2Apic (CpuMpData); + + // + // Sort BSP/Aps by CPU APIC ID in ascending order + // + SortApicId (CpuMpData); + + DEBUG ((DEBUG_INFO, "MpInitLib: Find %d processors in system.\n", CpuMpData->CpuCount)); } } else { // From 7ed398916605be3e9fd3b1bfc8f49cc36e86fd3f Mon Sep 17 00:00:00 2001 From: Ray Ni Date: Fri, 14 Apr 2023 13:58:15 +0800 Subject: [PATCH 094/280] UefiCpuPkg/MpInitLib: Sync BSP's APIC mode to APs in InitConfig path The change saves the BSP's initial APIC mode and syncs to all APs in first time wakeup. It allows certain platforms to switch to X2 APIC as early as possible and also independent on CpuFeaturePei/Dxe. The platform should switch BSP to X2 APIC mode first before the CpuMpPeim runs. Signed-off-by: Ray Ni Cc: Eric Dong Cc: Gerd Hoffmann --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 11 +++++++++++ UefiCpuPkg/Library/MpInitLib/MpLib.h | 22 +++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index e708b3fef4fa..4e28ff3fe421 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -758,6 +758,12 @@ ApWakeupFunction ( CurrentApicMode = GetApicMode (); while (TRUE) { if (CpuMpData->InitFlag == ApInitConfig) { + // + // Synchronize APIC mode with BSP in the first time AP wakeup ONLY. + // + SetApicMode (CpuMpData->InitialBspApicMode); + CurrentApicMode = CpuMpData->InitialBspApicMode; + ProcessorNumber = ApIndex; // // This is first time AP wakeup, get BIST information from AP stack @@ -2221,6 +2227,11 @@ MpInitLibInitialize ( ); DEBUG ((DEBUG_INFO, "AP Vector: non-16-bit = %p/%x\n", CpuMpData->WakeupBufferHigh, ApResetVectorSizeAbove1Mb)); + // + // Save APIC mode for AP to sync + // + CpuMpData->InitialBspApicMode = GetApicMode (); + // // Enable the local APIC for Virtual Wire Mode. // diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index e92991d5dc99..690b7b0e1bc4 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -250,11 +250,23 @@ typedef struct { // in assembly code. // struct _CPU_MP_DATA { - UINT64 CpuInfoInHob; - UINT32 CpuCount; - UINT32 BspNumber; - SPIN_LOCK MpLock; - UINTN Buffer; + UINT64 CpuInfoInHob; + UINT32 CpuCount; + UINT32 BspNumber; + SPIN_LOCK MpLock; + UINTN Buffer; + + // + // InitialBspApicMode stores the initial BSP APIC mode. + // It is used to synchronize the BSP APIC mode with APs + // in the first time APs wake up. + // Its value doesn't reflect the current APIC mode since there are + // two cases the APIC mode is changed: + // 1. MpLib explicitly switches to X2 APIC mode because number of threads is greater than 255, + // or there are any logical processors reporting an initial APIC ID of 255 or greater. + // 2. Some code switches to X2 APIC mode in all threads through MP services PPI/Protocol. + // + UINTN InitialBspApicMode; UINTN CpuApStackSize; MP_ASSEMBLY_ADDRESS_MAP AddressMap; UINTN WakeupBuffer; From 319835abb8517fde84bff31740fb1e61b33a3ae8 Mon Sep 17 00:00:00 2001 From: Ray Ni Date: Tue, 18 Apr 2023 17:41:21 +0800 Subject: [PATCH 095/280] UefiCpuPkg/MpInitLib: Skip X2APIC enabling when BSP in X2APIC already The BSP's APIC mode is synced to all APs in CollectProcessorCount(). So, it's safe to skip the X2 APIC enabling in AutoEnableX2Apic() which runs later when BSP's APIC mode is X2 APIC already. Signed-off-by: Ray Ni Cc: Eric Dong Cc: Rahul Kumar Cc: Gerd Hoffmann --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 4e28ff3fe421..67e8556a4ab9 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -2248,7 +2248,9 @@ MpInitLibInitialize ( // // Enable X2APIC if needed. // - AutoEnableX2Apic (CpuMpData); + if (CpuMpData->InitialBspApicMode == LOCAL_APIC_MODE_XAPIC) { + AutoEnableX2Apic (CpuMpData); + } // // Sort BSP/Aps by CPU APIC ID in ascending order From 7cde720e5126a47dadfb63ec9fd11b637620102d Mon Sep 17 00:00:00 2001 From: HoraceX Lien Date: Thu, 8 Aug 2024 16:50:22 +0800 Subject: [PATCH 096/280] ShellPkg: Correct smbiosview strings and conditions for SMBIOS Type9 REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4826 Using smbiosview to dump SMBIOS Type9, some code condition and string are incorrect. Signed-off-by: HoraceX Lien Cc: Liming Gao Reviewed-by: Liming Gao --- .../SmbiosView/PrintInfo.c | 19 +++++++++---------- .../SmbiosView/QueryTable.c | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c index 5c4413cbe35d..a31f823304ea 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c @@ -3173,7 +3173,7 @@ DisplaySystemSlotId ( // case 0x04: ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_LOGICAL_MICRO_CHAN), gShellDebug1HiiHandle); - if ((SlotId > 0) && (SlotId < 15)) { + if ((SlotId > 0) && (SlotId <= 15)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ONE_VAR_D), gShellDebug1HiiHandle, SlotId); } else { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ERROR_NOT_1_15), gShellDebug1HiiHandle); @@ -3182,11 +3182,11 @@ DisplaySystemSlotId ( break; // - // EISA + // Slot Type: EISA // case 0x05: ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_LOGICAL_EISA_NUM), gShellDebug1HiiHandle); - if ((SlotId > 0) && (SlotId < 15)) { + if ((SlotId > 0) && (SlotId <= 15)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ONE_VAR_D), gShellDebug1HiiHandle, SlotId); } else { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ERROR_NOT_1_15), gShellDebug1HiiHandle); @@ -3202,21 +3202,20 @@ DisplaySystemSlotId ( break; // - // PCMCIA + // Slot Type: PCMCIA // case 0x07: ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_IDENTIFIES_ADAPTER_NUM), gShellDebug1HiiHandle, SlotId); break; // - // Slot Type: PCI-E + // Slot Type: PCI 66MHz Capable, AGP, PCI-E, etc // - case 0xA5: - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_VALUE_PRESENT), gShellDebug1HiiHandle, SlotId); - break; - default: - if (((SlotType >= 0x0E) && (SlotType <= 0x12)) || ((SlotType >= 0xA6) && (SlotType <= 0xC4))) { + if (((SlotType >= 0x0E) && (SlotType <= 0x13)) || + ((SlotType >= 0x1F) && (SlotType <= 0x25)) || + ((SlotType >= 0xA5) && (SlotType <= 0xC6))) + { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_VALUE_PRESENT), gShellDebug1HiiHandle, SlotId); } else { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNDEFINED_SLOT_ID), gShellDebug1HiiHandle); diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c index 36f8739d6c87..0db28b66de62 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c @@ -1924,7 +1924,7 @@ TABLE_ITEM SystemSlotHeightTable[] = { }, { 0x02, - L" Unkown" + L" Unknown" }, { 0x03, From 41a51d173557350ec8bcf64075a3e97730bf70dd Mon Sep 17 00:00:00 2001 From: Nhi Pham Date: Fri, 23 Aug 2024 09:01:37 +0700 Subject: [PATCH 097/280] ArmPkg/GenericWatchdogDxe: Disable WDOG before the protocol installed This moves the WatchdogDisable() function before the installation of the gEfiWatchdogTimerArchProtocolGuid protocol. It allows a platform to promptly carry out platform specific configurations, such as UEFI boot monitoring, by registering the protocol installation callback. Signed-off-by: Nhi Pham --- ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c index 5bff073bc53b..b91e62e1a815 100644 --- a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c +++ b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c @@ -391,6 +391,8 @@ GenericWatchdogEntry ( goto UnregisterHandler; } + WatchdogDisable (); + // Install the Timer Architectural Protocol onto a new handle Handle = NULL; Status = gBS->InstallMultipleProtocolInterfaces ( @@ -413,8 +415,6 @@ GenericWatchdogEntry ( ); ASSERT_EFI_ERROR (Status); - WatchdogDisable (); - return EFI_SUCCESS; UnregisterHandler: From 9cd66aca1a54b10dd3f6adcfef8d784281385a2c Mon Sep 17 00:00:00 2001 From: "Michael G.A. Holland" Date: Wed, 21 Aug 2024 12:18:38 -0500 Subject: [PATCH 098/280] CryptoPkg: Support BrainpoolP512r1 algorithm REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4830 Allow BrainpoolP512r1 to be leveraged when the corresponding curve ID is passed to crypto libraries in EDK2 Signed-off-by: Michael G.A. Holland --- CryptoPkg/Include/Library/BaseCryptLib.h | 7 ++++--- CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c | 9 +++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h index 95e4142f52a4..84ed87e05acf 100644 --- a/CryptoPkg/Include/Library/BaseCryptLib.h +++ b/CryptoPkg/Include/Library/BaseCryptLib.h @@ -23,9 +23,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define CRYPTO_NID_SHA512 0x0003 // Key Exchange -#define CRYPTO_NID_SECP256R1 0x0204 -#define CRYPTO_NID_SECP384R1 0x0205 -#define CRYPTO_NID_SECP521R1 0x0206 +#define CRYPTO_NID_SECP256R1 0x0204 +#define CRYPTO_NID_SECP384R1 0x0205 +#define CRYPTO_NID_SECP521R1 0x0206 +#define CRYPTO_NID_BRAINPOOLP512R1 0x03A5 /// /// MD5 digest size in bytes diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c index d8cc9ba0e8f9..f85232bf6e70 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c @@ -42,6 +42,9 @@ CryptoNidToOpensslNid ( case CRYPTO_NID_SECP521R1: Nid = NID_secp521r1; break; + case CRYPTO_NID_BRAINPOOLP512R1: + Nid = NID_brainpoolP512r1; + break; default: return -1; } @@ -833,6 +836,9 @@ EcDsaSign ( case NID_secp521r1: HalfSize = 66; break; + case NID_brainpoolP512r1: + HalfSize = 64; + break; default: return FALSE; } @@ -961,6 +967,9 @@ EcDsaVerify ( case NID_secp521r1: HalfSize = 66; break; + case NID_brainpoolP512r1: + HalfSize = 64; + break; default: return FALSE; } From 383f729ac096b8deb279933fce86e83a5f7f5ec7 Mon Sep 17 00:00:00 2001 From: Ceping Sun Date: Thu, 15 Aug 2024 05:10:06 +0800 Subject: [PATCH 099/280] OvmfPkg/PlatformInitLib: Reserve Sec Page Tables in TDVF In the system boot phase, if OS postpone onlining some CPU until later, the sec page tables could be overwritten. So, TDVF needs to reserve the initial page tables that would be used by APs on Mailbox wakeup. Cc: Erdem Aktas Cc: Jiewen Yao Cc: Min Xu Cc: Gerd Hoffmann Cc: Elena Reshetova Cc: Kirill A Shutemov Signed-off-by: Ceping Sun --- OvmfPkg/Library/PlatformInitLib/IntelTdx.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c index e561cee30b17..12e4501c5b5e 100644 --- a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c +++ b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c @@ -153,6 +153,18 @@ PlatformTdxPublishRamRegions ( TransferTdxHobList (); + // + // Reserve the initial page tables built by the reset vector code. + // + // Since this memory range will be used by APs on Mailbox + // wakeup, it must be reserved as ACPI NVS. + // + BuildMemoryAllocationHob ( + (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecPageTablesBase), + (UINT64)(UINTN)PcdGet32 (PcdOvmfSecPageTablesSize), + EfiACPIMemoryNVS + ); + // // The memory region defined by PcdOvmfSecGhcbBackupBase is pre-allocated by // host VMM and used as the td mailbox at the beginning of system boot. From 2fe9b6c22fcc9b8617b95d4a2cf091fea4f66537 Mon Sep 17 00:00:00 2001 From: Prachotan Reddy Bathi Date: Thu, 22 Aug 2024 15:42:15 -0500 Subject: [PATCH 100/280] MdePkg:BaseArmTrngLibNull: Assert causing FVP stalling FVP Base Revc doesn't support Trng. ASSERT (FALSE) is causing the boot to stall. Replacing ASSERT with ERROR log. Signed-off-by: Prachotan Reddy Bathi --- MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.c b/MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.c index 316d78bf5e83..84366a4e96bd 100644 --- a/MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.c +++ b/MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.c @@ -41,7 +41,7 @@ GetArmTrngVersion ( OUT UINT16 *MinorRevision ) { - ASSERT (FALSE); + DEBUG ((DEBUG_ERROR, "ArmTrng Backend not found\n")); return RETURN_UNSUPPORTED; } From 14e6c48103d7bff65226a063c263a405c4de426e Mon Sep 17 00:00:00 2001 From: Nickle Wang Date: Fri, 2 Aug 2024 10:22:31 +0800 Subject: [PATCH 101/280] RedfishPkg/RedfishHttpDxe: add status code check for modification request Add HTTP status code check for POST, PUT, PATCH and DELETE Redfish request. When status code is not expected, return failure to caller. The expected HTTP status code is defined in Redfish specification. Signed-off-by: Nickle Wang --- RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c | 69 ++++++++++++++++++++-- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c b/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c index f15b371f5b50..2de5443bcdec 100644 --- a/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c +++ b/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c @@ -92,6 +92,67 @@ RedfishRetryRequired ( return FALSE; } +/** + + This function follows below sections in Redfish specification to + check HTTP status code and see if this is success response or not. + + 7.5.2 Modification success responses + 7.11 POST (action) + + @param[in] Method HTTP method of this status code. + @param[in] StatusCode HTTP status code. + + @retval BOOLEAN Return true when this is success response. + Return false when this is not success response. + +**/ +BOOLEAN +RedfishSuccessResponse ( + IN EFI_HTTP_METHOD Method, + IN EFI_HTTP_STATUS_CODE *StatusCode + ) +{ + BOOLEAN SuccessResponse; + + if (StatusCode == NULL) { + return TRUE; + } + + SuccessResponse = FALSE; + switch (Method) { + case HttpMethodPost: + if ((*StatusCode == HTTP_STATUS_200_OK) || + (*StatusCode == HTTP_STATUS_201_CREATED) || + (*StatusCode == HTTP_STATUS_202_ACCEPTED) || + (*StatusCode == HTTP_STATUS_204_NO_CONTENT)) + { + SuccessResponse = TRUE; + } + + break; + case HttpMethodPatch: + case HttpMethodPut: + case HttpMethodDelete: + if ((*StatusCode == HTTP_STATUS_200_OK) || + (*StatusCode == HTTP_STATUS_202_ACCEPTED) || + (*StatusCode == HTTP_STATUS_204_NO_CONTENT)) + { + SuccessResponse = TRUE; + } + + break; + default: + // + // Return true for unsupported method to prevent false alarm. + // + SuccessResponse = TRUE; + break; + } + + return SuccessResponse; +} + /** Convert Unicode string to ASCII string. It's call responsibility to release returned buffer. @@ -824,7 +885,7 @@ RedfishPatchResource ( DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri)); RedfishExpireResponse (This, Uri); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || !RedfishSuccessResponse (HttpMethodPatch, Response->StatusCode)) { DEBUG_CODE ( DumpRedfishResponse (NULL, DEBUG_ERROR, Response); ); @@ -941,7 +1002,7 @@ RedfishPutResource ( DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri)); RedfishExpireResponse (This, Uri); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || !RedfishSuccessResponse (HttpMethodPut, Response->StatusCode)) { DEBUG_CODE ( DumpRedfishResponse (NULL, DEBUG_ERROR, Response); ); @@ -1058,7 +1119,7 @@ RedfishPostResource ( DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri)); RedfishExpireResponse (This, Uri); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || !RedfishSuccessResponse (HttpMethodPost, Response->StatusCode)) { DEBUG_CODE ( DumpRedfishResponse (NULL, DEBUG_ERROR, Response); ); @@ -1177,7 +1238,7 @@ RedfishDeleteResource ( DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri)); RedfishExpireResponse (This, Uri); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || !RedfishSuccessResponse (HttpMethodDelete, Response->StatusCode)) { DEBUG_CODE ( DumpRedfishResponse (NULL, DEBUG_ERROR, Response); ); From 31f022500549f1d862af531da704a9b3c6568ff5 Mon Sep 17 00:00:00 2001 From: Nickle Wang Date: Wed, 7 Aug 2024 15:48:37 +0800 Subject: [PATCH 102/280] RedfishPkg/RedfishHttpDxe: check response content type. Check HTTP response content type to see if it is application/json type or not. In Redfish, we expect to see response data in JSON format. If it is not, show warning message to developer. Signed-off-by: Nickle Wang --- RedfishPkg/RedfishHttpDxe/RedfishHttpOperation.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/RedfishPkg/RedfishHttpDxe/RedfishHttpOperation.c b/RedfishPkg/RedfishHttpDxe/RedfishHttpOperation.c index 8110985addaf..8ae1d2d7a30b 100644 --- a/RedfishPkg/RedfishHttpDxe/RedfishHttpOperation.c +++ b/RedfishPkg/RedfishHttpDxe/RedfishHttpOperation.c @@ -493,6 +493,7 @@ ParseResponseMessage ( EFI_STATUS Status; EDKII_JSON_VALUE JsonData; EFI_HTTP_HEADER *ContentEncodedHeader; + EFI_HTTP_HEADER *ContentTypeHeader; VOID *DecodedBody; UINTN DecodedLength; @@ -545,6 +546,17 @@ ParseResponseMessage ( // if ((ResponseMsg->BodyLength != 0) && (ResponseMsg->Body != NULL)) { DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: body length: %d\n", __func__, ResponseMsg->BodyLength)); + + // + // We expect to see JSON body + // + ContentTypeHeader = HttpFindHeader (RedfishResponse->HeaderCount, RedfishResponse->Headers, HTTP_HEADER_CONTENT_TYPE); + if (ContentTypeHeader != NULL) { + if (AsciiStrCmp (ContentTypeHeader->FieldValue, HTTP_CONTENT_TYPE_APP_JSON) != 0) { + DEBUG ((DEBUG_WARN, "%a: body is not in %a format\n", __func__, HTTP_CONTENT_TYPE_APP_JSON)); + } + } + // // Check if data is encoded. // From 254641f342ac3c1991e0e4d32c0ea9c8cfc723f3 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Mon, 26 Aug 2024 10:18:04 -0700 Subject: [PATCH 103/280] MdeModulePkg: MAT: Do Not Set EfiMemoryMappedIo[PortSpace] Attrs Per UEFI spec 2.10 section 4.6.3 EFI_MEMORY_ATTRIBUTES_TABLE, "The Memory Attributes Table is currently used to describe memory protections that may be applied to the EFI Runtime code and data by an operating system or hypervisor. Consumers of this table must currently ignore entries containing any values for Type except for EfiRuntimeServicesData and EfiRuntimeServicesCode to ensure compatibility with future uses of this table." However, the current MAT code also enforces attributes for EfiMemoryMappedIo and EfiMemoryMappedIoPortSpace, which it should not be. Per https://edk2.groups.io/g/devel/topic/patch_v1_mdemodulepkg/105570114?p=,,,20,0,0,0::recentpostdate/sticky,,,20,2,0,105570114, it was suggested to remove these types from the MAT logic. This patch removes EfiMemoryMappedIo and EfiMemoryMappedIoPortSpace from the MAT logic in accordance with the UEFI spec. Signed-off-by: Oliver Smith-Denny --- MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c index e9343a2c4ef1..5fe285c48bbb 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c @@ -426,7 +426,7 @@ MergeMemoryMap ( /** Enforce memory map attributes. - This function will set EfiRuntimeServicesData/EfiMemoryMappedIO/EfiMemoryMappedIOPortSpace to be EFI_MEMORY_XP. + This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP. @param MemoryMap A pointer to the buffer in which firmware places the current memory map. @@ -452,8 +452,6 @@ EnforceMemoryMapAttribute ( // do nothing break; case EfiRuntimeServicesData: - case EfiMemoryMappedIO: - case EfiMemoryMappedIOPortSpace: MemoryMapEntry->Attribute |= EFI_MEMORY_XP; break; case EfiReservedMemoryType: From bb248a95091ab542440053d9c289a97e80eb6630 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Mon, 26 Aug 2024 10:23:14 -0700 Subject: [PATCH 104/280] MdeModulePkg: MAT Set RO/XP on Code/Data Sections Outside Image Memory The Memory Attributes Table is generated by fetching the EFI memory map and splitting entries which contain loaded images so DATA and CODE sections have separate descriptors. The splitting is done via a call to SplitTable() which marks image DATA sections with the EFI_MEMORY_XP attribute and CODE sections with the EFI_MEMORY_RO attribute when splitting. After this process, there may still be EfiRuntimeServicesCode regions which did not have their attributes set because they are not part of loaded images. This patch updates the MAT EnforceMemoryMapAttribute logic to set the access attributes of runtime memory regions which are not part of loaded images (have not had their access attributes set). The attributes of the code regions will be read-only and no-execute because the UEFI spec dictates that runtime code regions should only contain loaded EFI modules. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4832 Refs: 1. https://edk2.groups.io/g/devel/topic/patch_v1_mdemodulepkg/105570114?p=,,,20,0,0,0::recentpostdate/sticky,,,20,2,0,105570114 2. https://edk2.groups.io/g/devel/topic/mdemodulepkg_fix_mat/105477564?p=,,,20,0,0,0::recentpostdate/sticky,,,20,2,0,105477564 Signed-off-by: Oliver Smith-Denny --- .../Core/Dxe/Misc/MemoryAttributesTable.c | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c index 5fe285c48bbb..58b947423a0e 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c @@ -447,16 +447,23 @@ EnforceMemoryMapAttribute ( MemoryMapEntry = MemoryMap; MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize); while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { - switch (MemoryMapEntry->Type) { - case EfiRuntimeServicesCode: - // do nothing - break; - case EfiRuntimeServicesData: - MemoryMapEntry->Attribute |= EFI_MEMORY_XP; - break; - case EfiReservedMemoryType: - case EfiACPIMemoryNVS: - break; + if ((MemoryMapEntry->Attribute & EFI_MEMORY_ACCESS_MASK) == 0) { + switch (MemoryMapEntry->Type) { + case EfiRuntimeServicesCode: + // If at this point the attributes have not been set on an EfiRuntimeServicesCode + // region, the memory range must not contain a loaded image. It's possible these + // non-image EfiRuntimeServicesCode regions are part of the unused memory bucket. + // It could also be that this region was explicitly allocated outside of the PE + // loader but the UEFI spec requires that all EfiRuntimeServicesCode regions contain + // EFI modules. In either case, set the attributes to RO and XP. + MemoryMapEntry->Attribute |= (EFI_MEMORY_RO | EFI_MEMORY_XP); + break; + case EfiRuntimeServicesData: + MemoryMapEntry->Attribute |= EFI_MEMORY_XP; + break; + default: + break; + } } MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); From 01735bbe4a46a6fb7d5d739d0fc5a14897ad18da Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Wed, 7 Aug 2024 14:44:03 -0700 Subject: [PATCH 105/280] MdeModulePkg: Gcd: Only Update gMemoryMap Attributes if Correct GCD Type Currently whenever gDS->SetMemorySpaceCapabilities() is called, it attempts to set the corresponding attributes in the gMemoryMap descriptor. However, gMemoryMap only contains entries from GCD types EfiGcdMemoryTypeSystemMemory and EfiGcdMemoryTypeMoreReliable, so for all other types a failure is reported in the code. This is a failure that is expected, so it does not provide value and can lead to real failures being ignored. This patch updates the gDS->SetMemorySpaceCapabilities() code to only call into updating gMemoryMap if the GCD type is SystemMemory or MoreReliable, to avoid spurious errors being reported. This also avoids the expensive operation of searching through gMemoryMap for entries we know we will fail to find. Signed-off-by: Oliver Smith-Denny --- MdeModulePkg/Core/Dxe/Gcd/Gcd.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c index 99364508cd36..6ea89fbc8b3e 100644 --- a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c +++ b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c @@ -989,6 +989,20 @@ CoreConvertSpace ( // case GCD_SET_CAPABILITIES_MEMORY_OPERATION: Entry->Capabilities = Capabilities; + + // Only SystemMemory and MoreReliable memory is in gMemoryMap + // so only attempt to update the attributes there if this is + // a relevant GCD type + if ((Entry->GcdMemoryType == EfiGcdMemoryTypeSystemMemory) || + (Entry->GcdMemoryType == EfiGcdMemoryTypeMoreReliable)) + { + CoreUpdateMemoryAttributes ( + BaseAddress, + RShiftU64 (Length, EFI_PAGE_SHIFT), + Capabilities & (~EFI_MEMORY_RUNTIME) + ); + } + break; } @@ -1700,17 +1714,10 @@ CoreSetMemorySpaceCapabilities ( IN UINT64 Capabilities ) { - EFI_STATUS Status; - DEBUG ((DEBUG_GCD, "GCD:CoreSetMemorySpaceCapabilities(Base=%016lx,Length=%016lx)\n", BaseAddress, Length)); DEBUG ((DEBUG_GCD, " Capabilities = %016lx\n", Capabilities)); - Status = CoreConvertSpace (GCD_SET_CAPABILITIES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, Capabilities, 0); - if (!EFI_ERROR (Status)) { - CoreUpdateMemoryAttributes (BaseAddress, RShiftU64 (Length, EFI_PAGE_SHIFT), Capabilities & (~EFI_MEMORY_RUNTIME)); - } - - return Status; + return CoreConvertSpace (GCD_SET_CAPABILITIES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, Capabilities, 0); } /** From 1169122c6f22d4db3e44b7b720480522b6933a62 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Wed, 26 Apr 2023 12:04:37 -0700 Subject: [PATCH 106/280] MdeModulePkg NonDiscoverablePciDeviceIo: MMIO Memory XP By Default When allocating memory for a non-discoverable PCI device's IO, the current core code removes the XP attribute, allowing code to execute from that region. This is a security vulnerability and unneeded. This change updates to mark the region as XP when allocating memory for the non-discoverable PCI device. These allocations in this function are limited to `EfiBootServicesData` and `EfiRuntimeServicesData`, which we expect to be XP. Signed-off-by: Aaron Pop --- .../NonDiscoverablePciDeviceIo.c | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c b/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c index e31c38deed6c..4daf51761ba0 100644 --- a/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c +++ b/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c @@ -1111,6 +1111,8 @@ NonCoherentPciIoAllocateBuffer ( NON_DISCOVERABLE_DEVICE_UNCACHED_ALLOCATION *Alloc; VOID *AllocAddress; + MemType = EFI_MEMORY_XP; + if (HostAddress == NULL) { return EFI_INVALID_PARAMETER; } @@ -1152,9 +1154,9 @@ NonCoherentPciIoAllocateBuffer ( // Use write combining if it was requested, or if it is the only // type supported by the region. // - MemType = EFI_MEMORY_WC; + MemType |= EFI_MEMORY_WC; } else { - MemType = EFI_MEMORY_UC; + MemType |= EFI_MEMORY_UC; } Alloc = AllocatePool (sizeof *Alloc); @@ -1172,6 +1174,34 @@ NonCoherentPciIoAllocateBuffer ( // InsertHeadList (&Dev->UncachedAllocationList, &Alloc->List); + // + // Ensure that EFI_MEMORY_XP is in the capability set + // + if ((GcdDescriptor.Capabilities & EFI_MEMORY_XP) != EFI_MEMORY_XP) { + Status = gDS->SetMemorySpaceCapabilities ( + (PHYSICAL_ADDRESS)(UINTN)AllocAddress, + EFI_PAGES_TO_SIZE (Pages), + GcdDescriptor.Capabilities | EFI_MEMORY_XP + ); + + // if we were to fail setting the capability, this would indicate an internal failure of the GCD code. We should + // assert here to let a platform know something went crazy, but for a release build we can let the allocation occur + // without the EFI_MEMORY_XP bit set, as that was the existing behavior + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a failed to set EFI_MEMORY_XP capability on 0x%llx for length 0x%llx. Attempting to allocate without XP set.\n", + __func__, + AllocAddress, + EFI_PAGES_TO_SIZE (Pages) + )); + + ASSERT_EFI_ERROR (Status); + + MemType &= ~EFI_MEMORY_XP; + } + } + Status = gDS->SetMemorySpaceAttributes ( (EFI_PHYSICAL_ADDRESS)(UINTN)AllocAddress, EFI_PAGES_TO_SIZE (Pages), From 7801fe428b0b43099966b68f2441329f4dfc0234 Mon Sep 17 00:00:00 2001 From: Ray Robles Date: Thu, 18 Jul 2024 10:25:35 -0700 Subject: [PATCH 107/280] MdePkg Nvme.h: Update fields from 1.4c specification. Implement 1.4c specification update, specifically for nvme sanitize capabilities. Signed-off-by: Aaron Pop --- MdePkg/Include/IndustryStandard/Nvme.h | 76 ++++++++++++++++++-------- 1 file changed, 53 insertions(+), 23 deletions(-) diff --git a/MdePkg/Include/IndustryStandard/Nvme.h b/MdePkg/Include/IndustryStandard/Nvme.h index 2a94e2120310..ffb8b843148b 100644 --- a/MdePkg/Include/IndustryStandard/Nvme.h +++ b/MdePkg/Include/IndustryStandard/Nvme.h @@ -3,6 +3,7 @@ (C) Copyright 2016 Hewlett Packard Enterprise Development LP
Copyright (c) 2017 - 2023, Intel Corporation. All rights reserved.
+ Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Specification Reference: @@ -27,10 +28,12 @@ #define NVME_INTMC_OFFSET 0x0010 // Interrupt Mask Clear #define NVME_CC_OFFSET 0x0014 // Controller Configuration #define NVME_CSTS_OFFSET 0x001c // Controller Status -#define NVME_NSSR_OFFSET 0x0020 // NVM Subsystem Reset +#define NVME_NSSR_OFFSET 0x0020 // NVM Subsystem Reset (Optional) #define NVME_AQA_OFFSET 0x0024 // Admin Queue Attributes #define NVME_ASQ_OFFSET 0x0028 // Admin Submission Queue Base Address #define NVME_ACQ_OFFSET 0x0030 // Admin Completion Queue Base Address +#define NVME_CMBLOC_OFFSET 0x0038 // Control Memory Buffer Location (Optional) +#define NVME_CMBSZ_OFFSET 0x003C // Control Memory Buffer Size (Optional) #define NVME_BPINFO_OFFSET 0x0040 // Boot Partition Information #define NVME_BPRSEL_OFFSET 0x0044 // Boot Partition Read Select #define NVME_BPMBL_OFFSET 0x0048 // Boot Partition Memory Buffer Location @@ -382,7 +385,21 @@ typedef struct { UINT8 Cmic; /* Multi-interface Capabilities */ UINT8 Mdts; /* Maximum Data Transfer Size */ UINT8 Cntlid[2]; /* Controller ID */ - UINT8 Rsvd1[176]; /* Reserved as of Nvm Express 1.1 Spec */ + UINT32 Ver; /* Version */ + UINT32 Rtd3r; /* RTD3 Resume Latency */ + UINT32 Rtd3e; /* RTD3 Entry Latency */ + UINT32 Oaes; /* Optional Async Events Supported */ + UINT32 Ctratt; /* Controller Attributes */ + UINT16 Rrls; /* Read Recovery Levels Supported */ + UINT8 Rsvd1[9]; /* Reserved as of NVM Express 1.4c Spec */ + UINT8 Cntrltype; /* Controller Type */ + UINT8 Fguid[16]; /* FRU Globally Unique Identifier */ + UINT16 Crdt1; /* Command Retry Delay Time 1 */ + UINT16 Crdt2; /* Command Retry Delay Time 2 */ + UINT16 Crdt3; /* Command Retry Delay Time 3 */ + UINT8 Rsvd2[106]; /* Reserved as of NVM Express 1.4c Spec */ + UINT8 Rsvd3[16]; /* Reserved for NVMe MI Spec */ + // // Admin Command Set Attributes // @@ -418,30 +435,39 @@ typedef struct { UINT16 Mntmt; /* Minimum Thermal Management Temperature */ UINT16 Mxtmt; /* Maximum Thermal Management Temperature */ NVME_SANICAP Sanicap; /* Sanitize Capabilities */ - UINT8 Rsvd2[180]; /* Reserved as of Nvm Express 1.4 Spec */ + UINT32 Hmminds; /* Host Memory Buffer Minimum Descriptor Entry Size */ + UINT16 Hmmaxd; /* Host Memory Maximum Descriptors Entries */ + UINT16 Nsetidmax; /* NVM Set Identifier Maximum */ + UINT16 Endgidmax; /* Endurance Group Identifier Maximum */ + UINT8 Anatt; /* ANA Transition Time */ + UINT8 Anacap; /* Asymmetric Namespace Access Capabilities */ + UINT32 Anagrpmax; /* ANA Group Identifier Maximum */ + UINT32 Nanagrpid; /* Number of ANA Group Identifiers */ + UINT32 Pels; /* Persistent Event Log Size */ + UINT8 Rsvd4[156]; /* Reserved as of NVM Express 1.4c Spec */ // // NVM Command Set Attributes // - UINT8 Sqes; /* Submission Queue Entry Size */ - UINT8 Cqes; /* Completion Queue Entry Size */ - UINT16 Rsvd3; /* Reserved as of Nvm Express 1.1 Spec */ - UINT32 Nn; /* Number of Namespaces */ - UINT16 Oncs; /* Optional NVM Command Support */ - UINT16 Fuses; /* Fused Operation Support */ - UINT8 Fna; /* Format NVM Attributes */ - UINT8 Vwc; /* Volatile Write Cache */ - UINT16 Awun; /* Atomic Write Unit Normal */ - UINT16 Awupf; /* Atomic Write Unit Power Fail */ - UINT8 Nvscc; /* NVM Vendor Specific Command Configuration */ - UINT8 Rsvd4; /* Reserved as of Nvm Express 1.1 Spec */ - UINT16 Acwu; /* Atomic Compare & Write Unit */ - UINT16 Rsvd5; /* Reserved as of Nvm Express 1.1 Spec */ - UINT32 Sgls; /* SGL Support */ - UINT8 Rsvd6[164]; /* Reserved as of Nvm Express 1.1 Spec */ - // - // I/O Command set Attributes - // - UINT8 Rsvd7[1344]; /* Reserved as of Nvm Express 1.1 Spec */ + UINT8 Sqes; /* Submission Queue Entry Size */ + UINT8 Cqes; /* Completion Queue Entry Size */ + UINT16 Maxcmd; /* Maximum Outstanding Commands */ + UINT32 Nn; /* Number of Namespaces */ + UINT16 Oncs; /* Optional NVM Command Support */ + UINT16 Fuses; /* Fused Operation Support */ + UINT8 Fna; /* Format NVM Attributes */ + UINT8 Vwc; /* Volatile Write Cache */ + UINT16 Awun; /* Atomic Write Unit Normal */ + UINT16 Awupf; /* Atomic Write Unit Power Fail */ + UINT8 Nvscc; /* NVM Vendor Specific Command Configuration */ + UINT8 Nwpc; /* Namespace Write Protection Capabilities */ + UINT16 Acwu; /* Atomic Compare & Write Unit */ + UINT16 Rsvd5; /* Reserved as of NVM Express 1.4c Spec */ + UINT32 Sgls; /* SGL Support */ + UINT32 Mnan; /* Maximum Number of Allowed Namespace */ + UINT8 Rsvd6[224]; /* Reserved as of NVM Express 1.4c Spec */ + UINT8 Subnqn[256]; /* NVM Subsystem NVMe Qualified Name */ + UINT8 Rsvd7[768]; /* Reserved as of NVM Express 1.4c Spec */ + UINT8 Rsvd8[256]; /* Reserved for NVMe over Fabrics Spec */ // // Power State Descriptors // @@ -764,6 +790,10 @@ typedef struct { UINT32 Rsvd1 : 20; } NVME_ADMIN_FORMAT_NVM; +#define SES_NO_SECURE_ERASE 0x0 +#define SES_USER_DATA_ERASE 0x1 +#define SES_CRYPTO_ERASE 0x2 + // // NvmExpress Admin Security Receive Command // From b6c4708c4d3470cfd9f465771a665510d3ad1a66 Mon Sep 17 00:00:00 2001 From: Ray Robles Date: Thu, 18 Jul 2024 10:26:05 -0700 Subject: [PATCH 108/280] MdeModulePkg/Bus/Pci/NvmExpressDxe: Nvm Express Media Sanitize Protocol. Implementation of MEDIA_SANITIZE_PROTOCOL for NIST purge/clear actions with mapping to NVM Express native commands. Signed-off-by: Aaron Pop --- .../Bus/Pci/NvmExpressDxe/NvmExpress.c | 27 + .../Bus/Pci/NvmExpressDxe/NvmExpress.h | 36 + .../Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf | 5 +- .../NvmExpressDxe/NvmExpressMediaSanitize.c | 582 +++++++++ .../NvmExpressDxe/NvmExpressMediaSanitize.h | 191 +++ .../UnitTest/MediaSanitizeUnitTest.c | 1128 +++++++++++++++++ .../UnitTest/MediaSanitizeUnitTestHost.inf | 37 + MdeModulePkg/Include/Protocol/MediaSanitize.h | 173 +++ MdeModulePkg/MdeModulePkg.ci.yaml | 1 + MdeModulePkg/MdeModulePkg.dec | 4 + MdeModulePkg/Test/MdeModulePkgHostTest.dsc | 5 + 11 files changed, 2188 insertions(+), 1 deletion(-) create mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.c create mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.h create mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTest.c create mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTestHost.inf create mode 100644 MdeModulePkg/Include/Protocol/MediaSanitize.h diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c index 069da12a9b1b..c8d8be32b0c8 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c @@ -3,6 +3,7 @@ NVM Express specification. Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.
+ Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -181,6 +182,26 @@ EnumerateNvmeDevNamespace ( Device->BlockIo2.FlushBlocksEx = NvmeBlockIoFlushBlocksEx; InitializeListHead (&Device->AsyncQueue); + // + // Create Media Sanitize Protocol instance + // + Device->MediaSanitize.Revision = MEDIA_SANITIZE_PROTOCOL_REVISION; + Device->MediaSanitize.Media = &Device->Media; + Device->MediaSanitize.MediaClear = NvmExpressMediaClear; + Device->MediaSanitize.MediaPurge = NvmExpressMediaPurge; + Device->MediaSanitize.MediaFormat = NvmExpressMediaFormat; + + ASSERT ( + sizeof (Device->MediaSanitize.SanitizeCapabilities) == + sizeof (Device->Controller->ControllerData->Sanicap) + ); + + CopyMem ( + &(Device->MediaSanitize.SanitizeCapabilities), + &(Device->Controller->ControllerData->Sanicap), + sizeof (Device->MediaSanitize.SanitizeCapabilities) + ); + // // Create StorageSecurityProtocol Instance // @@ -241,6 +262,8 @@ EnumerateNvmeDevNamespace ( &Device->BlockIo2, &gEfiDiskInfoProtocolGuid, &Device->DiskInfo, + &gMediaSanitizeProtocolGuid, + &Device->MediaSanitize, NULL ); @@ -269,6 +292,8 @@ EnumerateNvmeDevNamespace ( &Device->BlockIo2, &gEfiDiskInfoProtocolGuid, &Device->DiskInfo, + &gMediaSanitizeProtocolGuid, + &Device->MediaSanitize, NULL ); goto Exit; @@ -468,6 +493,8 @@ UnregisterNvmeNamespace ( &Device->BlockIo2, &gEfiDiskInfoProtocolGuid, &Device->DiskInfo, + &gMediaSanitizeProtocolGuid, + &Device->MediaSanitize, NULL ); diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h index 2b9ab8a08e46..11207afa6332 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h @@ -4,6 +4,7 @@ (C) Copyright 2016 Hewlett Packard Enterprise Development LP
Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+ Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -29,6 +30,7 @@ #include #include #include +#include #include #include @@ -49,6 +51,7 @@ typedef struct _NVME_DEVICE_PRIVATE_DATA NVME_DEVICE_PRIVATE_DATA; #include "NvmExpressBlockIo.h" #include "NvmExpressDiskInfo.h" #include "NvmExpressHci.h" +#include "NvmExpressMediaSanitize.h" extern EFI_DRIVER_BINDING_PROTOCOL gNvmExpressDriverBinding; extern EFI_COMPONENT_NAME_PROTOCOL gNvmExpressComponentName; @@ -77,6 +80,30 @@ extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gNvmExpressDriverSupportedEfiV #define NVME_MAX_QUEUES 3 // Number of queues supported by the driver +// +// FormatNVM Admin Command LBA Format (LBAF) Mask +// +#define NVME_LBA_FORMATNVM_LBAF_MASK 0xF + +// +// NVMe Completion Queue Entry Bits, Fields, Masks +// +#define NVME_CQE_STATUS_FIELD_MASK 0xFFFF0000 +#define NVME_CQE_STATUS_FIELD_OFFSET 16 +#define NVME_CQE_STATUS_FIELD_SCT_MASK 0x0E00 +#define NVME_CQE_STATUS_FIELD_SCT_OFFSET 0x9 +#define NVME_CQE_STATUS_FIELD_SC_MASK 0x1FE +#define NVME_CQE_STATUS_FIELD_SC_OFFSET 0x01 +#define NVME_CQE_SCT_GENERIC_CMD_STATUS 0x0 +#define NVME_CQE_SCT_CMD_SPECIFIC_STATUS 0x1 +#define NVME_CQE_SCT_MEDIA_DATA_INTEGRITY_ERRORS_STATUS 0x2 +#define NVME_CQE_SCT_PATH_RELATED_STATUS 0x3 +#define NVME_CQE_SC_SUCCESSFUL_COMPLETION 0x00 +#define NVME_CQE_SC_INVALID_CMD_OPCODE 0x01 +#define NVME_CQE_SC_INVALID_FIELD_IN_CMD 0x02 + +#define NVME_ALL_NAMESPACES 0xFFFFFFFF + #define NVME_CONTROLLER_ID 0 // @@ -202,6 +229,8 @@ struct _NVME_DEVICE_PRIVATE_DATA { EFI_DISK_INFO_PROTOCOL DiskInfo; EFI_STORAGE_SECURITY_COMMAND_PROTOCOL StorageSecurity; + MEDIA_SANITIZE_PROTOCOL MediaSanitize; + LIST_ENTRY AsyncQueue; EFI_LBA NumBlocks; @@ -243,6 +272,13 @@ struct _NVME_DEVICE_PRIVATE_DATA { NVME_DEVICE_PRIVATE_DATA_SIGNATURE \ ) +#define NVME_DEVICE_PRIVATE_DATA_FROM_MEDIA_SANITIZE(a) \ + CR (a, \ + NVME_DEVICE_PRIVATE_DATA, \ + MediaSanitize, \ + NVME_DEVICE_PRIVATE_DATA_SIGNATURE \ + ) + // // Nvme block I/O 2 request. // diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf index 1a29c0b9073e..5fd0e468a922 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf @@ -5,7 +5,7 @@ # NVM Express specification. # # Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
-# +# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -40,6 +40,8 @@ NvmExpressHci.c NvmExpressHci.h NvmExpressPassthru.c + NvmExpressMediaSanitize.c + NvmExpressMediaSanitize.h [Guids] gNVMeEnableStartEventGroupGuid @@ -72,6 +74,7 @@ gEfiDiskInfoProtocolGuid ## BY_START gEfiStorageSecurityCommandProtocolGuid ## BY_START gEfiDriverSupportedEfiVersionProtocolGuid ## PRODUCES + gMediaSanitizeProtocolGuid ## PRODUCES gEfiResetNotificationProtocolGuid ## CONSUMES # [Event] diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.c new file mode 100644 index 000000000000..8632924899fd --- /dev/null +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.c @@ -0,0 +1,582 @@ +/** @file -- NvmExpressMediaSanitize.c + This driver will implement sanitize operations on all NVMe mass storage devices + based on NIST purge and clear operations. These operations will then be mapped to + one of two NVMe admin commands: + + -Format NVM + -Sanitize + + Implementation based off NVMe spec revision 1.4c. + + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "NvmExpress.h" + +/** + Send NVM Express FormatNVM Admin Command + + The Format NVM command is used to low level format the NVM media. This command is used by + the host to change the LBA data size and/or metadata size. + + A low level format may destroy all data and metadata associated with all namespaces or only + the specific namespace associated with the command (refer to the Format NVM Attributes field + in the Identify Controller data structure). + + After the Format NVM command successfully completes, the controller shall not return any user + data that was previously contained in an affected namespace. + + @param[in] This Indicates a pointer to the calling context (Block IO Protocol) + @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be + allocated and built. Caller must set the NamespaceId to zero if the + device path node will contain a valid UUID. + @param[in] Ses Secure Erase Setting (SES) value + - 000b: No secure erase operation requested + - 001b: User Data Erase + - 010b: Cryptographic Erase + - 011b to 111b: Reserved + @param[in] Flbas New LBA size (in terms of LBA Format size Index (bits 3:0) in NamespaceData). + If this param is 0 (NULL), then use existing LBA size. + + @retval EFI_SUCCESS The device formatted correctly. + @retval EFI_WRITE_PROTECTED The device can not be formatted due to write protection. + @retval EFI_DEVICE_ERROR The device reported an error while performing the format. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_INVALID_PARAMETER The format request contains parameters that are not valid. + + **/ +EFI_STATUS +NvmExpressFormatNvm ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 NamespaceId, + IN UINT32 Ses, + IN UINT32 Flbas + ) +{ + NVME_DEVICE_PRIVATE_DATA *Device; + EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; + EFI_NVM_EXPRESS_COMMAND Command; + EFI_NVM_EXPRESS_COMPLETION Completion; + NVME_ADMIN_FORMAT_NVM FormatNvmCdw10; + NVME_ADMIN_NAMESPACE_DATA *NewNamespaceData; + UINT32 Lbads; + UINT32 NewFlbas; + UINT32 LbaFmtIdx; + EFI_STATUS Status; + UINT32 LbaFormat; + UINT16 StatusField; + UINT16 Sct; + UINT16 Sc; + + Status = EFI_NOT_STARTED; + LbaFormat = 0; + Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); + + ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); + ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); + ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); + ZeroMem (&FormatNvmCdw10, sizeof (NVME_ADMIN_FORMAT_NVM)); + + NewNamespaceData = NULL; + Lbads = 0; + NewFlbas = 0; + LbaFmtIdx = 0; + StatusField = 0; + Sct = 0; + Sc = 0; + + CommandPacket.NvmeCmd = &Command; + CommandPacket.NvmeCompletion = &Completion; + CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; + CommandPacket.QueueType = NVME_ADMIN_QUEUE; + Command.Cdw0.Opcode = NVME_ADMIN_FORMAT_NVM_CMD; + Command.Nsid = NamespaceId; + + // + // SES (Secure Erase Settings) + // + FormatNvmCdw10.Ses = Ses; + + // + // Change LBA size/format if LbaFormat param != NULL, otherwise keep same LBA format. + // Current supported LBA format size in Identify Namespace LBA Format Table, indexed by + // FLBAS (bits 3:0). + // + LbaFormat = (Flbas == 0 ? Device->NamespaceData.Flbas : Flbas); + FormatNvmCdw10.Lbaf = LbaFormat & NVME_LBA_FORMATNVM_LBAF_MASK; + CopyMem (&CommandPacket.NvmeCmd->Cdw10, &FormatNvmCdw10, sizeof (NVME_ADMIN_FORMAT_NVM)); + + // + // Send Format NVM command via passthru and wait for completion + // + // If LBA size changed successfully, then update private data structures and Block IO + // and Media protocols to reflect new LBA size. + // + Status = Device->Controller->Passthru.PassThru ( + &(Device->Controller->Passthru), + NamespaceId, + &CommandPacket, + NULL + ); + + if (EFI_ERROR (Status)) { + StatusField = (UINT16)((CommandPacket.NvmeCompletion->DW3 & NVME_CQE_STATUS_FIELD_MASK) >> + NVME_CQE_STATUS_FIELD_OFFSET); + + Sc = (StatusField & NVME_CQE_STATUS_FIELD_SC_MASK) >> NVME_CQE_STATUS_FIELD_SC_OFFSET; + Sct = (StatusField & NVME_CQE_STATUS_FIELD_SCT_MASK) >> NVME_CQE_STATUS_FIELD_SCT_OFFSET; + + DEBUG ((DEBUG_ERROR, "%a: NVMe FormatNVM admin command failed SCT = 0x%x, SC = 0x%x\n", __func__, Sct, Sc)); + } else { + // + // Update Block IO and Media Protocols only if Flbas parameter was not NULL. + // Call Identify Namespace again and update all protocols fields and local + // cached copies of fields related to block size. + // + if (Flbas != 0) { + NewNamespaceData = AllocateZeroPool (sizeof (NVME_ADMIN_NAMESPACE_DATA)); + if (NewNamespaceData == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } else { + Status = NvmeIdentifyNamespace ( + Device->Controller, + NamespaceId, + (VOID *)NewNamespaceData + ); + + if (!EFI_ERROR (Status)) { + // + // Update all fields related to LBA size, allocation, and alignment + // + NewFlbas = NewNamespaceData->Flbas; + LbaFmtIdx = NewFlbas & NVME_LBA_FORMATNVM_LBAF_MASK; + Lbads = NewNamespaceData->LbaFormat[LbaFmtIdx].Lbads; + Device->Media.BlockSize = (UINT32)1 << Lbads; + Device->Media.LastBlock = NewNamespaceData->Nsze - 1; + + CopyMem (&Device->NamespaceData, NewNamespaceData, sizeof (NVME_ADMIN_NAMESPACE_DATA)); + } + } + } + } + + return Status; +} + +/** + Send NVM Express Sanitize Admin Command + + The Sanitize command is used to start a sanitize operation or to recover from a previously + failed sanitize operation. The sanitize operation types that may be supported are Block + Erase, Crypto Erase, and Overwrite. + + All sanitize operations are processed in the background (i.e., completion of the Sanitize + command does not indicate completion of the sanitize operation). + + @param[in] This Indicates a pointer to the calling context (Block IO Protocol) + @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be + allocated and built. Caller must set the NamespaceId to zero if the + device path node will contain a valid UUID. + @param[in] SanitizeAction Sanitize action + @param[in] NoDeallocAfterSanitize No deallocate after sanitize option + @param[in] OverwritePattern Pattern to overwrite old user data + + @retval EFI_SUCCESS The media was sanitized successfully on the device. + @retval EFI_WRITE_PROTECTED The device can not be sanitized due to write protection. + @retval EFI_DEVICE_ERROR The device reported an error while performing the sanitize. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not match the current device. + @retval EFI_INVALID_PARAMETER The sanitize request contains parameters that are not valid. + + **/ +EFI_STATUS +NvmExpressSanitize ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 NamespaceId, + IN UINT32 SanitizeAction, + IN UINT32 NoDeallocAfterSanitize, + IN UINT32 OverwritePattern + ) +{ + NVME_DEVICE_PRIVATE_DATA *Device; + EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; + EFI_NVM_EXPRESS_COMMAND Command; + EFI_NVM_EXPRESS_COMPLETION Completion; + NVME_ADMIN_SANITIZE SanitizeCdw10Cdw11; + EFI_STATUS Status; + UINT16 StatusField; + UINT16 Sct; + UINT16 Sc; + UINT32 FnvmSes; + + Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); + + ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); + ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); + ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); + ZeroMem (&SanitizeCdw10Cdw11, sizeof (NVME_ADMIN_SANITIZE)); + + StatusField = 0; + Sct = 0; + Sc = 0; + FnvmSes = 0; + + CommandPacket.NvmeCmd = &Command; + CommandPacket.NvmeCompletion = &Completion; + CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; + CommandPacket.QueueType = NVME_ADMIN_QUEUE; + Command.Cdw0.Opcode = NVME_ADMIN_SANITIZE_CMD; + Command.Nsid = NamespaceId; + + SanitizeCdw10Cdw11.Nodas = NoDeallocAfterSanitize; + SanitizeCdw10Cdw11.Sanact = SanitizeAction; + SanitizeCdw10Cdw11.Ovrpat = OverwritePattern; + CopyMem (&CommandPacket.NvmeCmd->Cdw10, &SanitizeCdw10Cdw11, sizeof (NVME_ADMIN_SANITIZE)); + + // + // Send Format NVM command via passthru and wait for completion + // + Status = Device->Controller->Passthru.PassThru ( + &(Device->Controller->Passthru), + NamespaceId, + &CommandPacket, + NULL + ); + + if (EFI_ERROR (Status)) { + StatusField = (UINT16)((CommandPacket.NvmeCompletion->DW3 & NVME_CQE_STATUS_FIELD_MASK) >> + NVME_CQE_STATUS_FIELD_OFFSET); + + Sc = (StatusField & NVME_CQE_STATUS_FIELD_SC_MASK) >> NVME_CQE_STATUS_FIELD_SC_OFFSET; + Sct = (StatusField & NVME_CQE_STATUS_FIELD_SCT_MASK) >> NVME_CQE_STATUS_FIELD_SCT_OFFSET; + + DEBUG ((DEBUG_ERROR, "%a: NVMe Sanitize admin command failed SCT = 0x%x, SC = 0x%x\n", __func__, Sct, Sc)); + + // + // Check for an error status code of "Invalid Command Opcode" in case + // the NVM Express controller does not support Sanitize. If the NVM + // Exress Controller does not support Sanitize, then send a Format NVM + // admin command instead to perform the Purge operation. + // + if ((Sct == NVME_CQE_SCT_GENERIC_CMD_STATUS) && + (Sc == NVME_CQE_SC_INVALID_CMD_OPCODE)) + { + switch (SanitizeCdw10Cdw11.Sanact) { + case SANITIZE_ACTION_BLOCK_ERASE: + FnvmSes = SES_USER_DATA_ERASE; // User Data Erase (LBAs indeterminate after) + break; + case SANITIZE_ACTION_CRYPTO_ERASE: + FnvmSes = SES_CRYPTO_ERASE; // Crypto Erase + break; + case SANITIZE_ACTION_OVERWRITE: + case SANITIZE_ACTION_EXIT_FAILURE_MODE: + default: + // + // Cannot perform an equivalent FormatNVM action/operation + // + FnvmSes = SES_NO_SECURE_ERASE; + break; + } + + if ((FnvmSes == SES_USER_DATA_ERASE) || (FnvmSes == SES_CRYPTO_ERASE)) { + Status = NvmExpressFormatNvm ( + This, + NVME_ALL_NAMESPACES, + FnvmSes, + 0 // Pass in NULL so existing LBA size is used in Format NVM + ); + } + } + } + + return Status; +} + +/** + Clear Media utilizes transport native WRITE commands to write a fixed pattern + of non-sensitive data to the media. + + NOTE: The caller shall send buffer of one sector/LBA size with overwrite data. + NOTE: This operation is a blocking call. + NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK. + + Functions are defined to erase and purge data at a block level from mass + storage devices as well as to manage such devices in the EFI boot services + environment. + + @param[in] This Indicates a pointer to the calling context. + @param[in] MediaId The media ID that the write request is for. + @param[in] PassCount The number of passes to write over media. + @param[in] SectorOwBuffer A pointer to the overwrite buffer. + + @retval EFI_SUCCESS The data was written correctly to the device. + @retval EFI_WRITE_PROTECTED The device can not be written to. + @retval EFI_DEVICE_ERROR The device reported an error while performing the write. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, + or the buffer is not on proper alignment. + +**/ +EFI_STATUS +EFIAPI +NvmExpressMediaClear ( + IN MEDIA_SANITIZE_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT32 PassCount, + IN VOID *SectorOwBuffer + ) +{ + NVME_DEVICE_PRIVATE_DATA *Device; + EFI_BLOCK_IO_MEDIA *Media; + EFI_LBA SectorOffset; + UINT32 TotalPassCount; + EFI_STATUS Status; + + // + // Check parameters. + // + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + Device = NVME_DEVICE_PRIVATE_DATA_FROM_MEDIA_SANITIZE (This); + Media = &Device->Media; + SectorOffset = 0; + + if ((MediaId != Media->MediaId) || (!Media->MediaPresent)) { + return EFI_MEDIA_CHANGED; + } + + // + // If an invalid buffer or buffer size is sent, the Media Clear operation + // cannot be performed as it requires a native WRITE command. The overwrite + // buffer must have granularity of a namespace block size. + // + if (SectorOwBuffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Per NIST 800-88r1, one or more pass of writes may be alteratively used. + // + for (TotalPassCount = 0; TotalPassCount < PassCount; TotalPassCount++) { + for (SectorOffset = 0; SectorOffset < Media->LastBlock; SectorOffset++ ) { + Status = Device->BlockIo.WriteBlocks ( + &Device->BlockIo, + MediaId, + SectorOffset, // Sector/LBA offset (increment each pass) + 1, // Write one sector per write + SectorOwBuffer // overwrite buffer + ); + } + + // + // Reset SectorOffset back to zero if another pass on namespace is needed + // + SectorOffset = 0; + } + + return Status; +} + +/** + Purge Media utilizes transport native Sanitize operations. Sanitize specific + purge actions include: overwrite, block erase, or crypto erase. + + Functions are defined to erase and purge data at a block level from mass + storage devices as well as to manage such devices in the EFI boot services + environment. Sanitization refers to a process that renders access to target + data on the media infeasible for a given level of effort. + + NOTE: This operation is a blocking call. + NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK. + + @param[in] This Indicates a pointer to the calling context. + @param[in] MediaId The media ID that the write request is for. + @param[in] PurgeAction The purage action (overwrite, crypto erase, block erase). + @param[in] OverwritePattern 32-bit pattern to overwrite on media (for overwrite). + + @retval EFI_SUCCESS The media was purged successfully on the device. + @retval EFI_WRITE_PROTECTED The device can not be purged due to write protection. + @retval EFI_DEVICE_ERROR The device reported an error while performing the purge. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not match the current device. + @retval EFI_INVALID_PARAMETER The purge request contains parameters that are not valid. + +**/ +EFI_STATUS +EFIAPI +NvmExpressMediaPurge ( + IN MEDIA_SANITIZE_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT32 PurgeAction, + IN UINT32 OverwritePattern + ) +{ + NVME_DEVICE_PRIVATE_DATA *Device; + EFI_BLOCK_IO_MEDIA *Media; + NVME_SANICAP SaniCap; + UINT32 SanitizeAction; + UINT32 NoDeallocate; + UINT32 NamespaceId; + EFI_STATUS Status; + + // + // Check parameters. + // + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + Device = NVME_DEVICE_PRIVATE_DATA_FROM_MEDIA_SANITIZE (This); + NamespaceId = Device->NamespaceId; + Media = &Device->Media; + SaniCap = Device->Controller->ControllerData->Sanicap; + NoDeallocate = 0; + + if ((MediaId != Media->MediaId) || (!Media->MediaPresent)) { + return EFI_MEDIA_CHANGED; + } + + // + // Purge action will directly map to sanitize action. If no valid purge + // action is selected, then default to no action and let the NVMe SSD handle + // the no-op sanitize action (as there may be other contingencies). + // + if (((PurgeAction & PURGE_ACTION_OVERWRITE) == PURGE_ACTION_OVERWRITE) && (SaniCap.Ows)) { + SanitizeAction = SANITIZE_ACTION_OVERWRITE; + } else if (((PurgeAction & PURGE_ACTION_BLOCK_ERASE) == PURGE_ACTION_BLOCK_ERASE) && (SaniCap.Bes)) { + SanitizeAction = SANITIZE_ACTION_BLOCK_ERASE; + } else if (((PurgeAction & PURGE_ACTION_CRYPTO_ERASE) == PURGE_ACTION_CRYPTO_ERASE) && (SaniCap.Ces)) { + SanitizeAction = SANITIZE_ACTION_CRYPTO_ERASE; + } else { + SanitizeAction = SANITIZE_ACTION_NO_ACTION; + } + + if ((PurgeAction & PURGE_ACTION_NO_DEALLOCATE) == PURGE_ACTION_NO_DEALLOCATE) { + NoDeallocate = NVME_NO_DEALLOCATE_AFTER_SANITZE; + } + + // + // Call NVM Express Admin command Sanitize (blocking call). + // + Status = NvmExpressSanitize ( + &Device->BlockIo, + NamespaceId, + SanitizeAction, + NoDeallocate, + OverwritePattern + ); + + return Status; +} + +/** + Format Media utilizes native format operations to modify sector/LBA size. + Secure erase actions are used to define how latent user data is erased. + + NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK. + + @param[in] This Indicates a pointer to the calling context. + @param[in] MediaId The media ID that the clear request is for. + @param[in] LbaSize Size of LBA (in terms of power of two: 2^n). + @param[in] SecureEraseAction Secure erase action, if any, to apply to format. + - 000b: No secure erase operation requested + - 001b: User Data Erase + - 010b: Cryptographic Erase + - 011b to 111b: Reserved + + @retval EFI_SUCCESS The media format request comopleted successfully on the device. + @retval EFI_WRITE_PROTECTED The device can't be formatted due to write protection. + @retval EFI_DEVICE_ERROR The device reported an error while attempting to perform the format operation. + @retval EFI_INVALID_PARAMETER The format request contains parameters that are not valid. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. + + **/ +EFI_STATUS +EFIAPI +NvmExpressMediaFormat ( + IN MEDIA_SANITIZE_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT32 LbaSize, + IN UINT32 SecureEraseAction + ) +{ + NVME_DEVICE_PRIVATE_DATA *Device; + EFI_BLOCK_IO_MEDIA *Media; + UINT32 NamespaceId; + UINT32 SecureEraseSettings; + UINT32 FlbaIndex; + BOOLEAN LbaSizeIsSupported; + EFI_STATUS Status; + + // + // Check parameters. + // + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + Device = NVME_DEVICE_PRIVATE_DATA_FROM_MEDIA_SANITIZE (This); + NamespaceId = Device->NamespaceId; + Media = &Device->Media; + SecureEraseSettings = FORMAT_SES_NO_SECURE_ERASE_REQUESTED; + FlbaIndex = 0; + + if ((MediaId != Media->MediaId) || (!Media->MediaPresent)) { + return EFI_MEDIA_CHANGED; + } + + // + // Convert secure erase action to NVMe secure erase setting + // + switch (SecureEraseAction) { + case FORMAT_SES_USER_DATA_ERASE: + SecureEraseSettings = SES_USER_DATA_ERASE; + break; + case FORMAT_SES_CRYPTOGRAPHIC_ERASE: + SecureEraseSettings = SES_CRYPTO_ERASE; + break; + case FORMAT_SES_NO_SECURE_ERASE_REQUESTED: + default: + // + // Cannot perform an equivalent FormatNVM action/operation + // + SecureEraseSettings = SES_NO_SECURE_ERASE; + break; + } + + // + // The requested LBA size must be supported by the NVMe SSD as defined in Identify + // Namespace structure. + // + // Current supported LBA format sizes is in Identify Namespace LBA Format Table, + // indexed by FLBAS (bits 3:0). Loop through all supported LBADF sizes and check + // to see if requested LBA size is supported. If yes, send FormatNVM command. + // + LbaSizeIsSupported = FALSE; + for (FlbaIndex = 0; FlbaIndex < Device->NamespaceData.Nlbaf; FlbaIndex++) { + if (Device->NamespaceData.LbaFormat[FlbaIndex].Lbads == LbaSize) { + LbaSizeIsSupported = TRUE; + break; + } + } + + if (LbaSizeIsSupported) { + Status = NvmExpressFormatNvm ( + &Device->BlockIo, + NamespaceId, + SecureEraseSettings, + FlbaIndex + ); + } else { + Status = EFI_INVALID_PARAMETER; + } + + return Status; +} diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.h b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.h new file mode 100644 index 000000000000..197b92397705 --- /dev/null +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.h @@ -0,0 +1,191 @@ +/** @file + Header file for MEDIA_SANITIZE_PROTOCOL interface. + + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef NVME_MEDIA_SANITIZE_H_ +#define NVME_MEDIA_SANITIZE_H_ + +#define NVME_NO_DEALLOCATE_AFTER_SANITZE 0x1 + +/** + Send NVM Express FormatNVM Admin Command + + The Format NVM command is used to low level format the NVM media. This command is used by + the host to change the LBA data size and/or metadata size. + + A low level format may destroy all data and metadata associated with all namespaces or only + the specific namespace associated with the command (refer to the Format NVM Attributes field + in the Identify Controller data structure). + + After the Format NVM command successfully completes, the controller shall not return any user + data that was previously contained in an affected namespace. + + @param[in] This Indicates a pointer to the calling context (Block IO Protocol) + @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be + allocated and built. Caller must set the NamespaceId to zero if the + device path node will contain a valid UUID. + @param[in] Ses Secure Erase Setting (SES) value + - 000b: No secure erase operation requested + - 001b: User Data Erase + - 010b: Cryptographic Erase + - 011b to 111b: Reserved + @param[in] Flbas New LBA size (in terms of LBA Format size Index (bits 3:0) in NamespaceData). + If this param is 0 (NULL), then use existing LBA size. + + @retval EFI_SUCCESS The device formatted correctly. + @retval EFI_WRITE_PROTECTED The device can not be formatted due to write protection. + @retval EFI_DEVICE_ERROR The device reported an error while performing the format. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_INVALID_PARAMETER The format request contains parameters that are not valid. + +**/ +EFI_STATUS +NvmExpressFormatNvm ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 NamespaceId, + IN UINT32 Ses, + IN UINT32 Flbas + ); + +/** + Send NVM Express Sanitize Admin Command + + The Sanitize command is used to start a sanitize operation or to recover from a previously + failed sanitize operation. The sanitize operation types that may be supported are Block + Erase, Crypto Erase, and Overwrite. + + All sanitize operations are processed in the background (i.e., completion of the Sanitize + command does not indicate completion of the sanitize operation). + + @param[in] This Indicates a pointer to the calling context (Block IO Protocol) + @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be + allocated and built. Caller must set the NamespaceId to zero if the + device path node will contain a valid UUID. + @param[in] SanitizeAction Sanitize action + @param[in] NoDeallocAfterSanitize No deallocate after sanitize option + @param[in] OverwritePattern Pattern to overwrite old user data + + @retval EFI_SUCCESS The media was sanitized successfully on the device. + @retval EFI_WRITE_PROTECTED The device can not be sanitized due to write protection. + @retval EFI_DEVICE_ERROR The device reported an error while performing the sanitize. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not match the current device. + @retval EFI_INVALID_PARAMETER The sanitize request contains parameters that are not valid. + +**/ +EFI_STATUS +NvmExpressSanitize ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 NamespaceId, + IN UINT32 SanitizeAction, + IN UINT32 NoDeallocAfterSanitize, + IN UINT32 OverwritePattern + ); + +/** + Clear Media utilizes transport native WRITE commands to write a fixed pattern + of non-sensitive data to the media. + + NOTE: The caller shall send buffer of one sector/LBA size with overwrite data. + NOTE: This operation is a blocking call. + NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK. + + Functions are defined to erase and purge data at a block level from mass + storage devices as well as to manage such devices in the EFI boot services + environment. + + @param[in] This Indicates a pointer to the calling context. + @param[in] MediaId The media ID that the write request is for. + @param[in] PassCount The number of passes to write over media. + @param[in] SectorOwBuffer A pointer to the overwrite buffer. + + @retval EFI_SUCCESS The data was written correctly to the device. + @retval EFI_WRITE_PROTECTED The device can not be written to. + @retval EFI_DEVICE_ERROR The device reported an error while performing the write. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, + or the buffer is not on proper alignment. + +**/ +EFI_STATUS +EFIAPI +NvmExpressMediaClear ( + IN MEDIA_SANITIZE_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT32 PassCount, + IN VOID *SectorOwBuffer + ); + +/** + Purge Media utilizes transport native Sanitize operations. Sanitize specific + purge actions include: overwrite, block erase, or crypto erase. + + Functions are defined to erase and purge data at a block level from mass + storage devices as well as to manage such devices in the EFI boot services + environment. Sanitization refers to a process that renders access to target + data on the media infeasible for a given level of effort. + + NOTE: This operation is a blocking call. + NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK. + + @param[in] This Indicates a pointer to the calling context. + @param[in] MediaId The media ID that the write request is for. + @param[in] PurgeAction The purage action (overwrite, crypto erase, block erase). + @param[in] OverwritePattern 32-bit pattern to overwrite on media (for overwrite). + + @retval EFI_SUCCESS The media was purged successfully on the device. + @retval EFI_WRITE_PROTECTED The device can not be purged due to write protection. + @retval EFI_DEVICE_ERROR The device reported an error while performing the purge. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not match the current device. + @retval EFI_INVALID_PARAMETER The purge request contains parameters that are not valid. + +**/ +EFI_STATUS +EFIAPI +NvmExpressMediaPurge ( + IN MEDIA_SANITIZE_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT32 PurgeAction, + IN UINT32 OverwritePattern + ); + +/** + Format Media utilizes native format operations to modify sector/LBA size. + Secure erase actions are used to define how latent user data is erased. + + NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK. + + @param[in] This Indicates a pointer to the calling context. + @param[in] MediaId The media ID that the clear request is for. + @param[in] LbaSize Size of LBA (in terms of power of two: 2^n). + @param[in] SecureEraseAction Secure erase action, if any, to apply to format. + - 000b: No secure erase operation requested + - 001b: User Data Erase + - 010b: Cryptographic Erase + - 011b to 111b: Reserved + + @retval EFI_SUCCESS The media format request completed successfully on the device. + @retval EFI_WRITE_PROTECTED The device can't be formatted due to write protection. + @retval EFI_DEVICE_ERROR The device reported an error while attempting to perform the format operation. + @retval EFI_INVALID_PARAMETER The format request contains parameters that are not valid. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. + + **/ +EFI_STATUS +EFIAPI +NvmExpressMediaFormat ( + IN MEDIA_SANITIZE_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT32 LbaSize, + IN UINT32 SecureEraseAction + ); + +#endif diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTest.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTest.c new file mode 100644 index 000000000000..b8728580c595 --- /dev/null +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTest.c @@ -0,0 +1,1128 @@ +/** @file -- MediaSanitizeUnitTest.c + Placeholder/framework for developing a Media Sanitize unit test package. + + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../NvmExpress.h" +#include "../NvmExpressBlockIo.h" +#include "../NvmExpressMediaSanitize.h" +#include "../NvmExpressHci.h" + +/** + Helper function for Nvme pass thru. + + @param[in] This Private Data. + @param[in] NamespaceId Name Space Id. + @param[in,out] Packet Transfer Buffer. + @param[in] Event Event handle. + + **/ +EFI_STATUS +EFIAPI +NvmeDeviceUnitTestPassthru ( + IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, + IN UINT32 NamespaceId, + IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet, + IN EFI_EVENT Event OPTIONAL + ) +{ + // + // Parse command packet for unit testing + // + EFI_NVM_EXPRESS_COMMAND *Command; + EFI_NVM_EXPRESS_COMPLETION *Completion; + NVME_CQ *Cqe; + NVME_ADMIN_FORMAT_NVM FormatNvmCdw10; + NVME_ADMIN_SANITIZE SanitizeCdw1011; + + ASSERT (This); + ASSERT (Packet); + + Command = Packet->NvmeCmd; + Completion = Packet->NvmeCompletion; + Cqe = (NVME_CQ *)Completion; + + ZeroMem (&FormatNvmCdw10, sizeof (NVME_ADMIN_FORMAT_NVM)); + ZeroMem (&SanitizeCdw1011, sizeof (NVME_ADMIN_SANITIZE)); + + switch (Command->Cdw0.Opcode) { + case NVME_ADMIN_FORMAT_NVM_CMD: + UT_LOG_VERBOSE ("%a: Opcode = NVME_ADMIN_FORMAT_NVM_CMD\n", __func__); + + CopyMem (&FormatNvmCdw10, &Command->Cdw10, sizeof (NVME_ADMIN_FORMAT_NVM)); + + // + // FormatNVM Check 1: Validate SES parameter + // + if (FormatNvmCdw10.Ses > 0x2) { + Cqe->Sct = NVME_CQE_SCT_GENERIC_CMD_STATUS; + Cqe->Sc = NVME_CQE_SC_INVALID_FIELD_IN_CMD; + + return EFI_INVALID_PARAMETER; + } + + // + // FormatNVM Check 2: Validate LbaIndex parameter + // + if (FormatNvmCdw10.Lbaf > 0x1) { + Cqe->Sct = NVME_CQE_SCT_GENERIC_CMD_STATUS; + Cqe->Sc = NVME_CQE_SC_INVALID_FIELD_IN_CMD; + + return EFI_INVALID_PARAMETER; + } + + break; + case NVME_ADMIN_SANITIZE_CMD: + UT_LOG_VERBOSE ("%a: Opcode = NVME_ADMIN_SANITIZE_CMD\n", __func__); + + CopyMem (&SanitizeCdw1011, &Command->Cdw10, sizeof (NVME_ADMIN_SANITIZE)); + + // + // Sanitize Check 1: Validate Sanitize Action parameter + // + if (SanitizeCdw1011.Sanact > 0x4) { + Cqe->Sct = NVME_CQE_SCT_GENERIC_CMD_STATUS; + Cqe->Sc = NVME_CQE_SC_INVALID_FIELD_IN_CMD; + + return EFI_INVALID_PARAMETER; + } + + // + // Sanitize Check 2: Validate overwrite action with non-NULL overwrite pattern + // + if (((SanitizeCdw1011.Sanact == SANITIZE_ACTION_OVERWRITE) && (SanitizeCdw1011.Ovrpat != 0xDEADBEEF)) || + ((SanitizeCdw1011.Sanact != SANITIZE_ACTION_OVERWRITE) && (SanitizeCdw1011.Ovrpat != 0))) + { + Cqe->Sct = NVME_CQE_SCT_GENERIC_CMD_STATUS; + Cqe->Sc = NVME_CQE_SC_INVALID_FIELD_IN_CMD; + + return EFI_INVALID_PARAMETER; + } + + break; + default: + UT_LOG_VERBOSE ("%a: Invalid Opcode = 0x%x!!!\n", __func__, Command->Cdw0.Opcode); + break; + } + + // + // Populate CQE (completion queue entry based on opcode and parameters + // + + return EFI_SUCCESS; +} + +/** + Helper function to simulate read. + + @param[in] Private Private Data. + @param[in] NamespaceId Name Space Id. + @param[in] Buffer Transfer Buffer. + + **/ +EFI_STATUS +NvmeIdentifyNamespace ( + IN NVME_CONTROLLER_PRIVATE_DATA *Private, + IN UINT32 NamespaceId, + IN VOID *Buffer + ) +{ + EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; + EFI_NVM_EXPRESS_COMMAND Command; + EFI_NVM_EXPRESS_COMPLETION Completion; + + ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); + ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); + ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); + + CommandPacket.NvmeCmd = &Command; + CommandPacket.NvmeCompletion = &Completion; + Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD; + Command.Nsid = NamespaceId; + CommandPacket.TransferBuffer = Buffer; + CommandPacket.TransferLength = sizeof (NVME_ADMIN_NAMESPACE_DATA); + CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; + CommandPacket.QueueType = NVME_ADMIN_QUEUE; + + // + // Set bit 0 (Cns bit) to 1 to identify a namespace + // + CommandPacket.NvmeCmd->Cdw10 = 0; + CommandPacket.NvmeCmd->Flags = CDW10_VALID; + + return EFI_SUCCESS; +} + +/** + Helper function to simulate read. + + @param[in] Device Private Data. + @param[out] Buffer Buffer to read into. + @param[in] Lba Logical Block Addess to read from. + @param[in] Blocks Number of blocks. + + **/ +EFI_STATUS +NvmeUnitTestRead ( + IN NVME_DEVICE_PRIVATE_DATA *Device, + OUT VOID *Buffer, + IN UINT64 Lba, + IN UINTN Blocks + ) +{ + UT_ASSERT_NOT_NULL (Device); + Buffer = NULL; + Lba = 0; + Blocks = 0; + + return EFI_SUCCESS; +} + +/** + Helper function to simulate write. + + @param[in] Device Private Data. + @param[in] Buffer Buffer to write. + @param[in] Lba Logical Block Addess to write. + @param[in] Blocks Number of blocks. + + **/ +EFI_STATUS +NvmeUnitTestWrite ( + IN NVME_DEVICE_PRIVATE_DATA *Device, + IN VOID *Buffer, + IN UINT64 Lba, + IN UINTN Blocks + ) +{ + UT_ASSERT_NOT_NULL (Device); + Buffer = NULL; + Lba = 0; + Blocks = 0; + + return EFI_SUCCESS; +} + +/** + Simulated BlockIo read block function. + + @param[in] This BlockIo Protocol. + @param[in] MediaId Id of the media. + @param[in] Lba Logical Block Address. + @param[in] BufferSize Size of Buffer. + @param[out] Buffer Actual buffer to use to read. + + **/ +EFI_STATUS +EFIAPI +NvmeBlockIoReadBlocks ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + NVME_DEVICE_PRIVATE_DATA *Device; + EFI_STATUS Status; + EFI_BLOCK_IO_MEDIA *Media; + UINTN BlockSize; + UINTN NumberOfBlocks; + UINTN IoAlign; + + // + // Check parameters. + // + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + Media = This->Media; + + if (MediaId != Media->MediaId) { + return EFI_MEDIA_CHANGED; + } + + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (BufferSize == 0) { + return EFI_SUCCESS; + } + + BlockSize = Media->BlockSize; + if ((BufferSize % BlockSize) != 0) { + return EFI_BAD_BUFFER_SIZE; + } + + NumberOfBlocks = BufferSize / BlockSize; + if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { + return EFI_INVALID_PARAMETER; + } + + IoAlign = Media->IoAlign; + if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) { + return EFI_INVALID_PARAMETER; + } + + Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); + Status = NvmeUnitTestRead (Device, Buffer, Lba, NumberOfBlocks); + + return Status; +} + +/** + Simulated BlockIo write block function. + + @param[in] This BlockIo Protocol. + @param[in] MediaId Id of the media. + @param[in] Lba Logical Block Address. + @param[in] BufferSize Size of Buffer. + @param[in] Buffer Actual buffer to use to write. + + **/ +EFI_STATUS +EFIAPI +NvmeBlockIoWriteBlocks ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + NVME_DEVICE_PRIVATE_DATA *Device; + EFI_STATUS Status; + EFI_BLOCK_IO_MEDIA *Media; + UINTN BlockSize; + UINTN NumberOfBlocks; + UINTN IoAlign; + + // + // Check parameters. + // + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + Media = This->Media; + + if (MediaId != Media->MediaId) { + return EFI_MEDIA_CHANGED; + } + + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (BufferSize == 0) { + return EFI_SUCCESS; + } + + BlockSize = Media->BlockSize; + if ((BufferSize % BlockSize) != 0) { + return EFI_BAD_BUFFER_SIZE; + } + + NumberOfBlocks = BufferSize / BlockSize; + if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { + return EFI_INVALID_PARAMETER; + } + + IoAlign = Media->IoAlign; + if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) { + return EFI_INVALID_PARAMETER; + } + + Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); + Status = NvmeUnitTestWrite (Device, Buffer, Lba, NumberOfBlocks); + + return Status; +} + +/** + Simulated BlockIo read block ex function. + + @param[in] This BlockIo2 Protocol. + @param[in] MediaId Id of the media. + @param[in] Lba Logical Block Address. + @param[in,out] Token Block Io2 token. + + @param[in] BufferSize Size of Buffer. + @param[out] Buffer Actual buffer to use to read. + + **/ +EFI_STATUS +EFIAPI +NvmeBlockIoReadBlocksEx ( + IN EFI_BLOCK_IO2_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN OUT EFI_BLOCK_IO2_TOKEN *Token, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + NVME_DEVICE_PRIVATE_DATA *Device; + EFI_BLOCK_IO_MEDIA *Media; + UINTN BlockSize; + UINTN NumberOfBlocks; + UINTN IoAlign; + EFI_STATUS Status; + + // + // Check parameters. + // + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + Media = This->Media; + + if (MediaId != Media->MediaId) { + return EFI_MEDIA_CHANGED; + } + + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + BlockSize = Media->BlockSize; + if ((BufferSize % BlockSize) != 0) { + return EFI_BAD_BUFFER_SIZE; + } + + NumberOfBlocks = BufferSize / BlockSize; + if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { + return EFI_INVALID_PARAMETER; + } + + IoAlign = Media->IoAlign; + if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) { + return EFI_INVALID_PARAMETER; + } + + Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2 (This); + Status = NvmeUnitTestRead (Device, Buffer, Lba, NumberOfBlocks); + + return Status; +} + +/** + Simulated BlockIo write block ex function. + + @param[in] This BlockIo2 Protocol. + @param[in] MediaId Id of the media. + @param[in] Lba Logical Block Address. + @param[in,out] Token Block Io2 token. + @param[in] BufferSize Size of Buffer. + + @param[in] Buffer Actual buffer to use to write. + + **/ +EFI_STATUS +EFIAPI +NvmeBlockIoWriteBlocksEx ( + IN EFI_BLOCK_IO2_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN OUT EFI_BLOCK_IO2_TOKEN *Token, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + NVME_DEVICE_PRIVATE_DATA *Device; + EFI_BLOCK_IO_MEDIA *Media; + UINTN BlockSize; + UINTN NumberOfBlocks; + UINTN IoAlign; + EFI_STATUS Status; + + // + // Check parameters. + // + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + Media = This->Media; + + if (MediaId != Media->MediaId) { + return EFI_MEDIA_CHANGED; + } + + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + BlockSize = Media->BlockSize; + if ((BufferSize % BlockSize) != 0) { + return EFI_BAD_BUFFER_SIZE; + } + + NumberOfBlocks = BufferSize / BlockSize; + if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { + return EFI_INVALID_PARAMETER; + } + + IoAlign = Media->IoAlign; + if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) { + return EFI_INVALID_PARAMETER; + } + + Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2 (This); + Status = NvmeUnitTestWrite (Device, Buffer, Lba, NumberOfBlocks); + + return Status; +} + +/** + MediaSanitizePurgeUnitTest to initialize a Private Namespace instance. + + @param[in] ppDevice Nvme Private Data structure to destory and free. + **/ +UNIT_TEST_STATUS +EFIAPI +NvmeDestroyDeviceInstance ( + NVME_DEVICE_PRIVATE_DATA **ppDevice + ) +{ + // + // Free in following order to to avoid dangling pointers: + // + // 1 - NVME_ADMIN_CONTROLLER_DATA + // 2 - NVME_CONTROLLER_PRIVATE_DATA + // 3 - NVME_DEVICE_PRIVATE_DATA + // + FreePool ((*ppDevice)->Controller->ControllerData); + (*ppDevice)->Controller->ControllerData = NULL; + + FreePool ((*ppDevice)->Controller); + (*ppDevice)->Controller = NULL; + + FreePool ((*ppDevice)); + *ppDevice = NULL; + + return UNIT_TEST_PASSED; +} + +/** + MediaSanitizePurgeUnitTest to initialize a Private Namespace instance. + + @param[in] ppDevice Nvme Private Data structure to initialize. + **/ +UNIT_TEST_STATUS +EFIAPI +NvmeCreateDeviceInstance ( + NVME_DEVICE_PRIVATE_DATA **ppDevice + ) +{ + NVME_ADMIN_NAMESPACE_DATA *NamespaceData; + NVME_CONTROLLER_PRIVATE_DATA *Private; + NVME_DEVICE_PRIVATE_DATA *Device; + + Private = AllocateZeroPool (sizeof (NVME_CONTROLLER_PRIVATE_DATA)); + + Private->Signature = NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE; + Private->Cid[0] = 0; + Private->Cid[1] = 0; + Private->Cid[2] = 0; + Private->Pt[0] = 0; + Private->Pt[1] = 0; + Private->Pt[2] = 0; + Private->SqTdbl[0].Sqt = 0; + Private->SqTdbl[1].Sqt = 0; + Private->SqTdbl[2].Sqt = 0; + Private->CqHdbl[0].Cqh = 0; + Private->CqHdbl[1].Cqh = 0; + Private->CqHdbl[2].Cqh = 0; + Private->AsyncSqHead = 0; + + Private->ControllerData = (NVME_ADMIN_CONTROLLER_DATA *)AllocateZeroPool (sizeof (NVME_ADMIN_CONTROLLER_DATA)); + + UT_LOG_VERBOSE ("%a: Allocated and Initialized NVME_CONTROLLER_PRIVATE_DATA\n", __func__); + UT_LOG_VERBOSE ("%a: Allocated and Initialized NVME_ADMIN_CONTROLLER_DATA\n", __func__); + + Private->ControllerData->Nn = 1; // One namespace + Private->ControllerData->Sanicap.Bes = 1; // Block Erase Supported + Private->ControllerData->Sanicap.Ces = 1; // Crypto Erase Supported + Private->ControllerData->Sanicap.Ows = 1; // Overwrite Supported + + NamespaceData = AllocateZeroPool (sizeof (NVME_ADMIN_NAMESPACE_DATA)); + UT_LOG_VERBOSE ("%a: Allocated and Initialized NVME_ADMIN_NAMESPACE_DATA\n", __func__); + + Device = (NVME_DEVICE_PRIVATE_DATA *)(AllocateZeroPool (sizeof (NVME_DEVICE_PRIVATE_DATA))); + + // + // Initialize SSD namespace instance data + // + Device->Signature = NVME_DEVICE_PRIVATE_DATA_SIGNATURE; + Device->NamespaceId = 0; + Device->NamespaceUuid = 1; + + Device->Controller = Private; + + // + // Build BlockIo media structure + // + Device->Media.MediaId = 0; + Device->Media.RemovableMedia = FALSE; + Device->Media.MediaPresent = TRUE; + Device->Media.LogicalPartition = FALSE; + Device->Media.ReadOnly = FALSE; + Device->Media.WriteCaching = FALSE; + Device->Media.BlockSize = (UINT32)(1 << 9); // 512 byte sector size + + Device->Media.LastBlock = 0x4000; // NamespaceData=>Nsze + Device->Media.LogicalBlocksPerPhysicalBlock = 1; + Device->Media.LowestAlignedLba = 1; + + Device->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2; + Device->BlockIo.Media = &Device->Media; + Device->BlockIo.ReadBlocks = NvmeBlockIoReadBlocks; + Device->BlockIo.WriteBlocks = NvmeBlockIoWriteBlocks; + + Device->BlockIo2.Media = &Device->Media; + Device->BlockIo2.ReadBlocksEx = NvmeBlockIoReadBlocksEx; + Device->BlockIo2.WriteBlocksEx = NvmeBlockIoWriteBlocksEx; + + Device->MediaSanitize.Revision = MEDIA_SANITIZE_PROTOCOL_REVISION; + Device->MediaSanitize.Media = &Device->Media; + Device->MediaSanitize.MediaClear = NvmExpressMediaClear; + Device->MediaSanitize.MediaPurge = NvmExpressMediaPurge; + Device->MediaSanitize.MediaFormat = NvmExpressMediaFormat; + + Device->Controller->Passthru.Mode = 0; + Device->Controller->Passthru.PassThru = NvmeDeviceUnitTestPassthru; + Device->Controller->Passthru.BuildDevicePath = NULL; + Device->Controller->Passthru.GetNamespace = NULL; + Device->Controller->Passthru.GetNextNamespace = NULL; + + CopyMem (&Device->NamespaceData, NamespaceData, sizeof (NVME_ADMIN_NAMESPACE_DATA)); + *ppDevice = Device; + + UT_LOG_VERBOSE ("%a: Allocated and Initialized NVME_DEVICE_PRIVATE_DATA\n", __func__); + + return UNIT_TEST_PASSED; +} + +/** + MediaSanitizePurgeUnitTest to Test calls to NvmExpressMediaPurge. + + @param[in] Context Unit test case context + **/ +UNIT_TEST_STATUS +EFIAPI +MediaSanitizePurgeUnitTest ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UINT32 PurgeAction; + UINT32 OverwritePattern; + UNIT_TEST_STATUS UnitTestStatus; + NVME_DEVICE_PRIVATE_DATA *NvmeDevice; + EFI_STATUS Status; + + UnitTestStatus = UNIT_TEST_PASSED; + NvmeDevice = NULL; + Status = EFI_SUCCESS; + + UnitTestStatus = NvmeCreateDeviceInstance (&NvmeDevice); + + UT_ASSERT_STATUS_EQUAL (UnitTestStatus, UNIT_TEST_PASSED); + UT_ASSERT_NOT_NULL (NvmeDevice); + + UT_LOG_VERBOSE ("%a: Create Device Instance Status = 0x%x\n", __func__, UnitTestStatus); + UT_LOG_VERBOSE ("%a: Device = 0x%x\n", __func__, NvmeDevice); + UT_LOG_VERBOSE ("%a: Device->BlockIo = 0x%x\n", __func__, NvmeDevice->BlockIo); + UT_LOG_VERBOSE ("%a: Device->Signature = 0x%x\n", __func__, NvmeDevice->Signature); + + // + // Case 1: Block Erase + // + PurgeAction = SANITIZE_ACTION_BLOCK_ERASE; + OverwritePattern = 0; + + Status = NvmExpressMediaPurge ( + &NvmeDevice->MediaSanitize, + NvmeDevice->Media.MediaId, + PurgeAction, + OverwritePattern + ); + + UT_ASSERT_NOT_EFI_ERROR (Status); + + UnitTestStatus = NvmeDestroyDeviceInstance (&NvmeDevice); + + return UNIT_TEST_PASSED; +} + +/** + NvmeSanitizeUnitTest to Test calls to NvmExpressSanitize. + + @param[in] Context Unit test case context + **/ +UNIT_TEST_STATUS +EFIAPI +NvmeSanitizeUnitTest ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UINT32 NamespaceId; + UINT32 SanitizeAction; + UINT32 NoDeallocateAfterSanitize; + UINT32 OverwritePattern; + UNIT_TEST_STATUS UnitTestStatus; + NVME_DEVICE_PRIVATE_DATA *NvmeDevice; + EFI_STATUS Status; + + NamespaceId = 0; + UnitTestStatus = UNIT_TEST_PASSED; + NvmeDevice = NULL; + Status = EFI_SUCCESS; + SanitizeAction = SANITIZE_ACTION_BLOCK_ERASE; + NoDeallocateAfterSanitize = 0; + OverwritePattern = 0; + + UnitTestStatus = NvmeCreateDeviceInstance (&NvmeDevice); + + UT_ASSERT_STATUS_EQUAL (UnitTestStatus, UNIT_TEST_PASSED); + UT_ASSERT_NOT_NULL (NvmeDevice); + + UT_LOG_VERBOSE ("%a: Create Device Instance Status = 0x%x\n", __func__, UnitTestStatus); + UT_LOG_VERBOSE ("%a: Device = 0x%x\n", __func__, NvmeDevice); + UT_LOG_VERBOSE ("%a: Device->BlockIo = 0x%x\n", __func__, NvmeDevice->BlockIo); + UT_LOG_VERBOSE ("%a: Device->Signature = 0x%x\n", __func__, NvmeDevice->Signature); + + // + // Case 1: Block Erase + // + SanitizeAction = SANITIZE_ACTION_BLOCK_ERASE; + NoDeallocateAfterSanitize = 0; + OverwritePattern = 0; + + Status = NvmExpressSanitize ( + &NvmeDevice->BlockIo, + NamespaceId, + SanitizeAction, + NoDeallocateAfterSanitize, + OverwritePattern + ); + + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Case 2: Crypto Erase + // + SanitizeAction = SANITIZE_ACTION_CRYPTO_ERASE; + NoDeallocateAfterSanitize = 0; + OverwritePattern = 0; + + Status = NvmExpressSanitize ( + &NvmeDevice->BlockIo, + NamespaceId, + SanitizeAction, + NoDeallocateAfterSanitize, + OverwritePattern + ); + + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Case 3: Overwrite + // + SanitizeAction = SANITIZE_ACTION_OVERWRITE; + NoDeallocateAfterSanitize = 0; + OverwritePattern = 0xDEADBEEF; + + Status = NvmExpressSanitize ( + &NvmeDevice->BlockIo, + NamespaceId, + SanitizeAction, + NoDeallocateAfterSanitize, + OverwritePattern + ); + + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Case 4: Block Erase (invalid overwrite pattern) + // + SanitizeAction = SANITIZE_ACTION_BLOCK_ERASE; + NoDeallocateAfterSanitize = 0; + OverwritePattern = 0xDEADBEEF; + + Status = NvmExpressSanitize ( + &NvmeDevice->BlockIo, + NamespaceId, + SanitizeAction, + NoDeallocateAfterSanitize, + OverwritePattern + ); + + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); + + // + // Case 5: Overwrite (invalid overwrite pattern) + // + SanitizeAction = SANITIZE_ACTION_OVERWRITE; + NoDeallocateAfterSanitize = 0; + OverwritePattern = 0; + + Status = NvmExpressSanitize ( + &NvmeDevice->BlockIo, + NamespaceId, + SanitizeAction, + NoDeallocateAfterSanitize, + OverwritePattern + ); + + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); + + UnitTestStatus = NvmeDestroyDeviceInstance (&NvmeDevice); + + return UNIT_TEST_PASSED; +} + +/** + NvmeFormatNvmUnitTest to Test calls to NvmExpressFormatNvm. + + @param[in] Context Unit test case context + **/ +UNIT_TEST_STATUS +EFIAPI +NvmeFormatNvmUnitTest ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UINT32 NamespaceId; + UINT32 Ses; + UINT32 Flbas; + NVME_DEVICE_PRIVATE_DATA *NvmeDevice; + UNIT_TEST_STATUS UnitTestStatus; + EFI_STATUS Status; + + NamespaceId = 0; + NvmeDevice = NULL; + UnitTestStatus = UNIT_TEST_PASSED; + Status = EFI_SUCCESS; + + UnitTestStatus = NvmeCreateDeviceInstance (&NvmeDevice); + + UT_ASSERT_STATUS_EQUAL (UnitTestStatus, UNIT_TEST_PASSED); + UT_ASSERT_NOT_NULL (NvmeDevice); + + UT_LOG_VERBOSE ("%a: Create Device Instance Status = 0x%x\n", __func__, UnitTestStatus); + UT_LOG_VERBOSE ("%a: Device = 0x%x\n", __func__, NvmeDevice); + UT_LOG_VERBOSE ("%a: Device->BlockIo = 0x%x\n", __func__, NvmeDevice->BlockIo); + UT_LOG_VERBOSE ("%a: Device->Signature = 0x%x\n", __func__, NvmeDevice->Signature); + + // + // Case 1: User Data Erase (Flbas = 0) + // + Ses = SES_USER_DATA_ERASE; + Flbas = 0; + Status = NvmExpressFormatNvm ( + &NvmeDevice->BlockIo, + NamespaceId, + Ses, + Flbas + ); + + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Case 2: Crypto Erase (Flbas = 0) + // + Ses = SES_CRYPTO_ERASE; + Flbas = 0; + Status = NvmExpressFormatNvm ( + &NvmeDevice->BlockIo, + NamespaceId, + Ses, + Flbas + ); + + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Case 3: User Data Erase (Invalid Flbas = 3) + // + Ses = SES_USER_DATA_ERASE; + Flbas = 3; + Status = NvmExpressFormatNvm ( + &NvmeDevice->BlockIo, + NamespaceId, + Ses, + Flbas + ); + + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); + + // + // Case 4: Invalid SES (Flba = 0) + // + Ses = 0xFF; + Flbas = 0; + Status = NvmExpressFormatNvm ( + &NvmeDevice->BlockIo, + NamespaceId, + Ses, + Flbas + ); + + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); + + UnitTestStatus = NvmeDestroyDeviceInstance (&NvmeDevice); + + return UNIT_TEST_PASSED; +} + +/** + Baseline Unit Test. + + @param[in] Context Unit test case context + **/ +UNIT_TEST_STATUS +EFIAPI +UnitTestBaseline ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UINT32 A; + UINT32 B; + UINT32 C; + + A = 1; + B = 1; + C = A + B; + + UT_ASSERT_EQUAL (C, 2); + UT_ASSERT_NOT_EQUAL (0, 1); + + return UNIT_TEST_PASSED; +} + +/** + Test Case that locks a variable using the Variable Policy Protocol with a + policy other than LOCK_NOW then attempts to lock the same variable using the + Variable Lock Protocol. The call to Variable Policy is expected to succeed + and the call to Variable Lock is expected to fail. + + @retval EFI_SUCCES Success + @retval Other Error + **/ +EFI_STATUS +EFIAPI +MediaSanitizeUnitTestEntry ( + VOID + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE NvmeFormatNvmTestSuite; + UNIT_TEST_SUITE_HANDLE NvmeSanitizeTestSuite; + UNIT_TEST_SUITE_HANDLE MediaSanitizeProtocolTestSuite; + + Framework = NULL; + + #define UNIT_TEST_NAME "Media Sanitize Protocol Unit Test" + #define UNIT_TEST_VERSION "1.0" + + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION)); + + // + // Start setting up the test framework for running the tests. + // + Status = InitUnitTestFramework ( + &Framework, + UNIT_TEST_NAME, + gEfiCallerBaseName, + UNIT_TEST_VERSION + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status)); + goto EXIT; + } + + // + // Populate the NVM Express Format NVM Unit Test Suite. + // + Status = CreateUnitTestSuite ( + &NvmeFormatNvmTestSuite, + Framework, + "NVM Express Format NVM Test Suite", + "Nvm.Express.Format.Nvm", + NULL, + NULL + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for NvmeFormatNvmTestSuite. Status = %r\n", Status)); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + // + // Add baseline sanity test case + // + AddTestCase ( + NvmeFormatNvmTestSuite, // Test Suite Handle + "Baseline Format NVM Unit Test", // Test Description + "FormatNVM", // Test Class + UnitTestBaseline, // UNIT_TEST_FUNCTION() + NULL, // (Optional) UNIT_TEST_PREREQUISITE() + NULL, // (Optional) UNIT_TEST_CLEANUP() + NULL // (Optional) UNIT_TEST_CONTEXT + ); + + // + // Add test case for NvmExpressFormatNvm() + // + AddTestCase ( + NvmeFormatNvmTestSuite, // Test Suite Handle + "Admin Format NVM Command Unit Test", // Test Description + "FormatNVM", // Test Class + NvmeFormatNvmUnitTest, // UNIT_TEST_FUNCTION() + NULL, // (Optional) UNIT_TEST_PREREQUISITE() + NULL, // (Optional) UNIT_TEST_CLEANUP() + NULL // (Optional) UNIT_TEST_CONTEXT + ); + + // + // Populate the NVM Express Sanitize Unit Test Suite. + // + Status = CreateUnitTestSuite ( + &NvmeSanitizeTestSuite, + Framework, + "NVM Express Sanitize Test Suite", + "Nvm.Express.Sanitize", + NULL, + NULL + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for NvmeSanitizTestSuite. Status = %r\n", Status)); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + // + // Add baseline sanity test + // + AddTestCase ( + NvmeSanitizeTestSuite, // Test Suite Handle + "Baseline Sanitize Unit Test", // Test Description + "Sanitize", // Test Class + UnitTestBaseline, // UNIT_TEST_FUNCTION() + NULL, // (Optional) UNIT_TEST_PREREQUISITE() + NULL, // (Optional) UNIT_TEST_CLEANUP() + NULL // (Optional) UNIT_TEST_CONTEXT + ); + + // + // Add test case for NvmExressSanitize() + // + AddTestCase ( + NvmeSanitizeTestSuite, // Test Suite Handle + "Admin Sanitize Command Unit Test", // Test Description + "Sanitize", // Test Class + NvmeSanitizeUnitTest, // UNIT_TEST_FUNCTION() + NULL, // (Optional) UNIT_TEST_PREREQUISITE() + NULL, // (Optional) UNIT_TEST_CLEANUP() + NULL // (Optional) UNIT_TEST_CONTEXT + ); + + // + // Populate the Media Sanitize Protocol Unit Test Suite. + // + Status = CreateUnitTestSuite ( + &MediaSanitizeProtocolTestSuite, + Framework, + "Media Sanitize Protocol Test Suite", + "Media.Sanitize.Protocol", + NULL, + NULL + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MediaSanitizeProtocolTestSuite. Status = %r\n", Status)); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + // + // Add test case for Media Purge + // + AddTestCase ( + MediaSanitizeProtocolTestSuite, // Test Suite Handle + "Baseline MediaSanitize Unit Test", // Test Description + "MediaSanitize", // Test Class + UnitTestBaseline, // UNIT_TEST_FUNCTION() + NULL, // (Optional) UNIT_TEST_PREREQUISITE() + NULL, // (Optional) UNIT_TEST_CLEANUP() + NULL // (Optional) UNIT_TEST_CONTEXT + ); + + // + // Add test case for Media Purge + // + AddTestCase ( + MediaSanitizeProtocolTestSuite, // Test Suite Handle + "Protocol Media Sanitize Unit Test", // Test Description + "MediaPurge", // Test Class + MediaSanitizePurgeUnitTest, // UNIT_TEST_FUNCTION() + NULL, // (Optional) UNIT_TEST_PREREQUISITE() + NULL, // (Optional) UNIT_TEST_CLEANUP() + NULL // (Optional) UNIT_TEST_CONTEXT + ); + + // + // Execute the tests. + // + Status = RunAllTestSuites (Framework); + +EXIT: + if (Framework) { + FreeUnitTestFramework (Framework); + } + + return Status; +} + +/// +/// Avoid ECC error for function name that starts with lower case letter +/// +#define MediaSanitizeUnitTestMain main + +/** + Standard POSIX C entry point for host based unit test execution. + + @param[in] Argc Number of arguments + @param[in] Argv Array of pointers to arguments + + @retval 0 Success + @retval other Error +**/ +INT32 +MediaSanitizeUnitTestMain ( + IN INT32 Argc, + IN CHAR8 *Argv[] + ) +{ + return MediaSanitizeUnitTestEntry (); +} diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTestHost.inf b/MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTestHost.inf new file mode 100644 index 000000000000..feeeea340f39 --- /dev/null +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTestHost.inf @@ -0,0 +1,37 @@ +## @file +# Unit tests for MEDIA_SANITIZE_PROTOCOL and mapping to NVM Express native commands (Sanitize and FormatNVM) +# +# Copyright (C) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = MediaSanitizeUnitTestHost + FILE_GUID = AAE328E9-37C3-4F4A-A2C0-0BE0E681ADA6 + MODULE_TYPE = HOST_APPLICATION + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + MediaSanitizeUnitTest.c + ../NvmExpressMediaSanitize.c + ../NvmExpressMediaSanitize.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + UnitTestLib + PrintLib + MemoryAllocationLib diff --git a/MdeModulePkg/Include/Protocol/MediaSanitize.h b/MdeModulePkg/Include/Protocol/MediaSanitize.h new file mode 100644 index 000000000000..029b13561f8f --- /dev/null +++ b/MdeModulePkg/Include/Protocol/MediaSanitize.h @@ -0,0 +1,173 @@ +/** @file + This file defines the Media Sanitize Protocol. + + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef MEDIA_SANITIZE_PROTOCOL_H_ +#define MEDIA_SANITIZE_PROTOCOL_H_ + +#define MEDIA_SANITIZE_PROTOCOL_GUID \ + { \ + 0x0d799a99, 0x25af, 0x429e, { 0x92, 0x72, 0xd0, 0xb2, 0x7d, 0x6d, 0x5f, 0x14 } \ + } + +typedef struct _MEDIA_SANITIZE_PROTOCOL MEDIA_SANITIZE_PROTOCOL; + +#define MEDIA_SANITIZE_PROTOCOL_REVISION 0x00010000 + +/// +/// Sanitize actions for purge operation. +/// +/// NOTE: First four actions (no action, overwrite, block erase, crypto erase) cannot +/// be overlapped. All other fields may be overlapped as they apply. +/// +#define PURGE_ACTION_NO_ACTION 0x00000000 // No purge action requested +#define PURGE_ACTION_OVERWRITE 0x00000001 // Overwrite with 32-bit pattern +#define PURGE_ACTION_BLOCK_ERASE 0x00000002 // Erase Blocks with indeterminate pattern +#define PURGE_ACTION_CRYPTO_ERASE 0x00000004 // Delete encryption keys only +#define PURGE_ACTION_RESET_REQUIRED 0x00000008 // Reset required after purge +#define PURGE_ACTION_NO_DEALLOCATE 0x00000010 // Do no deallocate (trim) flash medai after sanitize +#define PURGE_ACTION_INVERT_OW_PATTERN 0x00000020 // Invert overwrite pattern between passes +#define PURGE_ACTION_ALLOW_UNRESTRICTED_SANITIZE_EXIT 0x00000040 // Allow exit without restrictions + +/// +/// Secure erase action for media format operation +/// +#define FORMAT_SES_NO_SECURE_ERASE_REQUESTED 0x0 // No secure erase operation requested +#define FORMAT_SES_USER_DATA_ERASE 0x1 // User Data Erase +#define FORMAT_SES_CRYPTOGRAPHIC_ERASE 0x2 // Cryptographic Erase + +/** + Clear Media utilizes transport native WRITE commands to write a fixed pattern + of non-sensitive data. The size of the overwrite buffer shall be equal to the + one sector/LBA (in bytes). + + NOTE: This function must be called from TPL aaplication or callback. + + @param[in] This Indicates a pointer to the calling context. + @param[in] MediaId The media ID that the clear request is for. + @param[in] PassCount Number of passes to write over the media. + @param[in] SectorOwBuffer Pointer to overwrite pattern buffer. + + @retval EFI_SUCCESS The media clear request completed successfully + on the device. + @retval EFI_WRITE_PROTECTED The device can't be cleared due to write + protection. + @retval EFI_DEVICE_ERROR The device reported an error while attempting + to perform the clear operation. + @retval EFI_INVALID_PARAMETER The clear request contains parameters that + are not valid. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. + +**/ +typedef +EFI_STATUS +(EFIAPI *BLOCK_MEDIA_CLEAR)( + IN MEDIA_SANITIZE_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT32 PassCount, + IN VOID *SectorOwBuffer + ); + +/** + Purge Media utilizes native Sanitize operations. Transport specific + overwrite, block erase, or crypto erase functions shall be invoked based + on transport. + + NOTE: This function must be called from TPL aaplication or callback. + + @param[in] This Indicates a pointer to the calling context. + @param[in] MediaId The media ID that the clear request is for. + @param[in] PurgeAction Purge action: overwrite, crypto or block erase. + @param[in] OverwritePattern 32-bit pattern to overwrite on media. + + @retval EFI_SUCCESS The media purge request completed successfully + on the device. + @retval EFI_WRITE_PROTECTED The device can't be purged due to write + protection. + @retval EFI_DEVICE_ERROR The device reported an error while attempting + to perform the purge operation. + @retval EFI_INVALID_PARAMETER The purge request contains parameters that + are not valid. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. + +**/ +typedef +EFI_STATUS +(EFIAPI *BLOCK_MEDIA_PURGE)( + IN MEDIA_SANITIZE_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT32 PurgeAction, + IN UINT32 OverwritePattern + ); + +/** + Format Media utilizes native format operations to modify sector/LBA size. + Secure erase actions are used to define how latent user data is erased. + + NOTE: This function must be called from TPL aaplication or callback. + + @param[in] This Indicates a pointer to the calling context. + @param[in] MediaId The media ID that the clear request is for. + @param[in] LbaSize Size of LBA (in terms of power of two: 2^n). + @param[in] SecureEraseAction Secure erase action, if any, to apply to format. + + @retval EFI_SUCCESS The media format request comopleted + successfully on the device. + @retval EFI_WRITE_PROTECTED The device can't be formatted due to write + protection. + @retval EFI_DEVICE_ERROR The device reported an error while attempting + to perform the format operation. + @retval EFI_INVALID_PARAMETER The format request contains parameters that + are not valid. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. + + **/ +typedef +EFI_STATUS +(EFIAPI *BLOCK_MEDIA_FORMAT)( + IN MEDIA_SANITIZE_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT32 LbaSize, + IN UINT32 SecureEraseAction + ); + +/// +/// The Media Sanitize Protocol provides the ability for a device to expose +/// sanitize functionality. This optional protocol is installed on the same handle +/// as the EFI_BLOCK_IO_PROTOCOL or EFI_BLOCK_IO2_PROTOCOL. +/// +struct _MEDIA_SANITIZE_PROTOCOL { + /// + /// The revision to which the MEDIA_SANITIZE_PROTOCOL adheres. All future + /// revisions must be backwards compatible. If a future version is not + /// backwards compatible, it is not the same GUID. + /// + UINT64 Revision; + + /// + /// A pointer to the EFI_BLOCK_IO_MEDIA data for this device. + /// Type EFI_BLOCK_IO_MEDIA is defined in BlockIo.h. + /// + EFI_BLOCK_IO_MEDIA *Media; + + /// + /// SanitizeCapabilities shall which sanitize operations (crypto erase, block + /// erase, overwrite) is supported by this Block Io device. + /// + UINT32 SanitizeCapabilities; + + BLOCK_MEDIA_CLEAR MediaClear; + BLOCK_MEDIA_PURGE MediaPurge; + BLOCK_MEDIA_FORMAT MediaFormat; +}; + +extern EFI_GUID gMediaSanitizeProtocolGuid; + +#endif diff --git a/MdeModulePkg/MdeModulePkg.ci.yaml b/MdeModulePkg/MdeModulePkg.ci.yaml index a3de60a12c9e..34d8b7e4091b 100644 --- a/MdeModulePkg/MdeModulePkg.ci.yaml +++ b/MdeModulePkg/MdeModulePkg.ci.yaml @@ -23,6 +23,7 @@ "8005", "UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE.UID", "8005", "UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE.HID", "8001", "UefiSortLibUnitTestMain", + "8001", "MediaSanitizeUnitTestMain", ], ## Both file path and directory path are accepted. "IgnoreFiles": [ diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index a25f380d0281..1324b6d1000c 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -589,6 +589,10 @@ gEfiPrint2ProtocolGuid = { 0xf05976ef, 0x83f1, 0x4f3d, { 0x86, 0x19, 0xf7, 0x59, 0x5d, 0x41, 0xe5, 0x38 } } gEfiPrint2SProtocolGuid = { 0xcc252d2, 0xc106, 0x4661, { 0xb5, 0xbd, 0x31, 0x47, 0xa4, 0xf8, 0x1f, 0x92 } } + ## This protocol defines the Media Clear and Sanitize operations defined by NIST + # Include/Protocol/MediaSanitize.h + gMediaSanitizeProtocolGuid = { 0x0d799a99, 0x25af, 0x429e, {0x92, 0x72, 0xd0, 0xb2, 0x7d, 0x6d, 0x5f, 0x14 } } + ## This protocol defines the generic memory test interfaces in Dxe phase. # Include/Protocol/GenericMemoryTest.h gEfiGenericMemTestProtocolGuid = { 0x309DE7F1, 0x7F5E, 0x4ACE, { 0xB4, 0x9C, 0x53, 0x1B, 0xE5, 0xAA, 0x95, 0xEF }} diff --git a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc index 198cdd814fb9..5ee505349f94 100644 --- a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc +++ b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc @@ -60,6 +60,11 @@ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf } + MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTestHost.inf { + + NvmExpressDxe|MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf + } + # # Build HOST_APPLICATION Libraries # From 6a7be5a8418ab6397375e32e399e9523db9d4293 Mon Sep 17 00:00:00 2001 From: Abdul Lateef Attar Date: Wed, 7 Aug 2024 10:27:36 +0000 Subject: [PATCH 109/280] DynamicTablesPkg: AML code generation for IO resouce descriptor. Add helper functions to generate AML resource data for I/O resource descriptor. Cc: Pierre Gondois Cc: Sami Mujawar Signed-off-by: Abdul Lateef Attar --- .../Include/Library/AmlLib/AmlLib.h | 42 ++++++++++ .../AmlLib/CodeGen/AmlResourceDataCodeGen.c | 83 +++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h index 7c130736b4d9..13ce97c3ddf8 100644 --- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h +++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h @@ -1028,6 +1028,48 @@ AmlCodeGenRdInterrupt ( OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL ); +/** Code generation for the "IO ()" ASL function. + + The Resource Data effectively created is a IO Resource + Data. Cf ACPI 6.5: + - s19.6.65 IO (IO Resource Descriptor Macro) + - s6.4.2.5 I/O Port Descriptor + + The created resource data node can be: + - appended to the list of resource data elements of the NameOpNode. + In such case NameOpNode must be defined by a the "Name ()" ASL statement + and initially contain a "ResourceTemplate ()". + - returned through the NewRdNode parameter. + + @param [in] IsDecoder16 Decoder parameter. + TRUE if 16-bit decoder. + FALSE if 10-bit decoder. + @param [in] AddressMinimum Minimum address. + @param [in] AddressMaximum Maximum address. + @param [in] Alignment Alignment. + @param [in] RangeLength Range length. + @param [in] NameOpNode NameOp object node defining a named object. + If provided, append the new resource data + node to the list of resource data elements + of this node. + @param [out] NewRdNode If provided and success, + contain the created node. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +AmlCodeGenRdIo ( + IN BOOLEAN IsDecoder16, + IN UINT16 AddressMinimum, + IN UINT16 AddressMaximum, + IN UINT8 Alignment, + IN UINT8 RangeLength, + IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL + OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL + ); + /** AML code generation for DefinitionBlock. Create a Root Node handle. diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c index 46243f981c7f..3db536dddf49 100644 --- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c +++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c @@ -1475,6 +1475,89 @@ AmlCodeGenRdRegister ( return LinkRdNode (RdNode, NameOpNode, NewRdNode); } +/** Code generation for the "IO ()" ASL function. + + The Resource Data effectively created is a IO Resource + Data. Cf ACPI 6.5: + - s19.6.65 IO (IO Resource Descriptor Macro) + - s6.4.2.5 I/O Port Descriptor + + The created resource data node can be: + - appended to the list of resource data elements of the NameOpNode. + In such case NameOpNode must be defined by a the "Name ()" ASL statement + and initially contain a "ResourceTemplate ()". + - returned through the NewRdNode parameter. + + @param [in] IsDecoder16 Decoder parameter. + TRUE if 16-bit decoder. + FALSE if 10-bit decoder. + @param [in] AddressMinimum Minimum address. + @param [in] AddressMaximum Maximum address. + @param [in] Alignment Alignment. + @param [in] RangeLength Range length. + @param [in] NameOpNode NameOp object node defining a named object. + If provided, append the new resource data + node to the list of resource data elements + of this node. + @param [out] NewRdNode If provided and success, + contain the created node. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +AmlCodeGenRdIo ( + IN BOOLEAN IsDecoder16, + IN UINT16 AddressMinimum, + IN UINT16 AddressMaximum, + IN UINT8 Alignment, + IN UINT8 RangeLength, + IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL + OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_ACPI_IO_PORT_DESCRIPTOR IoDesc; + AML_DATA_NODE *IoNode; + + if (AddressMinimum > AddressMaximum) { + return EFI_INVALID_PARAMETER; + } + + if (Alignment != 0) { + /// check the alignment + if ((AddressMinimum % Alignment) != 0) { + return EFI_INVALID_PARAMETER; + } + + if ((AddressMaximum % Alignment) != 0) { + return EFI_INVALID_PARAMETER; + } + } + + IoDesc.Header.Byte = ACPI_IO_PORT_DESCRIPTOR; + IoDesc.Information = IsDecoder16 ? BIT0 : 0; + + IoDesc.BaseAddressMin = AddressMinimum; + IoDesc.BaseAddressMax = AddressMaximum; + IoDesc.Alignment = Alignment; + IoDesc.Length = RangeLength; + + Status = AmlCreateDataNode ( + EAmlNodeDataTypeResourceData, + (UINT8 *)&IoDesc, + sizeof (IoDesc), + &IoNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + return LinkRdNode (IoNode, NameOpNode, NewRdNode); +} + /** Code generation for the EndTag resource data. The EndTag resource data is automatically generated by the ASL compiler From 58035e8b5e11cfe2b9e6428d14c7817b6b1c83a2 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 23 Aug 2024 14:35:53 +0200 Subject: [PATCH 110/280] OvmfPkg/VirtioGpuDxe: ignore display resolutions smaller than 640x480 GraphicsConsoleDxe will assert in case the resolution is too small. Signed-off-by: Gerd Hoffmann --- OvmfPkg/VirtioGpuDxe/Gop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/VirtioGpuDxe/Gop.c b/OvmfPkg/VirtioGpuDxe/Gop.c index f64dfce5f400..d767114bbbd9 100644 --- a/OvmfPkg/VirtioGpuDxe/Gop.c +++ b/OvmfPkg/VirtioGpuDxe/Gop.c @@ -265,7 +265,8 @@ GopInitialize ( // query host for display resolution // GopNativeResolution (VgpuGop, &XRes, &YRes); - if ((XRes == 0) || (YRes == 0)) { + if ((XRes < 640) || (YRes < 480)) { + /* ignore hint, GraphicsConsoleDxe needs 640x480 or larger */ return; } From 391666da2c1dc5671bbb3393079d86f46e3435af Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 23 Aug 2024 14:36:16 +0200 Subject: [PATCH 111/280] OvmfPkg/QemuVideoDxe: ignore display resolutions smaller than 640x480 GraphicsConsoleDxe will assert in case the resolution is too small. Signed-off-by: Gerd Hoffmann --- OvmfPkg/QemuVideoDxe/Initialize.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/OvmfPkg/QemuVideoDxe/Initialize.c b/OvmfPkg/QemuVideoDxe/Initialize.c index 050ae878ecde..2d1f50637fe2 100644 --- a/OvmfPkg/QemuVideoDxe/Initialize.c +++ b/OvmfPkg/QemuVideoDxe/Initialize.c @@ -293,6 +293,8 @@ QemuVideoBochsEdid ( ) { EFI_STATUS Status; + UINT32 X; + UINT32 Y; if (Private->Variant != QEMU_VIDEO_BOCHS_MMIO) { return; @@ -344,16 +346,24 @@ QemuVideoBochsEdid ( return; } - *XRes = Private->Edid[56] | ((Private->Edid[58] & 0xf0) << 4); - *YRes = Private->Edid[59] | ((Private->Edid[61] & 0xf0) << 4); + X = Private->Edid[56] | ((Private->Edid[58] & 0xf0) << 4); + Y = Private->Edid[59] | ((Private->Edid[61] & 0xf0) << 4); DEBUG (( DEBUG_INFO, "%a: default resolution: %dx%d\n", __func__, - *XRes, - *YRes + X, + Y )); + if ((X < 640) || (Y < 480)) { + /* ignore hint, GraphicsConsoleDxe needs 640x480 or larger */ + return; + } + + *XRes = X; + *YRes = Y; + if (PcdGet8 (PcdVideoResolutionSource) == 0) { Status = PcdSet32S (PcdVideoHorizontalResolution, *XRes); ASSERT_RETURN_ERROR (Status); From 76c5f035a148288fa1a4ecfa846464f546728b74 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 30 Jul 2024 19:06:52 +0200 Subject: [PATCH 112/280] ArmPlatformPkg: Retire ArmPlatformStackLib ArmPlatformStackLib is no longer used so it can be retired. Signed-off-by: Ard Biesheuvel --- ArmPlatformPkg/ArmPlatformPkg.dsc | 2 - .../AArch64/ArmPlatformStackLib.S | 99 ------------------- .../Arm/ArmPlatformStackLib.S | 98 ------------------ .../ArmPlatformStackLib.inf | 33 ------- 4 files changed, 232 deletions(-) delete mode 100644 ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S delete mode 100644 ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S delete mode 100644 ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc index bc6f2b5ede20..f87c7d50f573 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg.dsc @@ -40,7 +40,6 @@ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf - ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf BaseLib|MdePkg/Library/BaseLib/BaseLib.inf BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf @@ -103,7 +102,6 @@ ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf - ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf ArmPlatformPkg/Library/HdLcd/HdLcd.inf ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.inf ArmPlatformPkg/Library/LcdPlatformNullLib/LcdPlatformNullLib.inf diff --git a/ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S b/ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S deleted file mode 100644 index db0912c19f6a..000000000000 --- a/ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S +++ /dev/null @@ -1,99 +0,0 @@ -// -// Copyright (c) 2012-2014, ARM Limited. All rights reserved. -// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// -// - -#include - -//VOID -//ArmPlatformStackSet ( -// IN UINTN StackBase, -// IN UINTN MpId, -// IN UINTN PrimaryStackSize, -// IN UINTN SecondaryStackSize -// ); -ASM_FUNC(ArmPlatformStackSet) - // Save parameters - mov x26, x3 - mov x25, x2 - mov x24, x1 - mov x23, x0 - - // Save the Link register - mov x27, x30 - - // Identify Stack - mov x0, x1 - bl ASM_PFX(ArmPlatformIsPrimaryCore) - cmp x0, #1 - - // Restore parameters - mov x0, x23 - mov x1, x24 - mov x2, x25 - mov x3, x26 - - // Restore the Link register - mov x30, x27 - - b.ne 0f - - b ASM_PFX(ArmPlatformStackSetPrimary) -0:b ASM_PFX(ArmPlatformStackSetSecondary) - -//VOID -//ArmPlatformStackSetPrimary ( -// IN UINTN StackBase, -// IN UINTN MpId, -// IN UINTN PrimaryStackSize, -// IN UINTN SecondaryStackSize -// ); -ASM_FUNC(ArmPlatformStackSetPrimary) - // Add size of primary stack to StackBase - add x0, x0, x2 - - // Compute SecondaryCoresCount * SecondaryCoreStackSize - MOV32 (w1, FixedPcdGet32(PcdCoreCount) - 1) - mul x3, x3, x1 - - // Set Primary Stack ((StackBase + PrimaryStackSize) + (SecondaryCoresCount * SecondaryCoreStackSize)) - add sp, x0, x3 - - ret - -//VOID -//ArmPlatformStackSetSecondary ( -// IN UINTN StackBase, -// IN UINTN MpId, -// IN UINTN PrimaryStackSize, -// IN UINTN SecondaryStackSize -// ); -ASM_FUNC(ArmPlatformStackSetSecondary) - // Save the Link register - mov x24, x30 - mov sp, x0 - - // Get Core Position - mov x0, x1 - bl ASM_PFX(ArmPlatformGetCorePosition) - mov x25, x0 - - // Get Primary Core Position - bl ASM_PFX(ArmPlatformGetPrimaryCoreMpId) - bl ASM_PFX(ArmPlatformGetCorePosition) - - // Get Secondary Core Position. We should get consecutive secondary stack number from 1...(CoreCount-1) - cmp x25, x0 - - // Decrement the position if after the primary core - cinc x25, x25, ls - - // Compute top of the secondary stack - mul x3, x3, x25 - - // Set stack - add sp, sp, x3 - - ret x24 diff --git a/ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S b/ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S deleted file mode 100644 index 0e47032ed1e6..000000000000 --- a/ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S +++ /dev/null @@ -1,98 +0,0 @@ -// -// Copyright (c) 2012-2013, ARM Limited. All rights reserved. -// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// -// - -#include - -//VOID -//ArmPlatformStackSet ( -// IN UINTN StackBase, -// IN UINTN MpId, -// IN UINTN PrimaryStackSize, -// IN UINTN SecondaryStackSize -// ); -ASM_FUNC(ArmPlatformStackSet) - // Save parameters - mov r6, r3 - mov r5, r2 - mov r4, r1 - mov r3, r0 - - // Save the Link register - mov r7, lr - - // Identify Stack - mov r0, r1 - bl ASM_PFX(ArmPlatformIsPrimaryCore) - cmp r0, #1 - - // Restore parameters - mov r0, r3 - mov r1, r4 - mov r2, r5 - mov r3, r6 - - // Restore the Link register - mov lr, r7 - - beq ASM_PFX(ArmPlatformStackSetPrimary) - bne ASM_PFX(ArmPlatformStackSetSecondary) - -//VOID -//ArmPlatformStackSetPrimary ( -// IN UINTN StackBase, -// IN UINTN MpId, -// IN UINTN PrimaryStackSize, -// IN UINTN SecondaryStackSize -// ); -ASM_FUNC(ArmPlatformStackSetPrimary) - mov r4, lr - - // Add stack of primary stack to StackBase - add r0, r0, r2 - - // Compute SecondaryCoresCount * SecondaryCoreStackSize - MOV32 (r1, FixedPcdGet32(PcdCoreCount) - 1) - mul r3, r3, r1 - - // Set Primary Stack ((StackBase + PrimaryStackSize) + (SecondaryCoresCount * SecondaryCoreStackSize)) - add sp, r0, r3 - - bx r4 - -//VOID -//ArmPlatformStackSetSecondary ( -// IN UINTN StackBase, -// IN UINTN MpId, -// IN UINTN PrimaryStackSize, -// IN UINTN SecondaryStackSize -// ); -ASM_FUNC(ArmPlatformStackSetSecondary) - mov r4, lr - mov sp, r0 - - // Get Core Position - mov r0, r1 - bl ASM_PFX(ArmPlatformGetCorePosition) - mov r5, r0 - - // Get Primary Core Position - bl ASM_PFX(ArmPlatformGetPrimaryCoreMpId) - bl ASM_PFX(ArmPlatformGetCorePosition) - - // Get Secondary Core Position. We should get consecutive secondary stack number from 1...(CoreCount-1) - cmp r5, r0 - subhi r5, r5, #1 - add r5, r5, #1 - - // Compute top of the secondary stack - mul r3, r3, r5 - - // Set stack - add sp, sp, r3 - - bx r4 - diff --git a/ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf b/ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf deleted file mode 100644 index dfa0e7b9e786..000000000000 --- a/ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf +++ /dev/null @@ -1,33 +0,0 @@ -#/* @file -# -# Copyright (c) 2012, ARM Limited. All rights reserved. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#*/ - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = ArmPlatformStackLib - FILE_GUID = 5e2e44af-53c1-44c2-a801-9c149f3d6ba0 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = ArmPlatformStackLib - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - ArmPkg/ArmPkg.dec - ArmPlatformPkg/ArmPlatformPkg.dec - -[Sources.ARM] - Arm/ArmPlatformStackLib.S | GCC - -[Sources.AARCH64] - AArch64/ArmPlatformStackLib.S - -[LibraryClasses] - ArmPlatformLib - -[FixedPcd] - gArmPlatformTokenSpaceGuid.PcdCoreCount From 029c7a2829a619cb1404468351a0fa6cb04e2ce1 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Wed, 31 Jul 2024 15:20:25 +0200 Subject: [PATCH 113/280] ArmPlatformPkg: Retire PrePeiCore Retire the PrePeiCore SEC driver, which has been replaced by Sec.inf Signed-off-by: Ard Biesheuvel --- ArmPlatformPkg/ArmPlatformPkg.dsc | 1 - .../PrePeiCore/AArch64/ArchPrePeiCore.c | 46 ----- ArmPlatformPkg/PrePeiCore/AArch64/Exception.S | 116 ------------ ArmPlatformPkg/PrePeiCore/AArch64/Helper.S | 42 ---- .../PrePeiCore/AArch64/PrePeiCoreEntryPoint.S | 61 ------ .../PrePeiCore/AArch64/SwitchStack.S | 32 ---- .../PrePeiCore/Arm/ArchPrePeiCore.c | 57 ------ ArmPlatformPkg/PrePeiCore/Arm/Exception.S | 96 ---------- .../PrePeiCore/Arm/PrePeiCoreEntryPoint.S | 40 ---- ArmPlatformPkg/PrePeiCore/Arm/SwitchStack.S | 32 ---- ArmPlatformPkg/PrePeiCore/MainUniCore.c | 48 ----- ArmPlatformPkg/PrePeiCore/PrePeiCore.c | 179 ------------------ ArmPlatformPkg/PrePeiCore/PrePeiCore.h | 61 ------ .../PrePeiCore/PrePeiCoreUniCore.inf | 66 ------- 14 files changed, 877 deletions(-) delete mode 100644 ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c delete mode 100644 ArmPlatformPkg/PrePeiCore/AArch64/Exception.S delete mode 100644 ArmPlatformPkg/PrePeiCore/AArch64/Helper.S delete mode 100644 ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S delete mode 100644 ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S delete mode 100644 ArmPlatformPkg/PrePeiCore/Arm/ArchPrePeiCore.c delete mode 100644 ArmPlatformPkg/PrePeiCore/Arm/Exception.S delete mode 100644 ArmPlatformPkg/PrePeiCore/Arm/PrePeiCoreEntryPoint.S delete mode 100644 ArmPlatformPkg/PrePeiCore/Arm/SwitchStack.S delete mode 100644 ArmPlatformPkg/PrePeiCore/MainUniCore.c delete mode 100644 ArmPlatformPkg/PrePeiCore/PrePeiCore.c delete mode 100644 ArmPlatformPkg/PrePeiCore/PrePeiCore.h delete mode 100644 ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc index f87c7d50f573..d7c29054cfa9 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg.dsc @@ -118,7 +118,6 @@ ArmPlatformPkg/PlatformPei/PlatformPeim.inf ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf - ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf ArmPlatformPkg/Sec/Sec.inf ArmPlatformPkg/PrePi/PeiUniCore.inf diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c b/ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c deleted file mode 100644 index 2dc77f4b879b..000000000000 --- a/ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c +++ /dev/null @@ -1,46 +0,0 @@ -/** @file - Main file supporting the transition to PEI Core in Normal World for Versatile Express - - Copyright (c) 2012-2013, ARM Limited. All rights reserved. - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include - -#include "PrePeiCore.h" - -VOID -PeiCommonExceptionEntry ( - IN UINT32 Entry, - IN UINTN LR - ) -{ - CHAR8 Buffer[100]; - UINTN CharCount; - - switch (Entry) { - case EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS: - CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Synchronous Exception at 0x%X\n\r", LR); - break; - case EXCEPT_AARCH64_IRQ: - CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "IRQ Exception at 0x%X\n\r", LR); - break; - case EXCEPT_AARCH64_FIQ: - CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "FIQ Exception at 0x%X\n\r", LR); - break; - case EXCEPT_AARCH64_SERROR: - CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "SError/Abort Exception at 0x%X\n\r", LR); - break; - default: - CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Unknown Exception at 0x%X\n\r", LR); - break; - } - - SerialPortWrite ((UINT8 *)Buffer, CharCount); - - while (1) { - } -} diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S b/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S deleted file mode 100644 index d0d6bc44f78c..000000000000 --- a/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S +++ /dev/null @@ -1,116 +0,0 @@ -# -# Copyright (c) 2011-2021, Arm Limited. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -# - -#include -#include -#include -#include - -.text - -//============================================================ -//Default Exception Handlers -//============================================================ - -#define TO_HANDLER \ - EL1_OR_EL2(x1) \ -1: mrs x1, elr_el1 /* EL1 Exception Link Register */ ;\ - b 3f ;\ -2: mrs x1, elr_el2 /* EL2 Exception Link Register */ ;\ -3: bl ASM_PFX(PeiCommonExceptionEntry) ; - - -// -// Default Exception handlers: There is no plan to return from any of these exceptions. -// No context saving at all. -// - -VECTOR_BASE(PeiVectorTable) - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SP0_SYNC) -_DefaultSyncExceptHandler_t: - mov x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SP0_IRQ) -_DefaultIrq_t: - mov x0, #EXCEPT_AARCH64_IRQ - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SP0_FIQ) -_DefaultFiq_t: - mov x0, #EXCEPT_AARCH64_FIQ - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SP0_SERR) -_DefaultSError_t: - mov x0, #EXCEPT_AARCH64_SERROR - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SPX_SYNC) -_DefaultSyncExceptHandler_h: - mov x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SPX_IRQ) -_DefaultIrq_h: - mov x0, #EXCEPT_AARCH64_IRQ - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SPX_FIQ) -_DefaultFiq_h: - mov x0, #EXCEPT_AARCH64_FIQ - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SPX_SERR) -_DefaultSError_h: - mov x0, #EXCEPT_AARCH64_SERROR - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A64_SYNC) -_DefaultSyncExceptHandler_LowerA64: - mov x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A64_IRQ) -_DefaultIrq_LowerA64: - mov x0, #EXCEPT_AARCH64_IRQ - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A64_FIQ) -_DefaultFiq_LowerA64: - mov x0, #EXCEPT_AARCH64_FIQ - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A64_SERR) -_DefaultSError_LowerA64: - mov x0, #EXCEPT_AARCH64_SERROR - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A32_SYNC) -_DefaultSyncExceptHandler_LowerA32: - mov x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A32_IRQ) -_DefaultIrq_LowerA32: - mov x0, #EXCEPT_AARCH64_IRQ - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A32_FIQ) -_DefaultFiq_LowerA32: - mov x0, #EXCEPT_AARCH64_FIQ - TO_HANDLER - -VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A32_SERR) -_DefaultSError_LowerA32: - mov x0, #EXCEPT_AARCH64_SERROR - TO_HANDLER - -VECTOR_END(PeiVectorTable) - -AARCH64_BTI_NOTE() diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S b/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S deleted file mode 100644 index 9b81b96a4949..000000000000 --- a/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S +++ /dev/null @@ -1,42 +0,0 @@ -#======================================================================================== -# Copyright (c) 2011-2017, ARM Limited. All rights reserved. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#======================================================================================= - -#include -#include - -// Setup EL1 while in EL1 -ASM_FUNC(SetupExceptionLevel1) - mov x5, x30 // Save LR - - mov x0, #CPACR_CP_FULL_ACCESS - bl ASM_PFX(ArmWriteCpacr) // Disable copro traps to EL1 - - ret x5 - -// Setup EL2 while in EL2 -ASM_FUNC(SetupExceptionLevel2) - msr sctlr_el2, xzr - mrs x0, hcr_el2 // Read EL2 Hypervisor configuration Register - - // Send all interrupts to their respective Exception levels for EL2 - orr x0, x0, #(1 << 3) // Enable EL2 FIQ - orr x0, x0, #(1 << 4) // Enable EL2 IRQ - orr x0, x0, #(1 << 5) // Enable EL2 SError and Abort - msr hcr_el2, x0 // Write back our settings - - msr cptr_el2, xzr // Disable copro traps to EL2 - - // Enable Timer access for non-secure EL1 and EL0 - // The cnthctl_el2 register bits are architecturally - // UNKNOWN on reset. - // Disable event stream as it is not in use at this stage - mov x0, #(CNTHCTL_EL2_EL1PCTEN | CNTHCTL_EL2_EL1PCEN) - msr cnthctl_el2, x0 - - ret - -ASM_FUNCTION_REMOVE_IF_UNREFERENCED diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S b/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S deleted file mode 100644 index 1c1054304ad5..000000000000 --- a/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S +++ /dev/null @@ -1,61 +0,0 @@ -// -// Copyright (c) 2011-2014, ARM Limited. All rights reserved. -// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// -// - -#include - -ASM_FUNC(_ModuleEntryPoint) - // Do early platform specific actions - bl ASM_PFX(ArmPlatformPeiBootAction) - -// NOTE: We could be booting from EL3, EL2 or EL1. Need to correctly detect -// and configure the system accordingly. EL2 is default if possible. -// If we started in EL3 we need to switch and run at EL2. -// If we are running at EL2 stay in EL2 -// If we are starting at EL1 stay in EL1. - -// If started at EL3 Sec is run and switches to EL2 before jumping to PEI. -// If started at EL1 or EL2 Sec jumps directly to PEI without making any -// changes. - -// Which EL are we running at? Every EL needs some level of setup... -// We should not run this code in EL3 - EL1_OR_EL2(x0) -1:bl ASM_PFX(SetupExceptionLevel1) - b ASM_PFX(MainEntryPoint) -2:bl ASM_PFX(SetupExceptionLevel2) - b ASM_PFX(MainEntryPoint) - -ASM_PFX(MainEntryPoint): - // Get the top of the primary stacks (and the base of the secondary stacks) - MOV64 (x1, FixedPcdGet64(PcdCPUCoresStackBase) + FixedPcdGet32(PcdCPUCorePrimaryStackSize)) - - // Set up the stack pointer - mov sp, x1 - - // Apply the init value to the entire stack - MOV64 (x8, FixedPcdGet64 (PcdCPUCoresStackBase)) - MOV64 (x9, FixedPcdGet32 (PcdInitValueInTempStack) |\ - FixedPcdGet32 (PcdInitValueInTempStack) << 32) -0:stp x9, x9, [x8], #16 - cmp x8, x1 - b.lt 0b - - // The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector - MOV64 (x2, FixedPcdGet64(PcdFvBaseAddress)) - ldr x0, [x2, #8] - - // Move sec startup address into a data register - // Ensure we're jumping to FV version of the code (not boot remapped alias) - ldr x3, =ASM_PFX(CEntryPoint) - - // Set the frame pointer to NULL so any backtraces terminate here - mov x29, xzr - - // Jump to PrePeiCore C code - // x0 = pei_core_address - mov x0, x5 - blr x3 diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S b/ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S deleted file mode 100644 index 308b8764fc69..000000000000 --- a/ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S +++ /dev/null @@ -1,32 +0,0 @@ -#------------------------------------------------------------------------------ -# -# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
-# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
-# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#------------------------------------------------------------------------------ - -#include - -#/** -# This allows the caller to switch the stack and return -# -# @param StackDelta Signed amount by which to modify the stack pointer -# -# @return Nothing. Goes to the Entry Point passing in the new parameters -# -#**/ -#VOID -#EFIAPI -#SecSwitchStack ( -# VOID *StackDelta -# )# -# -ASM_FUNC(SecSwitchStack) - mov x1, sp - add x1, x0, x1 - mov sp, x1 - ret - diff --git a/ArmPlatformPkg/PrePeiCore/Arm/ArchPrePeiCore.c b/ArmPlatformPkg/PrePeiCore/Arm/ArchPrePeiCore.c deleted file mode 100644 index debf32880391..000000000000 --- a/ArmPlatformPkg/PrePeiCore/Arm/ArchPrePeiCore.c +++ /dev/null @@ -1,57 +0,0 @@ -/** @file - Main file supporting the transition to PEI Core in Normal World for Versatile Express - - Copyright (c) 2012, ARM Limited. All rights reserved. - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include - -#include "PrePeiCore.h" - -VOID -PeiCommonExceptionEntry ( - IN UINT32 Entry, - IN UINTN LR - ) -{ - CHAR8 Buffer[100]; - UINTN CharCount; - - switch (Entry) { - case 0: - CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Reset Exception at 0x%X\n\r", LR); - break; - case 1: - CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Undefined Exception at 0x%X\n\r", LR); - break; - case 2: - CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "SWI Exception at 0x%X\n\r", LR); - break; - case 3: - CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "PrefetchAbort Exception at 0x%X\n\r", LR); - break; - case 4: - CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "DataAbort Exception at 0x%X\n\r", LR); - break; - case 5: - CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Reserved Exception at 0x%X\n\r", LR); - break; - case 6: - CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "IRQ Exception at 0x%X\n\r", LR); - break; - case 7: - CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "FIQ Exception at 0x%X\n\r", LR); - break; - default: - CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Unknown Exception at 0x%X\n\r", LR); - break; - } - - SerialPortWrite ((UINT8 *)Buffer, CharCount); - while (1) { - } -} diff --git a/ArmPlatformPkg/PrePeiCore/Arm/Exception.S b/ArmPlatformPkg/PrePeiCore/Arm/Exception.S deleted file mode 100644 index 956ae8471459..000000000000 --- a/ArmPlatformPkg/PrePeiCore/Arm/Exception.S +++ /dev/null @@ -1,96 +0,0 @@ -// -// Copyright (c) 2011, ARM Limited. All rights reserved. -// -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -# - -#include -#include -#include - -#start of the code section -.text -.align 5 - -# IMPORT -GCC_ASM_IMPORT(PeiCommonExceptionEntry) - -# EXPORT -GCC_ASM_EXPORT(PeiVectorTable) - -//============================================================ -//Default Exception Handlers -//============================================================ - - -ASM_PFX(PeiVectorTable): - b _DefaultResetHandler - b _DefaultUndefined - b _DefaultSWI - b _DefaultPrefetchAbort - b _DefaultDataAbort - b _DefaultReserved - b _DefaultIrq - b _DefaultFiq - -// -// Default Exception handlers: There is no plan to return from any of these exceptions. -// No context saving at all. -// -_DefaultResetHandler: - mov r1, lr - # Switch to SVC for common stack - cps #0x13 - mov r0, #0 - blx ASM_PFX(PeiCommonExceptionEntry) - -_DefaultUndefined: - sub r1, LR, #4 - # Switch to SVC for common stack - cps #0x13 - mov r0, #1 - blx ASM_PFX(PeiCommonExceptionEntry) - -_DefaultSWI: - sub r1, LR, #4 - # Switch to SVC for common stack - cps #0x13 - mov r0, #2 - blx ASM_PFX(PeiCommonExceptionEntry) - -_DefaultPrefetchAbort: - sub r1, LR, #4 - # Switch to SVC for common stack - cps #0x13 - mov r0, #3 - blx ASM_PFX(PeiCommonExceptionEntry) - -_DefaultDataAbort: - sub r1, LR, #8 - # Switch to SVC for common stack - cps #0x13 - mov r0, #4 - blx ASM_PFX(PeiCommonExceptionEntry) - -_DefaultReserved: - mov r1, lr - # Switch to SVC for common stack - cps #0x13 - mov r0, #5 - blx ASM_PFX(PeiCommonExceptionEntry) - -_DefaultIrq: - sub r1, LR, #4 - # Switch to SVC for common stack - cps #0x13 - mov r0, #6 - blx ASM_PFX(PeiCommonExceptionEntry) - -_DefaultFiq: - sub r1, LR, #4 - # Switch to SVC for common stack - cps #0x13 - mov r0, #7 - blx ASM_PFX(PeiCommonExceptionEntry) - diff --git a/ArmPlatformPkg/PrePeiCore/Arm/PrePeiCoreEntryPoint.S b/ArmPlatformPkg/PrePeiCore/Arm/PrePeiCoreEntryPoint.S deleted file mode 100644 index b3c67234e9c9..000000000000 --- a/ArmPlatformPkg/PrePeiCore/Arm/PrePeiCoreEntryPoint.S +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (c) 2011-2013, ARM Limited. All rights reserved. -// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// -// - -#include - -ASM_FUNC(_ModuleEntryPoint) - // Do early platform specific actions - bl ASM_PFX(ArmPlatformPeiBootAction) - - // Get the top of the primary stacks (and the base of the secondary stacks) - MOV32 (r1, FixedPcdGet64(PcdCPUCoresStackBase) + FixedPcdGet32(PcdCPUCorePrimaryStackSize)) - - // Set up the stack pointer - mov sp, r1 - - // Apply the init value to the entire stack - MOV32 (r8, FixedPcdGet64 (PcdCPUCoresStackBase)) - MOV32 (r9, FixedPcdGet32 (PcdInitValueInTempStack)) - mov r10, r9 - mov r11, r9 - mov r12, r9 -0:stm r8!, {r9-r12} - cmp r8, r1 - blt 0b - - // The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector - MOV32 (r2, FixedPcdGet32(PcdFvBaseAddress)) - ldr r0, [r2, #4] - - // Move sec startup address into a data register - // Ensure we're jumping to FV version of the code (not boot remapped alias) - ldr r3, =ASM_PFX(CEntryPoint) - - // Jump to PrePeiCore C code - // r0 = pei_core_address - blx r3 diff --git a/ArmPlatformPkg/PrePeiCore/Arm/SwitchStack.S b/ArmPlatformPkg/PrePeiCore/Arm/SwitchStack.S deleted file mode 100644 index d64772b8edbf..000000000000 --- a/ArmPlatformPkg/PrePeiCore/Arm/SwitchStack.S +++ /dev/null @@ -1,32 +0,0 @@ -#------------------------------------------------------------------------------ -# -# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
-# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
-# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#------------------------------------------------------------------------------ - -#include - -#/** -# This allows the caller to switch the stack and return -# -# @param StackDelta Signed amount by which to modify the stack pointer -# -# @return Nothing. Goes to the Entry Point passing in the new parameters -# -#**/ -#VOID -#EFIAPI -#SecSwitchStack ( -# VOID *StackDelta -# )# -# -ASM_FUNC(SecSwitchStack) - mov R1, R13 - add R1, R0, R1 - mov R13, R1 - bx LR - - - diff --git a/ArmPlatformPkg/PrePeiCore/MainUniCore.c b/ArmPlatformPkg/PrePeiCore/MainUniCore.c deleted file mode 100644 index 3d3c6caaa32a..000000000000 --- a/ArmPlatformPkg/PrePeiCore/MainUniCore.c +++ /dev/null @@ -1,48 +0,0 @@ -/** @file - - Copyright (c) 2011-2012, ARM Limited. All rights reserved. - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "PrePeiCore.h" - -VOID -EFIAPI -PrimaryMain ( - IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint - ) -{ - EFI_SEC_PEI_HAND_OFF SecCoreData; - UINTN PpiListSize; - EFI_PEI_PPI_DESCRIPTOR *PpiList; - UINTN TemporaryRamBase; - UINTN TemporaryRamSize; - - CreatePpiList (&PpiListSize, &PpiList); - - // Adjust the Temporary Ram as the new Ppi List (Common + Platform Ppi Lists) is created at - // the base of the primary core stack - PpiListSize = ALIGN_VALUE (PpiListSize, CPU_STACK_ALIGNMENT); - TemporaryRamBase = (UINTN)PcdGet64 (PcdCPUCoresStackBase) + PpiListSize; - TemporaryRamSize = (UINTN)PcdGet32 (PcdCPUCorePrimaryStackSize) - PpiListSize; - - // - // Bind this information into the SEC hand-off state - // Note: this must be in sync with the stuff in the asm file - // Note also: HOBs (pei temp ram) MUST be above stack - // - SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF); - SecCoreData.BootFirmwareVolumeBase = (VOID *)(UINTN)PcdGet64 (PcdFvBaseAddress); - SecCoreData.BootFirmwareVolumeSize = PcdGet32 (PcdFvSize); - SecCoreData.TemporaryRamBase = (VOID *)TemporaryRamBase; // We run on the primary core (and so we use the first stack) - SecCoreData.TemporaryRamSize = TemporaryRamSize; - SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase; - SecCoreData.PeiTemporaryRamSize = ALIGN_VALUE (SecCoreData.TemporaryRamSize / 2, CPU_STACK_ALIGNMENT); - SecCoreData.StackBase = (VOID *)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize); - SecCoreData.StackSize = (TemporaryRamBase + TemporaryRamSize) - (UINTN)SecCoreData.StackBase; - - // Jump to PEI core entry point - (PeiCoreEntryPoint)(&SecCoreData, PpiList); -} diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c deleted file mode 100644 index 5911c3a08a23..000000000000 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c +++ /dev/null @@ -1,179 +0,0 @@ -/** @file - Main file supporting the transition to PEI Core in Normal World for Versatile Express - - Copyright (c) 2011 - 2022, ARM Limited. All rights reserved. - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include -#include -#include -#include -#include - -#include "PrePeiCore.h" - -CONST EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = { PrePeiCoreTemporaryRamSupport }; - -CONST EFI_PEI_PPI_DESCRIPTOR gCommonPpiTable[] = { - { - EFI_PEI_PPI_DESCRIPTOR_PPI, - &gEfiTemporaryRamSupportPpiGuid, - (VOID *)&mTemporaryRamSupportPpi - } -}; - -VOID -CreatePpiList ( - OUT UINTN *PpiListSize, - OUT EFI_PEI_PPI_DESCRIPTOR **PpiList - ) -{ - EFI_PEI_PPI_DESCRIPTOR *PlatformPpiList; - UINTN PlatformPpiListSize; - UINTN ListBase; - EFI_PEI_PPI_DESCRIPTOR *LastPpi; - - // Get the Platform PPIs - PlatformPpiListSize = 0; - ArmPlatformGetPlatformPpiList (&PlatformPpiListSize, &PlatformPpiList); - - // Copy the Common and Platform PPis in Temporary Memory - ListBase = PcdGet64 (PcdCPUCoresStackBase); - CopyMem ((VOID *)ListBase, gCommonPpiTable, sizeof (gCommonPpiTable)); - CopyMem ((VOID *)(ListBase + sizeof (gCommonPpiTable)), PlatformPpiList, PlatformPpiListSize); - - // Set the Terminate flag on the last PPI entry - LastPpi = (EFI_PEI_PPI_DESCRIPTOR *)ListBase + ((sizeof (gCommonPpiTable) + PlatformPpiListSize) / sizeof (EFI_PEI_PPI_DESCRIPTOR)) - 1; - LastPpi->Flags |= EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; - - *PpiList = (EFI_PEI_PPI_DESCRIPTOR *)ListBase; - *PpiListSize = sizeof (gCommonPpiTable) + PlatformPpiListSize; -} - -/** - - Prints firmware version and build time to serial console. - -**/ -STATIC -VOID -PrintFirmwareVersion ( - VOID - ) -{ - CHAR8 Buffer[100]; - UINTN CharCount; - - CharCount = AsciiSPrint ( - Buffer, - sizeof (Buffer), - "UEFI firmware (version %s built at %a on %a)\n\r", - (CHAR16 *)PcdGetPtr (PcdFirmwareVersionString), - __TIME__, - __DATE__ - ); - - // Because we are directly bit banging the serial port instead of going through the DebugLib, we need to make sure - // the serial port is initialized before we write to it - SerialPortInitialize (); - SerialPortWrite ((UINT8 *)Buffer, CharCount); -} - -VOID -CEntryPoint ( - IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint - ) -{ - if (!ArmMmuEnabled ()) { - // Data Cache enabled on Primary core when MMU is enabled. - ArmDisableDataCache (); - // Invalidate instruction cache - ArmInvalidateInstructionCache (); - // Enable Instruction Caches on all cores. - ArmEnableInstructionCache (); - - InvalidateDataCacheRange ( - (VOID *)(UINTN)PcdGet64 (PcdCPUCoresStackBase), - PcdGet32 (PcdCPUCorePrimaryStackSize) - ); - } - - // - // Note: Doesn't have to Enable CPU interface in non-secure world, - // as Non-secure interface is already enabled in Secure world. - // - - // Write VBAR - The Exception Vector table must be aligned to its requirement - // Note: The AArch64 Vector table must be 2k-byte aligned - if this assertion fails ensure - // 'Align=4K' is defined into your FDF for this module. - ASSERT (((UINTN)PeiVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0); - ArmWriteVBar ((UINTN)PeiVectorTable); - - // Enable Floating Point - if (FixedPcdGet32 (PcdVFPEnabled)) { - ArmEnableVFP (); - } - - // Note: The MMU will be enabled by MemoryPeim. Only the primary core will have the MMU on. - - // Invoke "ProcessLibraryConstructorList" to have all library constructors - // called. - ProcessLibraryConstructorList (); - - PrintFirmwareVersion (); - - // Initialize the Debug Agent for Source Level Debugging - InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL); - SaveAndSetDebugTimerInterrupt (TRUE); - - // Initialize the platform specific controllers - ArmPlatformInitialize (ArmReadMpidr ()); - - // Goto primary Main. - PrimaryMain (PeiCoreEntryPoint); - - // PEI Core should always load and never return - ASSERT (FALSE); -} - -EFI_STATUS -EFIAPI -PrePeiCoreTemporaryRamSupport ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, - IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, - IN UINTN CopySize - ) -{ - VOID *OldHeap; - VOID *NewHeap; - VOID *OldStack; - VOID *NewStack; - UINTN HeapSize; - - HeapSize = ALIGN_VALUE (CopySize / 2, CPU_STACK_ALIGNMENT); - - OldHeap = (VOID *)(UINTN)TemporaryMemoryBase; - NewHeap = (VOID *)((UINTN)PermanentMemoryBase + (CopySize - HeapSize)); - - OldStack = (VOID *)((UINTN)TemporaryMemoryBase + HeapSize); - NewStack = (VOID *)(UINTN)PermanentMemoryBase; - - // - // Migrate the temporary memory stack to permanent memory stack. - // - CopyMem (NewStack, OldStack, CopySize - HeapSize); - - // - // Migrate the temporary memory heap to permanent memory heap. - // - CopyMem (NewHeap, OldHeap, HeapSize); - - SecSwitchStack ((UINTN)NewStack - (UINTN)OldStack); - - return EFI_SUCCESS; -} diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.h b/ArmPlatformPkg/PrePeiCore/PrePeiCore.h deleted file mode 100644 index 966b0e7eee5e..000000000000 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCore.h +++ /dev/null @@ -1,61 +0,0 @@ -/** @file - Main file supporting the transition to PEI Core in Normal World for Versatile Express - - Copyright (c) 2011 - 2022, ARM Limited. All rights reserved. - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __PREPEICORE_H_ -#define __PREPEICORE_H_ - -#include -#include -#include -#include -#include -#include - -#include -#include - -VOID -CreatePpiList ( - OUT UINTN *PpiListSize, - OUT EFI_PEI_PPI_DESCRIPTOR **PpiList - ); - -EFI_STATUS -EFIAPI -PrePeiCoreTemporaryRamSupport ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, - IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, - IN UINTN CopySize - ); - -VOID -SecSwitchStack ( - INTN StackDelta - ); - -// Vector Table for Pei Phase -VOID -PeiVectorTable ( - VOID - ); - -VOID -EFIAPI -PrimaryMain ( - IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint - ); - -VOID -PeiCommonExceptionEntry ( - IN UINT32 Entry, - IN UINTN LR - ); - -#endif diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf deleted file mode 100644 index 772bd14db074..000000000000 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf +++ /dev/null @@ -1,66 +0,0 @@ -#/** @file -# Pre PeiCore - Hand-off to PEI Core in Normal World -# -# Copyright (c) 2011, ARM Limited. All rights reserved. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#**/ - -[Defines] - INF_VERSION = 1.30 - BASE_NAME = ArmPlatformPrePeiCore - FILE_GUID = 469fc080-aec1-11df-927c-0002a5d5c51b - MODULE_TYPE = SEC - VERSION_STRING = 1.0 - -[Sources.common] - PrePeiCore.h - PrePeiCore.c - MainUniCore.c - -[Sources.ARM] - Arm/ArchPrePeiCore.c - Arm/PrePeiCoreEntryPoint.S | GCC - Arm/SwitchStack.S | GCC - Arm/Exception.S | GCC - -[Sources.AARCH64] - AArch64/ArchPrePeiCore.c - AArch64/PrePeiCoreEntryPoint.S - AArch64/SwitchStack.S - AArch64/Exception.S - AArch64/Helper.S - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - ArmPkg/ArmPkg.dec - ArmPlatformPkg/ArmPlatformPkg.dec - -[LibraryClasses] - ArmLib - ArmPlatformLib - CacheMaintenanceLib - BaseLib - DebugLib - DebugAgentLib - IoLib - PrintLib - SerialPortLib - -[Ppis] - gEfiTemporaryRamSupportPpiGuid - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString - -[FixedPcd] - gArmTokenSpaceGuid.PcdFvBaseAddress - gArmTokenSpaceGuid.PcdFvSize - gArmTokenSpaceGuid.PcdVFPEnabled - - gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase - gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize - - gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack From 5749b70b5a892e1cf0f2bfa37865a552ba8f96e5 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 1 Aug 2024 09:40:02 +0200 Subject: [PATCH 114/280] ArmPlatformPkg: Retire PrePi Retire the PrePi SEC driver, which has been replaced by PeilessSec.inf Signed-off-by: Ard Biesheuvel --- ArmPlatformPkg/ArmPlatformPkg.dsc | 3 - ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c | 34 --- .../PrePi/AArch64/ModuleEntryPoint.S | 96 -------- ArmPlatformPkg/PrePi/Arm/ArchPrePi.c | 22 -- ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S | 103 --------- ArmPlatformPkg/PrePi/PeiUniCore.inf | 99 -------- ArmPlatformPkg/PrePi/PrePi.c | 214 ------------------ ArmPlatformPkg/PrePi/PrePi.h | 51 ----- 8 files changed, 622 deletions(-) delete mode 100644 ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c delete mode 100644 ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S delete mode 100644 ArmPlatformPkg/PrePi/Arm/ArchPrePi.c delete mode 100644 ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S delete mode 100644 ArmPlatformPkg/PrePi/PeiUniCore.inf delete mode 100644 ArmPlatformPkg/PrePi/PrePi.c delete mode 100644 ArmPlatformPkg/PrePi/PrePi.h diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc index d7c29054cfa9..919e4cf80a3a 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg.dsc @@ -51,7 +51,6 @@ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf LcdHwLib|ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.inf LcdPlatformLib|ArmPlatformPkg/Library/LcdPlatformNullLib/LcdPlatformNullLib.inf - LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf @@ -119,8 +118,6 @@ ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf ArmPlatformPkg/Sec/Sec.inf - - ArmPlatformPkg/PrePi/PeiUniCore.inf ArmPlatformPkg/PeilessSec/PeilessSec.inf ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.inf diff --git a/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c b/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c deleted file mode 100644 index 27a85049fa78..000000000000 --- a/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c +++ /dev/null @@ -1,34 +0,0 @@ -/** @file - - Copyright (c) 2011-2017, ARM Limited. All rights reserved. - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "PrePi.h" - -#include - -VOID -ArchInitialize ( - VOID - ) -{ - // Enable Floating Point - if (FixedPcdGet32 (PcdVFPEnabled)) { - ArmEnableVFP (); - } - - if (ArmReadCurrentEL () == AARCH64_EL2) { - // Trap General Exceptions. All exceptions that would be routed to EL1 are routed to EL2 - ArmWriteHcr (ARM_HCR_TGE); - - /* Enable Timer access for non-secure EL1 and EL0 - The cnthctl_el2 register bits are architecturally - UNKNOWN on reset. - Disable event stream as it is not in use at this stage - */ - ArmWriteCntHctl (CNTHCTL_EL2_EL1PCTEN | CNTHCTL_EL2_EL1PCEN); - } -} diff --git a/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S deleted file mode 100644 index c45fc5f4009e..000000000000 --- a/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S +++ /dev/null @@ -1,96 +0,0 @@ -// -// Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.
-// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// -// - -#include - -ASM_FUNC(_ModuleEntryPoint) - // Do early platform specific actions - bl ASM_PFX(ArmPlatformPeiBootAction) - -_SetSVCMode: -// Check if we can install the stack at the top of the System Memory or if we need -// to install the stacks at the bottom of the Firmware Device (case the FD is located -// at the top of the DRAM) -_SystemMemoryEndInit: - ldr x1, mSystemMemoryEnd - -_SetupStackPosition: - // r1 = SystemMemoryTop - - // Calculate Top of the Firmware Device - MOV64 (x2, FixedPcdGet64(PcdFdBaseAddress)) - MOV32 (x3, FixedPcdGet32(PcdFdSize) - 1) - sub x3, x3, #1 - add x3, x3, x2 // x3 = FdTop = PcdFdBaseAddress + PcdFdSize - - // UEFI Memory Size (stacks are allocated in this region) - MOV32 (x4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize)) - - // - // Reserve the memory for the UEFI region (contain stacks on its top) - // - - // Calculate how much space there is between the top of the Firmware and the Top of the System Memory - subs x0, x1, x3 // x0 = SystemMemoryTop - FdTop - b.mi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM - cmp x0, x4 - b.ge _SetupStack - - // Case the top of stacks is the FdBaseAddress - mov x1, x2 - -_SetupStack: - // x1 contains the top of the stack (and the UEFI Memory) - - // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment - // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the - // top of the memory space) - adds x11, x1, #1 - b.cs _SetupOverflowStack - -_SetupAlignedStack: - mov x1, x11 - b _GetBaseUefiMemory - -_SetupOverflowStack: - // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE - // aligned (4KB) - and x1, x1, ~EFI_PAGE_MASK - -_GetBaseUefiMemory: - // Calculate the Base of the UEFI Memory - sub x11, x1, x4 - -_GetStackBase: - // r1 = The top of the stack - mov sp, x1 - - // Stack for the primary core = PrimaryCoreStack - MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)) - sub x12, x1, x2 - - // Get ID of this CPU in multi-core system - bl ASM_PFX(ArmReadMpidr) - - mov x1, x11 - mov x2, x12 - - // Move sec startup address into a data register - // Ensure we're jumping to FV version of the code (not boot remapped alias) - ldr x4, =ASM_PFX(CEntryPoint) - - // Set the frame pointer to NULL so any backtraces terminate here - mov x29, xzr - - // Jump to PrePiCore C code - // x0 = MpId - // x1 = UefiMemoryBase - // x2 = StacksBase - blr x4 - -_NeverReturn: - b _NeverReturn diff --git a/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c b/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c deleted file mode 100644 index ac8abe5ff555..000000000000 --- a/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c +++ /dev/null @@ -1,22 +0,0 @@ -/** @file - - Copyright (c) 2011 - 2013, ARM Limited. All rights reserved. - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "PrePi.h" - -VOID -ArchInitialize ( - VOID - ) -{ - // Enable program flow prediction, if supported. - ArmEnableBranchPrediction (); - - if (FixedPcdGet32 (PcdVFPEnabled)) { - ArmEnableVFP (); - } -} diff --git a/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S b/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S deleted file mode 100644 index c87f94689c75..000000000000 --- a/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S +++ /dev/null @@ -1,103 +0,0 @@ -// -// Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.
-// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// -// - -#include - -#include - -ASM_FUNC(_ModuleEntryPoint) - // Do early platform specific actions - bl ASM_PFX(ArmPlatformPeiBootAction) - -_SetSVCMode: - // Enter SVC mode, Disable FIQ and IRQ - mov r1, #(CPSR_MODE_SVC | CPSR_IRQ | CPSR_FIQ) - msr CPSR_c, r1 - -// Check if we can install the stack at the top of the System Memory or if we need -// to install the stacks at the bottom of the Firmware Device (case the FD is located -// at the top of the DRAM) -_SystemMemoryEndInit: - ADRL (r1, mSystemMemoryEnd) - ldrd r2, r3, [r1] - teq r3, #0 - moveq r1, r2 - mvnne r1, #0 - -_SetupStackPosition: - // r1 = SystemMemoryTop - - // Calculate Top of the Firmware Device - MOV32 (r2, FixedPcdGet32(PcdFdBaseAddress)) - MOV32 (r3, FixedPcdGet32(PcdFdSize) - 1) - add r3, r3, r2 // r3 = FdTop = PcdFdBaseAddress + PcdFdSize - - // UEFI Memory Size (stacks are allocated in this region) - MOV32 (r4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize)) - - // - // Reserve the memory for the UEFI region (contain stacks on its top) - // - - // Calculate how much space there is between the top of the Firmware and the Top of the System Memory - subs r0, r1, r3 // r0 = SystemMemoryTop - FdTop - bmi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM - cmp r0, r4 - bge _SetupStack - - // Case the top of stacks is the FdBaseAddress - mov r1, r2 - -_SetupStack: - // r1 contains the top of the stack (and the UEFI Memory) - - // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment - // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the - // top of the memory space) - adds r9, r1, #1 - bcs _SetupOverflowStack - -_SetupAlignedStack: - mov r1, r9 - b _GetBaseUefiMemory - -_SetupOverflowStack: - // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE - // aligned (4KB) - MOV32 (r9, ~EFI_PAGE_MASK & 0xFFFFFFFF) - and r1, r1, r9 - -_GetBaseUefiMemory: - // Calculate the Base of the UEFI Memory - sub r9, r1, r4 - -_GetStackBase: - // r1 = The top of the stack - mov sp, r1 - - // Stack for the primary core = PrimaryCoreStack - MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)) - sub r10, r1, r2 - - // Get ID of this CPU in multi-core system - bl ASM_PFX(ArmReadMpidr) - - mov r1, r9 - mov r2, r10 - - // Move sec startup address into a data register - // Ensure we're jumping to FV version of the code (not boot remapped alias) - ldr r4, =ASM_PFX(CEntryPoint) - - // Jump to PrePiCore C code - // r0 = MpId - // r1 = UefiMemoryBase - // r2 = StacksBase - blx r4 - -_NeverReturn: - b _NeverReturn diff --git a/ArmPlatformPkg/PrePi/PeiUniCore.inf b/ArmPlatformPkg/PrePi/PeiUniCore.inf deleted file mode 100644 index 9aa97d0a307e..000000000000 --- a/ArmPlatformPkg/PrePi/PeiUniCore.inf +++ /dev/null @@ -1,99 +0,0 @@ -#/** @file -# -# (C) Copyright 2015 Hewlett-Packard Development Company, L.P.
-# Copyright (c) 2011-2017, ARM Ltd. All rights reserved.
-# Copyright (c) 2020, Arm Limited. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#**/ - -[Defines] - INF_VERSION = 1.30 - BASE_NAME = ArmPlatformPrePiUniCore - FILE_GUID = 3e401783-cc94-4fcd-97bc-bd35ac369d2f - MODULE_TYPE = SEC - VERSION_STRING = 1.0 - -[Sources] - PrePi.h - PrePi.c - -[Sources.ARM] - Arm/ArchPrePi.c - Arm/ModuleEntryPoint.S | GCC - -[Sources.AArch64] - AArch64/ArchPrePi.c - AArch64/ModuleEntryPoint.S - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - ArmPkg/ArmPkg.dec - ArmPlatformPkg/ArmPlatformPkg.dec - -[LibraryClasses] - BaseLib - CacheMaintenanceLib - DebugLib - DebugAgentLib - ArmLib - IoLib - TimerLib - SerialPortLib - ExtractGuidedSectionLib - LzmaDecompressLib - DebugAgentLib - PrePiLib - ArmPlatformLib - MemoryAllocationLib - HobLib - PrePiHobListPointerLib - PlatformPeiLib - MemoryInitPeiLib - -[Ppis] - gArmMpCoreInfoPpiGuid - -[Guids] - gArmMpCoreInfoGuid - gEfiFirmwarePerformanceGuid - -[FeaturePcd] - gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString - -[FixedPcd] - gArmTokenSpaceGuid.PcdVFPEnabled - - gArmTokenSpaceGuid.PcdFdBaseAddress - gArmTokenSpaceGuid.PcdFdSize - - gArmTokenSpaceGuid.PcdFvBaseAddress - gArmTokenSpaceGuid.PcdFvSize - - gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize - - gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize - - gArmPlatformTokenSpaceGuid.PcdCoreCount - - gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize - - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData - -[Pcd] - gArmTokenSpaceGuid.PcdSystemMemoryBase - gArmTokenSpaceGuid.PcdSystemMemorySize diff --git a/ArmPlatformPkg/PrePi/PrePi.c b/ArmPlatformPkg/PrePi/PrePi.c deleted file mode 100644 index f98a0e56c15f..000000000000 --- a/ArmPlatformPkg/PrePi/PrePi.c +++ /dev/null @@ -1,214 +0,0 @@ -/** @file - - Copyright (c) 2011-2017, ARM Limited. All rights reserved. - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "PrePi.h" - -#define IS_XIP() (((UINT64)FixedPcdGet64 (PcdFdBaseAddress) > mSystemMemoryEnd) ||\ - ((FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= FixedPcdGet64 (PcdSystemMemoryBase))) - -UINT64 mSystemMemoryEnd = FixedPcdGet64 (PcdSystemMemoryBase) + - FixedPcdGet64 (PcdSystemMemorySize) - 1; - -/** - Obtain a PPI from the list of PPIs provided by the platform code. - - @param[in] PpiGuid GUID of the PPI to obtain - @param[out] Ppi Address of GUID pointer to return the PPI - - @return Whether the PPI was obtained successfully -**/ -STATIC -EFI_STATUS -GetPlatformPpi ( - IN EFI_GUID *PpiGuid, - OUT VOID **Ppi - ) -{ - UINTN PpiListSize; - UINTN PpiListCount; - EFI_PEI_PPI_DESCRIPTOR *PpiList; - UINTN Index; - - PpiListSize = 0; - ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList); - PpiListCount = PpiListSize / sizeof (EFI_PEI_PPI_DESCRIPTOR); - for (Index = 0; Index < PpiListCount; Index++, PpiList++) { - if (CompareGuid (PpiList->Guid, PpiGuid) == TRUE) { - *Ppi = PpiList->Ppi; - return EFI_SUCCESS; - } - } - - return EFI_NOT_FOUND; -} - -/** - SEC main routine. - - @param[in] UefiMemoryBase Start of the PI/UEFI memory region - @param[in] StacksBase Start of the stack - @param[in] StartTimeStamp Timer value at start of execution -**/ -STATIC -VOID -PrePiMain ( - IN UINTN UefiMemoryBase, - IN UINTN StacksBase, - IN UINT64 StartTimeStamp - ) -{ - EFI_HOB_HANDOFF_INFO_TABLE *HobList; - ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi; - UINTN ArmCoreCount; - ARM_CORE_INFO *ArmCoreInfoTable; - EFI_STATUS Status; - CHAR8 Buffer[100]; - UINTN CharCount; - UINTN StacksSize; - FIRMWARE_SEC_PERFORMANCE Performance; - - // If ensure the FD is either part of the System Memory or totally outside of the System Memory (XIP) - ASSERT ( - IS_XIP () || - ((FixedPcdGet64 (PcdFdBaseAddress) >= FixedPcdGet64 (PcdSystemMemoryBase)) && - ((UINT64)(FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= (UINT64)mSystemMemoryEnd)) - ); - - // Initialize the architecture specific bits - ArchInitialize (); - - // Initialize the Serial Port - SerialPortInitialize (); - CharCount = AsciiSPrint ( - Buffer, - sizeof (Buffer), - "UEFI firmware (version %s built at %a on %a)\n\r", - (CHAR16 *)PcdGetPtr (PcdFirmwareVersionString), - __TIME__, - __DATE__ - ); - SerialPortWrite ((UINT8 *)Buffer, CharCount); - - // Initialize the Debug Agent for Source Level Debugging - InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL); - SaveAndSetDebugTimerInterrupt (TRUE); - - // Declare the PI/UEFI memory region - HobList = HobConstructor ( - (VOID *)UefiMemoryBase, - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize), - (VOID *)UefiMemoryBase, - (VOID *)StacksBase // The top of the UEFI Memory is reserved for the stacks - ); - PrePeiSetHobList (HobList); - - // Initialize MMU and Memory HOBs (Resource Descriptor HOBs) - Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)); - ASSERT_EFI_ERROR (Status); - - // Create the Stacks HOB - StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize); - BuildStackHob (StacksBase, StacksSize); - - // TODO: Call CpuPei as a library - BuildCpuHob (ArmGetPhysicalAddressBits (), PcdGet8 (PcdPrePiCpuIoSize)); - - if (ArmIsMpCore ()) { - // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid - Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID **)&ArmMpCoreInfoPpi); - - // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid) - ASSERT_EFI_ERROR (Status); - - // Build the MP Core Info Table - ArmCoreCount = 0; - Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable); - if (!EFI_ERROR (Status) && (ArmCoreCount > 0)) { - // Build MPCore Info HOB - BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount); - } - } - - // Store timer value logged at the beginning of firmware image execution - Performance.ResetEnd = GetTimeInNanoSecond (StartTimeStamp); - - // Build SEC Performance Data Hob - BuildGuidDataHob (&gEfiFirmwarePerformanceGuid, &Performance, sizeof (Performance)); - - // Set the Boot Mode - SetBootMode (ArmPlatformGetBootMode ()); - - // Initialize Platform HOBs (CpuHob and FvHob) - Status = PlatformPeim (); - ASSERT_EFI_ERROR (Status); - - // Now, the HOB List has been initialized, we can register performance information - PERF_START (NULL, "PEI", NULL, StartTimeStamp); - - // SEC phase needs to run library constructors by hand. - ProcessLibraryConstructorList (); - - // Assume the FV that contains the SEC (our code) also contains a compressed FV. - Status = DecompressFirstFv (); - ASSERT_EFI_ERROR (Status); - - // Load the DXE Core and transfer control to it - Status = LoadDxeCoreFromFv (NULL, 0); - ASSERT_EFI_ERROR (Status); -} - -VOID -CEntryPoint ( - IN UINTN MpId, - IN UINTN UefiMemoryBase, - IN UINTN StacksBase - ) -{ - UINT64 StartTimeStamp; - - // Initialize the platform specific controllers - ArmPlatformInitialize (MpId); - - if (PerformanceMeasurementEnabled ()) { - // We cannot call yet the PerformanceLib because the HOB List has not been initialized - StartTimeStamp = GetPerformanceCounter (); - } else { - StartTimeStamp = 0; - } - - // Data Cache enabled on Primary core when MMU is enabled. - ArmDisableDataCache (); - // Invalidate instruction cache - ArmInvalidateInstructionCache (); - // Enable Instruction Caches on all cores. - ArmEnableInstructionCache (); - - InvalidateDataCacheRange ( - (VOID *)UefiMemoryBase, - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) - ); - - PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp); - - // DXE Core should always load and never return - ASSERT (FALSE); -} diff --git a/ArmPlatformPkg/PrePi/PrePi.h b/ArmPlatformPkg/PrePi/PrePi.h deleted file mode 100644 index 9d3e7feaa0c5..000000000000 --- a/ArmPlatformPkg/PrePi/PrePi.h +++ /dev/null @@ -1,51 +0,0 @@ -/** @file - - Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _PREPI_H_ -#define _PREPI_H_ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern UINT64 mSystemMemoryEnd; - -EFI_STATUS -EFIAPI -MemoryPeim ( - IN EFI_PHYSICAL_ADDRESS UefiMemoryBase, - IN UINT64 UefiMemorySize - ); - -EFI_STATUS -EFIAPI -PlatformPeim ( - VOID - ); - -// Either implemented by PrePiLib or by MemoryInitPei -VOID -BuildMemoryTypeInformationHob ( - VOID - ); - -// Initialize the Architecture specific controllers -VOID -ArchInitialize ( - VOID - ); - -#endif /* _PREPI_H_ */ From 5c566abb126a4ab0e462ef9d0667e4617a8f8a44 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 1 Aug 2024 13:15:17 +0200 Subject: [PATCH 115/280] ArmVirtPkg/ArmPlatformLib: Drop unused MPCore routines Some of the boilerplate in ArmPlatformLib is only relevant when entering UEFI on multiple cores, and this is no longer supported. So retire the associated helper routines. Signed-off-by: Ard Biesheuvel --- .../AArch64/ArmPlatformHelper.S | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S b/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S index 5ac7c732f6ec..bdb460c7ee7b 100644 --- a/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S +++ b/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S @@ -101,28 +101,3 @@ ASM_FUNC(ArmPlatformPeiBootAction) isb 0:b ArmEnableVFP // enable SIMD before entering C code - -//UINTN -//ArmPlatformGetCorePosition ( -// IN UINTN MpId -// ); -// With this function: CorePos = (ClusterId * 4) + CoreId -ASM_FUNC(ArmPlatformGetCorePosition) - mov x0, xzr - ret - -//UINTN -//ArmPlatformGetPrimaryCoreMpId ( -// VOID -// ); -ASM_FUNC(ArmPlatformGetPrimaryCoreMpId) - MOV32 (w0, FixedPcdGet32 (PcdArmPrimaryCore)) - ret - -//UINTN -//ArmPlatformIsPrimaryCore ( -// IN UINTN MpId -// ); -ASM_FUNC(ArmPlatformIsPrimaryCore) - mov x0, #1 - ret From 0a6d41ba0a080ff40620ff304fa9c99bb2874570 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 1 Aug 2024 12:22:44 +0200 Subject: [PATCH 116/280] ArmPlatformPkg/ArmPlatformLib: Drop unused MPCore routines Some of the boilerplate in ArmPlatformLib is only relevant when entering UEFI on multiple cores, and this is no longer supported. So retire the associated helper routines. Signed-off-by: Ard Biesheuvel --- .../Include/Library/ArmPlatformLib.h | 43 ------------------- .../AArch64/ArmPlatformHelper.S | 33 -------------- .../Arm/ArmPlatformHelper.S | 31 ------------- .../ArmPlatformLibNull/ArmPlatformLibNull.c | 4 -- 4 files changed, 111 deletions(-) diff --git a/ArmPlatformPkg/Include/Library/ArmPlatformLib.h b/ArmPlatformPkg/Include/Library/ArmPlatformLib.h index cd87743eba52..38e7bdaf5896 100644 --- a/ArmPlatformPkg/Include/Library/ArmPlatformLib.h +++ b/ArmPlatformPkg/Include/Library/ArmPlatformLib.h @@ -21,49 +21,6 @@ #include -/** - Return the core position from the value of its MpId register - - This function returns the core position from the position 0 in the processor. - This function might be called from assembler before any stack is set. - - @return Return the core position - -**/ -UINTN -ArmPlatformGetCorePosition ( - IN UINTN MpId - ); - -/** - Return a non-zero value if the callee is the primary core - - This function returns a non-zero value if the callee is the primary core. - The primary core is the core responsible to initialize the hardware and run UEFI. - This function might be called from assembler before any stack is set. - - @return Return a non-zero value if the callee is the primary core. - -**/ -UINTN -ArmPlatformIsPrimaryCore ( - IN UINTN MpId - ); - -/** - Return the MpId of the primary core - - This function returns the MpId of the primary core. - This function might be called from assembler before any stack is set. - - @return Return the MpId of the primary core - -**/ -UINTN -ArmPlatformGetPrimaryCoreMpId ( - VOID - ); - /** Return the current Boot Mode diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S b/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S index b7c6dbdc2e61..1eeb7fed6f19 100644 --- a/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S +++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S @@ -10,36 +10,3 @@ ASM_FUNC(ArmPlatformPeiBootAction) ret - -//UINTN -//ArmPlatformGetCorePosition ( -// IN UINTN MpId -// ); -// With this function: CorePos = (ClusterId * 4) + CoreId -ASM_FUNC(ArmPlatformGetCorePosition) - and x1, x0, #ARM_CORE_MASK - and x0, x0, #ARM_CLUSTER_MASK - add x0, x1, x0, LSR #6 - ret - -//UINTN -//ArmPlatformGetPrimaryCoreMpId ( -// VOID -// ); -ASM_FUNC(ArmPlatformGetPrimaryCoreMpId) - MOV32 (w0, FixedPcdGet32 (PcdArmPrimaryCore)) - ret - -//UINTN -//ArmPlatformIsPrimaryCore ( -// IN UINTN MpId -// ); -ASM_FUNC(ArmPlatformIsPrimaryCore) - MOV32 (w1, FixedPcdGet32 (PcdArmPrimaryCoreMask)) - and x0, x0, x1 - MOV32 (w1, FixedPcdGet32 (PcdArmPrimaryCore)) - cmp w0, w1 - mov x0, #1 - mov x1, #0 - csel x0, x0, x1, eq - ret diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/Arm/ArmPlatformHelper.S b/ArmPlatformPkg/Library/ArmPlatformLibNull/Arm/ArmPlatformHelper.S index aedae556237a..342d6d5e0a9d 100644 --- a/ArmPlatformPkg/Library/ArmPlatformLibNull/Arm/ArmPlatformHelper.S +++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/Arm/ArmPlatformHelper.S @@ -10,34 +10,3 @@ ASM_FUNC(ArmPlatformPeiBootAction) bx lr - -//UINTN -//ArmPlatformGetCorePosition ( -// IN UINTN MpId -// ); -ASM_FUNC(ArmPlatformGetCorePosition) - and r1, r0, #ARM_CORE_MASK - and r0, r0, #ARM_CLUSTER_MASK - add r0, r1, r0, LSR #7 - bx lr - -//UINTN -//ArmPlatformGetPrimaryCoreMpId ( -// VOID -// ); -ASM_FUNC(ArmPlatformGetPrimaryCoreMpId) - MOV32 (r0, FixedPcdGet32 (PcdArmPrimaryCore)) - bx lr - -//UINTN -//ArmPlatformIsPrimaryCore ( -// IN UINTN MpId -// ); -ASM_FUNC(ArmPlatformIsPrimaryCore) - MOV32 (r1, FixedPcdGet32 (PcdArmPrimaryCoreMask)) - and r0, r0, r1 - MOV32 (r1, FixedPcdGet32 (PcdArmPrimaryCore)) - cmp r0, r1 - moveq r0, #1 - movne r0, #0 - bx lr diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c b/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c index 852275f44fc3..83c7d16be4a5 100644 --- a/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c +++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c @@ -90,10 +90,6 @@ ArmPlatformInitialize ( IN UINTN MpId ) { - if (!ArmPlatformIsPrimaryCore (MpId)) { - return RETURN_SUCCESS; - } - // TODO: Implement me return RETURN_SUCCESS; From a63a7dbf85963d0c11617173b117ca9edb645875 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 27 Aug 2024 17:05:37 +0200 Subject: [PATCH 117/280] ArmVirtPkg: Drop incorrect reference to LzmaDecompressLib LzmaDecompressLib does not exist as a library class, and the library implementation that is usually referenced in this context is intended to be incorporated using NULL library class resolution. Let's fix this so that we can drop the reference to LzmaDecompressLib. Signed-off-by: Ard Biesheuvel Tested-by: Sami Mujawar --- ArmVirtPkg/ArmVirtKvmTool.dsc | 2 +- ArmVirtPkg/ArmVirtQemuKernel.dsc | 2 +- ArmVirtPkg/ArmVirtXen.dsc | 2 +- ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc index 8688236084d8..c5cf2a75d9f5 100644 --- a/ArmVirtPkg/ArmVirtKvmTool.dsc +++ b/ArmVirtPkg/ArmVirtKvmTool.dsc @@ -244,7 +244,7 @@ ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf { ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf - LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc index 4e8ed6c96896..f4fb8ee69ee7 100644 --- a/ArmVirtPkg/ArmVirtQemuKernel.dsc +++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc @@ -278,7 +278,7 @@ ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf { ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf - LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc index 6c1190dce391..fd4f88725432 100644 --- a/ArmVirtPkg/ArmVirtXen.dsc +++ b/ArmVirtPkg/ArmVirtXen.dsc @@ -144,7 +144,7 @@ ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf { ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf - LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf diff --git a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf index 6ac210760f5d..ed8b89e2b68c 100755 --- a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf +++ b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf @@ -46,7 +46,6 @@ TimerLib SerialPortLib ExtractGuidedSectionLib - LzmaDecompressLib PeCoffLib PrePiLib MemoryAllocationLib From 0596e5fa05a7badb30fb3d4092d41a787788655c Mon Sep 17 00:00:00 2001 From: Xiaoqiang Zhang Date: Wed, 7 Aug 2024 16:42:44 +0800 Subject: [PATCH 118/280] MdeModulePkg: CoreValidateHandle Optimization REF : https://bugzilla.tianocore.org/show_bug.cgi?id=4817 Before entering BIOS setup, CoreValidateHandle function executed over 600,000 times during BDS phase on latest 8S server platform. In CoreValidateHandle function, current implementation will go through the doubly-linked list handle database in each call, and this will have big impact on boot performance. The optimization is using Red-black tree to store the EFI handle address when insert each EFI handle into the handle database, and remove the handle from Red-black tree if the handle is removed from the handle database. CoreValidateHandle function changed to go through the Red-black tree. After verification on latest 8S server platform, BDS boot time can save 20s+ after this change. Cc: Ray Ni Cc: Star Zeng Cc: Liming Gao Signed-off-by: Andrew Fish Tested-by: Xiaoqiang Zhang --- MdeModulePkg/Core/Dxe/DxeMain.h | 12 ++++ MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 6 ++ MdeModulePkg/Core/Dxe/Hand/Handle.c | 89 ++++++++++++++++++++++--- 4 files changed, 97 insertions(+), 11 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 53e26703f8c7..cd3940d34b2a 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -84,6 +84,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include // // attributes for reserved memory before it is promoted to system memory @@ -2790,4 +2791,15 @@ MergeMemoryMap ( IN UINTN DescriptorSize ); +/** + Initializes "handle" support. + + @return Status code. + ++**/ +EFI_STATUS +CoreInitializeHandleServices ( + VOID + ); + #endif diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 090970aec6df..cc315ac92ae8 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -95,6 +95,7 @@ CpuExceptionHandlerLib PcdLib ImagePropertiesRecordLib + OrderedCollectionLib [Guids] gEfiEventMemoryMapChangeGuid ## PRODUCES ## Event diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 17d510a287e5..8a877330dd73 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -276,6 +276,12 @@ DxeMain ( MemoryProfileInit (HobStart); + // + // Start the Handle Services. + // + Status = CoreInitializeHandleServices (); + ASSERT_EFI_ERROR (Status); + // // Start the Image Services. // diff --git a/MdeModulePkg/Core/Dxe/Hand/Handle.c b/MdeModulePkg/Core/Dxe/Hand/Handle.c index 24e4fbf5f369..b5ff3fdcd1d4 100644 --- a/MdeModulePkg/Core/Dxe/Hand/Handle.c +++ b/MdeModulePkg/Core/Dxe/Hand/Handle.c @@ -15,10 +15,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent // gProtocolDatabaseLock - Lock to protect the mProtocolDatabase // gHandleDatabaseKey - The Key to show that the handle has been created/modified // -LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase); -LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList); -EFI_LOCK gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); -UINT64 gHandleDatabaseKey = 0; +LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase); +LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList); +EFI_LOCK gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); +UINT64 gHandleDatabaseKey = 0; +ORDERED_COLLECTION *gOrderedHandleList = NULL; /** Acquire lock on gProtocolDatabaseLock. @@ -44,6 +45,60 @@ CoreReleaseProtocolLock ( CoreReleaseLock (&gProtocolDatabaseLock); } +/** + Comparator function for two opaque pointers, ordering on (unsigned) pointer + value itself. + Can be used as both Key and UserStruct comparator. + + @param[in] Pointer1 First pointer. + + @param[in] Pointer2 Second pointer. + + @retval <0 If Pointer1 compares less than Pointer2. + + @retval 0 If Pointer1 compares equal to Pointer2. + + @retval >0 If Pointer1 compares greater than Pointer2. +**/ +STATIC +INTN +EFIAPI +PointerCompare ( + IN CONST VOID *Pointer1, + IN CONST VOID *Pointer2 + ) +{ + if (Pointer1 == Pointer2) { + return 0; + } + + if ((UINTN)Pointer1 < (UINTN)Pointer2) { + return -1; + } + + return 1; +} + +/** + Initializes "handle" support. + + @return Status code. + +**/ +EFI_STATUS +CoreInitializeHandleServices ( + VOID + ) +{ + gOrderedHandleList = OrderedCollectionInit (PointerCompare, PointerCompare); + + if (gOrderedHandleList == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + /** Check whether a handle is a valid EFI_HANDLE The gProtocolDatabaseLock must be owned @@ -59,8 +114,7 @@ CoreValidateHandle ( IN EFI_HANDLE UserHandle ) { - IHANDLE *Handle; - LIST_ENTRY *Link; + ORDERED_COLLECTION_ENTRY *Entry; if (UserHandle == NULL) { return EFI_INVALID_PARAMETER; @@ -68,11 +122,9 @@ CoreValidateHandle ( ASSERT_LOCKED (&gProtocolDatabaseLock); - for (Link = gHandleList.BackLink; Link != &gHandleList; Link = Link->BackLink) { - Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE); - if (Handle == (IHANDLE *)UserHandle) { - return EFI_SUCCESS; - } + Entry = OrderedCollectionFind (gOrderedHandleList, UserHandle); + if (Entry != NULL) { + return EFI_SUCCESS; } return EFI_INVALID_PARAMETER; @@ -452,6 +504,16 @@ CoreInstallProtocolInterfaceNotify ( goto Done; } + // + // Add this handle to the ordered list of all handles + // in the system + // + Status = OrderedCollectionInsert (gOrderedHandleList, NULL, Handle); + if (EFI_ERROR (Status)) { + CoreFreePool (Handle); + goto Done; + } + // // Initialize new handler structure // @@ -825,6 +887,11 @@ CoreUninstallProtocolInterface ( // if (IsListEmpty (&Handle->Protocols)) { Handle->Signature = 0; + OrderedCollectionDelete ( + gOrderedHandleList, + OrderedCollectionFind (gOrderedHandleList, Handle), + NULL + ); RemoveEntryList (&Handle->AllHandles); CoreFreePool (Handle); } From f31aa47deea9239d61b41fda8d445ecf607fcef9 Mon Sep 17 00:00:00 2001 From: Xiaoqiang Zhang Date: Mon, 12 Aug 2024 10:53:21 +0800 Subject: [PATCH 119/280] MdePkg: CoreValidateHandle Optimization REF : https://bugzilla.tianocore.org/show_bug.cgi?id=4817 This commit is to add OrderedCollectionLib in MdePkg for DxeCore usage. Cc: Ray Ni Cc: Star Zeng Cc: Liming Gao Signed-off-by: Andrew Fish Tested-by: Xiaoqiang Zhang --- MdePkg/MdeLibs.dsc.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/MdePkg/MdeLibs.dsc.inc b/MdePkg/MdeLibs.dsc.inc index ddd27115f515..a8c8f4ef3639 100644 --- a/MdePkg/MdeLibs.dsc.inc +++ b/MdePkg/MdeLibs.dsc.inc @@ -12,6 +12,7 @@ ## [LibraryClasses] + OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf ArmTrngLib|MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.inf RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf From 5aa684271512d180514e671f7a7266e67db8df92 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Fri, 16 Aug 2024 16:33:44 +0800 Subject: [PATCH 120/280] MdeModulePkg/VariableStandaloneMm: Fix TCG MOR secure feature issue According to TCG's Platform Reset Attack Mitigation spec, the OS should never create the MOR variable, only read and write it. But some OSes (Fedora 24 and 25) don't follow the TCG's Platform Reset Attack Mitigation spec and unintentionally create MOR variable. The commit fda8f631edbbf3823760542a06f12bd60fd39181 added function VariableHaveTcgProtocols() to check against Tcg/Tcg2 protocol to infer whether the MOR variable is created by platform firmware or not. If not, delete the variable created by OS and lock the variable to avoid OS to create it. But in VariableStandaloneMm, VariableHaveTcgProtocols() always returns FALSE, it causes TCG MOR secure feature does not work in standalone MM environment. As Fedora 24 and 25 are EOL today, directly returns TRUE in the function VariableHaveTcgProtocols() for VariableStandaloneMm, and rename the function to VariableIsMorVariableLegitimate() to make it more obvious what the narrow use-case is for which it exists. Signed-off-by: Wei6 Xu --- .../Variable/RuntimeDxe/PrivilegePolymorphic.h | 14 +++++--------- .../Variable/RuntimeDxe/TcgMorLockSmm.c | 2 +- .../Variable/RuntimeDxe/VariableStandaloneMm.c | 16 ++++++---------- .../Variable/RuntimeDxe/VariableTraditionalMm.c | 6 +++--- 4 files changed, 15 insertions(+), 23 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h index e7bd4c9706b1..969a4f7e9d85 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h @@ -156,17 +156,13 @@ VariableSmmIsNonPrimaryBufferValid ( ); /** - Whether the TCG or TCG2 protocols are installed in the UEFI protocol database. - This information is used by the MorLock code to infer whether an existing - MOR variable is legitimate or not. - - @retval TRUE Either the TCG or TCG2 protocol is installed in the UEFI - protocol database - @retval FALSE Neither the TCG nor the TCG2 protocol is installed in the UEFI - protocol database + Whether the MOR variable is legitimate or not. + + @retval TRUE MOR Variable is legitimate. + @retval FALSE MOR Variable in not legitimate. **/ BOOLEAN -VariableHaveTcgProtocols ( +VariableIsMorVariableLegitimate ( VOID ); diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c index 28e8cc55d9c0..7f8b2a7776ef 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c @@ -475,7 +475,7 @@ MorLockInitAtEndOfDxe ( // can be deduced from the absence of the TCG / TCG2 protocols, as edk2's // MOR implementation depends on (one of) those protocols. // - if (VariableHaveTcgProtocols ()) { + if (VariableIsMorVariableLegitimate ()) { // // The MOR variable originates from the platform firmware; set the MOR // Control Lock variable to report the locking capability to the OS. diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c index 1b9cf6dfd9d0..f3daca3eba4e 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c @@ -89,19 +89,15 @@ VariableServiceInitialize ( } /** - Whether the TCG or TCG2 protocols are installed in the UEFI protocol database. - This information is used by the MorLock code to infer whether an existing - MOR variable is legitimate or not. - - @retval TRUE Either the TCG or TCG2 protocol is installed in the UEFI - protocol database - @retval FALSE Neither the TCG nor the TCG2 protocol is installed in the UEFI - protocol database + Whether the MOR variable is legitimate or not. + + @retval TRUE MOR Variable is legitimate. + @retval FALSE MOR Variable in not legitimate. **/ BOOLEAN -VariableHaveTcgProtocols ( +VariableIsMorVariableLegitimate ( VOID ) { - return FALSE; + return TRUE; } diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c index 7247f7574d09..cd82bb56756f 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c @@ -118,12 +118,12 @@ VariableServiceInitialize ( MOR variable is legitimate or not. @retval TRUE Either the TCG or TCG2 protocol is installed in the UEFI - protocol database + protocol database. MOR variable is legitimate. @retval FALSE Neither the TCG nor the TCG2 protocol is installed in the UEFI - protocol database + protocol database. MOR variable is not legitimate. **/ BOOLEAN -VariableHaveTcgProtocols ( +VariableIsMorVariableLegitimate ( VOID ) { From a1b0703e8ea59b2b353e644b92f01b8cad182d04 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Sun, 28 Apr 2024 16:02:16 -0600 Subject: [PATCH 121/280] EmbeddedPkg: Improve LocateAndInstallAcpiFromFvConditional LocateAndInstallAcpiFromFvConditional was always returning EFI_SUCCESS even when it failed to find `AcpiFile`. Fix that, and improve the layout by checking if an error occurred and breaking earlier. Signed-off-by: Rebecca Cran --- EmbeddedPkg/Library/AcpiLib/AcpiLib.c | 86 ++++++++++++++------------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/EmbeddedPkg/Library/AcpiLib/AcpiLib.c b/EmbeddedPkg/Library/AcpiLib/AcpiLib.c index cb593a7b2a3a..0f75cd5bf9af 100644 --- a/EmbeddedPkg/Library/AcpiLib/AcpiLib.c +++ b/EmbeddedPkg/Library/AcpiLib/AcpiLib.c @@ -52,6 +52,9 @@ LocateAndInstallAcpiFromFvConditional ( UINTN AcpiTableSize; UINTN AcpiTableKey; BOOLEAN Valid; + BOOLEAN FoundAcpiFile; + + FoundAcpiFile = FALSE; // Ensure the ACPI Table is present Status = gBS->LocateProtocol ( @@ -107,47 +110,48 @@ LocateAndInstallAcpiFromFvConditional ( &SectionSize, &FvStatus ); - if (!EFI_ERROR (Status)) { - AcpiTableKey = 0; - AcpiTableSize = ((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Length; - ASSERT (SectionSize >= AcpiTableSize); - - DEBUG (( - DEBUG_ERROR, - "- Found '%c%c%c%c' ACPI Table\n", - (((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature & 0xFF), - ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 8) & 0xFF), - ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 16) & 0xFF), - ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 24) & 0xFF) - )); - - // Is the ACPI table valid? - if (CheckAcpiTableFunction) { - Valid = CheckAcpiTableFunction ((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable); - } else { - Valid = TRUE; - } - - // Install the ACPI Table - if (Valid) { - Status = AcpiProtocol->InstallAcpiTable ( - AcpiProtocol, - AcpiTable, - AcpiTableSize, - &AcpiTableKey - ); - } - - // Free memory allocated by ReadSection - gBS->FreePool (AcpiTable); - - if (EFI_ERROR (Status)) { - break; - } - - // Increment the section instance - SectionInstance++; + + if (EFI_ERROR (Status)) { + break; + } + + FoundAcpiFile = TRUE; + + AcpiTableKey = 0; + AcpiTableSize = ((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Length; + ASSERT (SectionSize >= AcpiTableSize); + + DEBUG (( + DEBUG_ERROR, + "- Found '%c%c%c%c' ACPI Table\n", + (((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature & 0xFF), + ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 8) & 0xFF), + ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 16) & 0xFF), + ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 24) & 0xFF) + )); + + // Is the ACPI table valid? + if (CheckAcpiTableFunction != NULL) { + Valid = CheckAcpiTableFunction ((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable); + } else { + Valid = TRUE; } + + // Install the ACPI Table + if (Valid) { + Status = AcpiProtocol->InstallAcpiTable ( + AcpiProtocol, + AcpiTable, + AcpiTableSize, + &AcpiTableKey + ); + } + + // Free memory allocated by ReadSection + gBS->FreePool (AcpiTable); + + // Increment the section instance + SectionInstance++; } } @@ -157,7 +161,7 @@ LocateAndInstallAcpiFromFvConditional ( // gBS->FreePool (HandleBuffer); - return EFI_SUCCESS; + return (FoundAcpiFile ? EFI_SUCCESS : EFI_NOT_FOUND); } /** From 9d5a9940e4b1bf7cc9080ff245485abbf1858d2c Mon Sep 17 00:00:00 2001 From: Ceping Sun Date: Wed, 8 May 2024 02:10:26 +0800 Subject: [PATCH 122/280] OvmfPkg: Refactor PcdSetNxForStack usage in TDVF In the current code, TDVF reads the PcdSetNxForStack value via fw_cfg , but overwrites it with a fixed value after the read is complete. In this patch, TDVF removes the redundant logic code. Cc: Erdem Aktas Cc: Jiewen Yao Cc: Min Xu Cc: Gerd Hoffmann Cc: Elena Reshetova Signed-off-by: Ceping Sun --- OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c | 1 - OvmfPkg/Library/PlatformInitLib/Platform.c | 5 +++++ OvmfPkg/PlatformPei/IntelTdx.c | 2 -- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c index 1632a2317718..42db1a61cb50 100644 --- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c +++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c @@ -109,7 +109,6 @@ InitializePlatform ( if (TdIsEnabled ()) { PlatformInfoHob->PcdConfidentialComputingGuestAttr = CCAttrIntelTdx; PlatformInfoHob->PcdTdxSharedBitMask = TdSharedPageMask (); - PlatformInfoHob->PcdSetNxForStack = TRUE; } PlatformMiscInitialization (PlatformInfoHob); diff --git a/OvmfPkg/Library/PlatformInitLib/Platform.c b/OvmfPkg/Library/PlatformInitLib/Platform.c index f48bf16ae300..c2e0430d2269 100644 --- a/OvmfPkg/Library/PlatformInitLib/Platform.c +++ b/OvmfPkg/Library/PlatformInitLib/Platform.c @@ -261,6 +261,11 @@ PlatformNoexecDxeInitialization ( IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob ) { + if (TdIsEnabled ()) { + PlatformInfoHob->PcdSetNxForStack = TRUE; + return EFI_SUCCESS; + } + return QemuFwCfgParseBool ("opt/ovmf/PcdSetNxForStack", &PlatformInfoHob->PcdSetNxForStack); } diff --git a/OvmfPkg/PlatformPei/IntelTdx.c b/OvmfPkg/PlatformPei/IntelTdx.c index 3d625cabd844..1cb6729e56e6 100644 --- a/OvmfPkg/PlatformPei/IntelTdx.c +++ b/OvmfPkg/PlatformPei/IntelTdx.c @@ -48,7 +48,5 @@ IntelTdxInitialize ( PcdStatus = PcdSet64S (PcdTdxSharedBitMask, TdSharedPageMask ()); ASSERT_RETURN_ERROR (PcdStatus); - PcdStatus = PcdSetBoolS (PcdSetNxForStack, TRUE); - ASSERT_RETURN_ERROR (PcdStatus); #endif } From 0e6f6c715c59a6a44f86e523460526b3217c8b62 Mon Sep 17 00:00:00 2001 From: Jason Andryuk Date: Thu, 11 Apr 2024 15:43:56 -0400 Subject: [PATCH 123/280] OvmfPkg/XenHypercallLib: Use direct hypercalls This removes the need to allocate memory for the hypercall page, particularly for use during runtime. This also makes the library usable in all phases, so LIBRARY_CLASS can remove the restrictions. The processor vendor is used to select vmmcall or vmcall instructions. The listed vendors are those in the Xen tree. Signed-off-by: Jason Andryuk --- .../XenHypercallLib/Ia32/hypercall.nasm | 37 ++++-- .../XenHypercallLib/X64/hypercall.nasm | 37 ++++-- .../Library/XenHypercallLib/X86XenHypercall.c | 112 ++++++++++++++---- .../XenHypercallLib/XenHypercallLib.inf | 6 +- 4 files changed, 148 insertions(+), 44 deletions(-) diff --git a/OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm b/OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm index e0fa71bb5ba8..abcfcb55ce30 100644 --- a/OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm +++ b/OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm @@ -2,24 +2,47 @@ SECTION .text ; INTN ; EFIAPI -; __XenHypercall2 ( -; IN VOID *HypercallAddr, +; __XenVmmcall2 ( +; IN INTN HypercallNum, ; IN OUT INTN Arg1, ; IN OUT INTN Arg2 ; ); -global ASM_PFX(__XenHypercall2) -ASM_PFX(__XenHypercall2): +global ASM_PFX(__XenVmmcall2) +ASM_PFX(__XenVmmcall2): ; Save only ebx, ecx is supposed to be a scratch register and needs to be ; saved by the caller push ebx - ; Copy HypercallAddr to eax + ; Copy HypercallNum to eax mov eax, [esp + 8] ; Copy Arg1 to the register expected by Xen mov ebx, [esp + 12] ; Copy Arg2 to the register expected by Xen mov ecx, [esp + 16] - ; Call HypercallAddr - call eax + ; Call Hypercall + vmmcall + pop ebx + ret + +; INTN +; EFIAPI +; __XenVmcall2 ( +; IN INTN HypercallNum, +; IN OUT INTN Arg1, +; IN OUT INTN Arg2 +; ); +global ASM_PFX(__XenVmcall2) +ASM_PFX(__XenVmcall2): + ; Save only ebx, ecx is supposed to be a scratch register and needs to be + ; saved by the caller + push ebx + ; Copy HypercallNum to eax + mov eax, [esp + 8] + ; Copy Arg1 to the register expected by Xen + mov ebx, [esp + 12] + ; Copy Arg2 to the register expected by Xen + mov ecx, [esp + 16] + ; Call Hypercall + vmcall pop ebx ret diff --git a/OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm b/OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm index 5e6a0c05c5c4..469ac212f1dd 100644 --- a/OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm +++ b/OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm @@ -3,23 +3,46 @@ SECTION .text ; INTN ; EFIAPI -; __XenHypercall2 ( -; IN VOID *HypercallAddr, +; __XenVmmcall2 ( +; IN INTN HypercallNum, ; IN OUT INTN Arg1, ; IN OUT INTN Arg2 ; ); -global ASM_PFX(__XenHypercall2) -ASM_PFX(__XenHypercall2): +global ASM_PFX(__XenVmmcall2) +ASM_PFX(__XenVmmcall2): push rdi push rsi - ; Copy HypercallAddr to rax + ; Copy HypercallNum to rax mov rax, rcx ; Copy Arg1 to the register expected by Xen mov rdi, rdx ; Copy Arg2 to the register expected by Xen mov rsi, r8 - ; Call HypercallAddr - call rax + ; Call HypercallNum + vmmcall + pop rsi + pop rdi + ret + +; INTN +; EFIAPI +; __XenVmcall2 ( +; IN INTN HypercallNum, +; IN OUT INTN Arg1, +; IN OUT INTN Arg2 +; ); +global ASM_PFX(__XenVmcall2) +ASM_PFX(__XenVmcall2): + push rdi + push rsi + ; Copy HypercallNum to rax + mov rax, rcx + ; Copy Arg1 to the register expected by Xen + mov rdi, rdx + ; Copy Arg2 to the register expected by Xen + mov rsi, r8 + ; Call HypercallNum + vmcall pop rsi pop rdi ret diff --git a/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c b/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c index dcc657525028..a07d9e4d4608 100644 --- a/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c +++ b/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c @@ -7,11 +7,31 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include -#include +#include #include -#include +#include -STATIC VOID *HyperPage; +static INTN mUseVmmCall = -1; +static BOOLEAN mHypercallAvail; + +// +// Interface exposed by the ASM implementation of the core hypercall +// +INTN +EFIAPI +__XenVmmcall2 ( + IN INTN HypercallNum, + IN OUT INTN Arg1, + IN OUT INTN Arg2 + ); + +INTN +EFIAPI +__XenVmcall2 ( + IN INTN HypercallNum, + IN OUT INTN Arg1, + IN OUT INTN Arg2 + ); /** Check if the Xen Hypercall library is able to make calls to the Xen @@ -29,23 +49,38 @@ XenHypercallIsAvailable ( VOID ) { - return HyperPage != NULL; + return mHypercallAvail; } -// -// Interface exposed by the ASM implementation of the core hypercall -// -INTN -EFIAPI -__XenHypercall2 ( - IN VOID *HypercallAddr, - IN OUT INTN Arg1, - IN OUT INTN Arg2 - ); +STATIC +UINT32 +XenCpuidLeaf ( + VOID + ) +{ + UINT8 Signature[13]; + UINT32 XenLeaf; + + Signature[12] = '\0'; + for (XenLeaf = 0x40000000; XenLeaf < 0x40010000; XenLeaf += 0x100) { + AsmCpuid ( + XenLeaf, + NULL, + (UINT32 *)&Signature[0], + (UINT32 *)&Signature[4], + (UINT32 *)&Signature[8] + ); + + if (!AsciiStrCmp ((CHAR8 *)Signature, "XenVMMXenVMM")) { + return XenLeaf; + } + } + + return 0; +} /** - Library constructor: retrieves the Hyperpage address - from the gEfiXenInfoGuid HOB + Library constructor: Check for Xen leaf in CPUID **/ RETURN_STATUS EFIAPI @@ -53,16 +88,41 @@ XenHypercallLibInit ( VOID ) { - EFI_HOB_GUID_TYPE *GuidHob; - EFI_XEN_INFO *XenInfo; + UINT32 XenLeaf; + CHAR8 sig[13]; - GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid); - if (GuidHob == NULL) { + XenLeaf = XenCpuidLeaf (); + if (XenLeaf == 0) { return RETURN_NOT_FOUND; } - XenInfo = (EFI_XEN_INFO *)GET_GUID_HOB_DATA (GuidHob); - HyperPage = XenInfo->HyperPages; + sig[12] = '\0'; + AsmCpuid ( + 0, + NULL, + (UINT32 *)&sig[0], + (UINT32 *)&sig[8], + (UINT32 *)&sig[4] + ); + + DEBUG ((DEBUG_INFO, "Detected CPU \"%12a\"\n", sig)); + + if ((AsciiStrCmp ("AuthenticAMD", sig) == 0) || + (AsciiStrCmp ("HygonGenuine", sig) == 0)) + { + mUseVmmCall = TRUE; + } else if ((AsciiStrCmp ("GenuineIntel", sig) == 0) || + (AsciiStrCmp ("CentaurHauls", sig) == 0) || + (AsciiStrCmp (" Shanghai ", sig) == 0)) + { + mUseVmmCall = FALSE; + } else { + DEBUG ((DEBUG_ERROR, "Unsupported CPU vendor\n")); + return RETURN_NOT_FOUND; + } + + mHypercallAvail = TRUE; + return RETURN_SUCCESS; } @@ -84,7 +144,9 @@ XenHypercall2 ( IN OUT INTN Arg2 ) { - ASSERT (HyperPage != NULL); - - return __XenHypercall2 ((UINT8 *)HyperPage + HypercallID * 32, Arg1, Arg2); + if (mUseVmmCall) { + return __XenVmmcall2 (HypercallID, Arg1, Arg2); + } else { + return __XenVmcall2 (HypercallID, Arg1, Arg2); + } } diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf b/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf index edb77872391c..2321b61bf8f4 100644 --- a/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf +++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf @@ -13,11 +13,6 @@ MODULE_TYPE = BASE VERSION_STRING = 1.0 CONSTRUCTOR = XenHypercallLibConstruct - -[Defines.IA32, Defines.X64] - LIBRARY_CLASS = XenHypercallLib|PEIM DXE_DRIVER UEFI_DRIVER - -[Defines.ARM, Defines.AARCH64] LIBRARY_CLASS = XenHypercallLib # @@ -52,6 +47,7 @@ OvmfPkg/OvmfPkg.dec [LibraryClasses.IA32, LibraryClasses.X64] + CpuLib BaseLib HobLib DebugLib From 043eab84e5adb2013c9623ce44f44f6a7ef8e037 Mon Sep 17 00:00:00 2001 From: Jason Andryuk Date: Thu, 11 Apr 2024 16:25:30 -0400 Subject: [PATCH 124/280] OvmfPkg/XenPlatformPei: Remove Hypercall Page XenHypercallLib now makes direct hypercalls, so HyperPages is unnecessary and can be removed. Change the XenPvhDetected() ASSERT to use the Xen version. That has never been 0, AFAIK. Signed-off-by: Jason Andryuk --- OvmfPkg/Include/Guid/XenInfo.h | 4 ---- OvmfPkg/XenPlatformPei/Xen.c | 23 +---------------------- 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/OvmfPkg/Include/Guid/XenInfo.h b/OvmfPkg/Include/Guid/XenInfo.h index a8f6a36f1cbb..c5de783c063e 100644 --- a/OvmfPkg/Include/Guid/XenInfo.h +++ b/OvmfPkg/Include/Guid/XenInfo.h @@ -13,10 +13,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent { 0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d } } typedef struct { - /// - /// Beginning of the hypercall page. - /// - VOID *HyperPages; /// /// Hypervisor major version. /// diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c index 7f00eef11e8f..a54fd55c70d2 100644 --- a/OvmfPkg/XenPlatformPei/Xen.c +++ b/OvmfPkg/XenPlatformPei/Xen.c @@ -128,9 +128,6 @@ EFI_STATUS XenConnect ( ) { - UINT32 Index; - UINT32 TransferReg; - UINT32 TransferPages; UINT32 XenVersion; EFI_XEN_OVMF_INFO *Info; CHAR8 Sig[sizeof (Info->Signature) + 1]; @@ -139,24 +136,6 @@ XenConnect ( ASSERT (mXenLeaf != 0); - // - // Prepare HyperPages to be able to make hypercalls - // - - AsmCpuid (mXenLeaf + 2, &TransferPages, &TransferReg, NULL, NULL); - mXenInfo.HyperPages = AllocatePages (TransferPages); - if (!mXenInfo.HyperPages) { - return EFI_OUT_OF_RESOURCES; - } - - for (Index = 0; Index < TransferPages; Index++) { - AsmWriteMsr64 ( - TransferReg, - (UINTN)mXenInfo.HyperPages + - (Index << EFI_PAGE_SHIFT) + Index - ); - } - // // Find out the Xen version // @@ -283,7 +262,7 @@ XenPvhDetected ( // // This function should only be used after XenConnect // - ASSERT (mXenInfo.HyperPages != NULL); + ASSERT (mXenInfo.VersionMajor); return mXenHvmloaderInfo == NULL; } From 6ed258d89dea23b1864f8fdd730879377099a129 Mon Sep 17 00:00:00 2001 From: Anthony PERARD Date: Mon, 19 Sep 2022 17:16:46 +0100 Subject: [PATCH 125/280] OvmfPkg/XenHypercallLib: Add SchedOp hypercall Add a new function to allow to make an hypercall to shutdown the machine. This import "sched.h" public header from Xen Project's repo. Some changes have been made to be closer to EDK2's coding style. Add the entire OvmfPkg/Include/IndustryStandard/Xen/ directory to LicenseCheck ignore. All the existing header files, as well as the new sched.h, are MIT licensed. Signed-off-by: Anthony PERARD Signed-off-by: Jason Andryuk --- OvmfPkg/Include/IndustryStandard/Xen/sched.h | 50 +++++++++++++++++++ OvmfPkg/Include/Library/XenHypercallLib.h | 7 +++ .../Library/XenHypercallLib/XenHypercall.c | 14 ++++++ OvmfPkg/OvmfPkg.ci.yaml | 3 +- 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/sched.h diff --git a/OvmfPkg/Include/IndustryStandard/Xen/sched.h b/OvmfPkg/Include/IndustryStandard/Xen/sched.h new file mode 100644 index 000000000000..5ca0017f1ad6 --- /dev/null +++ b/OvmfPkg/Include/IndustryStandard/Xen/sched.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * sched.h + * + * Scheduler state interactions + * + * SPDX-License-Identifier: MIT + * + * Copyright (c) 2005, Keir Fraser + */ + +#ifndef __XEN_PUBLIC_SCHED_H__ +#define __XEN_PUBLIC_SCHED_H__ + +#include "event_channel.h" + +/* + * Halt execution of this domain (all VCPUs) and notify the system controller. + * @arg == pointer to sched_shutdown_t structure. + * + * If the sched_shutdown_t reason is SHUTDOWN_suspend then + * x86 PV guests must also set RDX (EDX for 32-bit guests) to the MFN + * of the guest's start info page. RDX/EDX is the third hypercall + * argument. + * + * In addition, which reason is SHUTDOWN_suspend this hypercall + * returns 1 if suspend was cancelled or the domain was merely + * checkpointed, and 0 if it is resuming in a new domain. + */ +#define XEN_SCHEDOP_SHUTDOWN 2 + +struct _XEN_SCHED_SHUTDOWN { + UINT32 Reason; /* SHUTDOWN_* => enum sched_shutdown_reason */ +}; + +typedef struct _XEN_SCHED_SHUTDOWN XEN_SCHED_SHUTDOWN; +DEFINE_XEN_GUEST_HANDLE (XEN_SCHED_SHUTDOWN); + +/* + * Reason codes for SCHEDOP_shutdown. These may be interpreted by control + * software to determine the appropriate action. For the most part, Xen does + * not care about the shutdown code. + */ +/* ` enum sched_shutdown_reason { */ +#define XEN_SHED_SHUTDOWN_POWEROFF 0 /* Domain exited normally. Clean up and kill. */ +#define XEN_SHED_SHUTDOWN_REBOOT 1 /* Clean up, kill, and then restart. */ +#define XEN_SHED_SHUTDOWN_SUSPEND 2 /* Clean up, save suspend info, kill. */ +#define XEN_SHED_SHUTDOWN_CRASH 3 /* Tell controller we've crashed. */ +#define XEN_SHED_SHUTDOWN_WATCHDOG 4 /* Restart because watchdog time expired. */ + +#endif /* __XEN_PUBLIC_SCHED_H__ */ diff --git a/OvmfPkg/Include/Library/XenHypercallLib.h b/OvmfPkg/Include/Library/XenHypercallLib.h index 28eee8ccac85..d7cf2c0c505b 100644 --- a/OvmfPkg/Include/Library/XenHypercallLib.h +++ b/OvmfPkg/Include/Library/XenHypercallLib.h @@ -101,4 +101,11 @@ XenHypercallEventChannelOp ( IN OUT VOID *Arguments ); +INTN +EFIAPI +XenHypercallSchedOp ( + IN INTN Operation, + IN OUT VOID *Arguments + ); + #endif diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercall.c b/OvmfPkg/Library/XenHypercallLib/XenHypercall.c index 65b14a11f402..b1a129998fdc 100644 --- a/OvmfPkg/Library/XenHypercallLib/XenHypercall.c +++ b/OvmfPkg/Library/XenHypercallLib/XenHypercall.c @@ -87,3 +87,17 @@ XenHypercallEventChannelOp ( (INTN)Arguments ); } + +INTN +EFIAPI +XenHypercallSchedOp ( + IN INTN Operation, + IN OUT VOID *Arguments + ) +{ + return XenHypercall2 ( + __HYPERVISOR_sched_op, + Operation, + (INTN)Arguments + ); +} diff --git a/OvmfPkg/OvmfPkg.ci.yaml b/OvmfPkg/OvmfPkg.ci.yaml index ff022242b018..7ce1be283f77 100644 --- a/OvmfPkg/OvmfPkg.ci.yaml +++ b/OvmfPkg/OvmfPkg.ci.yaml @@ -11,7 +11,8 @@ { ## options defined .pytool/Plugin/LicenseCheck "LicenseCheck": { - "IgnoreFiles": [] + ## Imported from Xen and MIT licensed. + "IgnoreFiles": ["OvmfPkg/Include/IndustryStandard/Xen"] }, "EccCheck": { ## Exception sample looks like below: From 0b0b7041cc6cab48479caeb4013f2a77b26b9b1d Mon Sep 17 00:00:00 2001 From: Anthony PERARD Date: Mon, 19 Sep 2022 17:18:16 +0100 Subject: [PATCH 126/280] OvmfPkg/OvmfXen: Introduce Xen's ResetSystemLib, to use xen hypercall When booting OvmfXen, the ACPI interface for shutdown/reset might not be available, instead use the hypercall interface. While it's probably possible to use the hypercall in all cases, we keep using the same interface while it still possible. That is ACPI on HVM guest, and fallback to hypercall on PVH guest. Signed-off-by: Anthony PERARD Signed-off-by: Jason Andryuk --- .../ResetSystemLib/BaseResetShutdownXen.c | 65 ++++++++++++++++ .../ResetSystemLib/BaseResetSystemLibXen.inf | 41 ++++++++++ .../ResetSystemLib/DxeResetShutdownXen.c | 77 +++++++++++++++++++ .../ResetSystemLib/DxeResetSystemLibXen.inf | 46 +++++++++++ OvmfPkg/OvmfXen.dsc | 10 +-- 5 files changed, 234 insertions(+), 5 deletions(-) create mode 100644 OvmfPkg/Library/ResetSystemLib/BaseResetShutdownXen.c create mode 100644 OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibXen.inf create mode 100644 OvmfPkg/Library/ResetSystemLib/DxeResetShutdownXen.c create mode 100644 OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf diff --git a/OvmfPkg/Library/ResetSystemLib/BaseResetShutdownXen.c b/OvmfPkg/Library/ResetSystemLib/BaseResetShutdownXen.c new file mode 100644 index 000000000000..f45d9125feb4 --- /dev/null +++ b/OvmfPkg/Library/ResetSystemLib/BaseResetShutdownXen.c @@ -0,0 +1,65 @@ +/** @file + Base Reset System Library Shutdown API implementation for OVMF. + + Copyright (C) 2020, Red Hat, Inc. + Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2022, Citrix Systems, Inc. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include // BIT13 + +#include // CpuDeadLoop() +#include // ASSERT() +#include // IoOr16() +#include // PciRead16() +#include // ResetShutdown() +#include +#include // OVMF_HOSTBRIDGE_DID + +/** + Calling this function causes the system to enter a power state equivalent + to the ACPI G2/S5 or G3 states. + + System shutdown should not return, if it returns, it means the system does + not support shut down reset. +**/ +VOID +EFIAPI +ResetShutdown ( + VOID + ) +{ + UINT16 AcpiPmBaseAddress; + UINT16 HostBridgeDevId; + + AcpiPmBaseAddress = 0; + HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID); + switch (HostBridgeDevId) { + case INTEL_82441_DEVICE_ID: + AcpiPmBaseAddress = PIIX4_PMBA_VALUE; + break; + case INTEL_Q35_MCH_DEVICE_ID: + AcpiPmBaseAddress = ICH9_PMBASE_VALUE; + break; + default: + { + // + // Fallback to using hypercall. + // Necessary for PVH guest, but should work for HVM guest. + // + INTN ReturnCode; + XEN_SCHED_SHUTDOWN ShutdownOp = { + .Reason = XEN_SHED_SHUTDOWN_POWEROFF, + }; + ReturnCode = XenHypercallSchedOp (XEN_SCHEDOP_SHUTDOWN, ShutdownOp); + ASSERT (ReturnCode == 0); + CpuDeadLoop (); + } + } + + IoBitFieldWrite16 (AcpiPmBaseAddress + 4, 10, 13, 0); + IoOr16 (AcpiPmBaseAddress + 4, BIT13); + CpuDeadLoop (); +} diff --git a/OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibXen.inf b/OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibXen.inf new file mode 100644 index 000000000000..8d75dd565365 --- /dev/null +++ b/OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibXen.inf @@ -0,0 +1,41 @@ +## @file +# Base library instance for ResetSystem library class for Xen +# +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2022, Citrix Systems, Inc. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseResetSystemLib + FILE_GUID = 9ef32aa1-9e82-4fb1-9c49-0eff538601f8 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ResetSystemLib|SEC PEI_CORE PEIM DXE_CORE + +# +# The following information is for reference only and not required by the build +# tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + BaseResetShutdownXen.c + ResetSystemLib.c + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + IoLib + PciLib + TimerLib + XenHypercallLib diff --git a/OvmfPkg/Library/ResetSystemLib/DxeResetShutdownXen.c b/OvmfPkg/Library/ResetSystemLib/DxeResetShutdownXen.c new file mode 100644 index 000000000000..f7f32765cfc9 --- /dev/null +++ b/OvmfPkg/Library/ResetSystemLib/DxeResetShutdownXen.c @@ -0,0 +1,77 @@ +/** @file + DXE Reset System Library Shutdown API implementation for OVMF. + + Copyright (C) 2020, Red Hat, Inc. + Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include // BIT13 + +#include +#include // CpuDeadLoop() +#include // ASSERT() +#include // IoOr16() +#include // PcdGet16() +#include // ResetShutdown() +#include +#include // PIIX4_PMBA_VALUE + +STATIC UINT16 mAcpiPmBaseAddress; + +EFI_STATUS +EFIAPI +DxeResetInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + UINT16 HostBridgeDevId; + + HostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId); + switch (HostBridgeDevId) { + case INTEL_82441_DEVICE_ID: + mAcpiPmBaseAddress = PIIX4_PMBA_VALUE; + break; + case INTEL_Q35_MCH_DEVICE_ID: + mAcpiPmBaseAddress = ICH9_PMBASE_VALUE; + break; + default: + // + // Fallback to using hypercall. + // Necessary for PVH guest, but should work for HVM guest. + // + mAcpiPmBaseAddress = 0xffff; + break; + } + + return EFI_SUCCESS; +} + +/** + Calling this function causes the system to enter a power state equivalent + to the ACPI G2/S5 or G3 states. + + System shutdown should not return, if it returns, it means the system does + not support shut down reset. +**/ +VOID +EFIAPI +ResetShutdown ( + VOID + ) +{ + if (mAcpiPmBaseAddress != 0xffff) { + IoBitFieldWrite16 (mAcpiPmBaseAddress + 4, 10, 13, 0); + IoOr16 (mAcpiPmBaseAddress + 4, BIT13); + } else { + INTN ReturnCode; + XEN_SCHED_SHUTDOWN ShutdownOp = { + .Reason = XEN_SHED_SHUTDOWN_POWEROFF, + }; + ReturnCode = XenHypercallSchedOp (XEN_SCHEDOP_SHUTDOWN, &ShutdownOp); + ASSERT (ReturnCode == 0); + } + + CpuDeadLoop (); +} diff --git a/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf b/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf new file mode 100644 index 000000000000..ccee69e6e1fa --- /dev/null +++ b/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf @@ -0,0 +1,46 @@ +## @file +# DXE library instance for ResetSystem library class for Xen +# +# Copyright (C) 2020, Red Hat, Inc. +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2022, Citrix Systems, Inc. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = DxeResetSystemLibXen + FILE_GUID = a5ac25e6-4dc5-4fd9-92cd-74e46bd2e72a + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = ResetSystemLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION + CONSTRUCTOR = DxeResetInit + +# +# The following information is for reference only and not required by the build +# tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + DxeResetShutdownXen.c + ResetSystemLib.c + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + IoLib + PcdLib + TimerLib + XenHypercallLib + +[Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId ## CONSUMES diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc index c6fc3031caee..f6846c20ff40 100644 --- a/OvmfPkg/OvmfXen.dsc +++ b/OvmfPkg/OvmfXen.dsc @@ -120,7 +120,7 @@ [LibraryClasses] PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf - ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLib.inf + ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibXen.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf BaseLib|MdePkg/Library/BaseLib/BaseLib.inf @@ -302,7 +302,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf - ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf + ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf @@ -315,7 +315,7 @@ [LibraryClasses.common.UEFI_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf - ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf + ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf @@ -326,7 +326,7 @@ [LibraryClasses.common.DXE_DRIVER] AcpiPlatformLib|OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf - ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf + ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf @@ -346,7 +346,7 @@ [LibraryClasses.common.UEFI_APPLICATION] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf - ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf + ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf From d5c7bba5048e634c4363b6fdd89fe4e74e70107b Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Thu, 29 Aug 2024 13:37:09 +0800 Subject: [PATCH 127/280] StandaloneMmPkg: Restart dispatcher once MM entry is registered for X64 X64 arch needs to restart the MM dispatcher once MM entry point is registered, therefore set PcdRestartMmDispatcherOnceMmEntryRegistered to TRUE by default for X64 only. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/StandaloneMmPkg.dec | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/StandaloneMmPkg/StandaloneMmPkg.dec b/StandaloneMmPkg/StandaloneMmPkg.dec index 54fe59e99989..5ac57c1013c5 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dec +++ b/StandaloneMmPkg/StandaloneMmPkg.dec @@ -63,3 +63,10 @@ # FALSE - Do not restart MM Dispatcher once MM Entry Point is registered.
# @Prompt Restart MM Dispatcher once MM Entry Point is registered. gStandaloneMmPkgTokenSpaceGuid.PcdRestartMmDispatcherOnceMmEntryRegistered|FALSE|BOOLEAN|0x00000002 + +[PcdsFeatureFlag.X64] + ## Indicates if restart MM Dispatcher once MM Entry Point is registered.

+ # TRUE - Restart MM Dispatcher once MM Entry Point is registered.
+ # FALSE - Do not restart MM Dispatcher once MM Entry Point is registered.
+ # @Prompt Restart MM Dispatcher once MM Entry Point is registered. + gStandaloneMmPkgTokenSpaceGuid.PcdRestartMmDispatcherOnceMmEntryRegistered|TRUE|BOOLEAN|0x00000002 From a066ca16d348122b160b407008d77ea6329fe6f3 Mon Sep 17 00:00:00 2001 From: Chao Li Date: Thu, 29 Aug 2024 15:24:53 +0800 Subject: [PATCH 128/280] MdePkg: Rename the LoongArch CSR 0x20 register Added a new name for CSR 0x20 because LoongArch SPEC has adjustd the CSR 0x20 register name. Ref: LoongArch Reference Manual Vol 1, Seciton 7.1. https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#control-and-status-registers Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Signed-off-by: Chao Li --- MdePkg/Include/Register/LoongArch64/Csr.h | 1 + MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S | 24 ++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/MdePkg/Include/Register/LoongArch64/Csr.h b/MdePkg/Include/Register/LoongArch64/Csr.h index aa22a265640f..0f04b7ab5b9a 100644 --- a/MdePkg/Include/Register/LoongArch64/Csr.h +++ b/MdePkg/Include/Register/LoongArch64/Csr.h @@ -113,6 +113,7 @@ // Config CSR registers // #define LOONGARCH_CSR_CPUNUM 0x20 // CPU core number +#define LOONGARCH_CSR_CPUID 0x20 // CPU core ID #define LOONGARCH_CSR_PRCFG1 0x21 // Config1 #define LOONGARCH_CSR_PRCFG2 0x22 // Config2 #define LOONGARCH_CSR_PRCFG3 0x23 // Config3 diff --git a/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S b/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S index eb827245033d..bb57924bc485 100644 --- a/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S +++ b/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S @@ -50,12 +50,12 @@ TlbCsrRd: jirl $zero, $t0, 0 CfgCsrRd: - li.w $t0, LOONGARCH_CSR_CPUNUM + li.w $t0, LOONGARCH_CSR_CPUID bltu $a0, $t0, ReadSelNumErr li.w $t0, LOONGARCH_CSR_PRCFG3 bltu $t0, $a0, KcsCsrRd la.pcrel $t0, CfgCsrRead - addi.w $t1, $a0, -LOONGARCH_CSR_CPUNUM + addi.w $t1, $a0, -LOONGARCH_CSR_CPUID alsl.d $t0, $t1, $t0, 3 jirl $zero, $t0, 0 @@ -117,8 +117,8 @@ TlbCsrRead: .endr CfgCsrRead: - CsrSel = LOONGARCH_CSR_CPUNUM - .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUNUM + 1 + CsrSel = LOONGARCH_CSR_CPUID + .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUID + 1 AsmCsrRd CsrSel CsrSel = CsrSel + 1 .endr @@ -174,12 +174,12 @@ TlbCsrWr: jirl $zero, $t0, 0 CfgCsrWr: - li.w $t0, LOONGARCH_CSR_CPUNUM + li.w $t0, LOONGARCH_CSR_CPUID bltu $a0, $t0, WriteSelNumErr li.w $t0, LOONGARCH_CSR_PRCFG3 bltu $t0, $a0, KcsCsrWr la.pcrel $t0, CfgCsrWrite - addi.w $t1, $a0, -LOONGARCH_CSR_CPUNUM + addi.w $t1, $a0, -LOONGARCH_CSR_CPUID alsl.d $t0, $t1, $t0, 3 move $a0, $a1 jirl $zero, $t0, 0 @@ -246,8 +246,8 @@ TlbCsrWrite: .endr CfgCsrWrite: - CsrSel = LOONGARCH_CSR_CPUNUM - .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUNUM + 1 + CsrSel = LOONGARCH_CSR_CPUID + .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUID + 1 AsmCsrWr CsrSel CsrSel = CsrSel + 1 .endr @@ -306,12 +306,12 @@ TlbCsrXchg: jirl $zero, $t0, 0 CfgCsrXchg: - li.w $t0, LOONGARCH_CSR_CPUNUM + li.w $t0, LOONGARCH_CSR_CPUID bltu $a0, $t0, XchgSelNumErr li.w $t0, LOONGARCH_CSR_PRCFG3 bltu $t0, $a0, KcsCsrXchg la.pcrel $t0, CfgCsrXchange - addi.w $t1, $a0, -LOONGARCH_CSR_CPUNUM + addi.w $t1, $a0, -LOONGARCH_CSR_CPUID alsl.d $t0, $t1, $t0, 3 move $a0, $a1 move $a1, $a2 @@ -383,8 +383,8 @@ TlbCsrXchange: .endr CfgCsrXchange: - CsrSel = LOONGARCH_CSR_CPUNUM - .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUNUM + 1 + CsrSel = LOONGARCH_CSR_CPUID + .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUID + 1 AsmCsrXChange CsrSel CsrSel = CsrSel + 1 .endr From 2fe24171acec5e032cc19ce6b958d3274062d00d Mon Sep 17 00:00:00 2001 From: Chao Li Date: Thu, 29 Aug 2024 15:51:31 +0800 Subject: [PATCH 129/280] UefiCpuPkg: Using the new name of LoongArch CSR 0x20 register Since the LoongArch SPEC has adjusted the CSR 0x20 register name and the MdePkg also added the new name, so enable it in UefiCpuPkg. Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Jiaxin Wu Signed-off-by: Chao Li --- .../LoongArch/LoongArch64/ArchExceptionHandler.c | 2 +- UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/LoongArch/LoongArch64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/LoongArch/LoongArch64/ArchExceptionHandler.c index c0219deba5b8..519fe1e24e41 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/LoongArch/LoongArch64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/LoongArch/LoongArch64/ArchExceptionHandler.c @@ -260,7 +260,7 @@ IpiInterruptHandler ( // // Set $a0 as APIC ID and $a1 as parameter value. // - SystemContext.SystemContextLoongArch64->R4 = CsrRead (LOONGARCH_CSR_CPUNUM); + SystemContext.SystemContextLoongArch64->R4 = CsrRead (LOONGARCH_CSR_CPUID); SystemContext.SystemContextLoongArch64->R5 = Parameter; } diff --git a/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c b/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c index 54c23ecf1091..ff2c033da681 100644 --- a/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c @@ -60,7 +60,7 @@ GetApicId ( { UINTN CpuNum; - CpuNum = CsrRead (LOONGARCH_CSR_CPUNUM); + CpuNum = CsrRead (LOONGARCH_CSR_CPUID); return CpuNum & 0x3ff; } From bc518f81fd8c3b2f17220aded95acf8ab41cd65e Mon Sep 17 00:00:00 2001 From: Chao Li Date: Thu, 29 Aug 2024 15:54:58 +0800 Subject: [PATCH 130/280] OvmfPkg: Using the new name of LoongArch CSR 0x20 register Since the LoongArch SPEC has adjusted the CSR 0x20 register name and the MdePkg also added the new name, so enable it in OvmfPkg. Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Signed-off-by: Chao Li --- OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S b/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S index dd74c6b296f6..dd598212353a 100644 --- a/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S +++ b/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S @@ -105,7 +105,7 @@ ASM_PFX(EnableIPI): # ) #**/ ASM_PFX(GetApicId): - csrrd $a0, LOONGARCH_CSR_CPUNUM + csrrd $a0, LOONGARCH_CSR_CPUID andi $a0, $a0, 0x3ff jirl $zero, $ra, 0 # End of GetApicId From f6092b5e2be20139393a58bf454fb000020a3918 Mon Sep 17 00:00:00 2001 From: Chao Li Date: Thu, 29 Aug 2024 15:56:55 +0800 Subject: [PATCH 131/280] MdePkg: Remove the old name of LoongArch CSR 0x20 Since all places where the old name was used for the LoongArch CSR 0x20 regiser have been changed to the new name, the old name is removed. Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Signed-off-by: Chao Li --- MdePkg/Include/Register/LoongArch64/Csr.h | 1 - 1 file changed, 1 deletion(-) diff --git a/MdePkg/Include/Register/LoongArch64/Csr.h b/MdePkg/Include/Register/LoongArch64/Csr.h index 0f04b7ab5b9a..fe2ebd9f16e0 100644 --- a/MdePkg/Include/Register/LoongArch64/Csr.h +++ b/MdePkg/Include/Register/LoongArch64/Csr.h @@ -112,7 +112,6 @@ // // Config CSR registers // -#define LOONGARCH_CSR_CPUNUM 0x20 // CPU core number #define LOONGARCH_CSR_CPUID 0x20 // CPU core ID #define LOONGARCH_CSR_PRCFG1 0x21 // Config1 #define LOONGARCH_CSR_PRCFG2 0x22 // Config2 From 2069a63a8e4b190a6992b45060c0dd0d5a5f3c73 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 26 Jun 2024 13:26:08 +0200 Subject: [PATCH 132/280] OvmfPkg/PlatformInitLib: allow switching to 4-level paging There are a number of mostly older guests such as RHEL-7 which do not support 5-level paging. This patch adds support for switching from 5-level paging mode back to 4-level paging mode. This is done in PEI, after inspecting the address space needed (installed memory and reservations configured via fw_cfg). By default small guests (which need less than 1 TB) will use 4-level paging mode. There is a fw_cfg override though, so it is possible to force the one or the other this way: qemu-system-x86_64 -fw_cfg name=opt/org.tianocode/PagingLevel,string=5 Signed-off-by: Gerd Hoffmann --- OvmfPkg/Library/PlatformInitLib/MemDetect.c | 107 ++++++++++++++++++ .../PlatformInitLib/PlatformInitLib.inf | 2 + .../Library/PlatformInitLib/X64/Paging.nasm | 76 +++++++++++++ 3 files changed, 185 insertions(+) create mode 100644 OvmfPkg/Library/PlatformInitLib/X64/Paging.nasm diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c index bd6c79e4e4e4..0acc0e1275a4 100644 --- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c +++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c @@ -898,6 +898,111 @@ PlatformScanHostProvided64BitPciMmioEnd ( return EFI_NOT_FOUND; } +VOID +EFIAPI +Switch4Level ( + VOID + ); + +/** + Configure x64 paging levels. + + + The OVMF ResetVector code will enter long mode with 5-level paging if the + following conditions are true: + + (1) OVMF has been built with PcdUse5LevelPageTable = TRUE, and + (2) the CPU supports 5-level paging (aka la57), and + (3) the CPU supports gigabyte pages, and + (4) the VM is not running in SEV mode. + + Condition (4) is a temporary stopgap for BaseMemEncryptSevLib not supporting + 5-level paging yet. + + + This function looks at the virtual machine configuration, then decides + whenever it will continue to use 5-level paging or downgrade to 4-level + paging for better compatibility with older guest OS versions. + + There is a fw_cfg config option to explicitly request 4 or 5-level paging + using 'qemu -fw_cfg name=opt/org.tianocode/PagingLevel,string=4|5'. If the + option is present the requested paging level will be used. + + Should that not be the case the function checks the size of the address space + needed, which is the RAM installed plus fw_cfg reservations. The downgrade + to 4-level paging will happen for small guests where the address space needed + is lower than 1TB. + + + This function will also log the paging level used and the reason for that. +**/ +STATIC +VOID +PlatformSetupPagingLevel ( + IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob + ) +{ + #ifdef MDE_CPU_X64 + UINT32 PagingLevel; + EFI_STATUS Status; + IA32_CR4 Cr4; + + Cr4.UintN = AsmReadCr4 (); + if (!Cr4.Bits.LA57) { + /* The OvmfPkg ResetVector has NOT turned on 5-level paging, log the reason. */ + if (!PcdGetBool (PcdUse5LevelPageTable)) { + DEBUG ((DEBUG_INFO, "%a: using 4-level paging (PcdUse5LevelPageTable disabled)\n", __func__)); + } else { + DEBUG ((DEBUG_INFO, "%a: using 4-level paging (la57 not supported by cpu)\n", __func__)); + } + + return; + } + + Status = QemuFwCfgParseUint32 ( + "opt/org.tianocode/PagingLevel", + FALSE, + &PagingLevel + ); + switch (Status) { + case EFI_NOT_FOUND: + if (PlatformInfoHob->FirstNonAddress < (1ll << 40)) { + // + // If the highest address actually used is below 1TB switch back into + // 4-level paging mode for better compatibility with older guests. + // + DEBUG ((DEBUG_INFO, "%a: using 4-level paging (default for small guest)\n", __func__)); + PagingLevel = 4; + } else { + DEBUG ((DEBUG_INFO, "%a: using 5-level paging (default for large guest)\n", __func__)); + PagingLevel = 5; + } + + break; + case EFI_SUCCESS: + if ((PagingLevel != 4) && (PagingLevel != 5)) { + DEBUG ((DEBUG_INFO, "%a: invalid paging level in fw_cfg: %d\n", __func__, PagingLevel)); + return; + } + + DEBUG ((DEBUG_INFO, "%a: using %d-level paging (fw_cfg override)\n", __func__, PagingLevel)); + break; + default: + DEBUG ((DEBUG_WARN, "%a: QemuFwCfgParseUint32: %r\n", __func__, Status)); + return; + } + + if (PagingLevel == 4) { + Switch4Level (); + } + + if (PagingLevel == 5) { + /* The OvmfPkg ResetVector has turned on 5-level paging, nothing to do here. */ + } + + #endif +} + /** Initialize the PhysMemAddressWidth field in PlatformInfoHob based on guest RAM size. **/ @@ -946,6 +1051,8 @@ PlatformAddressWidthInitialization ( PlatformGetFirstNonAddress (PlatformInfoHob); } + PlatformSetupPagingLevel (PlatformInfoHob); + PlatformAddressWidthFromCpuid (PlatformInfoHob, TRUE); if (PlatformInfoHob->PhysMemAddressWidth != 0) { // physical address width is known diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf index 21e6efa5e022..e9c07467bbf0 100644 --- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf +++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf @@ -32,6 +32,7 @@ [Sources.X64] IntelTdx.c + X64/Paging.nasm [Packages] EmbeddedPkg/EmbeddedPkg.dec @@ -63,6 +64,7 @@ [Pcd] gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable + gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable [FixedPcd] gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase diff --git a/OvmfPkg/Library/PlatformInitLib/X64/Paging.nasm b/OvmfPkg/Library/PlatformInitLib/X64/Paging.nasm new file mode 100644 index 000000000000..895a80950e20 --- /dev/null +++ b/OvmfPkg/Library/PlatformInitLib/X64/Paging.nasm @@ -0,0 +1,76 @@ +;------------------------------------------------------------------------------ +; @file +; +; Switch from 5-level paging mode to 4-level paging mode. +; +; This assumes everything (code, stack, page tables) is in 32-bit +; address space. Which is true for PEI phase even in X64 builds +; because low memory is used for early firmware setup. +; +; This also assumes the standard ResetVector GDT is active. +; +; SPDX-License-Identifier: BSD-2-Clause-Patent +;------------------------------------------------------------------------------ + +SECTION .text +BITS 64 + +global ASM_PFX(Switch4Level) +ASM_PFX(Switch4Level): + + ; save regs + push rax + push rbx + push rcx + push rdx + + ; cs:ip for long mode + lea rax, [rel Switch4Level64] + mov rbx, 0x3800000000 ; LINEAR_CODE64_SEL << 32 + or rax, rbx + push rax + + ; cs:ip for 32-bit mode + lea rax, [rel Switch4Level32] + mov rbx, 0x1000000000 ; LINEAR_CODE_SEL << 32 + or rax, rbx + push rax + + ; enter 32-bit mode + retf + +Switch4Level64: + ; restore regs + pop rdx + pop rcx + pop rbx + pop rax + + ret + +BITS 32 + +Switch4Level32: + ; disable paging + mov eax, cr0 + btc eax, 31 ; clear PG + mov cr0, eax + + ; disable 5-level paging + mov eax, cr4 + btc eax, 12 ; clear la57 + mov cr4, eax + + ; fixup cr3 (dereference 5th level) + mov eax, cr3 + mov eax, [ eax ] + and eax, 0xfffff000 + mov cr3, eax + + ; enable paging + mov eax, cr0 + bts eax, 31 ; set PG + mov cr0, eax + + ; back to long mode + retf From 662272ef41fe848a6c0515de6b43e93d3dc5c672 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Fri, 21 Apr 2023 11:06:05 -0700 Subject: [PATCH 133/280] Sync AARCH64 GCD Capabilities with Page Table On AARCH64 systems, the GCD is not fully synced with the page table. On x86 systems, the GCD is synced by adding `EFI_MEMORY_RO`, `EFI_MEMORY_RP`, and `EFI_MEMORY_XP` to the current capabilities of the GCD, then the page table attributes are set on the GCD attributes. However, on AARCH64, the GCD capabilities do not get updated, instead only the attributes from the page table are masked by the existing GCD capabilities, which means that any new page table attribute which are already set are dropped and the GCD does not reflect the state of the system. This has been seen to cause issues where memory in the page table that was marked `EFI_MEMORY_XP` had an additional attribute set using the GCD capabilities, which did not include `EFI_MEMORY_XP`, this caused the page table to be updated to lose `EFI_MEMORY_XP`, which is a potential security issue. The existing behavior on AARCH64 systems is an implementation error, it assumes one of two things: - The page table attributes must be a subset of the GCD capabilities - The GCD does not need to have its capabilities synced to what the page table attributes are The first is incorrect as important attributes such as `EFI_MEMORY_XP` do not get applied to the GCD capabilities by default and therefore must be synced back. This comment from ArmPkg's CpuDxe driver helps explain: ```c // The GCD implementation maintains its own copy of the state of memory // space attributes. GCD needs to know what the initial memory space // attributes are. The CPU Arch. Protocol does not provide a // GetMemoryAttributes function for GCD to get this so we must resort to // calling GCD (as if we were a client) to update its copy of the // attributes. This is bad architecture and should be replaced with a // way for GCD to query the CPU Arch. driver of the existing memory // space attributes instead. ``` However, this comment misses that updating the capabilities is critical to updating the attributes. The second is incorrect because significant pieces of core code reference the GCD attributes instead of the page table attributes. For example, NonDiscoverablePciDeviceDxe uses the GCD capabilities and attributes when interacting with a non-discoverable PCI device. When the GCD is not synced to the page table, we get the errors and security concerns listed above. Signed-off-by: Oliver Smith-Denny --- ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c | 55 +++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c b/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c index 2d60c7d24dc0..dbe71e4d59e4 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c +++ b/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c @@ -90,6 +90,7 @@ SetGcdMemorySpaceAttributes ( UINTN EndIndex; EFI_PHYSICAL_ADDRESS RegionStart; UINT64 RegionLength; + UINT64 Capabilities; DEBUG (( DEBUG_GCD, @@ -146,14 +147,56 @@ SetGcdMemorySpaceAttributes ( RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart; } + // Always add RO, RP, and XP, as all memory is capable of supporting these types (they are software constructs, + // not hardware features) and they are critical to maintaining a security boundary. + Capabilities = MemorySpaceMap[Index].Capabilities | EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP; + + // Update GCD capabilities as these may have changed in the page table from the original GCD setting + // this follows the same pattern as x86 GCD and Page Table syncing + Status = gDS->SetMemorySpaceCapabilities ( + RegionStart, + RegionLength, + Capabilities + ); + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a - failed to update GCD capabilities: 0x%llx on memory region: 0x%llx length: 0x%llx Status: %r\n", + __func__, + Capabilities, + RegionStart, + RegionLength, + Status + )); + + // If we fail to set capabilities, we should assert as this is a GCD internal error, but follow the previous + // behavior and try to set the attributes (which may or may not fail) + ASSERT_EFI_ERROR (Status); + } + // - // Set memory attributes according to MTRR attribute and the original attribute of descriptor + // Set memory attributes according to page table attributes and the original attributes of descriptor // - gDS->SetMemorySpaceAttributes ( - RegionStart, - RegionLength, - (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes) - ); + Status = gDS->SetMemorySpaceAttributes ( + RegionStart, + RegionLength, + (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (Attributes & Capabilities) + ); + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a - failed to update GCD attributes: 0x%llx on memory region: 0x%llx length: 0x%llx Status: %r\n", + __func__, + Attributes, + RegionStart, + RegionLength, + Status + )); + + ASSERT_EFI_ERROR (Status); + } } return EFI_SUCCESS; From 5c63e22a9fe268bdfa18d49419cbf43d4ec65b93 Mon Sep 17 00:00:00 2001 From: Dionna Glaze Date: Tue, 6 Aug 2024 15:44:54 +0000 Subject: [PATCH 134/280] OvmfPkg: Move kernel hashes section to end When launching a SEV-SNP VM, the ROM is not all that must be measured. The OvmfSevMetadata sections describe ranges of memory that must be measured with different types than PAGE_TYPE_NORMAL, except one. The SevSnpKernelHashes page is also PAGE_TYPE_NORMAL, but is populated by the VMM from configuration data that is separate from the OVMF build itself. To more compactly provide reference values for the measurement of the firmware separately from the kernel hashes, it's advantageous to measure as much known information as possible first. Whereas VMMs are permitted to measure these sections in any order they prefer, the normative order of how they appear in the .fd is easiest to follow. This change is semantics-preserving. Measurement calculation tools that do not follow the normative ordering would need updating to accommodate, but I don't know of any. The accounting for EC2 moving the CPUID page to the end of measurement would be unchanged. This change is to improve performance of a proposed launch update event log to separate responsibility for initially measured data before VM launch, application/vnd.amd.sevsnp.launch-updates+cbor: https://github.com/deeglaze/draft-deeglaze-amd-sev-snp-corim-profile Signed-off-by: Dionna Glaze --- OvmfPkg/ResetVector/X64/OvmfSevMetadata.asm | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/OvmfPkg/ResetVector/X64/OvmfSevMetadata.asm b/OvmfPkg/ResetVector/X64/OvmfSevMetadata.asm index 2511073a466f..09e9cf9149ab 100644 --- a/OvmfPkg/ResetVector/X64/OvmfSevMetadata.asm +++ b/OvmfPkg/ResetVector/X64/OvmfSevMetadata.asm @@ -76,6 +76,12 @@ SvsmCaa: DD SVSM_CAA_SIZE DD OVMF_SECTION_TYPE_SVSM_CAA +; Region need to be pre-validated by the hypervisor +PreValidate3: + DD SNP_SEC_MEM_BASE_DESC_3 + DD SNP_SEC_MEM_SIZE_DESC_3 + DD OVMF_SECTION_TYPE_SNP_SEC_MEM + %if (SEV_SNP_KERNEL_HASHES_BASE > 0) ; Kernel hashes for measured direct boot, or zero page if ; there are no kernel hashes / SEV secrets @@ -85,10 +91,5 @@ SevSnpKernelHashes: DD OVMF_SECTION_TYPE_KERNEL_HASHES %endif -; Region need to be pre-validated by the hypervisor -PreValidate3: - DD SNP_SEC_MEM_BASE_DESC_3 - DD SNP_SEC_MEM_SIZE_DESC_3 - DD OVMF_SECTION_TYPE_SNP_SEC_MEM OvmfSevGuidedStructureEnd: ALIGN 16 From 468a36b22f0ac61b1f4def70ebbb98949def161d Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 1 Aug 2024 18:41:42 +0200 Subject: [PATCH 135/280] CryptoPkg/OpensslLib CLANGDWARF: Use gnu99 C dialect for asm() support 'asm' is not a keyword in C99, but GCC supports it nonetheless as a GNU extension. So when using Clang, we must specify the gnu99 dialect explicitly, or inline asm blocks using asm() rather than __asm__() will be rejected by the compiler. Signed-off-by: Ard Biesheuvel --- CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf | 2 +- CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf b/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf index 912fd07f09db..dd07d0f72260 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf @@ -2003,7 +2003,7 @@ # GCC:*_*_IA32_CC_FLAGS = -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_IA32) -Wno-error=maybe-uninitialized -Wno-error=unused-but-set-variable GCC:*_*_X64_CC_FLAGS = -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_X64) -Wno-error=maybe-uninitialized -Wno-error=format -Wno-format -Wno-error=unused-but-set-variable -DNO_MSABI_VA_FUNCS - GCC:*_CLANGDWARF_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize + GCC:*_CLANGDWARF_*_CC_FLAGS = -std=gnu99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize # Revisit after switching to 3.0 branch GCC:*_GCC5_*_CC_FLAGS = -Wno-unused-but-set-variable diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf b/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf index 8f8b94c3ac5c..b65ecf1e37cf 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf @@ -2155,7 +2155,7 @@ # GCC:*_*_IA32_CC_FLAGS = -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_IA32) -Wno-error=maybe-uninitialized -Wno-error=unused-but-set-variable GCC:*_*_X64_CC_FLAGS = -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_X64) -Wno-error=maybe-uninitialized -Wno-error=format -Wno-format -Wno-error=unused-but-set-variable -DNO_MSABI_VA_FUNCS - GCC:*_CLANGDWARF_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize + GCC:*_CLANGDWARF_*_CC_FLAGS = -std=gnu99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize # Revisit after switching to 3.0 branch GCC:*_GCC5_*_CC_FLAGS = -Wno-unused-but-set-variable From 90d861f63d0fe467cec9659703f02d3d32969dc3 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 29 Aug 2024 19:44:18 +0200 Subject: [PATCH 136/280] CryptoPkg/BaseCryptLibMbedTls: Fix uninitialized variable errors Clang complains about a couple of variables potentially being uninitialized, and those complaints seem to be valid. Signed-off-by: Ard Biesheuvel --- .../BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c | 1 + .../Library/BaseCryptLibMbedTls/Pk/CryptTs.c | 15 +++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c index e3283dad48ad..6caed97c9429 100644 --- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c @@ -486,6 +486,7 @@ Pkcs7Sign ( return FALSE; } + Buffer = NULL; BufferSize = 4096; SignatureLen = MAX_SIGNATURE_SIZE; diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptTs.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptTs.c index d3fa205f9ce1..d7a07836bb18 100644 --- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptTs.c +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptTs.c @@ -118,12 +118,11 @@ ImageTimestampVerify ( OUT EFI_TIME *SigningTime ) { - BOOLEAN Status; - UINT8 *Ptr; - UINT8 *End; - INT32 Len; - UINTN ObjLen; - UINT8 *TempPtr; + UINT8 *Ptr; + UINT8 *End; + INT32 Len; + UINTN ObjLen; + UINT8 *TempPtr; // // Initializations @@ -374,8 +373,8 @@ ImageTimestampVerify ( // if (SigningTime != NULL) { SetMem (SigningTime, sizeof (EFI_TIME), 0); - Status = ConvertAsn1TimeToEfiTime (Ptr, SigningTime); + return ConvertAsn1TimeToEfiTime (Ptr, SigningTime); } - return Status; + return TRUE; } From 95ee7f3ef7a34773e0528410fd0178aecfdd89b5 Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Thu, 27 Jun 2024 11:22:29 -0700 Subject: [PATCH 137/280] BaseTools: Trim: Add header/footer for ASL include When including one ASL file in another, add a header / footer to the included file to easily tell where the included file starts and ends. Signed-off-by: Joey Vagedes --- BaseTools/Source/Python/Trim/Trim.py | 33 +++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/BaseTools/Source/Python/Trim/Trim.py b/BaseTools/Source/Python/Trim/Trim.py index 6d7bc0551026..ea9d1a06d5e4 100644 --- a/BaseTools/Source/Python/Trim/Trim.py +++ b/BaseTools/Source/Python/Trim/Trim.py @@ -248,6 +248,23 @@ def TrimPreprocessedVfr(Source, Target): except: EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target) +# Create a banner to indicate the start and +# end of the included ASL file. Banner looks like:- +# +# /************************************* +# * @param * +# *************************************/ +# +# @param Pathname File pathname to be included in the banner +# +def AddIncludeHeader(Pathname): + StartLine = "/*" + '*' * (len(Pathname) + 4) + EndLine = '*' * (len(Pathname) + 4) + "*/" + Banner = '\n' + StartLine + Banner += '\n' + ('{0} {1} {0}'.format('*', Pathname)) + Banner += '\n' + EndLine + '\n' + return Banner + ## Read the content ASL file, including ASL included, recursively # # @param Source File to be read @@ -276,16 +293,18 @@ def DoInclude(Source, Indent='', IncludePathList=[], LocalSearchPath=None, Inclu try: with open(IncludeFile, "r") as File: F = File.readlines() - except: + except Exception: with codecs.open(IncludeFile, "r", encoding='utf-8') as File: F = File.readlines() break else: - EdkLogger.error("Trim", "Failed to find include file %s" % Source) + EdkLogger.error("Trim", FILE_NOT_FOUND, ExtraData="Failed to find include file %s" % Source) return [] - except: - EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source) - return [] + except Exception as e: + if str(e) == str(FILE_NOT_FOUND): + raise + else: + EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source) # avoid A "include" B and B "include" A @@ -312,7 +331,9 @@ def DoInclude(Source, Indent='', IncludePathList=[], LocalSearchPath=None, Inclu LocalSearchPath = os.path.dirname(IncludeFile) CurrentIndent = Indent + Result[0][0] IncludedFile = Result[0][1] + NewFileContent.append(AddIncludeHeader(IncludedFile+" --START")) NewFileContent.extend(DoInclude(IncludedFile, CurrentIndent, IncludePathList, LocalSearchPath,IncludeFileList,filetype)) + NewFileContent.append(AddIncludeHeader(IncludedFile+" --END")) NewFileContent.append("\n") elif filetype == "ASM": Result = gIncludePattern.findall(Line) @@ -324,7 +345,9 @@ def DoInclude(Source, Indent='', IncludePathList=[], LocalSearchPath=None, Inclu IncludedFile = IncludedFile.strip() IncludedFile = os.path.normpath(IncludedFile) + NewFileContent.append(AddIncludeHeader(IncludedFile+" --START")) NewFileContent.extend(DoInclude(IncludedFile, '', IncludePathList, LocalSearchPath,IncludeFileList,filetype)) + NewFileContent.append(AddIncludeHeader(IncludedFile+" --END")) NewFileContent.append("\n") gIncludedAslFile.pop() From baecba68a32b26778e902faed64f2e701e584531 Mon Sep 17 00:00:00 2001 From: Ashraf Ali Date: Sun, 11 Aug 2024 21:58:00 +0530 Subject: [PATCH 138/280] MdePkg: Remove duplicate source from BaseMemoryLib INF files Signed-off-by: Ashraf Ali --- .../BaseMemoryLibMmx/BaseMemoryLibMmx.inf | 23 --------- .../BaseMemoryLibOptDxe.inf | 11 ---- .../BaseMemoryLibOptPei.inf | 51 +++++-------------- .../BaseMemoryLibRepStr.inf | 22 -------- .../BaseMemoryLibSse2/BaseMemoryLibSse2.inf | 22 -------- 5 files changed, 13 insertions(+), 116 deletions(-) diff --git a/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf b/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf index c470fa442b75..18fc5875e24a 100644 --- a/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf +++ b/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf @@ -46,17 +46,6 @@ MemLibInternals.h [Sources.Ia32] - Ia32/ScanMem64.nasm - Ia32/ScanMem32.nasm - Ia32/ScanMem16.nasm - Ia32/ScanMem8.nasm - Ia32/CompareMem.nasm - Ia32/SetMem64.nasm - Ia32/SetMem32.nasm - Ia32/SetMem16.nasm - Ia32/ZeroMem.nasm - Ia32/SetMem.nasm - Ia32/CopyMem.nasm Ia32/ScanMem64.nasm Ia32/ScanMem32.nasm Ia32/ScanMem16.nasm @@ -82,20 +71,8 @@ X64/SetMem16.nasm X64/SetMem.nasm X64/CopyMem.nasm - X64/ScanMem64.nasm - X64/ScanMem32.nasm - X64/ScanMem16.nasm - X64/ScanMem8.nasm - X64/CompareMem.nasm - X64/SetMem64.nasm - X64/SetMem32.nasm - X64/SetMem16.nasm - X64/ZeroMem.nasm - X64/SetMem.nasm - X64/CopyMem.nasm X64/IsZeroBuffer.nasm - [LibraryClasses] DebugLib BaseLib diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf b/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf index 366a6c6f64a0..6a7fa9a5652a 100644 --- a/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf +++ b/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf @@ -29,17 +29,6 @@ MemLibInternals.h [Sources.Ia32] - Ia32/ScanMem64.nasm - Ia32/ScanMem32.nasm - Ia32/ScanMem16.nasm - Ia32/ScanMem8.nasm - Ia32/CompareMem.nasm - Ia32/ZeroMem.nasm - Ia32/SetMem64.nasm - Ia32/SetMem32.nasm - Ia32/SetMem16.nasm - Ia32/SetMem.nasm - Ia32/CopyMem.nasm Ia32/ScanMem64.nasm Ia32/ScanMem32.nasm Ia32/ScanMem16.nasm diff --git a/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf b/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf index 0bb4b7ce5ed2..43c2cc2a0a9b 100644 --- a/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf +++ b/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf @@ -27,19 +27,21 @@ [Sources] MemLibInternals.h + ScanMem64Wrapper.c + ScanMem32Wrapper.c + ScanMem16Wrapper.c + ScanMem8Wrapper.c + ZeroMemWrapper.c + CompareMemWrapper.c + SetMem64Wrapper.c + SetMem32Wrapper.c + SetMem16Wrapper.c + SetMemWrapper.c + CopyMemWrapper.c + IsZeroBufferWrapper.c + MemLibGuid.c [Sources.Ia32] - Ia32/ScanMem64.nasm - Ia32/ScanMem32.nasm - Ia32/ScanMem16.nasm - Ia32/ScanMem8.nasm - Ia32/CompareMem.nasm - Ia32/ZeroMem.nasm - Ia32/SetMem64.nasm - Ia32/SetMem32.nasm - Ia32/SetMem16.nasm - Ia32/SetMem.nasm - Ia32/CopyMem.nasm Ia32/ScanMem64.nasm Ia32/ScanMem32.nasm Ia32/ScanMem16.nasm @@ -52,19 +54,6 @@ Ia32/SetMem.nasm Ia32/CopyMem.nasm Ia32/IsZeroBuffer.nasm - ScanMem64Wrapper.c - ScanMem32Wrapper.c - ScanMem16Wrapper.c - ScanMem8Wrapper.c - ZeroMemWrapper.c - CompareMemWrapper.c - SetMem64Wrapper.c - SetMem32Wrapper.c - SetMem16Wrapper.c - SetMemWrapper.c - CopyMemWrapper.c - IsZeroBufferWrapper.c - MemLibGuid.c [Sources.X64] X64/ScanMem64.nasm @@ -79,20 +68,6 @@ X64/SetMem.nasm X64/CopyMem.nasm X64/IsZeroBuffer.nasm - ScanMem64Wrapper.c - ScanMem32Wrapper.c - ScanMem16Wrapper.c - ScanMem8Wrapper.c - ZeroMemWrapper.c - CompareMemWrapper.c - SetMem64Wrapper.c - SetMem32Wrapper.c - SetMem16Wrapper.c - SetMemWrapper.c - CopyMemWrapper.c - IsZeroBufferWrapper.c - MemLibGuid.c - [Packages] MdePkg/MdePkg.dec diff --git a/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf b/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf index 9d4f8769c01f..59983d0a0c5b 100644 --- a/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf +++ b/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf @@ -42,17 +42,6 @@ MemLibGuid.c [Sources.Ia32] - Ia32/ScanMem64.nasm - Ia32/ScanMem32.nasm - Ia32/ScanMem16.nasm - Ia32/ScanMem8.nasm - Ia32/CompareMem.nasm - Ia32/ZeroMem.nasm - Ia32/SetMem64.nasm - Ia32/SetMem32.nasm - Ia32/SetMem16.nasm - Ia32/SetMem.nasm - Ia32/CopyMem.nasm Ia32/ScanMem64.nasm Ia32/ScanMem32.nasm Ia32/ScanMem16.nasm @@ -67,17 +56,6 @@ Ia32/IsZeroBuffer.nasm [Sources.X64] - X64/ScanMem64.nasm - X64/ScanMem32.nasm - X64/ScanMem16.nasm - X64/ScanMem8.nasm - X64/CompareMem.nasm - X64/ZeroMem.nasm - X64/SetMem64.nasm - X64/SetMem32.nasm - X64/SetMem16.nasm - X64/SetMem.nasm - X64/CopyMem.nasm X64/ScanMem64.nasm X64/ScanMem32.nasm X64/ScanMem16.nasm diff --git a/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf b/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf index 79618c9fd563..69a29a1b7da3 100644 --- a/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf +++ b/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf @@ -41,17 +41,6 @@ MemLibGuid.c [Sources.Ia32] - Ia32/ScanMem64.nasm - Ia32/ScanMem32.nasm - Ia32/ScanMem16.nasm - Ia32/ScanMem8.nasm - Ia32/CompareMem.nasm - Ia32/ZeroMem.nasm - Ia32/SetMem64.nasm - Ia32/SetMem32.nasm - Ia32/SetMem16.nasm - Ia32/SetMem.nasm - Ia32/CopyMem.nasm Ia32/ScanMem64.nasm Ia32/ScanMem32.nasm Ia32/ScanMem16.nasm @@ -66,17 +55,6 @@ Ia32/IsZeroBuffer.nasm [Sources.X64] - X64/ScanMem64.nasm - X64/ScanMem32.nasm - X64/ScanMem16.nasm - X64/ScanMem8.nasm - X64/CompareMem.nasm - X64/ZeroMem.nasm - X64/SetMem64.nasm - X64/SetMem32.nasm - X64/SetMem16.nasm - X64/SetMem.nasm - X64/CopyMem.nasm X64/ScanMem64.nasm X64/ScanMem32.nasm X64/ScanMem16.nasm From 96b90e150c2f107c64a827e82451b642a42df686 Mon Sep 17 00:00:00 2001 From: Matthew Carlson Date: Fri, 19 Jun 2020 20:49:33 +0000 Subject: [PATCH 139/280] SecurityPkg: Measure Invoke EBS even in failure case This patch measures the ExitBootServices invocation to the TPM even in the case of ExitBootServices failing, per TCG PC Client Platform Firmware Profile Version 1.06 Revision 52 Family 2.0 section 8.2.4(i). Signed-off-by: Oliver Smith-Denny --- SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c index b55b6c12d2c5..4d0c241f4dea 100644 --- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c +++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c @@ -2615,6 +2615,17 @@ OnExitBootServicesFailed ( { EFI_STATUS Status; + // + // Measure invocation of ExitBootServices, + // + Status = TcgMeasureAction ( + 5, + EFI_EXIT_BOOT_SERVICES_INVOCATION + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION)); + } + // // Measure Failure of ExitBootServices, // From f7abf6af2db7a823aa139fbbf8a82d209aca4998 Mon Sep 17 00:00:00 2001 From: zodf0055980 Date: Wed, 21 Aug 2024 15:18:08 +0800 Subject: [PATCH 140/280] SecurityPkg: Fix exponent unmarshaled as 16 bits According issue #5536, exponent is 32 bits but is unmarshaled as 16 bits. Signed-off-by: zodf0055980 --- SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c index 335957d6cedc..888979e96923 100644 --- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c +++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c @@ -252,7 +252,7 @@ Tpm2ReadPublic ( OutPublic->publicArea.parameters.rsaDetail.keyBits = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); Buffer += sizeof (UINT16); - OutPublic->publicArea.parameters.rsaDetail.exponent = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); + OutPublic->publicArea.parameters.rsaDetail.exponent = SwapBytes32 (ReadUnaligned32 ((UINT32 *)Buffer)); Buffer += sizeof (UINT32); break; case TPM_ALG_ECC: From 4ef87f455b57e4529db1420fbfba22c9c16f1444 Mon Sep 17 00:00:00 2001 From: Saloni Kasbekar Date: Thu, 29 Aug 2024 20:59:22 -0700 Subject: [PATCH 141/280] MdePkg: Add Reset Reason definitions Add Reset Reason definitions defined in ACPI 6.5 Signed-off-by: Saloni Kasbekar --- MdePkg/Include/IndustryStandard/Acpi65.h | 48 ++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/MdePkg/Include/IndustryStandard/Acpi65.h b/MdePkg/Include/IndustryStandard/Acpi65.h index 1f2af6ad2a52..42a9aaf860e2 100644 --- a/MdePkg/Include/IndustryStandard/Acpi65.h +++ b/MdePkg/Include/IndustryStandard/Acpi65.h @@ -2944,6 +2944,54 @@ typedef struct { #define EFI_ACPI_6_5_PHAT_FIRMWARE_HEALTH_DATA_RECORD_UNKNOWN 0x02 #define EFI_ACPI_6_5_PHAT_FIRMWARE_HEALTH_DATA_RECORD_ADVISORY 0x03 +/// +/// Reset Reason Health Record Vendor Data Entry +/// +typedef struct { + GUID VendorDataID; + UINT16 Length; + UINT16 Revision; + // UINTN Data[]; +} EFI_ACPI_6_5_PHAT_RESET_REASON_HEALTH_RECORD_VENDOR_DATA_ENTRY; + +/// +/// Reset Reason Health Record Structure +/// +typedef struct { + UINT8 SupportedSources; + UINT8 Source; + UINT8 SubSource; + UINT8 Reason; + UINT16 VendorCount; + // EFI_ACPI_6_5_PHAT_RESET_REASON_HEALTH_RECORD_VENDOR_DATA_ENTRY VendorSpecificResetReasonEntry[]; +} EFI_ACPI_6_5_PHAT_RESET_REASON_HEALTH_RECORD_STRUCTURE; + +#define EFI_ACPI_6_5_PHAT_RESET_REASON_HEADER_GUID { 0x7a014ce2, 0xf263, 0x4b77, { 0xb8, 0x8a, 0xe6, 0x33, 0x6b, 0x78, 0x2c, 0x14 }} + +#define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_UNKNOWN BIT0 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_HARDWARE BIT1 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_FIRMWARE BIT2 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_SOFTWARE BIT3 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_SUPERVISOR BIT4 + +#define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_UNKNOWN BIT0 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_HARDWARE BIT1 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_FIRMWARE BIT2 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_SOFTWARE BIT3 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_SUPERVISOR BIT4 + +#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_UNKNOWN 0x00 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_COLD_BOOT 0x01 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_COLD_RESET 0x02 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_WARM_RESET 0x03 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_UPDATE 0x04 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_UNEXPECTED_RESET 0x20 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_FAULT 0x21 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_TIMEOUT 0x22 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_THERMAL 0x23 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_POWER_LOSS 0x24 +#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_POWER_BUTTON 0x25 + // // Known table signatures // From af15e4535dcd4b2bfd0799ab36f0a3622687bdd3 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Fri, 17 May 2024 11:49:22 +0100 Subject: [PATCH 142/280] ArmPkg: Fix timer wrap-around The timer counter register can wrap around and when this happens, we'll get misbehavior for any MicroSecondDelay() calls. This adds handling for that. Signed-off-by: Carsten Haitzler --- ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c index 76f94c916155..cc1be0125b65 100644 --- a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c +++ b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c @@ -62,6 +62,8 @@ MicroSecondDelay ( { UINT64 TimerTicks64; UINT64 SystemCounterVal; + UINT64 PreviousSystemCounterVal; + UINT64 DeltaCounterVal; // Calculate counter ticks that represent requested delay: // = MicroSeconds x TICKS_PER_MICRO_SEC @@ -75,13 +77,17 @@ MicroSecondDelay ( ); // Read System Counter value - SystemCounterVal = ArmGenericTimerGetSystemCount (); - - TimerTicks64 += SystemCounterVal; + PreviousSystemCounterVal = ArmGenericTimerGetSystemCount (); // Wait until delay count expires. - while (SystemCounterVal < TimerTicks64) { + while (TimerTicks64 > 0) { SystemCounterVal = ArmGenericTimerGetSystemCount (); + // Get how much we advanced this tick. Wrap around still has delta correct + DeltaCounterVal = (SystemCounterVal - PreviousSystemCounterVal) + & (MAX_UINT64 >> 8); // Account for a lesser (minimum) size + // Never wrap back around below zero by choosing the min and thus stop at 0 + TimerTicks64 -= MIN (TimerTicks64, DeltaCounterVal); + PreviousSystemCounterVal = SystemCounterVal; } return MicroSeconds; From 91853ca6a5497c1b6e8ff356b6fffd977f7f5b38 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Mon, 2 Sep 2024 10:06:18 +0800 Subject: [PATCH 143/280] MdeModulePkg/VariableStandaloneMm: Notify variable write ready in MM In Standalone MM, there is no notification to MM drivers that variable write is ready. Install gSmmVariableWriteGuid into MM handle database for the notification. Cc: Liming Gao Cc: Ray Ni Signed-off-by: Wei6 Xu --- .../Variable/RuntimeDxe/VariableStandaloneMm.c | 13 +++++++++++++ .../Variable/RuntimeDxe/VariableStandaloneMm.inf | 1 + 2 files changed, 14 insertions(+) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c index f3daca3eba4e..10578226c606 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c @@ -7,6 +7,8 @@ Copyright (c) 2018, Linaro, Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ + +#include #include #include "Variable.h" @@ -67,6 +69,17 @@ VariableNotifySmmWriteReady ( VOID ) { + EFI_STATUS Status; + EFI_HANDLE Handle; + + Handle = NULL; + Status = gMmst->MmInstallProtocolInterface ( + &Handle, + &gSmmVariableWriteGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); } /** diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf index c4185718aac0..2d651c3c3d50 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf @@ -115,6 +115,7 @@ gEfiMemoryOverwriteControlDataGuid ## SOMETIMES_CONSUMES ## Variable:L"MemoryOverwriteRequestControl" gEfiMemoryOverwriteRequestControlLockGuid ## SOMETIMES_PRODUCES ## Variable:L"MemoryOverwriteRequestControlLock" + gSmmVariableWriteGuid ## PRODUCES ## GUID # Install protocol gEfiSystemNvDataFvGuid ## CONSUMES ## GUID gEdkiiFaultTolerantWriteGuid ## SOMETIMES_CONSUMES ## HOB From 50871ee0ecd63bb9885068fb0b3ea1b47f5e2bb4 Mon Sep 17 00:00:00 2001 From: Ken Lautner Date: Fri, 23 Aug 2024 19:03:27 -0700 Subject: [PATCH 144/280] BaseTools: GenMake: FIx missing logs from GenMake.py EdkLogger logs were not showing up as part of the build log output. Adding the EdkLogger import to GenMake.py fixes the missing log prints. Signed-off-by: Kenneth Lautner --- BaseTools/Source/Python/AutoGen/GenMake.py | 1 + 1 file changed, 1 insertion(+) diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py index fbd35d498923..6d9c60b70298 100755 --- a/BaseTools/Source/Python/AutoGen/GenMake.py +++ b/BaseTools/Source/Python/AutoGen/GenMake.py @@ -14,6 +14,7 @@ import string import re import os.path as path +from Common import EdkLogger from Common.LongFilePathSupport import OpenLongFilePath as open from Common.MultipleWorkspace import MultipleWorkspace as mws from Common.BuildToolError import * From a5f543272899fcf3b04e0665ba87164fb19f564a Mon Sep 17 00:00:00 2001 From: zodf0055980 Date: Mon, 2 Sep 2024 14:07:37 +0800 Subject: [PATCH 145/280] SecurityPkg: Fix break missing at TPM_ALG_KEYEDHASH case According issue #5509, case TPM_ALG_KEYEDHASH is missing the break statement. Signed-off-by: zodf0055980 --- SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c | 1 + 1 file changed, 1 insertion(+) diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c index 888979e96923..3aaf012d7eb6 100644 --- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c +++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c @@ -178,6 +178,7 @@ Tpm2ReadPublic ( return EFI_UNSUPPORTED; } + break; case TPM_ALG_SYMCIPHER: OutPublic->publicArea.parameters.symDetail.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer)); Buffer += sizeof (UINT16); From 5dafa13d623a764648221ebb644f880c3cb1198f Mon Sep 17 00:00:00 2001 From: Abdul Lateef Attar Date: Thu, 29 Aug 2024 14:28:17 +0000 Subject: [PATCH 146/280] DynamicTablesPkg: Adds WSMT generator for X64 Adds ACPI WSMT table generator library. Updates acpi standard table enum with wsmt. Updates X64 namespace object. Updates the object parser. Updates the Readme. Cc: Sami Mujawar Cc: Pierre Gondois Signed-off-by: Abdul Lateef Attar --- DynamicTablesPkg/DynamicTables.dsc.inc | 6 + DynamicTablesPkg/Include/AcpiTableGenerator.h | 4 + .../Include/X64NameSpaceObjects.h | 14 +- .../Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf | 35 +++ .../Acpi/X64/AcpiWsmtLib/WsmtGenerator.c | 288 ++++++++++++++++++ .../ConfigurationManagerObjectParser.c | 7 + DynamicTablesPkg/Readme.md | 1 + 7 files changed, 353 insertions(+), 2 deletions(-) create mode 100644 DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf create mode 100644 DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/WsmtGenerator.c diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc index dc363dc802b0..f4866c2dd740 100644 --- a/DynamicTablesPkg/DynamicTables.dsc.inc +++ b/DynamicTablesPkg/DynamicTables.dsc.inc @@ -52,6 +52,11 @@ DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf [Components.IA32, Components.X64] + # + # Generators (IA32/X64 specific) + # + DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf + # # Dynamic Table Factory Dxe # @@ -60,6 +65,7 @@ # Generators # Common NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf + NULL|DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf } [Components.ARM, Components.AARCH64] diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h b/DynamicTablesPkg/Include/AcpiTableGenerator.h index 778a908bcda2..761a5ec6d368 100644 --- a/DynamicTablesPkg/Include/AcpiTableGenerator.h +++ b/DynamicTablesPkg/Include/AcpiTableGenerator.h @@ -2,6 +2,7 @@ Copyright (c) 2017 - 2022, Arm Limited. All rights reserved.
Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -72,6 +73,8 @@ The Dynamic Tables Framework implements the following ACPI table generators: The SSDT Pci Express generator collates the Pci Express information from the Configuration Manager and generates a SSDT table describing a Pci Express bus. + - WSMT : The WSMT generator collates the WSMT protection flag information + from the Configuration Manager and builds the WSMT table. */ /** The ACPI_TABLE_GENERATOR_ID type describes ACPI table generator ID. @@ -101,6 +104,7 @@ typedef enum StdAcpiTableId { EStdAcpiTableIdSsdtPciExpress, ///< SSDT Pci Express Generator EStdAcpiTableIdPcct, ///< PCCT Generator EStdAcpiTableIdTpm2, ///< TPM2 Generator + EStdAcpiTableIdWsmt, ///< WSMT Generator EStdAcpiTableIdMax } ESTD_ACPI_TABLE_ID; diff --git a/DynamicTablesPkg/Include/X64NameSpaceObjects.h b/DynamicTablesPkg/Include/X64NameSpaceObjects.h index 2fa696b4c309..d897051d88b6 100644 --- a/DynamicTablesPkg/Include/X64NameSpaceObjects.h +++ b/DynamicTablesPkg/Include/X64NameSpaceObjects.h @@ -30,8 +30,9 @@ typedef enum X64ObjectID { EX64ObjFadtXgpeBlockInfo, ///< 6 - FADT 64-bit GPE block info EX64ObjFadtSleepBlockInfo, ///< 7 - FADT Sleep block info EX64ObjFadtResetBlockInfo, ///< 8 - FADT Reset block info - EX64ObjFadtMiscInfo, ///< 0 - FADT Legacy fields info - EX64ObjMax ///< 10 - Maximum Object ID + EX64ObjFadtMiscInfo, ///< 9 - FADT Legacy fields info + EX64ObjWsmtFlagsInfo, ///< 10 - WSMT protection flags info + EX64ObjMax ///< 11 - Maximum Object ID } EX64_OBJECT_ID; /** A structure that describes the @@ -167,4 +168,13 @@ typedef struct CmX64FadtFadtMiscInfo { UINT8 Century; } CM_X64_FADT_MISC_INFO; +/** + A structure that describes the WSMT protection flags information. + + ID: EX64ObjWsmtFlagsInfo +*/ +typedef struct CmX64WsmtFlagsInfo { + UINT32 ProtectionFlags; +} CM_X64_WSMT_FLAGS_INFO; + #endif // X64_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf b/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf new file mode 100644 index 000000000000..06e8f8cd3fd0 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf @@ -0,0 +1,35 @@ +## @file +# WSMT Table Generator +# +# Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 1.30 + BASE_NAME = AcpiWsmtLib + FILE_GUID = FA6B175A-0AAF-4BFA-843A-1D885206C070 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiWsmtLibConstructor + DESTRUCTOR = AcpiWsmtLibDestructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.IA32, Sources.X64] + WsmtGenerator.c + +[Packages] + DynamicTablesPkg/DynamicTablesPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib diff --git a/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/WsmtGenerator.c b/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/WsmtGenerator.c new file mode 100644 index 000000000000..97622948f593 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/WsmtGenerator.c @@ -0,0 +1,288 @@ +/** @file + WSMT Table Generator Implementation. + + This file implements the WSMT Table Generator. + The WSMT table is used to specify the security mitigation + that are enabled in the Windows OS. + + Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WSMT_PROTECTION_VALID_FLAGS \ + (EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS | \ + EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION | \ + EFI_WSMT_PROTECTION_FLAGS_SYSTEM_RESOURCE_PROTECTION) + +/** This macro expands to a function that retrieves the + WSMT protection flags information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceX64, + EX64ObjWsmtFlagsInfo, + CM_X64_WSMT_FLAGS_INFO + ); + +/** The ACPI WSMT Table. +*/ +STATIC +EFI_ACPI_WSMT_TABLE AcpiWsmt = { + ACPI_HEADER ( + EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE, + EFI_ACPI_WSMT_TABLE, + EFI_WSMT_TABLE_REVISION + ), + // ProtectionFlags + 0 +}; + +/** Update the protection flags information in the WSMT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. + @retval EFI_UNSUPPORTED If invalid protection flags provided. +**/ +STATIC +EFI_STATUS +EFIAPI +WsmtAddProtectionFlagsInfo ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol + ) +{ + EFI_STATUS Status; + CM_X64_WSMT_FLAGS_INFO *WsmtFlagInfo; + + ASSERT (CfgMgrProtocol != NULL); + + // Get the WSMT protection flag from the Platform Configuration Manager + Status = GetEX64ObjWsmtFlagsInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &WsmtFlagInfo, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: WSMT: Failed to get WSMT protection flag information." \ + " Status = %r\n", + Status + )); + return Status; + } + + DEBUG (( + DEBUG_INFO, + "WSMT: Protection flags = 0x%x\n", + WsmtFlagInfo->ProtectionFlags + )); + + // Validate the protection flags + if ((WsmtFlagInfo->ProtectionFlags & ~WSMT_PROTECTION_VALID_FLAGS) != 0) { + DEBUG (( + DEBUG_ERROR, + "ERROR: WSMT: Invalid protection flags = 0x%x\n", + WsmtFlagInfo->ProtectionFlags + )); + return EFI_UNSUPPORTED; + } + + if ((WsmtFlagInfo->ProtectionFlags & EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION) != 0) { + if ((WsmtFlagInfo->ProtectionFlags & EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS) == 0) { + DEBUG (( + DEBUG_ERROR, + "ERROR: WSMT: Invalid protection flags. EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS not set.\n" + )); + return EFI_UNSUPPORTED; + } + } + + AcpiWsmt.ProtectionFlags = WsmtFlagInfo->ProtectionFlags; + return Status; +} + +/** Construct the WSMT table. + + This function invokes the Configuration Manager protocol interface + to get the required information for generating the ACPI table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResources function. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [out] Table Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildWsmtTable ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + EFI_STATUS Status; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || + (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) + { + DEBUG (( + DEBUG_ERROR, + "ERROR: WSMT: Requested table revision = %d, is not supported." + "Supported table revision: Minimum = %d, Maximum = %d\n", + AcpiTableInfo->AcpiTableRevision, + This->MinAcpiTableRevision, + This->AcpiTableRevision + )); + return EFI_INVALID_PARAMETER; + } + + *Table = NULL; + + Status = AddAcpiHeader ( + CfgMgrProtocol, + This, + (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiWsmt, + AcpiTableInfo, + sizeof (EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE) + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: WSMT: Failed to add ACPI header. Status = %r\n", + Status + )); + goto error_handler; + } + + // Update protection flags Info + Status = WsmtAddProtectionFlagsInfo (CfgMgrProtocol); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + *Table = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiWsmt; +error_handler: + return Status; +} + +/** This macro defines the WSMT Table Generator revision. +*/ +#define WSMT_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the WSMT Table Generator. +*/ +STATIC +CONST +ACPI_TABLE_GENERATOR WsmtGenerator = { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdWsmt), + // Generator Description + L"ACPI.STD.WSMT.GENERATOR", + // ACPI Table Signature + EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE, + // ACPI Table Revision supported by this Generator + EFI_WSMT_TABLE_REVISION, + // Minimum supported ACPI Table Revision + EFI_WSMT_TABLE_REVISION, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + WSMT_GENERATOR_REVISION, + // Build Table function + BuildWsmtTable, + // No additional resources are allocated by the generator. + // Hence the Free Resource function is not required. + NULL, + // Extended build function not needed + NULL, + // Extended build function not implemented by the generator. + // Hence extended free resource function is not required. + NULL +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiWsmtLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&WsmtGenerator); + DEBUG ((DEBUG_INFO, "WSMT: Register Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiWsmtLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&WsmtGenerator); + DEBUG ((DEBUG_INFO, "WSMT: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index eceb91a6d863..c9737f67c379 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -850,6 +850,12 @@ STATIC CONST CM_OBJ_PARSER CmX64ObjFadtMiscInfoParser[] = { { "Century", 1, "0x%x", NULL } }; +/** A parser for EX64ObjWsmtFlagsInfo. +*/ +STATIC CONST CM_OBJ_PARSER CmX64ObjWsmtFlagsInfoParser[] = { + { "WsmtFlags", 4, "0x%x", NULL } +}; + /** A parser for X64 namespace objects. */ STATIC CONST CM_OBJ_PARSER_ARRAY X64NamespaceObjectParser[] = { @@ -863,6 +869,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY X64NamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EX64ObjFadtSleepBlockInfo,CmX64ObjFadtSleepBlockInfoParser), CM_PARSER_ADD_OBJECT (EX64ObjFadtResetBlockInfo,CmX64ObjFadtResetBlockInfoParser), CM_PARSER_ADD_OBJECT (EX64ObjFadtMiscInfo, CmX64ObjFadtMiscInfoParser), + CM_PARSER_ADD_OBJECT (EX64ObjWsmtFlagsInfo, CmX64ObjWsmtFlagsInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EX64ObjMax) }; diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index b2230aff4659..84d7ca9fafd6 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -514,4 +514,5 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 7 | Sleep Block Info | | | 8 | Reset Block Info | | | 9 | Miscellaneous Block Info | | +| 10 | Windows protection flag Info | | | `*` | All other values are reserved. | | From 238ccc5944b89e6f57a1a775a84ea08b294bbba6 Mon Sep 17 00:00:00 2001 From: Abdul Lateef Attar Date: Fri, 2 Aug 2024 11:13:38 +0000 Subject: [PATCH 147/280] DynamicTablesPkg: Adds generic ACPI Creator ID Adds generic creator id as DYNT. Updates the common ACPI tables with generic CreatorId. Cc: Sami Mujawar Cc: Pierre Gondois Signed-off-by: Abdul Lateef Attar --- DynamicTablesPkg/Include/AcpiTableGenerator.h | 7 ++++++- .../Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c | 2 +- .../Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c | 2 +- .../Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c | 2 +- .../Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c | 2 +- .../Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c | 2 +- .../Library/Acpi/Common/AcpiRawLib/RawGenerator.c | 2 +- .../Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c | 2 +- .../Library/Acpi/Common/AcpiSratLib/SratGenerator.c | 2 +- .../AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c | 2 +- .../Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c | 2 +- .../Common/AcpiSsdtSerialPortLib/SsdtSerialPortGenerator.c | 2 +- .../Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c | 2 +- .../Library/Common/AmlLib/CodeGen/AmlCodeGen.c | 2 +- 14 files changed, 19 insertions(+), 14 deletions(-) diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h b/DynamicTablesPkg/Include/AcpiTableGenerator.h index 761a5ec6d368..d4ad603e2b85 100644 --- a/DynamicTablesPkg/Include/AcpiTableGenerator.h +++ b/DynamicTablesPkg/Include/AcpiTableGenerator.h @@ -160,9 +160,14 @@ typedef enum StdAcpiTableId { TableId \ ) -/** The Creator ID for the ACPI tables generated using +/** The generic creator ID for the ACPI tables generated using the standard ACPI table generators. */ +#define TABLE_GENERATOR_CREATOR_ID SIGNATURE_32('D', 'Y', 'N', 'T') + +/** The Creator ID for the ACPI tables generated using + the standard ACPI table generators for ARM. +*/ #define TABLE_GENERATOR_CREATOR_ID_ARM SIGNATURE_32('A', 'R', 'M', 'H') /** A macro to initialise the common header part of EFI ACPI tables as diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c index 6f49e6a27053..f387319f1475 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c @@ -534,7 +534,7 @@ ACPI_TABLE_GENERATOR Dbg2Generator = { // Minimum supported ACPI Table Revision EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION, // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, + TABLE_GENERATOR_CREATOR_ID, // Creator Revision DBG2_GENERATOR_REVISION, // Build table function. Use the extended version instead. diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c index c2140ef414d2..3ba3fc230b6c 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c @@ -582,7 +582,7 @@ ACPI_TABLE_GENERATOR FadtGenerator = { // Minimum supported ACPI Table Revision EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_REVISION, // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, + TABLE_GENERATOR_CREATOR_ID, // Creator Revision FADT_GENERATOR_REVISION, // Build Table function diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c index 40dea304e301..79a2f598f942 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c @@ -306,7 +306,7 @@ ACPI_TABLE_GENERATOR McfgGenerator = { // Minimum supported ACPI Table Revision EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION, // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, + TABLE_GENERATOR_CREATOR_ID, // Creator Revision MCFG_GENERATOR_REVISION, // Build Table function diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c index 36e6807023fb..e362254a3cb4 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c @@ -1121,7 +1121,7 @@ ACPI_PCCT_GENERATOR PcctGenerator = { // Minimum ACPI Table Revision supported by this Generator EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION, // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, + TABLE_GENERATOR_CREATOR_ID, // Creator Revision PCCT_GENERATOR_REVISION, // Build Table function diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c index fd465cbab0e9..8e2e1f61ab1f 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c @@ -1403,7 +1403,7 @@ ACPI_PPTT_GENERATOR PpttGenerator = { // Minimum supported ACPI Table Revision EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION, // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, + TABLE_GENERATOR_CREATOR_ID, // Creator Revision PPTT_GENERATOR_REVISION, // Build Table function diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/RawGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/RawGenerator.c index a8323ad4ea03..a4f1cfb0d774 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/RawGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/RawGenerator.c @@ -81,7 +81,7 @@ ACPI_TABLE_GENERATOR RawGenerator = { // Minimum ACPI Table Revision - Unused 0, // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, + TABLE_GENERATOR_CREATOR_ID, // Creator Revision RAW_GENERATOR_REVISION, // Build Table function diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c index 065729d7eecf..ddd8262f3824 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c @@ -419,7 +419,7 @@ ACPI_TABLE_GENERATOR SpcrGenerator = { // Minimum supported ACPI Table Revision EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION, // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, + TABLE_GENERATOR_CREATOR_ID, // Creator Revision SPCR_GENERATOR_REVISION, // Build table function. Use the extended version instead. diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c index 1a9434e6bd08..20e1a4bfd358 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c @@ -599,7 +599,7 @@ ACPI_TABLE_GENERATOR SratGenerator = { // Minimum supported ACPI Table Revision EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION, // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, + TABLE_GENERATOR_CREATOR_ID, // Creator Revision SRAT_GENERATOR_REVISION, // Build Table function diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c index 24b06d01dc4d..3bb0c2fe25a8 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c @@ -1359,7 +1359,7 @@ ACPI_CPU_TOPOLOGY_GENERATOR SsdtCpuTopologyGenerator = { // Minimum ACPI Table Revision - Unused 0, // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, + TABLE_GENERATOR_CREATOR_ID, // Creator Revision SSDT_CPU_TOPOLOGY_GENERATOR_REVISION, // Build Table function diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c index 618056e85a2a..7fe780d27ea3 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c @@ -1168,7 +1168,7 @@ ACPI_PCI_GENERATOR SsdtPcieGenerator = { // Minimum ACPI Table Revision - Unused 0, // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, + TABLE_GENERATOR_CREATOR_ID, // Creator Revision SSDT_PCI_GENERATOR_REVISION, // Build table function. Use the extended version instead. diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortGenerator.c index 671ba057400a..bbd8b65db92a 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortGenerator.c @@ -301,7 +301,7 @@ ACPI_TABLE_GENERATOR SsdtSerialPortGenerator = { // Minimum ACPI Table Revision - Unused 0, // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, + TABLE_GENERATOR_CREATOR_ID, // Creator Revision SSDT_SERIAL_GENERATOR_REVISION, // Build table function. Use the extended version instead. diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c index 93dca5e56417..7255c933d3b1 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c @@ -341,7 +341,7 @@ ACPI_TABLE_GENERATOR Tpm2Generator = { // Minimum supported ACPI Table Revision EFI_TPM2_ACPI_TABLE_REVISION_4, // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, + TABLE_GENERATOR_CREATOR_ID, // Creator Revision TPM2_GENERATOR_REVISION, // Build Table function diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c index f433a461b24f..35ec2aaa6703 100644 --- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c +++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c @@ -116,7 +116,7 @@ AmlCodeGenDefinitionBlock ( CopyMem (&AcpiHeader.OemId, OemId, 6); CopyMem (&AcpiHeader.OemTableId, OemTableId, 8); AcpiHeader.OemRevision = OemRevision; - AcpiHeader.CreatorId = TABLE_GENERATOR_CREATOR_ID_ARM; + AcpiHeader.CreatorId = TABLE_GENERATOR_CREATOR_ID; AcpiHeader.CreatorRevision = CREATE_REVISION (1, 0); Status = AmlCreateRootNode (&AcpiHeader, NewRootNode); From 4aea90ea53fd6541033be6c834ca21fa61d08435 Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Mon, 3 Jun 2024 10:52:53 +0800 Subject: [PATCH 148/280] MdeModulePkg: Relocation of mVarCheckHiiBin declaration Relocate the declaration of mVarCheckHiiBin to support for standalone MM modules utilizing the same mVarCheckHiiBin. 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 | 5 +---- MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c | 6 ++++-- MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h | 4 +++- .../Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c | 5 +---- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h index 89de54ddf45d..f6894c9cb31d 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h @@ -1,7 +1,7 @@ /** @file Include file for Var Check Hii handler and bin. -Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -51,7 +51,4 @@ DumpVarCheckHii ( IN UINTN VarCheckHiiBinSize ); -extern VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin; -extern UINTN mVarCheckHiiBinSize; - #endif diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c index ca8227df6b2b..5e54e19bc18f 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c @@ -1,14 +1,16 @@ /** @file Var Check Hii bin generation. -Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "VarCheckHiiGen.h" -LIST_ENTRY mVarCheckHiiList = INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckHiiList); +VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin = NULL; +UINTN mVarCheckHiiBinSize = 0; +LIST_ENTRY mVarCheckHiiList = INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckHiiList); #define VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE SIGNATURE_32 ('V', 'C', 'H', 'V') diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h index c70bf726cd09..ace1fe643029 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h @@ -1,7 +1,7 @@ /** @file Include file for Var Check Hii bin generation. -Copyright (c) 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -10,6 +10,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define _VAR_CHECK_HII_GEN_H_ #include "VarCheckHii.h" +extern VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin; +extern UINTN mVarCheckHiiBinSize; /** Dump Hii Package. diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c index ee2d98c7d13b..9de0b9d6e3ae 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c @@ -7,7 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "VarCheckHii.h" - +#include "VarCheckHiiGen.h" GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckHiiHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /** @@ -258,9 +258,6 @@ VarCheckHiiQuestion ( return TRUE; } -VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin = NULL; -UINTN mVarCheckHiiBinSize = 0; - /** SetVariable check handler HII. From 6b3ac9cbf8fd8364dd372f0191f2938d53911a93 Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Mon, 3 Jun 2024 10:52:53 +0800 Subject: [PATCH 149/280] 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 --- .../Library/VarCheckHiiLib/VarCheckHii.h | 7 + .../Library/VarCheckHiiLib/VarCheckHiiGen.c | 1 + .../VarCheckHiiLibMmDependency.c | 138 ++++++++++++++++++ .../VarCheckHiiLibMmDependency.inf | 53 +++++++ 4 files changed, 199 insertions(+) create mode 100644 MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.c create mode 100644 MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h index f6894c9cb31d..59b51e8155dd 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 5e54e19bc18f..e6e92af4e2d9 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 000000000000..9ba75b729997 --- /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 000000000000..9798a1b4ddd1 --- /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 From ee1e163a2f07a352cf27225a02347fee4222c170 Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Mon, 24 Jun 2024 16:28:06 +0800 Subject: [PATCH 150/280] MdeModulePkg: Enable VarCheckHiiLibMmDependency Cc: Liming Gao Cc: Jiaxin Wu Cc: Ray Ni Signed-off-by: Yuanhao Xie --- MdeModulePkg/MdeModulePkg.dsc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index fe7ab972ad17..aa2a2da49dfa 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -2,7 +2,7 @@ # EFI/PI Reference Module Package for All Architectures # # (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
-# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2024, Intel Corporation. All rights reserved.
# Copyright (c) Microsoft Corporation. # Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
# @@ -178,6 +178,7 @@ MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxStandaloneMmLib.inf MemLib|StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf + VarCheckHiiLibMmDependency|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf [LibraryClasses.ARM, LibraryClasses.AARCH64] LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf @@ -339,6 +340,7 @@ MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf + MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf MdeModulePkg/Library/PlatformVarCleanupLib/PlatformVarCleanupLib.inf MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf MdeModulePkg/Library/DxeFileExplorerProtocol/DxeFileExplorerProtocol.inf From 5718c9b06f2b3f348138cd6844c1059c1d98fc61 Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Fri, 5 Jul 2024 17:18:03 +0800 Subject: [PATCH 151/280] MdeModulePkg: Modified BuildVarCheckHiiBin parameter to IN OUT. Change the Size parameter of BuildVarCheckHiiBin from OUT to an input-output parameter. 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/VarCheckHiiGen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c index e6e92af4e2d9..abc5fd4117c3 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c @@ -1514,7 +1514,7 @@ DestroyHiiVariableNode ( **/ VOID * BuildVarCheckHiiBin ( - OUT UINTN *Size + IN OUT UINTN *Size ) { VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode; From db43a80c105c0ac89c3d918f375a05670a88e9ac Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Sat, 31 Aug 2024 02:25:55 +0800 Subject: [PATCH 152/280] MdeModulePkg: Rename VarCheckHiiLibNullClass as VarCheckHiiLib. No functional changes. 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 --- .../{VarCheckHiiLibNullClass.c => VarCheckHiiLib.c} | 2 +- MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename MdeModulePkg/Library/VarCheckHiiLib/{VarCheckHiiLibNullClass.c => VarCheckHiiLib.c} (96%) diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c similarity index 96% rename from MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c rename to MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c index 9de0b9d6e3ae..d824c6eb65e0 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c @@ -614,7 +614,7 @@ DumpVarCheckHii ( **/ EFI_STATUS EFIAPI -VarCheckHiiLibNullClassConstructor ( +VarCheckHiiLibConstructor ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf index 9e55d20f2814..2b99928475af 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf @@ -1,5 +1,5 @@ ## @file -# NULL class library to register var check HII handler. +# VarCheckHiiLib library to register var check HII handler. # # Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.
# @@ -15,10 +15,10 @@ MODULE_TYPE = DXE_RUNTIME_DRIVER VERSION_STRING = 1.0 LIBRARY_CLASS = NULL|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER - CONSTRUCTOR = VarCheckHiiLibNullClassConstructor + CONSTRUCTOR = VarCheckHiiLibConstructor [Sources] - VarCheckHiiLibNullClass.c + VarCheckHiiLib.c VarCheckHii.h VarCheckHiiGenFromFv.c VarCheckHiiGenFromHii.c From 3956f4e39273bd937f10959672c317f2c0dc02f2 Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Mon, 8 Jul 2024 11:41:28 +0800 Subject: [PATCH 153/280] MdeModulePkg: Wrap SetVariableCheckHandlerHii as a common API Rename SetVariableCheckHandlerHii and wrap it as a common API to facilitate the usage in the following patches. 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 --- .../Library/VarCheckHiiLib/VarCheckHiiLib.c | 86 ++------------ .../Library/VarCheckHiiLib/VarCheckHiiLib.inf | 2 + .../VarCheckHiiLib/VarCheckHiiLibCommon.c | 105 ++++++++++++++++++ .../VarCheckHiiLib/VarCheckHiiLibCommon.h | 43 +++++++ 4 files changed, 158 insertions(+), 78 deletions(-) create mode 100644 MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c create mode 100644 MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.h diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c index d824c6eb65e0..c6bd8cc88745 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c @@ -8,6 +8,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "VarCheckHii.h" #include "VarCheckHiiGen.h" +#include "VarCheckHiiLibCommon.h" GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckHiiHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /** @@ -259,17 +260,14 @@ VarCheckHiiQuestion ( } /** - SetVariable check handler HII. - - @param[in] VariableName Name of Variable to set. - @param[in] VendorGuid Variable vendor GUID. - @param[in] Attributes Attribute value of the variable. - @param[in] DataSize Size of Data to set. - @param[in] Data Data pointer. - + Sets the variable check handler for HII. + @param[in] VariableName Name of Variable to set. + @param[in] VendorGuid Variable vendor GUID. + @param[in] Attributes Attribute value of the variable. + @param[in] DataSize Size of Data to set. + @param[in] Data Data pointer. @retval EFI_SUCCESS The SetVariable check result was success. @retval EFI_SECURITY_VIOLATION Check fail. - **/ EFI_STATUS EFIAPI @@ -281,75 +279,7 @@ SetVariableCheckHandlerHii ( IN VOID *Data ) { - VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable; - VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion; - - if (mVarCheckHiiBin == NULL) { - return EFI_SUCCESS; - } - - if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) { - // - // Do not check delete variable. - // - return EFI_SUCCESS; - } - - // - // For Hii Variable header align. - // - HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (mVarCheckHiiBin); - while ((UINTN)HiiVariable < ((UINTN)mVarCheckHiiBin + mVarCheckHiiBinSize)) { - if ((StrCmp ((CHAR16 *)(HiiVariable + 1), VariableName) == 0) && - (CompareGuid (&HiiVariable->Guid, VendorGuid))) - { - // - // Found the Hii Variable that could be used to do check. - // - DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize)); - if (HiiVariable->Attributes != Attributes) { - DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Attributes - 0x%08x\n", HiiVariable->Attributes)); - return EFI_SECURITY_VIOLATION; - } - - if (DataSize == 0) { - DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - CHECK PASS with DataSize == 0 !\n")); - return EFI_SUCCESS; - } - - if (HiiVariable->Size != DataSize) { - DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Size - 0x%x\n", HiiVariable->Size)); - return EFI_SECURITY_VIOLATION; - } - - // - // Do the check. - // For Hii Question header align. - // - HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength)); - while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) { - if (!VarCheckHiiQuestion (HiiQuestion, Data, DataSize)) { - return EFI_SECURITY_VIOLATION; - } - - // - // For Hii Question header align. - // - HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length)); - } - - DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - ALL CHECK PASS!\n")); - return EFI_SUCCESS; - } - - // - // For Hii Variable header align. - // - HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length)); - } - - // Not found, so pass. - return EFI_SUCCESS; + return CheckHiiVariableCommon (mVarCheckHiiBin, mVarCheckHiiBinSize, VariableName, VendorGuid, Attributes, DataSize, Data); } #ifdef DUMP_VAR_CHECK_HII diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf index 2b99928475af..f25b1905579a 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf @@ -25,6 +25,8 @@ VarCheckHiiGen.c VarCheckHiiGen.h InternalVarCheckStructure.h + VarCheckHiiLibCommon.c + VarCheckHiiLibCommon.h [Packages] MdePkg/MdePkg.dec diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c new file mode 100644 index 000000000000..b8fbbf31f554 --- /dev/null +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c @@ -0,0 +1,105 @@ +/** @file + Var Check Hii Lib Common logic +Copyright (c) 2024, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include +#include + +#include "VarCheckHii.h" +#include "VarCheckHiiLibCommon.h" +EFI_HANDLE mEfiVariableCheckHiiHandle = NULL; + +/** + SetVariable check handler HII. + @param[in] HiiVariableBin Variable BIN. + @param[in] HiiVariableBinSize The size of Variable BIN. + @param[in] VariableName Name of Variable to set. + @param[in] VendorGuid Variable vendor GUID. + @param[in] Attributes Attribute value of the variable. + @param[in] DataSize Size of Data to set. + @param[in] Data Data pointer. + @retval EFI_SUCCESS The SetVariable check result was success. + @retval EFI_SECURITY_VIOLATION Check fail. +**/ +EFI_STATUS +EFIAPI +CheckHiiVariableCommon ( + IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariableBin, + IN UINTN HiiVariableBinSize, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable; + VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion; + + if (HiiVariableBin == NULL) { + return EFI_SUCCESS; + } + + if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) { + // + // Do not check delete variable. + // + } + + // + // For Hii Variable header align. + // + HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (HiiVariableBin); + while ((UINTN)HiiVariable < ((UINTN)HiiVariableBin + HiiVariableBinSize)) { + if ((StrCmp ((CHAR16 *)(HiiVariable + 1), VariableName) == 0) && + (CompareGuid (&HiiVariable->Guid, VendorGuid))) + { + // + // Found the Hii Variable that could be used to do check. + // + DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize)); + if (HiiVariable->Attributes != Attributes) { + DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Attributes - 0x%08x\n", HiiVariable->Attributes)); + return EFI_SECURITY_VIOLATION; + } + + if (DataSize == 0) { + DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - CHECK PASS with DataSize == 0 !\n")); + return EFI_SUCCESS; + } + + if (HiiVariable->Size != DataSize) { + DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Size - 0x%x\n", HiiVariable->Size)); + return EFI_SECURITY_VIOLATION; + } + + // + // Do the check. + // For Hii Question header align. + // + HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength)); + while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) { + if (!VarCheckHiiQuestion (HiiQuestion, Data, DataSize)) { + return EFI_SECURITY_VIOLATION; + } + + // + // For Hii Question header align. + // + HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length)); + } + + DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - ALL CHECK PASS!\n")); + return EFI_SUCCESS; + } + + // + // For Hii Variable header align. + // + HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length)); + } + + // Not found, so pass. + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.h b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.h new file mode 100644 index 000000000000..06249f0e4d4c --- /dev/null +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.h @@ -0,0 +1,43 @@ +/** @file + Var Check Hii Lib Common logic +Copyright (c) 2024, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef VAR_CHECK_HII_LIB_GUID_H_ +#define VAR_CHECK_HII_LIB_GUID_H_ + +#include +#include +#include +#include +#include +#include + +#include "VarCheckHii.h" + +/** + SetVariable check handler HII. + @param[in] HiiVariableBin Variable BIN. + @param[in] HiiVariableBinSize The size of Variable BIN. + @param[in] VariableName Name of Variable to set. + @param[in] VendorGuid Variable vendor GUID. + @param[in] Attributes Attribute value of the variable. + @param[in] DataSize Size of Data to set. + @param[in] Data Data pointer. + @retval EFI_SUCCESS The SetVariable check result was success. + @retval EFI_SECURITY_VIOLATION Check fail. +**/ +EFI_STATUS +EFIAPI +CheckHiiVariableCommon ( + IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariableBin, + IN UINTN HiiVariableBinSize, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ); + +#endif From 45cf57ce798860b02fbeca8c8f4d5e971c476e0e Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Mon, 24 Jun 2024 23:39:27 +0800 Subject: [PATCH 154/280] MdeModulePkg: Relocate VarCheckHiiInternalDumpHex, VarCheckHiiQuestion Move VarCheckHiiInternalDumpHex and VarCheckHiiQuestion to the common file. 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 --- .../Library/VarCheckHiiLib/VarCheckHiiLib.c | 249 ------------------ .../VarCheckHiiLib/VarCheckHiiLibCommon.c | 246 ++++++++++++++++- 2 files changed, 245 insertions(+), 250 deletions(-) diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c index c6bd8cc88745..d6d68bbb7b69 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c @@ -9,255 +9,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "VarCheckHii.h" #include "VarCheckHiiGen.h" #include "VarCheckHiiLibCommon.h" -GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckHiiHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - -/** - Dump some hexadecimal data. - - @param[in] Indent How many spaces to indent the output. - @param[in] Offset The offset of the dump. - @param[in] DataSize The size in bytes of UserData. - @param[in] UserData The data to dump. - -**/ -VOID -VarCheckHiiInternalDumpHex ( - IN UINTN Indent, - IN UINTN Offset, - IN UINTN DataSize, - IN VOID *UserData - ) -{ - UINT8 *Data; - - CHAR8 Val[50]; - - CHAR8 Str[20]; - - UINT8 TempByte; - UINTN Size; - UINTN Index; - - Data = UserData; - while (DataSize != 0) { - Size = 16; - if (Size > DataSize) { - Size = DataSize; - } - - for (Index = 0; Index < Size; Index += 1) { - TempByte = Data[Index]; - Val[Index * 3 + 0] = mVarCheckHiiHex[TempByte >> 4]; - Val[Index * 3 + 1] = mVarCheckHiiHex[TempByte & 0xF]; - Val[Index * 3 + 2] = (CHAR8)((Index == 7) ? '-' : ' '); - Str[Index] = (CHAR8)((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte); - } - - Val[Index * 3] = 0; - Str[Index] = 0; - DEBUG ((DEBUG_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str)); - - Data += Size; - Offset += Size; - DataSize -= Size; - } -} - -/** - Var Check Hii Question. - - @param[in] HiiQuestion Pointer to Hii Question - @param[in] Data Data pointer. - @param[in] DataSize Size of Data to set. - - @retval TRUE Check pass - @retval FALSE Check fail. - -**/ -BOOLEAN -VarCheckHiiQuestion ( - IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion, - IN VOID *Data, - IN UINTN DataSize - ) -{ - UINT64 OneData; - UINT64 Minimum; - UINT64 Maximum; - UINT64 OneValue; - UINT8 *Ptr; - UINT8 Index; - UINT8 MaxContainers; - UINT8 StartBit; - UINT8 EndBit; - UINT8 TotalBits; - UINT16 VarOffsetByteLevel; - UINT8 StorageWidthByteLevel; - - if (HiiQuestion->BitFieldStore) { - VarOffsetByteLevel = HiiQuestion->VarOffset / 8; - TotalBits = HiiQuestion->VarOffset % 8 + HiiQuestion->StorageWidth; - StorageWidthByteLevel = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1); - } else { - VarOffsetByteLevel = HiiQuestion->VarOffset; - StorageWidthByteLevel = HiiQuestion->StorageWidth; - } - - if (((UINT32)VarOffsetByteLevel + StorageWidthByteLevel) > DataSize) { - DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x)) > Size(0x%x)\n", VarOffsetByteLevel, StorageWidthByteLevel, DataSize)); - return FALSE; - } - - OneData = 0; - CopyMem (&OneData, (UINT8 *)Data + VarOffsetByteLevel, StorageWidthByteLevel); - if (HiiQuestion->BitFieldStore) { - // - // Get the value from the bit field. - // - StartBit = HiiQuestion->VarOffset % 8; - EndBit = StartBit + HiiQuestion->StorageWidth - 1; - OneData = BitFieldRead64 (OneData, StartBit, EndBit); - } - - switch (HiiQuestion->OpCode) { - case EFI_IFR_ONE_OF_OP: - Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1); - while ((UINTN)Ptr < (UINTN)HiiQuestion + HiiQuestion->Length) { - OneValue = 0; - if (HiiQuestion->BitFieldStore) { - // - // For OneOf stored in bit field, the value of options are saved as UINT32 type. - // - CopyMem (&OneValue, Ptr, sizeof (UINT32)); - } else { - CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth); - } - - if (OneData == OneValue) { - // - // Match - // - break; - } - - if (HiiQuestion->BitFieldStore) { - Ptr += sizeof (UINT32); - } else { - Ptr += HiiQuestion->StorageWidth; - } - } - - if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) { - // - // No match - // - DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OneOf mismatch (0x%lx)\n", OneData)); - DEBUG_CODE ( - VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion); - ); - return FALSE; - } - - break; - - case EFI_IFR_CHECKBOX_OP: - if ((OneData != 0) && (OneData != 1)) { - DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: CheckBox mismatch (0x%lx)\n", OneData)); - DEBUG_CODE ( - VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion); - ); - return FALSE; - } - - break; - - case EFI_IFR_NUMERIC_OP: - Minimum = 0; - Maximum = 0; - Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1); - if (HiiQuestion->BitFieldStore) { - // - // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type. - // - CopyMem (&Minimum, Ptr, sizeof (UINT32)); - Ptr += sizeof (UINT32); - CopyMem (&Maximum, Ptr, sizeof (UINT32)); - Ptr += sizeof (UINT32); - } else { - CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth); - Ptr += HiiQuestion->StorageWidth; - CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth); - Ptr += HiiQuestion->StorageWidth; - } - - // - // No need to check Step, because it is ONLY for UI. - // - if ((OneData < Minimum) || (OneData > Maximum)) { - DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: Numeric mismatch (0x%lx)\n", OneData)); - DEBUG_CODE ( - VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion); - ); - return FALSE; - } - - break; - - case EFI_IFR_ORDERED_LIST_OP: - MaxContainers = ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers; - if (((UINT32)HiiQuestion->VarOffset + HiiQuestion->StorageWidth * MaxContainers) > DataSize) { - DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x) * MaxContainers(0x%02x)) > Size(0x%x)\n", HiiQuestion->VarOffset, HiiQuestion->StorageWidth, MaxContainers, DataSize)); - return FALSE; - } - - for (Index = 0; Index < MaxContainers; Index++) { - OneData = 0; - CopyMem (&OneData, (UINT8 *)Data + HiiQuestion->VarOffset + HiiQuestion->StorageWidth * Index, HiiQuestion->StorageWidth); - if (OneData == 0) { - // - // The value of 0 is used to determine if a particular "slot" in the array is empty. - // - continue; - } - - Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1); - while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) { - OneValue = 0; - CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth); - if (OneData == OneValue) { - // - // Match - // - break; - } - - Ptr += HiiQuestion->StorageWidth; - } - - if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) { - // - // No match - // - DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OrderedList mismatch\n")); - DEBUG_CODE ( - VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->StorageWidth * MaxContainers, (UINT8 *)Data + HiiQuestion->VarOffset); - ); - DEBUG_CODE ( - VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion); - ); - return FALSE; - } - } - - break; - - default: - ASSERT (FALSE); - break; - } - - return TRUE; -} /** Sets the variable check handler for HII. diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c index b8fbbf31f554..00a37df01753 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c @@ -8,7 +8,251 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "VarCheckHii.h" #include "VarCheckHiiLibCommon.h" -EFI_HANDLE mEfiVariableCheckHiiHandle = NULL; +EFI_HANDLE mEfiVariableCheckHiiHandle = NULL; +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckHiiHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +/** + Dump some hexadecimal data. + @param[in] Indent How many spaces to indent the output. + @param[in] Offset The offset of the dump. + @param[in] DataSize The size in bytes of UserData. + @param[in] UserData The data to dump. +**/ +VOID +VarCheckHiiInternalDumpHex ( + IN UINTN Indent, + IN UINTN Offset, + IN UINTN DataSize, + IN VOID *UserData + ) +{ + UINT8 *Data; + + CHAR8 Val[50]; + + CHAR8 Str[20]; + + UINT8 TempByte; + UINTN Size; + UINTN Index; + + Data = UserData; + while (DataSize != 0) { + Size = 16; + if (Size > DataSize) { + Size = DataSize; + } + + for (Index = 0; Index < Size; Index += 1) { + TempByte = Data[Index]; + Val[Index * 3 + 0] = mVarCheckHiiHex[TempByte >> 4]; + Val[Index * 3 + 1] = mVarCheckHiiHex[TempByte & 0xF]; + Val[Index * 3 + 2] = (CHAR8)((Index == 7) ? '-' : ' '); + Str[Index] = (CHAR8)((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte); + } + + Val[Index * 3] = 0; + Str[Index] = 0; + DEBUG ((DEBUG_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str)); + + Data += Size; + Offset += Size; + DataSize -= Size; + } +} + +/** + Var Check Hii Question. + @param[in] HiiQuestion Pointer to Hii Question + @param[in] Data Data pointer. + @param[in] DataSize Size of Data to set. + @retval TRUE Check pass + @retval FALSE Check fail. +**/ +BOOLEAN +VarCheckHiiQuestion ( + IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion, + IN VOID *Data, + IN UINTN DataSize + ) +{ + UINT64 OneData; + UINT64 Minimum; + UINT64 Maximum; + UINT64 OneValue; + UINT8 *Ptr; + UINT8 Index; + UINT8 MaxContainers; + UINT8 StartBit; + UINT8 EndBit; + UINT8 TotalBits; + UINT16 VarOffsetByteLevel; + UINT8 StorageWidthByteLevel; + + if (HiiQuestion->BitFieldStore) { + VarOffsetByteLevel = HiiQuestion->VarOffset / 8; + TotalBits = HiiQuestion->VarOffset % 8 + HiiQuestion->StorageWidth; + StorageWidthByteLevel = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1); + } else { + VarOffsetByteLevel = HiiQuestion->VarOffset; + StorageWidthByteLevel = HiiQuestion->StorageWidth; + } + + if (((UINT32)VarOffsetByteLevel + StorageWidthByteLevel) > DataSize) { + DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x)) > Size(0x%x)\n", VarOffsetByteLevel, StorageWidthByteLevel, DataSize)); + return FALSE; + } + + OneData = 0; + CopyMem (&OneData, (UINT8 *)Data + VarOffsetByteLevel, StorageWidthByteLevel); + if (HiiQuestion->BitFieldStore) { + // + // Get the value from the bit field. + // + StartBit = HiiQuestion->VarOffset % 8; + EndBit = StartBit + HiiQuestion->StorageWidth - 1; + OneData = BitFieldRead64 (OneData, StartBit, EndBit); + } + + switch (HiiQuestion->OpCode) { + case EFI_IFR_ONE_OF_OP: + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1); + while ((UINTN)Ptr < (UINTN)HiiQuestion + HiiQuestion->Length) { + OneValue = 0; + if (HiiQuestion->BitFieldStore) { + // + // For OneOf stored in bit field, the value of options are saved as UINT32 type. + // + CopyMem (&OneValue, Ptr, sizeof (UINT32)); + } else { + CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth); + } + + if (OneData == OneValue) { + // + // Match + // + break; + } + + if (HiiQuestion->BitFieldStore) { + Ptr += sizeof (UINT32); + } else { + Ptr += HiiQuestion->StorageWidth; + } + } + + if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) { + // + // No match + // + DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OneOf mismatch (0x%lx)\n", OneData)); + DEBUG_CODE ( + VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion); + ); + return FALSE; + } + + break; + + case EFI_IFR_CHECKBOX_OP: + if ((OneData != 0) && (OneData != 1)) { + DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: CheckBox mismatch (0x%lx)\n", OneData)); + DEBUG_CODE ( + VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion); + ); + return FALSE; + } + + break; + + case EFI_IFR_NUMERIC_OP: + Minimum = 0; + Maximum = 0; + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1); + if (HiiQuestion->BitFieldStore) { + // + // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type. + // + CopyMem (&Minimum, Ptr, sizeof (UINT32)); + Ptr += sizeof (UINT32); + CopyMem (&Maximum, Ptr, sizeof (UINT32)); + Ptr += sizeof (UINT32); + } else { + CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth); + Ptr += HiiQuestion->StorageWidth; + CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth); + Ptr += HiiQuestion->StorageWidth; + } + + // + // No need to check Step, because it is ONLY for UI. + // + if ((OneData < Minimum) || (OneData > Maximum)) { + DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: Numeric mismatch (0x%lx)\n", OneData)); + DEBUG_CODE ( + VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion); + ); + return FALSE; + } + + break; + + case EFI_IFR_ORDERED_LIST_OP: + MaxContainers = ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers; + if (((UINT32)HiiQuestion->VarOffset + HiiQuestion->StorageWidth * MaxContainers) > DataSize) { + DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x) * MaxContainers(0x%02x)) > Size(0x%x)\n", HiiQuestion->VarOffset, HiiQuestion->StorageWidth, MaxContainers, DataSize)); + return FALSE; + } + + for (Index = 0; Index < MaxContainers; Index++) { + OneData = 0; + CopyMem (&OneData, (UINT8 *)Data + HiiQuestion->VarOffset + HiiQuestion->StorageWidth * Index, HiiQuestion->StorageWidth); + if (OneData == 0) { + // + // The value of 0 is used to determine if a particular "slot" in the array is empty. + // + continue; + } + + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1); + while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) { + OneValue = 0; + CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth); + if (OneData == OneValue) { + // + // Match + // + break; + } + + Ptr += HiiQuestion->StorageWidth; + } + + if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) { + // + // No match + // + DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OrderedList mismatch\n")); + DEBUG_CODE ( + VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->StorageWidth * MaxContainers, (UINT8 *)Data + HiiQuestion->VarOffset); + ); + DEBUG_CODE ( + VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion); + ); + return FALSE; + } + } + + break; + + default: + ASSERT (FALSE); + break; + } + + return TRUE; +} /** SetVariable check handler HII. From 02f67748039ad44aed83654b9048cfdd052ba424 Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Mon, 24 Jun 2024 23:39:27 +0800 Subject: [PATCH 155/280] MdeModulePkg: Move DUMP_VAR_CHECK_HII in common file No functional changes. Move DUMP_VAR_CHECK_HII in common file 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 --- .../VarCheckHiiLib/VarCheckHiiGenFromHii.c | 251 ++++++++++++++++++ .../Library/VarCheckHiiLib/VarCheckHiiLib.c | 251 ------------------ 2 files changed, 251 insertions(+), 251 deletions(-) diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c index 27d10f8bc6ea..6f152d4e5870 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c @@ -65,3 +65,254 @@ VarCheckHiiGenFromHiiDatabase ( gBS->FreePages (BufferAddress, EFI_SIZE_TO_PAGES (BufferSize)); } } + +#ifdef DUMP_VAR_CHECK_HII +GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING mHiiOpCodeStringTable[] = { + { EFI_IFR_VARSTORE_EFI_OP, "EfiVarStore" }, + { EFI_IFR_ONE_OF_OP, "OneOf" }, + { EFI_IFR_CHECKBOX_OP, "CheckBox" }, + { EFI_IFR_NUMERIC_OP, "Numeric" }, + { EFI_IFR_ORDERED_LIST_OP, "OrderedList" }, +}; + +/** + HII opcode to string. + + @param[in] HiiOpCode Hii OpCode. + + @return Pointer to string. + +**/ +CHAR8 * +HiiOpCodeToStr ( + IN UINT8 HiiOpCode + ) +{ + UINTN Index; + + for (Index = 0; Index < ARRAY_SIZE (mHiiOpCodeStringTable); Index++) { + if (mHiiOpCodeStringTable[Index].HiiOpCode == HiiOpCode) { + return mHiiOpCodeStringTable[Index].HiiOpCodeStr; + } + } + + return ""; +} + +/** + Dump Hii Question. + + @param[in] HiiQuestion Pointer to Hii Question. + +**/ +VOID +DumpHiiQuestion ( + IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion + ) +{ + UINT64 Minimum; + UINT64 Maximum; + UINT64 OneValue; + UINT8 *Ptr; + + DEBUG ((DEBUG_INFO, " VAR_CHECK_HII_QUESTION_HEADER\n")); + DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a) (%a)\n", HiiQuestion->OpCode, HiiOpCodeToStr (HiiQuestion->OpCode), (HiiQuestion->BitFieldStore ? "bit level" : "byte level"))); + DEBUG ((DEBUG_INFO, " Length - 0x%02x\n", HiiQuestion->Length)); + DEBUG ((DEBUG_INFO, " VarOffset - 0x%04x (%a)\n", HiiQuestion->VarOffset, (HiiQuestion->BitFieldStore ? "bit level" : "byte level"))); + DEBUG ((DEBUG_INFO, " StorageWidth - 0x%02x (%a)\n", HiiQuestion->StorageWidth, (HiiQuestion->BitFieldStore ? "bit level" : "byte level"))); + + switch (HiiQuestion->OpCode) { + case EFI_IFR_ONE_OF_OP: + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1); + while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) { + OneValue = 0; + if (HiiQuestion->BitFieldStore) { + // + // For OneOf stored in bit field, the value of options are saved as UINT32 type. + // + CopyMem (&OneValue, Ptr, sizeof (UINT32)); + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue)); + } else { + CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth); + switch (HiiQuestion->StorageWidth) { + case sizeof (UINT8): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue)); + break; + case sizeof (UINT16): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue)); + break; + case sizeof (UINT32): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue)); + break; + case sizeof (UINT64): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue)); + break; + default: + ASSERT (FALSE); + break; + } + } + + if (HiiQuestion->BitFieldStore) { + Ptr += sizeof (UINT32); + } else { + Ptr += HiiQuestion->StorageWidth; + } + } + + break; + + case EFI_IFR_CHECKBOX_OP: + break; + + case EFI_IFR_NUMERIC_OP: + Minimum = 0; + Maximum = 0; + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1); + if (HiiQuestion->BitFieldStore) { + // + // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type. + // + CopyMem (&Minimum, Ptr, sizeof (UINT32)); + Ptr += sizeof (UINT32); + CopyMem (&Maximum, Ptr, sizeof (UINT32)); + Ptr += sizeof (UINT32); + + DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum)); + DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum)); + } else { + CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth); + Ptr += HiiQuestion->StorageWidth; + CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth); + Ptr += HiiQuestion->StorageWidth; + + switch (HiiQuestion->StorageWidth) { + case sizeof (UINT8): + DEBUG ((DEBUG_INFO, " Minimum - 0x%02x\n", Minimum)); + DEBUG ((DEBUG_INFO, " Maximum - 0x%02x\n", Maximum)); + break; + case sizeof (UINT16): + DEBUG ((DEBUG_INFO, " Minimum - 0x%04x\n", Minimum)); + DEBUG ((DEBUG_INFO, " Maximum - 0x%04x\n", Maximum)); + break; + case sizeof (UINT32): + DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum)); + DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum)); + break; + case sizeof (UINT64): + DEBUG ((DEBUG_INFO, " Minimum - 0x%016lx\n", Minimum)); + DEBUG ((DEBUG_INFO, " Maximum - 0x%016lx\n", Maximum)); + break; + default: + ASSERT (FALSE); + break; + } + } + + break; + + case EFI_IFR_ORDERED_LIST_OP: + DEBUG ((DEBUG_INFO, " MaxContainers - 0x%02x\n", ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers)); + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1); + while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) { + OneValue = 0; + CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth); + switch (HiiQuestion->StorageWidth) { + case sizeof (UINT8): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue)); + break; + case sizeof (UINT16): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue)); + break; + case sizeof (UINT32): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue)); + break; + case sizeof (UINT64): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue)); + break; + default: + ASSERT (FALSE); + break; + } + + Ptr += HiiQuestion->StorageWidth; + } + + break; + + default: + ASSERT (FALSE); + break; + } +} + +/** + Dump Hii Variable. + + @param[in] HiiVariable Pointer to Hii Variable. + +**/ +VOID +DumpHiiVariable ( + IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable + ) +{ + VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion; + + DEBUG ((DEBUG_INFO, "VAR_CHECK_HII_VARIABLE_HEADER\n")); + DEBUG ((DEBUG_INFO, " Revision - 0x%04x\n", HiiVariable->Revision)); + DEBUG ((DEBUG_INFO, " HeaderLength - 0x%04x\n", HiiVariable->HeaderLength)); + DEBUG ((DEBUG_INFO, " Length - 0x%08x\n", HiiVariable->Length)); + DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a)\n", HiiVariable->OpCode, HiiOpCodeToStr (HiiVariable->OpCode))); + DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", HiiVariable->Size)); + DEBUG ((DEBUG_INFO, " Attributes - 0x%08x\n", HiiVariable->Attributes)); + DEBUG ((DEBUG_INFO, " Guid - %g\n", &HiiVariable->Guid)); + DEBUG ((DEBUG_INFO, " Name - %s\n", HiiVariable + 1)); + + // + // For Hii Question header align. + // + HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength)); + while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) { + // + // Dump Hii Question related to the Hii Variable. + // + DumpHiiQuestion (HiiQuestion); + // + // For Hii Question header align. + // + HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length)); + } +} + +/** + Dump Var Check HII. + + @param[in] VarCheckHiiBin Pointer to VarCheckHiiBin. + @param[in] VarCheckHiiBinSize VarCheckHiiBin size. + +**/ +VOID +DumpVarCheckHii ( + IN VOID *VarCheckHiiBin, + IN UINTN VarCheckHiiBinSize + ) +{ + VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable; + + DEBUG ((DEBUG_INFO, "DumpVarCheckHii\n")); + + // + // For Hii Variable header align. + // + HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (VarCheckHiiBin); + while ((UINTN)HiiVariable < ((UINTN)VarCheckHiiBin + VarCheckHiiBinSize)) { + DumpHiiVariable (HiiVariable); + // + // For Hii Variable header align. + // + HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length)); + } +} + +#endif diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c index d6d68bbb7b69..22b275525fd6 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c @@ -33,257 +33,6 @@ SetVariableCheckHandlerHii ( return CheckHiiVariableCommon (mVarCheckHiiBin, mVarCheckHiiBinSize, VariableName, VendorGuid, Attributes, DataSize, Data); } -#ifdef DUMP_VAR_CHECK_HII -GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING mHiiOpCodeStringTable[] = { - { EFI_IFR_VARSTORE_EFI_OP, "EfiVarStore" }, - { EFI_IFR_ONE_OF_OP, "OneOf" }, - { EFI_IFR_CHECKBOX_OP, "CheckBox" }, - { EFI_IFR_NUMERIC_OP, "Numeric" }, - { EFI_IFR_ORDERED_LIST_OP, "OrderedList" }, -}; - -/** - HII opcode to string. - - @param[in] HiiOpCode Hii OpCode. - - @return Pointer to string. - -**/ -CHAR8 * -HiiOpCodeToStr ( - IN UINT8 HiiOpCode - ) -{ - UINTN Index; - - for (Index = 0; Index < ARRAY_SIZE (mHiiOpCodeStringTable); Index++) { - if (mHiiOpCodeStringTable[Index].HiiOpCode == HiiOpCode) { - return mHiiOpCodeStringTable[Index].HiiOpCodeStr; - } - } - - return ""; -} - -/** - Dump Hii Question. - - @param[in] HiiQuestion Pointer to Hii Question. - -**/ -VOID -DumpHiiQuestion ( - IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion - ) -{ - UINT64 Minimum; - UINT64 Maximum; - UINT64 OneValue; - UINT8 *Ptr; - - DEBUG ((DEBUG_INFO, " VAR_CHECK_HII_QUESTION_HEADER\n")); - DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a) (%a)\n", HiiQuestion->OpCode, HiiOpCodeToStr (HiiQuestion->OpCode), (HiiQuestion->BitFieldStore ? "bit level" : "byte level"))); - DEBUG ((DEBUG_INFO, " Length - 0x%02x\n", HiiQuestion->Length)); - DEBUG ((DEBUG_INFO, " VarOffset - 0x%04x (%a)\n", HiiQuestion->VarOffset, (HiiQuestion->BitFieldStore ? "bit level" : "byte level"))); - DEBUG ((DEBUG_INFO, " StorageWidth - 0x%02x (%a)\n", HiiQuestion->StorageWidth, (HiiQuestion->BitFieldStore ? "bit level" : "byte level"))); - - switch (HiiQuestion->OpCode) { - case EFI_IFR_ONE_OF_OP: - Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1); - while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) { - OneValue = 0; - if (HiiQuestion->BitFieldStore) { - // - // For OneOf stored in bit field, the value of options are saved as UINT32 type. - // - CopyMem (&OneValue, Ptr, sizeof (UINT32)); - DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue)); - } else { - CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth); - switch (HiiQuestion->StorageWidth) { - case sizeof (UINT8): - DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue)); - break; - case sizeof (UINT16): - DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue)); - break; - case sizeof (UINT32): - DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue)); - break; - case sizeof (UINT64): - DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue)); - break; - default: - ASSERT (FALSE); - break; - } - } - - if (HiiQuestion->BitFieldStore) { - Ptr += sizeof (UINT32); - } else { - Ptr += HiiQuestion->StorageWidth; - } - } - - break; - - case EFI_IFR_CHECKBOX_OP: - break; - - case EFI_IFR_NUMERIC_OP: - Minimum = 0; - Maximum = 0; - Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1); - if (HiiQuestion->BitFieldStore) { - // - // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type. - // - CopyMem (&Minimum, Ptr, sizeof (UINT32)); - Ptr += sizeof (UINT32); - CopyMem (&Maximum, Ptr, sizeof (UINT32)); - Ptr += sizeof (UINT32); - - DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum)); - DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum)); - } else { - CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth); - Ptr += HiiQuestion->StorageWidth; - CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth); - Ptr += HiiQuestion->StorageWidth; - - switch (HiiQuestion->StorageWidth) { - case sizeof (UINT8): - DEBUG ((DEBUG_INFO, " Minimum - 0x%02x\n", Minimum)); - DEBUG ((DEBUG_INFO, " Maximum - 0x%02x\n", Maximum)); - break; - case sizeof (UINT16): - DEBUG ((DEBUG_INFO, " Minimum - 0x%04x\n", Minimum)); - DEBUG ((DEBUG_INFO, " Maximum - 0x%04x\n", Maximum)); - break; - case sizeof (UINT32): - DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum)); - DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum)); - break; - case sizeof (UINT64): - DEBUG ((DEBUG_INFO, " Minimum - 0x%016lx\n", Minimum)); - DEBUG ((DEBUG_INFO, " Maximum - 0x%016lx\n", Maximum)); - break; - default: - ASSERT (FALSE); - break; - } - } - - break; - - case EFI_IFR_ORDERED_LIST_OP: - DEBUG ((DEBUG_INFO, " MaxContainers - 0x%02x\n", ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers)); - Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1); - while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) { - OneValue = 0; - CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth); - switch (HiiQuestion->StorageWidth) { - case sizeof (UINT8): - DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue)); - break; - case sizeof (UINT16): - DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue)); - break; - case sizeof (UINT32): - DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue)); - break; - case sizeof (UINT64): - DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue)); - break; - default: - ASSERT (FALSE); - break; - } - - Ptr += HiiQuestion->StorageWidth; - } - - break; - - default: - ASSERT (FALSE); - break; - } -} - -/** - Dump Hii Variable. - - @param[in] HiiVariable Pointer to Hii Variable. - -**/ -VOID -DumpHiiVariable ( - IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable - ) -{ - VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion; - - DEBUG ((DEBUG_INFO, "VAR_CHECK_HII_VARIABLE_HEADER\n")); - DEBUG ((DEBUG_INFO, " Revision - 0x%04x\n", HiiVariable->Revision)); - DEBUG ((DEBUG_INFO, " HeaderLength - 0x%04x\n", HiiVariable->HeaderLength)); - DEBUG ((DEBUG_INFO, " Length - 0x%08x\n", HiiVariable->Length)); - DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a)\n", HiiVariable->OpCode, HiiOpCodeToStr (HiiVariable->OpCode))); - DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", HiiVariable->Size)); - DEBUG ((DEBUG_INFO, " Attributes - 0x%08x\n", HiiVariable->Attributes)); - DEBUG ((DEBUG_INFO, " Guid - %g\n", &HiiVariable->Guid)); - DEBUG ((DEBUG_INFO, " Name - %s\n", HiiVariable + 1)); - - // - // For Hii Question header align. - // - HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength)); - while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) { - // - // Dump Hii Question related to the Hii Variable. - // - DumpHiiQuestion (HiiQuestion); - // - // For Hii Question header align. - // - HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length)); - } -} - -/** - Dump Var Check HII. - - @param[in] VarCheckHiiBin Pointer to VarCheckHiiBin. - @param[in] VarCheckHiiBinSize VarCheckHiiBin size. - -**/ -VOID -DumpVarCheckHii ( - IN VOID *VarCheckHiiBin, - IN UINTN VarCheckHiiBinSize - ) -{ - VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable; - - DEBUG ((DEBUG_INFO, "DumpVarCheckHii\n")); - - // - // For Hii Variable header align. - // - HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (VarCheckHiiBin); - while ((UINTN)HiiVariable < ((UINTN)VarCheckHiiBin + VarCheckHiiBinSize)) { - DumpHiiVariable (HiiVariable); - // - // For Hii Variable header align. - // - HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length)); - } -} - -#endif - /** Constructor function of VarCheckHiiLib to register var check HII handler. From df58def118a72bcf540e049ae560c6bea0b0c488 Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Mon, 22 Jul 2024 14:31:41 +0800 Subject: [PATCH 156/280] MdeModulePkg: Add VarCheckHiiLibStandaloneMm. This library is designed for handling variable HII checks within the Standalone MMm environment. It includes the functions dedicated to registering handlers that process information received from VarCheckHiiLibMmDependency. 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 --- .../VarCheckHiiLibStandaloneMm.c | 152 ++++++++++++++++++ .../VarCheckHiiLibStandaloneMm.inf | 47 ++++++ .../VarCheckHiiLibStandaloneMm.uni | 15 ++ 3 files changed, 214 insertions(+) create mode 100644 MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.c create mode 100644 MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.inf create mode 100644 MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.uni diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.c new file mode 100644 index 000000000000..c1ee55bb2e15 --- /dev/null +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.c @@ -0,0 +1,152 @@ +/** @file + + Implementation functions and structures for var check services. + This file provides functions and structures to register and handle variable checks + in the Standalone MM environment, specifically for HII variables. + +Copyright (c) 2024, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +#include "VarCheckHii.h" +#include "VarCheckHiiLibCommon.h" + +// +// In the standalone setup, mVarCheckHiiBin is used for sending, while mVarCheckHiiBinMmReceived is used for receiving, +// while in the traditional setup, mVarCheckHiiBin is used for both sending and receiving. +// +VAR_CHECK_HII_VARIABLE_HEADER *mMmReceivedVarCheckHiiBin = NULL; +UINTN mMmReceivedVarCheckHiiBinSize = 0; +EFI_GUID gVarCheckReceivedHiiBinHandlerGuid = VAR_CHECK_RECEIVED_HII_BIN_HANDLER_GUID; + +/** + Registers a handler for HII variable checks in MM environment. + This function is intended to be called to register a handler for checking variables + in the Standalone MM environment. It allocates memory for the variable + check data and copies the data from the communication buffer. + + @param[in] DispatchHandle The handle of the dispatch function. + @param[in] Context Optional context for the handler, not used in this implementation. + @param CommBuffer The buffer of data being passed in. + @param CommBufferSize The size of the data being passed in. + @retval EFI_SUCCESS Registration and memory allocation were successful. + @retval EFI_INVALID_PARAMETER The CommBuffer or CommBufferSize is NULL. + @retval EFI_ACCESS_DENIED The buffer size is invalid or the buffer is in an invalid location. + @retval EFI_OUT_OF_RESOURCES Memory allocation for the variable check data failed. + +**/ +EFI_STATUS +EFIAPI +VarCheckHiiLibReceiveHiiBinHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ) +{ + EFI_STATUS Status; + + // + // If input is invalid, stop processing this SMI + // + if ((CommBuffer == NULL) || (CommBufferSize == NULL)) { + return EFI_SUCCESS; + } + + mMmReceivedVarCheckHiiBinSize = *CommBufferSize; + + if (mMmReceivedVarCheckHiiBinSize < sizeof (VAR_CHECK_HII_VARIABLE_HEADER)) { + DEBUG ((DEBUG_ERROR, "%a: MM Communication buffer size is invalid for this handler!\n", __func__)); + return EFI_ACCESS_DENIED; + } + + mMmReceivedVarCheckHiiBin = AllocateZeroPool (mMmReceivedVarCheckHiiBinSize); + if (mMmReceivedVarCheckHiiBin == NULL) { + DEBUG ((DEBUG_ERROR, "%a: Failed to allocate memory for mVarCheckHiiBinMm\n", __func__)); + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (mMmReceivedVarCheckHiiBin, CommBuffer, mMmReceivedVarCheckHiiBinSize); + if (DispatchHandle != NULL) { + Status = gMmst->MmiHandlerUnRegister (DispatchHandle); + } + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to unregister handler - %r!\n", __func__, Status)); + } else { + DEBUG ((DEBUG_INFO, "%a: Handler unregistered successfully.\n", __func__)); + } + + return EFI_SUCCESS; +} + +/** + + Sets the variable check handler for HII. + This function registers a handler that will be invoked for variable checks + in the HII environment. It allows for custom validation logic to be implemented + for setting HII variables. + @param[in] VariableName Name of Variable to set. + @param[in] VendorGuid Variable vendor GUID. + @param[in] Attributes Attribute value of the variable. + @param[in] DataSize Size of Data to set. + @param[in] Data Data pointer. + +**/ +EFI_STATUS +EFIAPI +SetVariableCheckHandlerHii ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + return CheckHiiVariableCommon (mMmReceivedVarCheckHiiBin, mMmReceivedVarCheckHiiBinSize, VariableName, VendorGuid, Attributes, DataSize, Data); +} + +/** + Constructor function for variable check library in Standalone MM. + This function registers a handler for variable checks and sets up the environment + for variable checking in the Standalone MM environment. + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI system table. + @retval EFI_SUCCESS The constructor executed successfully. + @retval Others An error occurred during execution. + +**/ +EFI_STATUS +EFIAPI +VarCheckHiiLibConstructorStandaloneMm ( + IN EFI_HANDLE ImageHandle, + IN EFI_MM_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE DispatchHandle; + + DEBUG ((DEBUG_INFO, "%a: starts.\n", __func__)); + // + // Register a handler to recieve the HII variable checking data. + // + Status = gMmst->MmiHandlerRegister (VarCheckHiiLibReceiveHiiBinHandler, &gVarCheckReceivedHiiBinHandlerGuid, &DispatchHandle); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to register handler - %r!\n", __func__, Status)); + + return Status; + } + + VarCheckLibRegisterAddressPointer ((VOID **)&mMmReceivedVarCheckHiiBin); + VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerHii); + DEBUG ((DEBUG_INFO, "%a: ends.\n", __func__)); + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.inf b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.inf new file mode 100644 index 000000000000..dcef8029404e --- /dev/null +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.inf @@ -0,0 +1,47 @@ +## @file +# Implementation functions and structures for var check services. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = VarCheckHiiLib + MODULE_UNI_FILE = VarCheckHiiLibStandaloneMm.uni + FILE_GUID = 8545E553-AF7D-4FA0-B402-9B5A67ABC812 + MODULE_TYPE = MM_STANDALONE + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x00010032 + LIBRARY_CLASS = VarCheckHiiLib|MM_STANDALONE + CONSTRUCTOR = VarCheckHiiLibConstructorStandaloneMm + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + VarCheckHiiLibStandaloneMm.c + VarCheckHii.h + InternalVarCheckStructure.h + VarCheckHiiLibCommon.c + VarCheckHiiLibCommon.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + StandaloneMmPkg/StandaloneMmPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + VarCheckLib + +[Protocols] + gEfiMmEndOfDxeProtocolGuid diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.uni b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.uni new file mode 100644 index 000000000000..a84a1ccb9645 --- /dev/null +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.uni @@ -0,0 +1,15 @@ +// /** @file +// Provides variable check services and database management. +// +// Provides variable check services and database management. +// +// Copyright (c) 2024, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Provides StandaloneMm variable check services and database management" + +#string STR_MODULE_DESCRIPTION #language en-US "Provides StandaloneMm variable check services and database management." From eaf78e43f206f8587bdf6c0f78c0f021192d5859 Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Mon, 3 Jun 2024 14:45:28 +0800 Subject: [PATCH 157/280] MdeModulePkg: Enable VarCheckHiiLibStandaloneMm. Enable VarCheckHiiLibStandaloneMm. 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/MdeModulePkg.dsc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index aa2a2da49dfa..8c864fe1838e 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -179,6 +179,7 @@ LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxStandaloneMmLib.inf MemLib|StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf VarCheckHiiLibMmDependency|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf + VarCheckHiiLib|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.inf [LibraryClasses.ARM, LibraryClasses.AARCH64] LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf @@ -341,6 +342,7 @@ MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf + MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.inf MdeModulePkg/Library/PlatformVarCleanupLib/PlatformVarCleanupLib.inf MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf MdeModulePkg/Library/DxeFileExplorerProtocol/DxeFileExplorerProtocol.inf From 829f773e5c512fe69db153e565213740e4d15394 Mon Sep 17 00:00:00 2001 From: Ken Lautner Date: Wed, 28 Aug 2024 11:15:52 -0700 Subject: [PATCH 158/280] MdePkg: Add HTTP error 429 Add support for HTTP error 429 in the protocol .h file. Signed-off-by: Kenneth Lautner --- MdePkg/Include/Protocol/Http.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MdePkg/Include/Protocol/Http.h b/MdePkg/Include/Protocol/Http.h index 28e622159392..7d9481a2e65d 100644 --- a/MdePkg/Include/Protocol/Http.h +++ b/MdePkg/Include/Protocol/Http.h @@ -98,7 +98,8 @@ typedef enum { HTTP_STATUS_503_SERVICE_UNAVAILABLE, HTTP_STATUS_504_GATEWAY_TIME_OUT, HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED, - HTTP_STATUS_308_PERMANENT_REDIRECT + HTTP_STATUS_308_PERMANENT_REDIRECT, + HTTP_STATUS_429_TOO_MANY_REQUESTS } EFI_HTTP_STATUS_CODE; /// From 82c5cacd134d64ea0d0f4dabdbbde38017acb70d Mon Sep 17 00:00:00 2001 From: Ken Lautner Date: Wed, 28 Aug 2024 11:17:22 -0700 Subject: [PATCH 159/280] NetworkPkg: DxeHttpLib: Use HTTP error 429 Include a mapping for HTTP error 429 to return the correct status code. Additionally include a link to the official HTTP status codes in the HttpMappingToStatusCode function header. Signed-off-by: Kenneth Lautner --- NetworkPkg/Include/Library/HttpLib.h | 3 +++ NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/NetworkPkg/Include/Library/HttpLib.h b/NetworkPkg/Include/Library/HttpLib.h index f8505ab4d7ea..a6894d3fe373 100644 --- a/NetworkPkg/Include/Library/HttpLib.h +++ b/NetworkPkg/Include/Library/HttpLib.h @@ -444,6 +444,9 @@ HttpGenRequestMessage ( Translate the status code in HTTP message to EFI_HTTP_STATUS_CODE defined in UEFI 2.5 specification. + The official HTTP status codes can be found here: + https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml + @param[in] StatusCode The status code value in HTTP message. @return Value defined in EFI_HTTP_STATUS_CODE . diff --git a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c index f1da69bbf795..edb8f580fae9 100644 --- a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c +++ b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c @@ -1995,6 +1995,9 @@ HttpGenRequestMessage ( Translate the status code in HTTP message to EFI_HTTP_STATUS_CODE defined in UEFI 2.5 specification. + The official HTTP status codes can be found here: + https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml + @param[in] StatusCode The status code value in HTTP message. @return Value defined in EFI_HTTP_STATUS_CODE . @@ -2077,6 +2080,8 @@ HttpMappingToStatusCode ( return HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED; case 417: return HTTP_STATUS_417_EXPECTATION_FAILED; + case 429: + return HTTP_STATUS_429_TOO_MANY_REQUESTS; case 500: return HTTP_STATUS_500_INTERNAL_SERVER_ERROR; case 501: From 814470b8340725095ad4db48b291b4e2b4e86941 Mon Sep 17 00:00:00 2001 From: Nickle Wang Date: Thu, 11 Jul 2024 15:41:47 +0800 Subject: [PATCH 160/280] NetworkPkg/SnpDxe: return error for unsupported parameter REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4729 From SCT testing report, Reset() does not support the case when ExtendedVerification is set to FALSE. So, we should return EFI_INVALID_PARAMETER in this case. For details, please refer to Bug 4729. Signed-off-by: Nickle Wang --- NetworkPkg/SnpDxe/Reset.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/NetworkPkg/SnpDxe/Reset.c b/NetworkPkg/SnpDxe/Reset.c index 2ff685376db8..72f31425d094 100644 --- a/NetworkPkg/SnpDxe/Reset.c +++ b/NetworkPkg/SnpDxe/Reset.c @@ -2,6 +2,7 @@ Implementation of resetting a network adapter. Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
+SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -93,10 +94,12 @@ SnpUndi32Reset ( EFI_STATUS Status; // - // Resolve Warning 4 unreferenced parameter problem + // There is no support when ExtendedVerification is set to FALSE. // - ExtendedVerification = 0; - DEBUG ((DEBUG_WARN, "ExtendedVerification = %d is not implemented!\n", ExtendedVerification)); + if (!ExtendedVerification) { + DEBUG ((DEBUG_WARN, "ExtendedVerification = %d is not implemented!\n", ExtendedVerification)); + return EFI_INVALID_PARAMETER; + } if (This == NULL) { return EFI_INVALID_PARAMETER; From 715200ea606829bf85b017e7fa116e0a0023d447 Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Mon, 19 Aug 2024 08:22:02 -0700 Subject: [PATCH 161/280] ArmPkg/ArmPkg.ci.yaml: Add PrEval CI config Adds an entry to the package's CI configuration file that enable policy 5 for stuart_pr_eval. With this Policy, all INFs used by the package are extracted from the provided DSC file and compared against the list of changed *.inf (INF) files in the PR. If there is a match, stuart_pr_eval will specify that this package is affected by the PR and needs to be tested. Signed-off-by: Joey Vagedes --- ArmPkg/ArmPkg.ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ArmPkg/ArmPkg.ci.yaml b/ArmPkg/ArmPkg.ci.yaml index 24db74250513..5c2e68b53460 100644 --- a/ArmPkg/ArmPkg.ci.yaml +++ b/ArmPkg/ArmPkg.ci.yaml @@ -5,6 +5,9 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## { + "PrEval": { + "DscPath": "ArmPkg.dsc", + }, ## options defined .pytool/Plugin/LicenseCheck "LicenseCheck": { "IgnoreFiles": [] From 2ccf94d37b69b3977758eac56d2416b3673a3dec Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Mon, 19 Aug 2024 08:32:50 -0700 Subject: [PATCH 162/280] ArmPlatformPkg/ArmPlatformPkg.ci.yaml: Add PrEval CI config Adds an entry to the package's CI configuration file that enable policy 5 for stuart_pr_eval. With this Policy, all INFs used by the package are extracted from the provided DSC file and compared against the list of changed *.inf (INF) files in the PR. If there is a match, stuart_pr_eval will specify that this package is affected by the PR and needs to be tested. Signed-off-by: Joey Vagedes --- ArmPlatformPkg/ArmPlatformPkg.ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ArmPlatformPkg/ArmPlatformPkg.ci.yaml b/ArmPlatformPkg/ArmPlatformPkg.ci.yaml index 03632e74df73..9c384a3febad 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.ci.yaml +++ b/ArmPlatformPkg/ArmPlatformPkg.ci.yaml @@ -5,6 +5,9 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## { + "PrEval": { + "DscPath": "ArmPlatformPkg.dsc", + }, ## options defined .pytool/Plugin/LicenseCheck "LicenseCheck": { "IgnoreFiles": [] From c79487605a8851a4e03aed2c58a36cbab22915d8 Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Mon, 19 Aug 2024 08:33:13 -0700 Subject: [PATCH 163/280] EmulatorPkg/EmulatorPkg.ci.yaml: Add PrEval CI config Adds an entry to the package's CI configuration file that enable policy 5 for stuart_pr_eval. With this Policy, all INFs used by the package are extracted from the provided DSC file and compared against the list of changed *.inf (INF) files in the PR. If there is a match, stuart_pr_eval will specify that this package is affected by the PR and needs to be tested. Signed-off-by: Joey Vagedes --- EmulatorPkg/EmulatorPkg.ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/EmulatorPkg/EmulatorPkg.ci.yaml b/EmulatorPkg/EmulatorPkg.ci.yaml index 6e9b2857cb75..6090fe336385 100644 --- a/EmulatorPkg/EmulatorPkg.ci.yaml +++ b/EmulatorPkg/EmulatorPkg.ci.yaml @@ -9,6 +9,9 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## { + "PrEval": { + "DscPath": "EmulatorPkg.dsc", + }, ## options defined .pytool/Plugin/LicenseCheck "LicenseCheck": { "IgnoreFiles": [] From ea5581186eaa10e74a02c98608a067d76af92c69 Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Mon, 19 Aug 2024 08:33:36 -0700 Subject: [PATCH 164/280] NetworkPkg/NetworkPkg.ci.yaml: Add PrEval CI config Adds an entry to the package's CI configuration file that enable policy 5 for stuart_pr_eval. With this Policy, all INFs used by the package are extracted from the provided DSC file and compared against the list of changed *.inf (INF) files in the PR. If there is a match, stuart_pr_eval will specify that this package is affected by the PR and needs to be tested. Signed-off-by: Joey Vagedes --- NetworkPkg/NetworkPkg.ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NetworkPkg/NetworkPkg.ci.yaml b/NetworkPkg/NetworkPkg.ci.yaml index 076424eb6065..5626e94434e2 100644 --- a/NetworkPkg/NetworkPkg.ci.yaml +++ b/NetworkPkg/NetworkPkg.ci.yaml @@ -7,6 +7,9 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## { + "PrEval": { + "DscPath": "NetworkPkg.dsc", + }, "LicenseCheck": { "IgnoreFiles": [] }, From 89bad0726c870067ad2f3dd7cdb562244d3b13f7 Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Mon, 19 Aug 2024 08:33:56 -0700 Subject: [PATCH 165/280] PcAtChipsetPkg/PcAtChipsetPkg.ci.yaml: Add PrEval CI config Adds an entry to the package's CI configuration file that enable policy 5 for stuart_pr_eval. With this Policy, all INFs used by the package are extracted from the provided DSC file and compared against the list of changed *.inf (INF) files in the PR. If there is a match, stuart_pr_eval will specify that this package is affected by the PR and needs to be tested. Signed-off-by: Joey Vagedes --- PcAtChipsetPkg/PcAtChipsetPkg.ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PcAtChipsetPkg/PcAtChipsetPkg.ci.yaml b/PcAtChipsetPkg/PcAtChipsetPkg.ci.yaml index 61f3fd7b5074..278bb43969a4 100644 --- a/PcAtChipsetPkg/PcAtChipsetPkg.ci.yaml +++ b/PcAtChipsetPkg/PcAtChipsetPkg.ci.yaml @@ -6,6 +6,9 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## { + "PrEval": { + "DscPath": "PcAtChipsetPkg.dsc", + }, ## options defined .pytool/Plugin/LicenseCheck "LicenseCheck": { "IgnoreFiles": [] From 6ead9a8b80c8ddff7017381c674ecdf1d94a7a67 Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Mon, 19 Aug 2024 08:34:21 -0700 Subject: [PATCH 166/280] SecurityPkg/SecurityPkg.ci.yaml: Add PrEval CI config Adds an entry to the package's CI configuration file that enable policy 5 for stuart_pr_eval. With this Policy, all INFs used by the package are extracted from the provided DSC file and compared against the list of changed *.inf (INF) files in the PR. If there is a match, stuart_pr_eval will specify that this package is affected by the PR and needs to be tested. Signed-off-by: Joey Vagedes --- SecurityPkg/SecurityPkg.ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.yaml index 2a4cbd379566..26fedd179c23 100644 --- a/SecurityPkg/SecurityPkg.ci.yaml +++ b/SecurityPkg/SecurityPkg.ci.yaml @@ -6,6 +6,9 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## { + "PrEval": { + "DscPath": "SecurityPkg.dsc", + }, "LicenseCheck": { "IgnoreFiles": [ "DeviceSecurity/SpdmLib/Include", From 0cfed096744f34db376ec9676fd3860dd703c479 Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Mon, 19 Aug 2024 08:34:36 -0700 Subject: [PATCH 167/280] ShellPkg/ShellPkg.ci.yaml: Add PrEval CI config Adds an entry to the package's CI configuration file that enable policy 5 for stuart_pr_eval. With this Policy, all INFs used by the package are extracted from the provided DSC file and compared against the list of changed *.inf (INF) files in the PR. If there is a match, stuart_pr_eval will specify that this package is affected by the PR and needs to be tested. Signed-off-by: Joey Vagedes --- ShellPkg/ShellPkg.ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ShellPkg/ShellPkg.ci.yaml b/ShellPkg/ShellPkg.ci.yaml index e741402459e5..74059d1488cf 100644 --- a/ShellPkg/ShellPkg.ci.yaml +++ b/ShellPkg/ShellPkg.ci.yaml @@ -6,6 +6,9 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## { + "PrEval": { + "DscPath": "ShellPkg.dsc", + }, "LicenseCheck": { "IgnoreFiles": [] }, From abf21d76e78eacc855913869612da7e8cf7a58e7 Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Mon, 19 Aug 2024 08:34:56 -0700 Subject: [PATCH 168/280] SignedCapsulePkg/SignedCapsulePkg.ci.yaml: Add PrEval CI config Adds an entry to the package's CI configuration file that enable policy 5 for stuart_pr_eval. With this Policy, all INFs used by the package are extracted from the provided DSC file and compared against the list of changed *.inf (INF) files in the PR. If there is a match, stuart_pr_eval will specify that this package is affected by the PR and needs to be tested. Signed-off-by: Joey Vagedes --- SignedCapsulePkg/SignedCapsulePkg.ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SignedCapsulePkg/SignedCapsulePkg.ci.yaml b/SignedCapsulePkg/SignedCapsulePkg.ci.yaml index 5f48613bd79f..e25218f95987 100644 --- a/SignedCapsulePkg/SignedCapsulePkg.ci.yaml +++ b/SignedCapsulePkg/SignedCapsulePkg.ci.yaml @@ -6,6 +6,9 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## { + "PrEval": { + "DscPath": "SignedCapsulePkg.dsc", + }, ## options defined .pytool/Plugin/LicenseCheck "LicenseCheck": { "IgnoreFiles": [] From 7c1047298377a7d48a2e1afcb58e134001ef2c80 Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Mon, 19 Aug 2024 08:35:23 -0700 Subject: [PATCH 169/280] SourceLevelDebugPkg/SourceLevelDebugPkg.ci.yaml: Add PrEval CI config Adds an entry to the package's CI configuration file that enable policy 5 for stuart_pr_eval. With this Policy, all INFs used by the package are extracted from the provided DSC file and compared against the list of changed *.inf (INF) files in the PR. If there is a match, stuart_pr_eval will specify that this package is affected by the PR and needs to be tested. Signed-off-by: Joey Vagedes --- SourceLevelDebugPkg/SourceLevelDebugPkg.ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SourceLevelDebugPkg/SourceLevelDebugPkg.ci.yaml b/SourceLevelDebugPkg/SourceLevelDebugPkg.ci.yaml index 8887a6d10bc5..0ddf60cd434c 100644 --- a/SourceLevelDebugPkg/SourceLevelDebugPkg.ci.yaml +++ b/SourceLevelDebugPkg/SourceLevelDebugPkg.ci.yaml @@ -6,6 +6,9 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## { + "PrEval": { + "DscPath": "SourceLevelDebugPkg.dsc", + }, ## options defined .pytool/Plugin/LicenseCheck "LicenseCheck": { "IgnoreFiles": [] From 6e727ed9dd2cf2f45f1995a8325d3af3081dbf3f Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Mon, 19 Aug 2024 08:35:43 -0700 Subject: [PATCH 170/280] StandaloneMmPkg/StandaloneMmPkg.ci.yaml: Add PrEval CI config Adds an entry to the package's CI configuration file that enable policy 5 for stuart_pr_eval. With this Policy, all INFs used by the package are extracted from the provided DSC file and compared against the list of changed *.inf (INF) files in the PR. If there is a match, stuart_pr_eval will specify that this package is affected by the PR and needs to be tested. Signed-off-by: Joey Vagedes --- StandaloneMmPkg/StandaloneMmPkg.ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/StandaloneMmPkg/StandaloneMmPkg.ci.yaml b/StandaloneMmPkg/StandaloneMmPkg.ci.yaml index e11449c6fb38..7d9b0c9cac7c 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.ci.yaml +++ b/StandaloneMmPkg/StandaloneMmPkg.ci.yaml @@ -6,6 +6,9 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## { + "PrEval": { + "DscPath": "StandaloneMmPkg.dsc", + }, "EccCheck": { ## Exception sample looks like below: ## "ExceptionList": [ From d214d75be0e79e5ad35271ba37187a5c252e8a94 Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Mon, 19 Aug 2024 08:36:03 -0700 Subject: [PATCH 171/280] UefiCpuPkg/UefiCpuPkg.ci.yaml: Add PrEval CI config Adds an entry to the package's CI configuration file that enable policy 5 for stuart_pr_eval. With this Policy, all INFs used by the package are extracted from the provided DSC file and compared against the list of changed *.inf (INF) files in the PR. If there is a match, stuart_pr_eval will specify that this package is affected by the PR and needs to be tested. Signed-off-by: Joey Vagedes --- UefiCpuPkg/UefiCpuPkg.ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/UefiCpuPkg/UefiCpuPkg.ci.yaml b/UefiCpuPkg/UefiCpuPkg.ci.yaml index c2280aedf5ce..80a043f339c1 100644 --- a/UefiCpuPkg/UefiCpuPkg.ci.yaml +++ b/UefiCpuPkg/UefiCpuPkg.ci.yaml @@ -6,6 +6,9 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## { + "PrEval": { + "DscPath": "UefiCpuPkg.dsc", + }, "LicenseCheck": { "IgnoreFiles": [] }, From 5b6ec1a7f487404504991c33918a6b02516f778a Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Mon, 19 Aug 2024 08:36:21 -0700 Subject: [PATCH 172/280] UefiPayloadPkg/UefiPayloadPkg.ci.yaml: Add PrEval CI config Adds an entry to the package's CI configuration file that enable policy 5 for stuart_pr_eval. With this Policy, all INFs used by the package are extracted from the provided DSC file and compared against the list of changed *.inf (INF) files in the PR. If there is a match, stuart_pr_eval will specify that this package is affected by the PR and needs to be tested. Signed-off-by: Joey Vagedes --- UefiPayloadPkg/UefiPayloadPkg.ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/UefiPayloadPkg/UefiPayloadPkg.ci.yaml b/UefiPayloadPkg/UefiPayloadPkg.ci.yaml index 0ceff5b2a54e..ac43a7a8ee46 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.ci.yaml +++ b/UefiPayloadPkg/UefiPayloadPkg.ci.yaml @@ -5,6 +5,9 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## { + "PrEval": { + "DscPath": "UefiPayloadPkg.dsc", + }, ## options defined .pytool/Plugin/LicenseCheck "LicenseCheck": { "IgnoreFiles": [] From f0f14aac3dd129932915feabb120b946ba0428fc Mon Sep 17 00:00:00 2001 From: Nhi Pham Date: Wed, 14 Aug 2024 18:06:22 +0700 Subject: [PATCH 173/280] FatPkg/EnhancedFatDxe: Downgrade debug level for no media found It is normal for a disk to not have FAT file system (known as No Media), therefore, it should not produce a "failed" entry in the boot console. This aims to lower the debug level to verbose. Signed-off-by: Nhi Pham --- FatPkg/EnhancedFatDxe/Init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FatPkg/EnhancedFatDxe/Init.c b/FatPkg/EnhancedFatDxe/Init.c index 208318c7ad6a..3a946199e78a 100644 --- a/FatPkg/EnhancedFatDxe/Init.c +++ b/FatPkg/EnhancedFatDxe/Init.c @@ -221,7 +221,7 @@ FatOpenDevice ( Status = DiskIo->ReadDisk (DiskIo, Volume->MediaId, 0, sizeof (FatBs), &FatBs); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_INIT, "FatOpenDevice: read of part_lba failed %r\n", Status)); + DEBUG ((DEBUG_VERBOSE, "%a: read of part_lba failed %r\n", __func__, Status)); return Status; } From 909849be87a7f931f9fb627522cc664c06987712 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Wed, 7 Aug 2024 06:57:28 -0600 Subject: [PATCH 174/280] pip-requirements.txt: Bump versions of several packages and fix URL edk2-basetools was depending on old versions of several packages. That was fixed in version 0.1.53. Update pip-requirements.txt to use that version, and bump the versions and dependency expressions of other packages to use or allow use of newer versions. Also, update the URL to the requirements file format since it's moved. Signed-off-by: Rebecca Cran --- pip-requirements.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pip-requirements.txt b/pip-requirements.txt index e07b9cac52c5..f9fb9e130bad 100644 --- a/pip-requirements.txt +++ b/pip-requirements.txt @@ -8,13 +8,13 @@ # # https://pypi.org/project/pip/ # https://pip.pypa.io/en/stable/user_guide/#requirements-files -# https://pip.pypa.io/en/stable/reference/pip_install/#requirements-file-format +# https://pip.pypa.io/en/stable/reference/requirements-file-format # https://www.python.org/dev/peps/pep-0440/#version-specifiers ## -edk2-pytool-library==0.21.8 -edk2-pytool-extensions==0.27.6 -edk2-basetools==0.1.51 -antlr4-python3-runtime==4.7.1 +edk2-pytool-library~=0.21.9 +edk2-pytool-extensions~=0.27.10 +edk2-basetools==0.1.53 +antlr4-python3-runtime>=4.7.1 lcov-cobertura==2.0.2 -regex==2024.5.15 +regex==2024.7.24 From a859f4fc0397ec4a9d1af016b7e1f03ccf14b605 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 3 Oct 2022 15:47:08 -0700 Subject: [PATCH 175/280] MdePkg: Fix a buffer overread. DevPathToTextUsbWWID allocates a separate copy of the SerialNumber string to append a null terminator if the original string is not null terminated. However, by using AllocateCopyPool, it tries to copy 'Length + 1' words from the existing string containing 'Length' characters into the target string. Split the copy out to only copy 'Length' characters instead. This was reported by GCC's -Wstringop-overread when compiling a copy of this routine included in a library on FreeBSD. Signed-off-by: John Baldwin --- MdePkg/Library/UefiDevicePathLib/DevicePathToText.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c b/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c index 468baa5a7626..afbd590787f4 100644 --- a/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c +++ b/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c @@ -1003,8 +1003,9 @@ DevPathToTextUsbWWID ( // // In case no NULL terminator in SerialNumber, create a new one with NULL terminator // - NewStr = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), SerialNumberStr); + NewStr = AllocatePool ((Length + 1) * sizeof (CHAR16)); ASSERT (NewStr != NULL); + CopyMem (NewStr, SerialNumberStr, Length * sizeof (CHAR16)); NewStr[Length] = 0; SerialNumberStr = NewStr; } From cb9bdf37532e8b75c38bd4874f9c797d7f66ed30 Mon Sep 17 00:00:00 2001 From: Ashraf Ali Date: Wed, 14 Aug 2024 23:16:29 +0530 Subject: [PATCH 176/280] SecurityPkg: Optimization by moving PeiServicesLocatePpi outside loop This update refactors the code by moving the LocatePpi function call outside of the for loop where it was previously called repeatedly. By relocating the LocatePpi invocation outside of the loop, we improve the efficiency of the code by avoiding redundant lookups. Signed-off-by: Ashraf Ali --- SecurityPkg/FvReportPei/FvReportPei.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/SecurityPkg/FvReportPei/FvReportPei.c b/SecurityPkg/FvReportPei/FvReportPei.c index 6288dde16b2a..50773db056bb 100644 --- a/SecurityPkg/FvReportPei/FvReportPei.c +++ b/SecurityPkg/FvReportPei/FvReportPei.c @@ -150,6 +150,16 @@ VerifyHashedFv ( HashValue = AllocateZeroPool (AlgInfo->HashSize * (FvNumber + 1)); ASSERT (HashValue != NULL); + Status = PeiServicesLocatePpi ( + &gEdkiiPeiFirmwareVolumeShadowPpiGuid, + 0, + NULL, + (VOID **)&FvShadowPpi + ); + if (EFI_ERROR (Status)) { + FvShadowPpi = NULL; + } + // // Calculate hash value for each FV first. // @@ -194,14 +204,8 @@ VerifyHashedFv ( FvBuffer = AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)FvInfo[FvIndex].Length)); ASSERT (FvBuffer != NULL); - Status = PeiServicesLocatePpi ( - &gEdkiiPeiFirmwareVolumeShadowPpiGuid, - 0, - NULL, - (VOID **)&FvShadowPpi - ); - if (!EFI_ERROR (Status)) { + if (FvShadowPpi != NULL) { Status = FvShadowPpi->FirmwareVolumeShadow ( (EFI_PHYSICAL_ADDRESS)FvInfo[FvIndex].Base, FvBuffer, @@ -209,7 +213,7 @@ VerifyHashedFv ( ); } - if (EFI_ERROR (Status)) { + if ((FvShadowPpi == NULL) || (EFI_ERROR (Status))) { CopyMem ( FvBuffer, (CONST VOID *)(UINTN)FvInfo[FvIndex].Base, From 72cf76868ce7b7cda1ba5f9eb28693557ff10256 Mon Sep 17 00:00:00 2001 From: Neo Hsueh Date: Thu, 1 Aug 2024 14:11:57 -0500 Subject: [PATCH 177/280] NetworkPkg/WifiConnectionManagerDxe: Fix Connection Manager HII errors REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4824 Fix the wrong logic in WifiMgrDxeHiiConfigAccessCallback with EFI_BROWSER_ACTION_CHANGING action. Cc: Jiangang He Cc: Abner Chang Signed-off-by: Neo Hsueh --- .../WifiConnectionMgrHiiConfigAccess.c | 34 +------------------ 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c index f242bdf0569d..00804e546750 100644 --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c @@ -1490,6 +1490,7 @@ WifiMgrDxeHiiConfigAccessCallback ( } else if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) { switch (QuestionId) { case KEY_EAP_ENROLL_CERT_FROM_FILE: + case KEY_REFRESH_NETWORK_LIST: if (Private->CurrentNic->UserSelectedProfile == NULL) { break; @@ -1911,39 +1912,6 @@ WifiMgrDxeHiiConfigAccessCallback ( NULL ); } - - if (Private->CurrentNic->UserSelectedProfile == NULL) { - break; - } - - Profile = Private->CurrentNic->UserSelectedProfile; - - // - // Enter the network connection configuration page - // Recovery from restored data - // - if (HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_SSID), Profile->SSId, NULL) == 0) { - return EFI_OUT_OF_RESOURCES; - } - - IfrNvData->SecurityType = Profile->SecurityType; - if (HiiSetString ( - Private->RegisteredHandle, - STRING_TOKEN (STR_SECURITY_TYPE), - mSecurityType[IfrNvData->SecurityType], - NULL - ) == 0) - { - return EFI_OUT_OF_RESOURCES; - } - - if ( (IfrNvData->SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE) - || (IfrNvData->SecurityType == SECURITY_TYPE_WPA3_ENTERPRISE)) - { - IfrNvData->EapAuthMethod = Profile->EapAuthMethod; - IfrNvData->EapSecondAuthMethod = Profile->EapSecondAuthMethod; - StrCpyS (IfrNvData->EapIdentity, EAP_IDENTITY_SIZE, Profile->EapIdentity); - } } break; From 7f505d377b44aeee59f34b3d898f6caf0a0df538 Mon Sep 17 00:00:00 2001 From: Jason Zhao Date: Tue, 27 Aug 2024 13:33:42 +0800 Subject: [PATCH 178/280] MdePkg/SmBios.h: Add new Socket Type for SMBIOS Type4 The patch adds new socket type(Type 4, Offset 32h) for SMBIOS Type4 based on SMBIOS v3.8.0. Signed-off-by: Jason Zhao --- MdePkg/Include/IndustryStandard/SmBios.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MdePkg/Include/IndustryStandard/SmBios.h b/MdePkg/Include/IndustryStandard/SmBios.h index c07cfcb81453..9d0dec25757f 100644 --- a/MdePkg/Include/IndustryStandard/SmBios.h +++ b/MdePkg/Include/IndustryStandard/SmBios.h @@ -1020,6 +1020,10 @@ typedef struct { // Add for smbios 3.6 // UINT16 ThreadEnabled; + // + // Add for smbios 3.8 + // + SMBIOS_TABLE_STRING SocketType; } SMBIOS_TABLE_TYPE4; /// From aebe9625c915c71c420d8ce6b15923dc01385436 Mon Sep 17 00:00:00 2001 From: Jason Zhao Date: Mon, 2 Sep 2024 20:41:42 +0800 Subject: [PATCH 179/280] MdePkg/SmBios.h: Add new Processor Upgrade definition for SMBIOS Type4 The patch adds ProcessorUpgradeInvalid(0xFF) definition in Processor Upgrade(Type 4, Offset 19h) for SMBIOS Type4 based on SMBIOS v3.8.0. Processor Upgrade should be 0xFF when no other valid enumeration is available. Signed-off-by: Jason Zhao --- MdePkg/Include/IndustryStandard/SmBios.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MdePkg/Include/IndustryStandard/SmBios.h b/MdePkg/Include/IndustryStandard/SmBios.h index 9d0dec25757f..8ba61297e860 100644 --- a/MdePkg/Include/IndustryStandard/SmBios.h +++ b/MdePkg/Include/IndustryStandard/SmBios.h @@ -887,7 +887,8 @@ typedef enum { ProcessorUpgradeSocketBGA2551 = 0x54, ProcessorUpgradeSocketLGA1851 = 0x55, ProcessorUpgradeSocketBGA2114 = 0x56, - ProcessorUpgradeSocketBGA2833 = 0x57 + ProcessorUpgradeSocketBGA2833 = 0x57, + ProcessorUpgradeInvalid = 0xFF } PROCESSOR_UPGRADE; /// From e48acc0fa98e307b1192037062f4623da3eeeb7f Mon Sep 17 00:00:00 2001 From: Jason Zhao Date: Wed, 28 Aug 2024 10:10:58 +0800 Subject: [PATCH 180/280] ShellPkg/SmbiosView: Add new Socket Type for SMBIOS Type4 The patch prints new socket type(Type 4, Offset 32h) for SMBIOS Type4 based on SMBIOS v3.8.0. Signed-off-by: Jason Zhao --- .../Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c index a31f823304ea..2ee2bb44bce0 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c @@ -524,6 +524,10 @@ SmbiosPrintStructure ( ShellPrintEx (-1, -1, L"Thread Enabled: %u\n", Struct->Type4->ThreadEnabled); } + if (AE_SMBIOS_VERSION (0x3, 0x8) && (Struct->Hdr->Length > 0x30)) { + ShellPrintEx (-1, -1, L"Socket Type: %a\n", LibGetSmbiosString (Struct, Struct->Type4->SocketType)); + } + break; // From d997d3c62f6c3255491da09235cc7410cefad850 Mon Sep 17 00:00:00 2001 From: Ceping Sun Date: Wed, 28 Aug 2024 01:16:34 -0400 Subject: [PATCH 181/280] OvmfPkg: Use TdHob instead of e820tables to get memory info in TDVF Currently, TDVF gets LowMemory and FistNonAddress from the e820tables via fw_cfg, while TD-Hob can also provide the memory info of LowMemory and FistNonAddress. In current stage e820tables are not measured but TD-Hob is measured in early phase by TDVF. So, from the security perspective we'd better use the information from TD-Hob instead of e820tables. Cc: Erdem Aktas Cc: Jiewen Yao Cc: Min Xu Cc: Gerd Hoffmann Cc: Elena Reshetova Signed-off-by: Ceping Sun --- OvmfPkg/Library/PlatformInitLib/MemDetect.c | 34 +++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c index 0acc0e1275a4..b6aefb321df5 100644 --- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c +++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c @@ -107,6 +107,36 @@ typedef VOID (*E820_SCAN_CALLBACK) ( EFI_HOB_PLATFORM_INFO *PlatformInfoHob ); +STATIC +EFI_STATUS +PlatformScanE820Tdx ( + IN E820_SCAN_CALLBACK Callback, + IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob + ) +{ + EFI_E820_ENTRY64 E820Entry; + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase); + + while (!END_OF_HOB_LIST (Hob)) { + if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_UNACCEPTED) || + (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)) + { + E820Entry.BaseAddr = Hob.ResourceDescriptor->PhysicalStart; + E820Entry.Length = Hob.ResourceDescriptor->ResourceLength; + E820Entry.Type = EfiAcpiAddressRangeMemory; + Callback (&E820Entry, PlatformInfoHob); + } + } + + Hob.Raw = (UINT8 *)(Hob.Raw + Hob.Header->HobLength); + } + + return EFI_SUCCESS; +} + /** Store first address not used by e820 RAM entries in PlatformInfoHob->FirstNonAddress @@ -347,6 +377,10 @@ PlatformScanE820 ( return PlatformScanE820Pvh (Callback, PlatformInfoHob); } + if (TdIsEnabled ()) { + return PlatformScanE820Tdx (Callback, PlatformInfoHob); + } + Status = QemuFwCfgFindFile ("etc/e820", &FwCfgItem, &FwCfgSize); if (EFI_ERROR (Status)) { return Status; From 5bb4f9694a6d765a8f3a3474c6835b0f167428d5 Mon Sep 17 00:00:00 2001 From: Ceping Sun Date: Wed, 6 Mar 2024 07:06:26 +0800 Subject: [PATCH 182/280] OvmfPkg/PlatformPei: Build gCcEventEntryHobGuid at First Since the PEI Hob service is ready after PEIM loaded, TDVF should build the Hob for TdHob and Cfv event at first. Cc: Erdem Aktas Cc: Jiewen Yao Cc: Min Xu Cc: Gerd Hoffmann Cc: Elena Reshetova Signed-off-by: Ceping Sun --- OvmfPkg/OvmfPkgIa32.dsc | 5 ++++- OvmfPkg/OvmfPkgIa32X64.dsc | 5 ++++- OvmfPkg/PlatformPei/IntelTdx.c | 2 -- OvmfPkg/PlatformPei/Platform.c | 5 +++++ 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index bd6e8abbcb5b..974ab6236211 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -704,7 +704,10 @@ } MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf - OvmfPkg/PlatformPei/PlatformPei.inf + OvmfPkg/PlatformPei/PlatformPei.inf { + + NULL|OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperLibNull.inf + } UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf { !if $(SMM_REQUIRE) == TRUE diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index f28049a36a7f..c0e3210a8340 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -717,7 +717,10 @@ } MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf - OvmfPkg/PlatformPei/PlatformPei.inf + OvmfPkg/PlatformPei/PlatformPei.inf { + + NULL|OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperLibNull.inf + } UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf { !if $(SMM_REQUIRE) == TRUE diff --git a/OvmfPkg/PlatformPei/IntelTdx.c b/OvmfPkg/PlatformPei/IntelTdx.c index 1cb6729e56e6..8aa796b3e9e0 100644 --- a/OvmfPkg/PlatformPei/IntelTdx.c +++ b/OvmfPkg/PlatformPei/IntelTdx.c @@ -40,8 +40,6 @@ IntelTdxInitialize ( return; } - TdxHelperBuildGuidHobForTdxMeasurement (); - PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrIntelTdx); ASSERT_RETURN_ERROR (PcdStatus); diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c index 0114529778e5..dc81ce9e2bff 100644 --- a/OvmfPkg/PlatformPei/Platform.c +++ b/OvmfPkg/PlatformPei/Platform.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "Platform.h" #include "PlatformId.h" @@ -311,6 +312,10 @@ InitializePlatform ( DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n")); PlatformInfoHob = BuildPlatformInfoHob (); + if (TdIsEnabled ()) { + TdxHelperBuildGuidHobForTdxMeasurement (); + } + PlatformInfoHob->SmmSmramRequire = FeaturePcdGet (PcdSmmSmramRequire); PlatformInfoHob->SevEsIsEnabled = MemEncryptSevEsIsEnabled (); PlatformInfoHob->PcdPciMmio64Size = PcdGet64 (PcdPciMmio64Size); From 1a89d9887ff41e804610c5687e646fe30af2d7b2 Mon Sep 17 00:00:00 2001 From: Parth <56894451+parthishere@users.noreply.github.com> Date: Tue, 6 Aug 2024 11:49:09 -0500 Subject: [PATCH 183/280] MdePkg:Update Return Error Macro in Base.h Fixing RETURN_ERROR macro. It is causing problem in Coverity Static analysis tool as we are directly converting the UINT value to INTN Changing value from UINT to INTN might cause problem. Here we know that the values would not be in loss of data. To increase the code quality and increase the static tool analysis score we have to change it Cc: Jiangang He Cc: Neo Hsueh Signed-off-by: Parth Thakkar --- MdePkg/Include/Base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h index 7caebbeb1f4a..363e0fea40fa 100644 --- a/MdePkg/Include/Base.h +++ b/MdePkg/Include/Base.h @@ -1058,7 +1058,7 @@ typedef UINTN RETURN_STATUS; @retval FALSE The high bit of StatusCode is clear. **/ -#define RETURN_ERROR(StatusCode) (((INTN)(RETURN_STATUS)(StatusCode)) < 0) +#define RETURN_ERROR(StatusCode) (((RETURN_STATUS)(StatusCode)) >= MAX_BIT) /// /// The operation completed successfully. From 8504d2be17c98265049ec334711aad4c0baed1d7 Mon Sep 17 00:00:00 2001 From: Sureshkumar Ponnusamy Date: Tue, 6 Aug 2024 18:16:33 -0400 Subject: [PATCH 184/280] MdeModulePkg/FaultTolerantWriteDxe: Fix buffer overrun issue - This PR aims to prevent a buffer overrun issue found in FtwGetLastWriteHeader function.As per the current code, when there is a malformed blocks (with all bytes as 0s) then `Offset += FTW_WRITE_TOTAL_SIZE (FtwHeader->NumberOfWrites, FtwHeader->PrivateDataSize)` would access beyond FtwWorkSpaceSize. - Also added the signature check to validate work space Signed-off-by: Sureshkumar Ponnusamy --- MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c index 508184f7a048..d442ccb52fc4 100644 --- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c @@ -810,12 +810,18 @@ FtwGetLastWriteHeader ( FtwHeader = (EFI_FAULT_TOLERANT_WRITE_HEADER *)(FtwWorkSpaceHeader + 1); Offset = sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER); + if (!CompareGuid (&FtwWorkSpaceHeader->Signature, &gEdkiiWorkingBlockSignatureGuid)) { + *FtwWriteHeader = FtwHeader; + return EFI_ABORTED; + } + while (FtwHeader->Complete == FTW_VALID_STATE) { Offset += FTW_WRITE_TOTAL_SIZE (FtwHeader->NumberOfWrites, FtwHeader->PrivateDataSize); // // If Offset exceed the FTW work space boudary, return error. // - if (Offset >= FtwWorkSpaceSize) { + + if ((Offset + sizeof (EFI_FAULT_TOLERANT_WRITE_HEADER)) >= FtwWorkSpaceSize) { *FtwWriteHeader = FtwHeader; return EFI_ABORTED; } From afba5358c816c88f2b202a45c31fe80e34dd9368 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 3 Sep 2024 09:58:49 +0200 Subject: [PATCH 185/280] ArmVirtPkg: Resolve RngLib via RngDxe for TRNG support Gerd reports that ArmVirtQemu running under KVM lost network boot support on systems that do not implement the RNDR/RNDRRS system registers, which provide an architectural, CPU-based source of random numbers. Under KVM, the TRNG SMCCC is available as a fallback, which is exposed via RngDxe but not via the base RngLib library. This means that direct users of RngLib, such as OpensslLib, have no access to the TRNG based entropy source. Let's fix this by resolving RngLib dependencies for UEFI_DRIVER type drivers via DxeRngLib, which uses the protocol exposed by RngDxe internally. Signed-off-by: Ard Biesheuvel --- ArmVirtPkg/ArmVirt.dsc.inc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 3462adf9b6ee..4f35da9a2aae 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -232,6 +232,10 @@ DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf !endif +[LibraryClasses.common.UEFI_DRIVER] + # resolve RngLib via RngDxe's EFI_RNG_PROTOCOL for UEFI_DRIVER type drivers such as TlsDxe + RngLib|MdePkg/Library/DxeRngLib/DxeRngLib.inf + [LibraryClasses.common.DXE_CORE] HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf From b17ac09cc4bb48692ec20ca583a8f70dc7d25d95 Mon Sep 17 00:00:00 2001 From: Ken Lautner Date: Fri, 23 Aug 2024 15:33:55 -0700 Subject: [PATCH 186/280] MdeModulePkg: Add extra RestoreTpl() call in DiskIo Adds a call to RestoreTpl() in DiskIo2ReadWriteDisk(). While the current implementation does not technically violate spec on raise/restore TPL, this extra call ensures symmetry between RaiseTpl and RestoreTpl calls, which makes analysis of TPL correctness simpler and permits certain non-standard TPL usages that some platforms require. Signed-off-by: Kenneth Lautner --- MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c b/MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c index 38af39f41ec2..15dfa3699fe9 100644 --- a/MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c +++ b/MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c @@ -847,6 +847,7 @@ DiskIo2ReadWriteDisk ( DISK_IO_SUBTASK *Subtask; DISK_IO2_TASK *Task; EFI_TPL OldTpl; + EFI_TPL OldTpl1; BOOLEAN Blocking; BOOLEAN SubtaskBlocking; LIST_ENTRY *SubtasksPtr; @@ -977,7 +978,7 @@ DiskIo2ReadWriteDisk ( } } - gBS->RaiseTPL (TPL_NOTIFY); + OldTpl1 = gBS->RaiseTPL (TPL_NOTIFY); // // Remove all the remaining subtasks when failure. @@ -1012,6 +1013,7 @@ DiskIo2ReadWriteDisk ( FreePool (Task); } + gBS->RestoreTPL (OldTpl1); gBS->RestoreTPL (OldTpl); return Status; From 559affab2e82aba4e0819d299d5a8de03e276af6 Mon Sep 17 00:00:00 2001 From: Ken Lautner Date: Fri, 23 Aug 2024 15:39:53 -0700 Subject: [PATCH 187/280] MdeModulePkg: Fix redundant call to RestoreTpl() Comments out a redundant call to RestoreTpl(). While this does not technically violate spec on raise/restore TPL, TPL should already be at the specified level. This extra call introduces an asymmetry between RaiseTpl and RestoreTpl calls, which makes analysis of TPL correctness more difficult and hampers certain non-standard TPL usages that some platforms require. Additionally, the two TPL variables were renamed to provide context for each of them. Signed-off-by: Kenneth Lautner --- MdeModulePkg/Core/Dxe/Image/Image.c | 4 +++- MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c | 12 ++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 37fc74d5d1b7..8d12f93d7f95 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1725,7 +1725,9 @@ CoreStartImage ( // Image has completed. Verify the tpl is the same // ASSERT (Image->Tpl == gEfiCurrentTpl); - CoreRestoreTpl (Image->Tpl); + if (Image->Tpl != gEfiCurrentTpl) { + CoreRestoreTpl (Image->Tpl); + } CoreFreePool (Image->JumpBuffer); diff --git a/MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c b/MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c index 15dfa3699fe9..54b634afe355 100644 --- a/MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c +++ b/MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c @@ -846,8 +846,8 @@ DiskIo2ReadWriteDisk ( LIST_ENTRY Subtasks; DISK_IO_SUBTASK *Subtask; DISK_IO2_TASK *Task; - EFI_TPL OldTpl; - EFI_TPL OldTpl1; + EFI_TPL SubtaskPerformTpl; + EFI_TPL SubtaskLockTpl; BOOLEAN Blocking; BOOLEAN SubtaskBlocking; LIST_ENTRY *SubtasksPtr; @@ -897,7 +897,7 @@ DiskIo2ReadWriteDisk ( ASSERT (!IsListEmpty (SubtasksPtr)); - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + SubtaskPerformTpl = gBS->RaiseTPL (TPL_CALLBACK); for ( Link = GetFirstNode (SubtasksPtr), NextLink = GetNextNode (SubtasksPtr, Link) ; !IsNull (SubtasksPtr, Link) ; Link = NextLink, NextLink = GetNextNode (SubtasksPtr, NextLink) @@ -978,7 +978,7 @@ DiskIo2ReadWriteDisk ( } } - OldTpl1 = gBS->RaiseTPL (TPL_NOTIFY); + SubtaskLockTpl = gBS->RaiseTPL (TPL_NOTIFY); // // Remove all the remaining subtasks when failure. @@ -1013,8 +1013,8 @@ DiskIo2ReadWriteDisk ( FreePool (Task); } - gBS->RestoreTPL (OldTpl1); - gBS->RestoreTPL (OldTpl); + gBS->RestoreTPL (SubtaskLockTpl); + gBS->RestoreTPL (SubtaskPerformTpl); return Status; } From a4245b265de78dd0640004263f0b39da7d5a0506 Mon Sep 17 00:00:00 2001 From: John Strange Date: Thu, 4 Jul 2024 08:49:55 -0700 Subject: [PATCH 188/280] SecurityPkg: Tcg2Smm: Remove Memory Clear SMI Handler Remove unused MemoryClear SMI Handler, which is no longer used due to _DSM Memory Clear no longer being used. _DSM Memory Clear was deprecated in 2019 by TCG PC Client Platform Reset Attack Mitigation Spec Version 1.10 revision 17 Family "2.0". Signed-off-by: Oliver Smith-Denny --- SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c | 85 ------------------------------- 1 file changed, 85 deletions(-) diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c index 0c2799b42a71..d4a4149ae4ea 100644 --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c +++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c @@ -170,81 +170,6 @@ PhysicalPresenceCallback ( return EFI_SUCCESS; } -/** - Software SMI callback for MemoryClear which is called from ACPI method. - - Caution: This function may receive untrusted input. - Variable and ACPINvs are external input, so this function will validate - its data structure to be valid value. - - @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param[in] Context Points to an optional handler context which was specified when the - handler was registered. - @param[in, out] CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param[in, out] CommBufferSize The size of the CommBuffer. - - @retval EFI_SUCCESS The interrupt was handled successfully. - -**/ -EFI_STATUS -EFIAPI -MemoryClearCallback ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context, - IN OUT VOID *CommBuffer, - IN OUT UINTN *CommBufferSize - ) -{ - EFI_STATUS Status; - UINTN DataSize; - UINT8 MorControl; - - mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_SUCCESS; - if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE) { - MorControl = (UINT8)mTcgNvs->MemoryClear.Request; - } else if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_PTS_CLEAR_MOR_BIT) { - DataSize = sizeof (UINT8); - Status = mSmmVariable->SmmGetVariable ( - MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, - &gEfiMemoryOverwriteControlDataGuid, - NULL, - &DataSize, - &MorControl - ); - if (EFI_ERROR (Status)) { - mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE; - DEBUG ((DEBUG_ERROR, "[TPM] Get MOR variable failure! Status = %r\n", Status)); - return EFI_SUCCESS; - } - - if (MOR_CLEAR_MEMORY_VALUE (MorControl) == 0x0) { - return EFI_SUCCESS; - } - - MorControl &= ~MOR_CLEAR_MEMORY_BIT_MASK; - } else { - mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE; - DEBUG ((DEBUG_ERROR, "[TPM] MOR Parameter error! Parameter = %x\n", mTcgNvs->MemoryClear.Parameter)); - return EFI_SUCCESS; - } - - DataSize = sizeof (UINT8); - Status = mSmmVariable->SmmSetVariable ( - MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, - &gEfiMemoryOverwriteControlDataGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - DataSize, - &MorControl - ); - if (EFI_ERROR (Status)) { - mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE; - DEBUG ((DEBUG_ERROR, "[TPM] Set MOR variable failure! Status = %r\n", Status)); - } - - return EFI_SUCCESS; -} - /** Notification for SMM ReadyToLock protocol. @@ -337,16 +262,6 @@ InitializeTcgCommon ( mPpSoftwareSmi = SwContext.SwSmiInputValue; - SwContext.SwSmiInputValue = (UINTN)-1; - Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, &SwContext, &McSwHandle); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "[%a] Failed to register MC callback as SW MM handler - %r!\n", __func__, Status)); - goto Cleanup; - } - - mMcSoftwareSmi = SwContext.SwSmiInputValue; - // // Locate SmmVariableProtocol. // From 1240a722f8466930cced7f7d40a3fb6a29efb146 Mon Sep 17 00:00:00 2001 From: John Strange Date: Thu, 4 Jul 2024 08:48:12 -0700 Subject: [PATCH 189/280] SecurityPkg: Tcg2Acpi: Remove _DSM Memory Clear and _PTS This patch removes the _DSM Memory Clear and MOR auto-detect functionality via _PTS, as _DSM Memory Clear was deprecated in TCG PC Client Reset Attack Mitigation Spec Version 1.10 revision 17 Family "2.0" and _PTS is deemed security deficient. Signed-off-by: Oliver Smith-Denny --- SecurityPkg/Tcg/Tcg2Acpi/Tpm.asl | 65 ++------------------------------ 1 file changed, 4 insertions(+), 61 deletions(-) diff --git a/SecurityPkg/Tcg/Tcg2Acpi/Tpm.asl b/SecurityPkg/Tcg/Tcg2Acpi/Tpm.asl index 95f9d7eae841..dcf3461861cf 100644 --- a/SecurityPkg/Tcg/Tcg2Acpi/Tpm.asl +++ b/SecurityPkg/Tcg/Tcg2Acpi/Tpm.asl @@ -241,26 +241,10 @@ DefinitionBlock ( Method (PTS, 1, Serialized) { // - // Detect Sx state for MOR, only S4, S5 need to handle + // _PTS is deprecated for being security deficient + // this implementation simply returns to maintain + // compatibility with older OSes using it. // - If (LAnd (LLess (Arg0, 6), LGreater (Arg0, 3))) - { - // - // Bit4 -- DisableAutoDetect. 0 -- Firmware MAY autodetect. - // - If (LNot (And (MORD, 0x10))) - { - // - // Trigger the SMI through ACPI _PTS method. - // - Store (0x02, MCIP) - - // - // Trigger the SMI interrupt - // - Store (MCIN, IOPN) - } - } Return (0) } @@ -446,43 +430,6 @@ DefinitionBlock ( Return (1) } - Method (TMCI, 2, Serialized, 0, IntObj, {UnknownObj, UnknownObj}) // IntObj, PkgObj - { - // - // Switch by function index - // - Switch (ToInteger (Arg0)) - { - Case (0) - { - // - // Standard query, supports function 1-1 - // - Return (Buffer () {0x03}) - } - Case (1) - { - // - // Save the Operation Value of the Request to MORD (reserved memory) - // - Store (DerefOf (Index (Arg1, 0x00)), MORD) - - // - // Trigger the SMI through ACPI _DSM method. - // - Store (0x01, MCIP) - - // - // Trigger the SMI interrupt - // - Store (MCIN, IOPN) - Return (MRET) - } - Default {BreakPoint} - } - Return (1) - } - Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj}) { @@ -503,12 +450,8 @@ DefinitionBlock ( } // - // TCG Memory Clear Interface + // _DSM Memory Clear is deprecated, so not called // - If(LEqual(Arg0, ToUUID ("376054ed-cc13-4675-901c-4756d7f2d45d"))) - { - Return (TMCI (Arg2, Arg3)) - } Return (Buffer () {0}) } From 99d60cbd3990fe8f5b86eaab40876fbbf9d99084 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 3 Sep 2024 22:21:23 +0200 Subject: [PATCH 190/280] ArmVirtPkg ARM: Move to MbedTls for crypto Move all BaseCryptLib resolutions for 32-bit ARM to MbedTls, which does not require a softfloat library, which can therefore be dropped from EDK2 entirely going forward. Note that this implies no TLS networking for 32-bit ARM, as this code has a direct dependency on OpenSSL, so move the TlsLib resolution to a AARCH64-only section to force the build to fail early when attempting to build 32-bit ARM targets with NETWORK_TLS_ENABLE set. Signed-off-by: Ard Biesheuvel --- ArmVirtPkg/ArmVirt.dsc.inc | 17 ++++++++++------- ArmVirtPkg/ArmVirtQemu.dsc | 8 ++++---- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 4f35da9a2aae..04394553044b 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -87,10 +87,6 @@ # Networking Requirements !include NetworkPkg/NetworkLibs.dsc.inc -!if $(NETWORK_TLS_ENABLE) == TRUE - TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf -!endif - # # It is not possible to prevent the ARM compiler from inserting calls to intrinsic functions. @@ -155,7 +151,6 @@ !else OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf !endif - BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf ArmTrngLib|ArmPkg/Library/ArmTrngLib/ArmTrngLib.inf ArmMonitorLib|ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf @@ -266,12 +261,20 @@ !endif VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf -!if $(SECURE_BOOT_ENABLE) == TRUE +[LibraryClasses.AARCH64.DXE_RUNTIME_DRIVER] BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf -!endif + +[LibraryClasses.ARM.DXE_RUNTIME_DRIVER] + BaseCryptLib|CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf + +[LibraryClasses.AARCH64] + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf + TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf [LibraryClasses.ARM] ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf + BaseCryptLib|CryptoPkg/Library/BaseCryptLibMbedTls/BaseCryptLib.inf + MbedTlsLib|CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf [BuildOptions] diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 713710c49905..56512594ad59 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -102,16 +102,16 @@ [LibraryClasses.common.PEIM] ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf - -!if $(TPM2_ENABLE) == TRUE ArmMonitorLib|ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.inf - BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf -!endif [LibraryClasses.AARCH64.PEIM] ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf + +[LibraryClasses.ARM.PEIM] + BaseCryptLib|CryptoPkg/Library/BaseCryptLibMbedTls/PeiCryptLib.inf [LibraryClasses.common.DXE_DRIVER] AcpiPlatformLib|OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf From 2ddce71142a6243aa4dc64242553d6591eb58def Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Mon, 5 Aug 2024 18:32:19 +0100 Subject: [PATCH 191/280] EmulatorPkg: fix X64 Unix/Host segfault with GCC toolchain profile Add the necessary toolchain override flags for ms_abi and LTO on X64 for the unversioned GCC toolchain profile. This resolves a runtime segmentation fault. Signed-off-by: Leif Lindholm --- EmulatorPkg/Unix/Host/Host.inf | 1 + 1 file changed, 1 insertion(+) diff --git a/EmulatorPkg/Unix/Host/Host.inf b/EmulatorPkg/Unix/Host/Host.inf index f5ebbed68344..1b7481d1e0d9 100644 --- a/EmulatorPkg/Unix/Host/Host.inf +++ b/EmulatorPkg/Unix/Host/Host.inf @@ -124,6 +124,7 @@ GCC:*_GCC48_X64_CC_FLAGS = "-DEFIAPI=__attribute__((ms_abi))" GCC:*_GCC49_X64_CC_FLAGS = "-DEFIAPI=__attribute__((ms_abi))" GCC:*_GCC5_X64_CC_FLAGS = "-DEFIAPI=__attribute__((ms_abi))" -flto -DUSING_LTO -Os + GCC:*_GCC_X64_CC_FLAGS = "-DEFIAPI=__attribute__((ms_abi))" -flto -DUSING_LTO -Os GCC:*_*_X64_PP_FLAGS == -m64 -E -x assembler-with-cpp -include $(DEST_DIR_DEBUG)/AutoGen.h GCC:*_*_X64_ASM_FLAGS == -m64 -c -x assembler -imacros $(DEST_DIR_DEBUG)/AutoGen.h From c9a59facd85f75bd30a6b9c0cccd789bc34402b1 Mon Sep 17 00:00:00 2001 From: Mike Maslenkin Date: Fri, 9 Aug 2024 02:46:12 +0300 Subject: [PATCH 192/280] RedfishPkg: RedfishDiscoverDxe: fix compilation warning /RedfishDiscoverDxe.c:1979:37: error: 'RestExInstance' may be used uninitialized in this function [-Werror=maybe-uninitialized] RestExInstance->Signature = EFI_REDFISH_DISCOVER_DATA_SIGNATURE; cc1: all warnings being treated as errors Signed-off-by: Mike Maslenkin --- RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c index 6870a2cae013..22fdbb74f1e1 100644 --- a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c +++ b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c @@ -1855,6 +1855,7 @@ BuildupNetworkInterface ( ListCount = (sizeof (mRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)); NewNetworkInterfaceInstalled = FALSE; Index = 0; + RestExInstance = NULL; for (Index = 0; Index < ListCount; Index++) { Status = gBS->OpenProtocol ( From 7acd8c9bd25de8e6af84d1696a8f963eac582089 Mon Sep 17 00:00:00 2001 From: Mike Maslenkin Date: Fri, 9 Aug 2024 02:48:34 +0300 Subject: [PATCH 193/280] RedfishPkg: PlatformHostInterfaceBmcUsbNicLib: fix compilation warning PlatformHostInterfaceBmcUsbNicLib.c: In function 'CheckBmcUsbNic': PlatformHostInterfaceBmcUsbNicLib.c:1253:14: error: error: 'HandleBuffer' may be used uninitialized in this function [-Werror=maybe-uninitialized] Status = CheckBmcUsbNicOnHandles (BufferSize/sizeof (EFI_HANDLE), HandleBuffer); cc1: all warnings being treated as errors Signed-off-by: Mike Maslenkin --- .../PlatformHostInterfaceBmcUsbNicLib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.c b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.c index c73e76df5791..6cb5a4b5a134 100644 --- a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.c +++ b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.c @@ -1202,6 +1202,7 @@ CheckBmcUsbNic ( DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry, the registration key - 0x%08x.\n", __func__, Registration)); Handle = NULL; + HandleBuffer = NULL; Status = EFI_SUCCESS; do { From 7b9f2018d1f2a850eca2ce1431e9eba8f185a716 Mon Sep 17 00:00:00 2001 From: Mike Maslenkin Date: Fri, 9 Aug 2024 13:16:52 +0300 Subject: [PATCH 194/280] RedfishPkg: PlatformHostInterfaceBmcUsbNicLib: use credential protocol This patch replaces call of IpmiSubmitCommand() issued REDFISH_IPMI_BOOTSTRAP_CREDENTIAL_ENABLE IPMI command to check whether bootstrap credential support enabled or not. The problem is that in accordance with IPMI spec while handling such command BMC creates bootstrap account. The credentials of this account is returned as a response. Obviously in this code the response is not used. From the other side there is an implementation of EDKII_REDFISH_CREDENTIAL_PROTOCOL exists and used by RedfishPlatformCredentialIpmiLib. By design RedfishPlatformCredentialIpmiLib keeps returned bootstrap credentials and uses it later. So all services using EDKII_REDFISH_CREDENTIAL_PROTOCOL instance operates with a same credentials. Current design of PlatformHostInterfaceBmcUsbNicLib leads to creation of two bootstrap accounts on BMC side. This is on nesseccary and one account is not used at all. Using EDKII_REDFISH_CREDENTIAL_PROTOCOL prevents from creating useless bootstrap account on BMC side. Signed-off-by: Mike Maslenkin --- .../PlatformHostInterfaceBmcUsbNicLib.c | 76 ++++++++++--------- .../PlatformHostInterfaceBmcUsbNicLib.h | 2 +- .../PlatformHostInterfaceBmcUsbNicLib.inf | 3 +- 3 files changed, 44 insertions(+), 37 deletions(-) diff --git a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.c b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.c index 6cb5a4b5a134..5c3f8f9c5031 100644 --- a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.c +++ b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.c @@ -23,7 +23,7 @@ static LIST_ENTRY mBmcIpmiLan; Bootstrapping. @retval TRUE Yes, it is supported. - TRUE No, it is not supported. + FALSE No, it is not supported. **/ BOOLEAN @@ -31,47 +31,53 @@ ProbeRedfishCredentialBootstrap ( VOID ) { - EFI_STATUS Status; - IPMI_BOOTSTRAP_CREDENTIALS_COMMAND_DATA CommandData; - IPMI_BOOTSTRAP_CREDENTIALS_RESULT_RESPONSE ResponseData; - UINT32 ResponseSize; - BOOLEAN ReturnBool; + EDKII_REDFISH_AUTH_METHOD AuthMethod; + EDKII_REDFISH_CREDENTIAL2_PROTOCOL *CredentialProtocol; + CHAR8 *UserName; + CHAR8 *Password; + BOOLEAN ReturnBool; + EFI_STATUS Status; DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry\n", __func__)); + ReturnBool = FALSE; // - // IPMI callout to NetFn 2C, command 02 - // Request data: - // Byte 1: REDFISH_IPMI_GROUP_EXTENSION - // Byte 2: DisableBootstrapControl + // Locate HII credential protocol. // - CommandData.GroupExtensionId = REDFISH_IPMI_GROUP_EXTENSION; - CommandData.DisableBootstrapControl = REDFISH_IPMI_BOOTSTRAP_CREDENTIAL_ENABLE; - ResponseData.CompletionCode = IPMI_COMP_CODE_UNSPECIFIED; - ResponseSize = sizeof (ResponseData); - // - // Response data: Ignored. - // - Status = IpmiSubmitCommand ( - IPMI_NETFN_GROUP_EXT, - REDFISH_IPMI_GET_BOOTSTRAP_CREDENTIALS_CMD, - (UINT8 *)&CommandData, - sizeof (CommandData), - (UINT8 *)&ResponseData, - &ResponseSize - ); - if (!EFI_ERROR (Status) && - ((ResponseData.CompletionCode == IPMI_COMP_CODE_NORMAL) || - (ResponseData.CompletionCode == REDFISH_IPMI_COMP_CODE_BOOTSTRAP_CREDENTIAL_DISABLED) - )) - { - DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Redfish Credential Bootstrapping is supported\n")); + Status = gBS->LocateProtocol ( + &gEdkIIRedfishCredential2ProtocolGuid, + NULL, + (VOID **)&CredentialProtocol + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return FALSE; + } + + Status = CredentialProtocol->GetAuthInfo ( + CredentialProtocol, + &AuthMethod, + &UserName, + &Password + ); + if (!EFI_ERROR (Status)) { + ZeroMem (Password, AsciiStrSize (Password)); + FreePool (Password); + ZeroMem (UserName, AsciiStrSize (UserName)); + FreePool (UserName); ReturnBool = TRUE; } else { - DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Redfish Credential Bootstrapping is not supported\n")); - ReturnBool = FALSE; + if (Status == EFI_ACCESS_DENIED) { + // bootstrap credential support was disabled + ReturnBool = TRUE; + } } + DEBUG (( + DEBUG_REDFISH_HOST_INTERFACE, + " Redfish Credential Bootstrapping is %a\n", + ReturnBool ? "supported" : "not supported" + )); return ReturnBool; } @@ -1201,9 +1207,9 @@ CheckBmcUsbNic ( DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry, the registration key - 0x%08x.\n", __func__, Registration)); - Handle = NULL; + Handle = NULL; HandleBuffer = NULL; - Status = EFI_SUCCESS; + Status = EFI_SUCCESS; do { BufferSize = 0; diff --git a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.h b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.h index 669c304fc3d8..96b2bdfbe721 100644 --- a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.h +++ b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.h @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -29,6 +28,7 @@ #include #include +#include #include #include diff --git a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.inf b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.inf index 3660249a3588..c37911993219 100644 --- a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.inf +++ b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.inf @@ -29,7 +29,6 @@ [LibraryClasses] BaseMemoryLib DebugLib - IpmiLib IpmiCommandLib MemoryAllocationLib UefiLib @@ -39,6 +38,7 @@ gEfiSimpleNetworkProtocolGuid ## CONSUMED gEfiUsbIoProtocolGuid ## CONSUMED gEfiDevicePathProtocolGuid ## CONSUMED + gEdkIIRedfishCredential2ProtocolGuid ## CONSUMED [Pcd] gEfiRedfishPkgTokenSpaceGuid.PcdRedfishHostName ## CONSUMED @@ -47,3 +47,4 @@ [Depex] gIpmiProtocolGuid + AND gEdkIIRedfishCredential2ProtocolGuid From 03bc4252fb68f0dcba72a19e1b2a861a5d6c927e Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Thu, 1 Aug 2024 18:39:12 -0600 Subject: [PATCH 195/280] XhciDxe: Fail the start of malfunctioning XHCI controllers Add missing error checking for malfunctioning XHCI controllers. Signed-off-by: Rebecca Cran --- MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c | 7 +++- MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c | 2 + MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c | 51 +++++++++++++++++------- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c index cf6b32959e68..a9d7e3616eb1 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c +++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c @@ -2077,7 +2077,12 @@ XhcDriverBindingStart ( XhcSetBiosOwnership (Xhc); - XhcResetHC (Xhc, XHC_RESET_TIMEOUT); + Status = XhcResetHC (Xhc, XHC_RESET_TIMEOUT); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to reset HC\n", __func__)); + goto FREE_POOL; + } + ASSERT (XhcIsHalt (Xhc)); // diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c index 525942a167b0..dc8228b429c7 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c +++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c @@ -29,6 +29,8 @@ XhcReadCapReg8 ( UINT8 Data; EFI_STATUS Status; + Data = 0; + Status = Xhc->PciIo->Mem.Read ( Xhc->PciIo, EfiPciIoWidthUint8, diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c index a97ed44dbfc3..3caa060f3564 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c +++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c @@ -2165,6 +2165,7 @@ XhcInitializeDeviceSlot ( DEVICE_CONTEXT *ParentDeviceContext; EFI_PHYSICAL_ADDRESS PhyAddr; + EvtTrb = NULL; ZeroMem (&CmdTrb, sizeof (CMD_TRB_ENABLE_SLOT)); CmdTrb.CycleBit = 1; CmdTrb.Type = TRB_TYPE_EN_SLOT; @@ -2175,7 +2176,7 @@ XhcInitializeDeviceSlot ( XHC_GENERIC_TIMEOUT, (TRB_TEMPLATE **)(UINTN)&EvtTrb ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || (EvtTrb == NULL)) { DEBUG ((DEBUG_ERROR, "XhcInitializeDeviceSlot: Enable Slot Failed, Status = %r\n", Status)); return Status; } @@ -2390,6 +2391,7 @@ XhcInitializeDeviceSlot64 ( DEVICE_CONTEXT_64 *ParentDeviceContext; EFI_PHYSICAL_ADDRESS PhyAddr; + EvtTrb = NULL; ZeroMem (&CmdTrb, sizeof (CMD_TRB_ENABLE_SLOT)); CmdTrb.CycleBit = 1; CmdTrb.Type = TRB_TYPE_EN_SLOT; @@ -2400,7 +2402,7 @@ XhcInitializeDeviceSlot64 ( XHC_GENERIC_TIMEOUT, (TRB_TEMPLATE **)(UINTN)&EvtTrb ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || (EvtTrb == NULL)) { DEBUG ((DEBUG_ERROR, "XhcInitializeDeviceSlot64: Enable Slot Failed, Status = %r\n", Status)); return Status; } @@ -2602,6 +2604,8 @@ XhcDisableSlotCmd ( UINT8 Index; VOID *RingSeg; + EvtTrb = NULL; + // // Disable the device slots occupied by these devices on its downstream ports. // Entry 0 is reserved. @@ -2637,7 +2641,7 @@ XhcDisableSlotCmd ( XHC_GENERIC_TIMEOUT, (TRB_TEMPLATE **)(UINTN)&EvtTrb ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || (EvtTrb == NULL)) { DEBUG ((DEBUG_ERROR, "XhcDisableSlotCmd: Disable Slot Command Failed, Status = %r\n", Status)); return Status; } @@ -2713,6 +2717,8 @@ XhcDisableSlotCmd64 ( UINT8 Index; VOID *RingSeg; + EvtTrb = NULL; + // // Disable the device slots occupied by these devices on its downstream ports. // Entry 0 is reserved. @@ -2748,7 +2754,7 @@ XhcDisableSlotCmd64 ( XHC_GENERIC_TIMEOUT, (TRB_TEMPLATE **)(UINTN)&EvtTrb ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || (EvtTrb == NULL)) { DEBUG ((DEBUG_ERROR, "XhcDisableSlotCmd: Disable Slot Command Failed, Status = %r\n", Status)); return Status; } @@ -3240,6 +3246,8 @@ XhcSetConfigCmd ( DEVICE_CONTEXT *OutputContext; EVT_TRB_COMMAND_COMPLETION *EvtTrb; + EvtTrb = NULL; + // // 4.6.6 Configure Endpoint // @@ -3290,7 +3298,7 @@ XhcSetConfigCmd ( XHC_GENERIC_TIMEOUT, (TRB_TEMPLATE **)(UINTN)&EvtTrb ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || (EvtTrb == NULL)) { DEBUG ((DEBUG_ERROR, "XhcSetConfigCmd: Config Endpoint Failed, Status = %r\n", Status)); } else { Xhc->UsbDevContext[SlotId].ActiveConfiguration = ConfigDesc->ConfigurationValue; @@ -3331,6 +3339,8 @@ XhcSetConfigCmd64 ( DEVICE_CONTEXT_64 *OutputContext; EVT_TRB_COMMAND_COMPLETION *EvtTrb; + EvtTrb = NULL; + // // 4.6.6 Configure Endpoint // @@ -3381,7 +3391,7 @@ XhcSetConfigCmd64 ( XHC_GENERIC_TIMEOUT, (TRB_TEMPLATE **)(UINTN)&EvtTrb ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || (EvtTrb == NULL)) { DEBUG ((DEBUG_ERROR, "XhcSetConfigCmd64: Config Endpoint Failed, Status = %r\n", Status)); } else { Xhc->UsbDevContext[SlotId].ActiveConfiguration = ConfigDesc->ConfigurationValue; @@ -3417,6 +3427,8 @@ XhcStopEndpoint ( DEBUG ((DEBUG_VERBOSE, "XhcStopEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci)); + EvtTrb = NULL; + // // When XhcCheckUrbResult waits for the Stop_Endpoint completion, it also checks // the PendingUrb completion status, because it's possible that the PendingUrb is @@ -3454,7 +3466,7 @@ XhcStopEndpoint ( XHC_GENERIC_TIMEOUT, (TRB_TEMPLATE **)(UINTN)&EvtTrb ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || (EvtTrb == NULL)) { DEBUG ((DEBUG_ERROR, "XhcStopEndpoint: Stop Endpoint Failed, Status = %r\n", Status)); } @@ -3488,6 +3500,8 @@ XhcResetEndpoint ( DEBUG ((DEBUG_INFO, "XhcResetEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci)); + EvtTrb = NULL; + // // Send stop endpoint command to transit Endpoint from running to stop state // @@ -3502,7 +3516,7 @@ XhcResetEndpoint ( XHC_GENERIC_TIMEOUT, (TRB_TEMPLATE **)(UINTN)&EvtTrb ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || (EvtTrb == NULL)) { DEBUG ((DEBUG_ERROR, "XhcResetEndpoint: Reset Endpoint Failed, Status = %r\n", Status)); } @@ -3538,6 +3552,8 @@ XhcSetTrDequeuePointer ( DEBUG ((DEBUG_VERBOSE, "XhcSetTrDequeuePointer: Slot = 0x%x, Dci = 0x%x, Urb = 0x%x\n", SlotId, Dci, Urb)); + EvtTrb = NULL; + // // Send stop endpoint command to transit Endpoint from running to stop state // @@ -3555,7 +3571,7 @@ XhcSetTrDequeuePointer ( XHC_GENERIC_TIMEOUT, (TRB_TEMPLATE **)(UINTN)&EvtTrb ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || (EvtTrb == NULL)) { DEBUG ((DEBUG_ERROR, "XhcSetTrDequeuePointer: Set TR Dequeue Pointer Failed, Status = %r\n", Status)); } @@ -3604,6 +3620,7 @@ XhcSetInterface ( EVT_TRB_COMMAND_COMPLETION *EvtTrb; Status = EFI_SUCCESS; + EvtTrb = NULL; InputContext = Xhc->UsbDevContext[SlotId].InputContext; OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; @@ -3755,7 +3772,7 @@ XhcSetInterface ( XHC_GENERIC_TIMEOUT, (TRB_TEMPLATE **)(UINTN)&EvtTrb ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || (EvtTrb == NULL)) { DEBUG ((DEBUG_ERROR, "SetInterface: Config Endpoint Failed, Status = %r\n", Status)); } else { // @@ -3810,6 +3827,7 @@ XhcSetInterface64 ( EVT_TRB_COMMAND_COMPLETION *EvtTrb; Status = EFI_SUCCESS; + EvtTrb = NULL; InputContext = Xhc->UsbDevContext[SlotId].InputContext; OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; @@ -3961,7 +3979,7 @@ XhcSetInterface64 ( XHC_GENERIC_TIMEOUT, (TRB_TEMPLATE **)(UINTN)&EvtTrb ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || (EvtTrb == NULL)) { DEBUG ((DEBUG_ERROR, "SetInterface64: Config Endpoint Failed, Status = %r\n", Status)); } else { // @@ -4001,6 +4019,8 @@ XhcEvaluateContext ( ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0); + EvtTrb = NULL; + // // 4.6.7 Evaluate Context // @@ -4028,7 +4048,7 @@ XhcEvaluateContext ( XHC_GENERIC_TIMEOUT, (TRB_TEMPLATE **)(UINTN)&EvtTrb ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || (EvtTrb == NULL)) { DEBUG ((DEBUG_ERROR, "XhcEvaluateContext: Evaluate Context Failed, Status = %r\n", Status)); } @@ -4062,6 +4082,8 @@ XhcEvaluateContext64 ( ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0); + EvtTrb = NULL; + // // 4.6.7 Evaluate Context // @@ -4089,7 +4111,7 @@ XhcEvaluateContext64 ( XHC_GENERIC_TIMEOUT, (TRB_TEMPLATE **)(UINTN)&EvtTrb ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || (EvtTrb == NULL)) { DEBUG ((DEBUG_ERROR, "XhcEvaluateContext64: Evaluate Context Failed, Status = %r\n", Status)); } @@ -4125,6 +4147,7 @@ XhcConfigHubContext ( EFI_PHYSICAL_ADDRESS PhyAddr; ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0); + EvtTrb = NULL; InputContext = Xhc->UsbDevContext[SlotId].InputContext; OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; @@ -4158,7 +4181,7 @@ XhcConfigHubContext ( XHC_GENERIC_TIMEOUT, (TRB_TEMPLATE **)(UINTN)&EvtTrb ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || (EvtTrb == NULL)) { DEBUG ((DEBUG_ERROR, "XhcConfigHubContext: Config Endpoint Failed, Status = %r\n", Status)); } From f0dc9e15048818e01c0556e6c461271aa9000d05 Mon Sep 17 00:00:00 2001 From: Ken Lautner Date: Tue, 27 Aug 2024 13:21:47 -0700 Subject: [PATCH 196/280] MdeModulePkg: UefiBootManagerLib: Update assert condition In BmFindBootOptionInVariable() we prevent passing a NULL pointer to EfiBootManagerFindLoadOption(). However, it can accept a NULL pointer as the second argument as long as count is zero. This change updates the assert condtion to only assert if the pointer is NULL and the count is non-zero. Signed-off-by: Kenneth Lautner --- MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c index 7a97f7cdcc6b..8d62b0c55835 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c @@ -147,6 +147,12 @@ BmFindBootOptionInVariable ( if (OptionNumber == LoadOptionNumberUnassigned) { BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot); + // Only assert if the BootOption is non-zero + if ((BootOptions == NULL) && (BootOptionCount > 0)) { + ASSERT (BootOptions != NULL); + return LoadOptionNumberUnassigned; + } + Index = EfiBootManagerFindLoadOption (OptionToFind, BootOptions, BootOptionCount); if (Index != -1) { OptionNumber = BootOptions[Index].OptionNumber; From 3151798123e1419e74ebef1df73e9d651f1fcd3e Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Tue, 23 Jul 2024 10:05:53 +0100 Subject: [PATCH 197/280] ShellPkg: Acpiview: Add GICC field parsing ACPI 6.5 adds mode flags that could do with more human-readable display in Acpiview. This adds support for displaying those flags. Signed-off-by: Carsten Haitzler --- .../Parsers/Madt/MadtParser.c | 109 ++++++++++++++---- 1 file changed, 87 insertions(+), 22 deletions(-) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c index 56ab507ef10a..8f0a454cc45f 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c @@ -146,33 +146,98 @@ ValidateTrbeInterrupt ( } } +/** + This function dumps the GICC Flags fields. + Format string is 2 fields separated by a \0 mapping to 0 or > 0 of + the buffer field bit. + + @param [in] Format Format string that is the list of strings to + map values to. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. +**/ +STATIC +VOID +EFIAPI +DumpValue ( + IN CONST CHAR16 *Format, + IN UINT8 *Ptr, + IN UINT32 Length OPTIONAL + ) +{ + UINT32 Value; + UINTN Len; + CONST CHAR16 *Format_Alt; + + Len = StrLen (Format); + Format_Alt = Format + Len + 1; + Value = *(UINT32 *)Ptr; + + Print (L"%s", Value ? Format : Format_Alt); +} + +STATIC CONST ACPI_PARSER GICCFlagParser[] = { + { L"Enabled", 1, 0, L"%d", NULL, NULL, NULL, NULL }, + { L"Performance Inter. Mode", 1, 1, L"Level Triggered\0Edge Triggered", DumpValue, NULL, NULL, NULL }, + { L"VGIC Maintenance Inter. Mode", 1, 2, L"Level Triggered\0Edge Triggered", DumpValue, NULL, NULL, NULL }, + { L"Online Capable", 1, 3, L"%d", NULL, NULL, NULL, NULL }, + { L"Reserved", 28, 4, L"%d", NULL, NULL, NULL, NULL } +}; + +/** + This function dumps the GICC Flags fields. + Format string is unused. + + @param [in] Format Unused + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. +**/ +STATIC +VOID +EFIAPI +DumpGicCFlags ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr, + IN UINT32 Length OPTIONAL + ) +{ + Print (L"0x%X\n", *(UINT32 *)Ptr); + ParseAcpiBitFields ( + TRUE, + 2, + NULL, + Ptr, + 4, + PARSER_PARAMS (GICCFlagParser) + ); +} + /** An ACPI_PARSER array describing the GICC Interrupt Controller Structure. **/ STATIC CONST ACPI_PARSER GicCParser[] = { - { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, - { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL }, - { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL }, - - { L"CPU Interface Number", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }, - { L"ACPI Processor UID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL }, - { L"Flags", 4, 12, L"0x%x", NULL, NULL, NULL, NULL }, - { L"Parking Protocol Version", 4, 16, L"0x%x", NULL, NULL, NULL, NULL }, - - { L"Performance Interrupt GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL }, - { L"Parked Address", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL }, - { L"Physical Base Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL }, - { L"GICV", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL }, - { L"GICH", 8, 48, L"0x%lx", NULL, NULL, NULL, NULL }, - { L"VGIC Maintenance interrupt", 4, 56, L"0x%x", NULL, NULL, NULL, NULL }, - { L"GICR Base Address", 8, 60, L"0x%lx", NULL, NULL, NULL, NULL }, - { L"MPIDR", 8, 68, L"0x%lx", NULL, NULL, NULL, NULL }, - { L"Processor Power Efficiency Class", 1, 76, L"0x%x", NULL, NULL, NULL, - NULL }, - { L"Reserved", 1, 77, L"0x%x", NULL, NULL, NULL, NULL }, - { L"SPE overflow Interrupt", 2, 78, L"0x%x", NULL, NULL, + { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL }, + + { L"CPU Interface Number", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }, + { L"ACPI Processor UID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Flags", 4, 12, NULL, DumpGicCFlags, NULL, NULL, NULL }, + { L"Parking Protocol Version", 4, 16, L"0x%x", NULL, NULL, NULL, NULL }, + + { L"Performance Interrupt GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Parked Address", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Physical Base Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"GICV", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"GICH", 8, 48, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"VGIC Maintenance interrupt", 4, 56, L"0x%x", NULL, NULL, NULL, NULL }, + { L"GICR Base Address", 8, 60, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"MPIDR", 8, 68, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Processor Power Efficiency Class", 1, 76, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 1, 77, L"0x%x", NULL, NULL, NULL, NULL }, + { L"SPE overflow Interrupt", 2, 78, L"0x%x", NULL, NULL, ValidateSpeOverflowInterrupt, NULL }, - { L"TRBE Interrupt", 2, 80, L"0x%x", NULL, NULL, + { L"TRBE Interrupt", 2, 80, L"0x%x", NULL, NULL, ValidateTrbeInterrupt, NULL } }; From 1204de7b50926b01394fefb28a04072305a39ca1 Mon Sep 17 00:00:00 2001 From: Vishal Oliyil Kunnil Date: Mon, 19 Aug 2024 14:05:57 -0700 Subject: [PATCH 198/280] EmbeddedPkg/PrePiHobLib: Align Doxygen comment between code and header The Doxygen comment for SetBootMode and GetBootMode in PrePiHobLib/Hob.c does not match declaration in PrePiLib.h. The C file has it wrong. Align the text to match the header. Signed-off-by: Vishal Oliyil Kunnil --- EmbeddedPkg/Library/PrePiHobLib/Hob.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/EmbeddedPkg/Library/PrePiHobLib/Hob.c b/EmbeddedPkg/Library/PrePiHobLib/Hob.c index cbc35152ccbc..c6a89e8ad6b3 100644 --- a/EmbeddedPkg/Library/PrePiHobLib/Hob.c +++ b/EmbeddedPkg/Library/PrePiHobLib/Hob.c @@ -333,14 +333,10 @@ GetFirstGuidHob ( } /** - Get the Boot Mode from the HOB list. + This service enables PEIMs to ascertain the present value of the boot mode. - This function returns the system boot mode information from the - PHIT HOB in HOB list. - @param VOID - - @return The Boot Mode. + @retval BootMode **/ EFI_BOOT_MODE @@ -356,14 +352,11 @@ GetBootMode ( } /** - Get the Boot Mode from the HOB list. - - This function returns the system boot mode information from the - PHIT HOB in HOB list. + This service enables PEIMs to update the boot mode variable. - @param VOID + @param BootMode The value of the boot mode to set. - @return The Boot Mode. + @retval EFI_SUCCESS The value was successfully updated **/ EFI_STATUS From 013d51771a67ff87e6cb17a57e156ef4b6f4ec54 Mon Sep 17 00:00:00 2001 From: Vishal Oliyil Kunnil Date: Mon, 19 Aug 2024 14:05:57 -0700 Subject: [PATCH 199/280] EmbeddedPkg/PrePiHobLib: Fix SetBootMode return value After updating Doxygen, we can see that SetBootMode returns the BootMode instead of status code as it should, fix it to return status. Signed-off-by: Vishal Oliyil Kunnil --- EmbeddedPkg/Library/PrePiHobLib/Hob.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EmbeddedPkg/Library/PrePiHobLib/Hob.c b/EmbeddedPkg/Library/PrePiHobLib/Hob.c index c6a89e8ad6b3..49b2fecb8a22 100644 --- a/EmbeddedPkg/Library/PrePiHobLib/Hob.c +++ b/EmbeddedPkg/Library/PrePiHobLib/Hob.c @@ -369,7 +369,7 @@ SetBootMode ( Hob.Raw = GetHobList (); Hob.HandoffInformationTable->BootMode = BootMode; - return BootMode; + return EFI_SUCCESS; } /** From bfb33c0e09b0cf05460168c00ec43817b835f897 Mon Sep 17 00:00:00 2001 From: Ashraf Ali Date: Sun, 1 Sep 2024 22:37:11 +0530 Subject: [PATCH 200/280] BaseTools: Disable MSVC volatileMetadata for VS2019 and VS2022 for X64 Starting with Visual Studio 2019 version 16.10, the /volatileMetadata option is enabled by default when generating x64 code. This patch disables the /volatileMetadata option for x64 builds in both VS2019 and VS2022. We observed a slight increase in used space for the Firmware volumes in VS2019. Upon investigation, we found that VS2019 version 16.10 enabled this feature by default. Disabling /volatileMetadata helps reduce the used space by approximately 3.5KB by considering the 2 Firmware volumes (2KB uncompressed FV and 1.5KB of compressed FV) Signed-off-by: Ashraf Ali --- BaseTools/Conf/tools_def.template | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index 76aaae726109..c2c24ca98c19 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -665,9 +665,9 @@ NOOPT_VS2019_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /O *_VS2019_X64_DLINK_PATH = DEF(VS2019_BIN_X64)\link.exe *_VS2019_X64_ASLDLINK_PATH = DEF(VS2019_BIN_X64)\link.exe - DEBUG_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Gw -RELEASE_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Gw -NOOPT_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Od + DEBUG_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Gw /volatileMetadata- +RELEASE_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Gw /volatileMetadata- +NOOPT_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Od /volatileMetadata- DEBUG_VS2019_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi RELEASE_VS2019_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd @@ -808,9 +808,9 @@ NOOPT_VS2022_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /O *_VS2022_X64_DLINK_PATH = DEF(VS2022_BIN_X64)\link.exe *_VS2022_X64_ASLDLINK_PATH = DEF(VS2022_BIN_X64)\link.exe - DEBUG_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Gw -RELEASE_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Gw -NOOPT_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Od + DEBUG_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Gw /volatileMetadata- +RELEASE_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Gw /volatileMetadata- +NOOPT_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Od /volatileMetadata- DEBUG_VS2022_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi RELEASE_VS2022_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd From 9dabe005f0cd422068fbb6cb915cf8180c55918d Mon Sep 17 00:00:00 2001 From: Nhi Pham Date: Fri, 30 Aug 2024 15:06:47 +0700 Subject: [PATCH 201/280] MdePkg/IndustryStandard: Add definitions for IPMI Boot Progress Code This adds constants and structure definitions for Send/Get Boot Progress Code through IPMI, according to Server Base Manageability Requirements (SBMR) [1], Appendix F. [1] https://developer.arm.com/documentation/den0069 Signed-off-by: Nhi Pham --- .../IpmiNetFnGroupExtension.h | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/MdePkg/Include/IndustryStandard/IpmiNetFnGroupExtension.h b/MdePkg/Include/IndustryStandard/IpmiNetFnGroupExtension.h index 6b26656cfe58..aa242efcbbff 100644 --- a/MdePkg/Include/IndustryStandard/IpmiNetFnGroupExtension.h +++ b/MdePkg/Include/IndustryStandard/IpmiNetFnGroupExtension.h @@ -2,12 +2,15 @@ IPMI 2.0 definitions from the IPMI Specification Version 2.0, Revision 1.1. Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.
+ Copyright (c) 2024, Ampere Computing LLC. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _IPMI_NET_FN_GROUP_EXTENSION_H_ #define _IPMI_NET_FN_GROUP_EXTENSION_H_ +#include + // // Net function definition for Group Extension command // @@ -17,4 +20,70 @@ // All Group Extension commands and their structure definitions to follow here // +/// +/// Constants and structure definitions for Boot Progress Codes +/// +/// See Section F of the Arm Server Base Manageability Requirements 2.0 specification, +/// https://developer.arm.com/documentation/den0069 +/// + +// +// Definitions for send progress code command +// +#define IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_SEND 0x02 + +// +// Definitions for get progress code command +// +#define IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_GET 0x03 + +// +// Definitions for send and get progress code command response +// +#define IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_COMPLETED_NORMALLY 0x00 +#define IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_COMPLETED_ERROR 0x80 +#define IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_DEFINING_BODY 0xAE + +// +// Structure for the format of the boot progress code data +// See Table 29: SBMR Boot Progress Codes format +// +typedef struct { + EFI_STATUS_CODE_TYPE CodeType; + EFI_STATUS_CODE_VALUE CodeValue; + UINT8 Instance; +} IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_FORMAT; + +// +// Structure for the boot progress code send request +// +typedef struct { + UINT8 DefiningBody; + IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_FORMAT BootProgressCode; +} IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_SEND_REQUEST; + +// +// Structure for the boot progress code send response +// +typedef struct { + UINT8 CompletionCode; + UINT8 DefiningBody; +} IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_SEND_RESPONSE; + +// +// Structure for the boot progress code get request +// +typedef struct { + UINT8 DefiningBody; +} IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_GET_REQUEST; + +// +// Structure for the boot progress code get response +// +typedef struct { + UINT8 CompletionCode; + UINT8 DefiningBody; + IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_FORMAT BootProgressCode; +} IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_GET_RESPONSE; + #endif From 253b3d678aa541b24a2e05f2279975de06abfeec Mon Sep 17 00:00:00 2001 From: ragavarshinib Date: Thu, 29 Aug 2024 16:10:26 +0530 Subject: [PATCH 202/280] MdeModulePkg/Core/Pei: Add error handling for Section Length This patch breaks the section processing loop if an invalid section with zero SectionLength is encountered. Signed-off-by: Ragavarshini B Cc: Liming Gao Cc: Dhanaraj V Cc: Sachin Ganesh --- MdeModulePkg/Core/Pei/FwVol/FwVol.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/MdeModulePkg/Core/Pei/FwVol/FwVol.c b/MdeModulePkg/Core/Pei/FwVol/FwVol.c index f7cc94c6ebd0..04bec986e42f 100644 --- a/MdeModulePkg/Core/Pei/FwVol/FwVol.c +++ b/MdeModulePkg/Core/Pei/FwVol/FwVol.c @@ -819,6 +819,10 @@ ProcessSection ( if (!IsFfs3Fv) { DEBUG ((DEBUG_ERROR, "Found a FFS3 formatted section in a non-FFS3 formatted FV.\n")); SectionLength = SECTION2_SIZE (Section); + if (SectionLength == 0) { + break; + } + // // SectionLength is adjusted it is 4 byte aligned. // Go to the next section @@ -854,6 +858,10 @@ ProcessSection ( SectionLength = SECTION_SIZE (Section); } + if (SectionLength == 0) { + break; + } + // // SectionLength is adjusted it is 4 byte aligned. // Go to the next section @@ -991,6 +999,10 @@ ProcessSection ( SectionLength = SECTION_SIZE (Section); } + if (SectionLength == 0) { + break; + } + // // SectionLength is adjusted it is 4 byte aligned. // Go to the next section From c047353a1244121f7d5b1780dbef2e2b30f762e1 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 6 Sep 2024 11:41:20 +0800 Subject: [PATCH 203/280] UefiCpuPkg/PiSmmCpuDxeSmm: Avoid to access MCA_CAP if CPU does not support Do not access MCA_CAP MSR unless the CPU supports the SmmRegFeatureControl Signed-off-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index c152dccea4bc..ee64d6b6d0bc 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -889,15 +889,13 @@ CheckFeatureSupported ( } if (mSmmCodeAccessCheckEnable) { - if (!SmmCpuFeaturesIsSmmRegisterSupported (CpuIndex, SmmRegFeatureControl)) { - mSmmCodeAccessCheckEnable = FALSE; - } - // // Check to see if the CPU supports the SMM Code Access Check feature // Do not access this MSR unless the CPU supports the SmmRegFeatureControl // - if ((AsmReadMsr64 (EFI_MSR_SMM_MCA_CAP) & SMM_CODE_ACCESS_CHK_BIT) == 0) { + if (!SmmCpuFeaturesIsSmmRegisterSupported (CpuIndex, SmmRegFeatureControl) || + ((AsmReadMsr64 (EFI_MSR_SMM_MCA_CAP) & SMM_CODE_ACCESS_CHK_BIT) == 0)) + { mSmmCodeAccessCheckEnable = FALSE; } } From 897284d47deec28a3f88a7694cfc899856b897b9 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 2 Sep 2024 14:40:05 +0800 Subject: [PATCH 204/280] UefiCpuPkg/PiSmmCpuDxeSmm: Fix IsSmmCommBufferForbiddenAddress check SmiPFHandler depends on the IsSmmCommBufferForbiddenAddress() to do the forbidden address check: For SMM, verifying whether an address is forbidden is necessary only when RestrictedMemoryAccess is enabled. For MM, all accessible address is recorded in the ResourceDescriptor HOB, so no need check the RestrictedMemoryAccess is enabled or not. This patch is to move RestrictedMemoryAccess check into SMM IsSmmCommBufferForbiddenAddress to align with above behavior. With the change, SmiPFHandler doesn't need to check the RestrictedMemoryAccess enable or not. Signed-off-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c | 4 ++++ UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c index a98013b7d01e..8c189ff6a057 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c @@ -546,6 +546,10 @@ IsSmmCommBufferForbiddenAddress ( UINTN Index; EFI_MEMORY_DESCRIPTOR *Entry; + if (!IsRestrictedMemoryAccess ()) { + return FALSE; + } + if (mUefiMemoryMap != NULL) { MemoryMap = mUefiMemoryMap; MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index 15d53b14114e..29b6125dce09 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -815,7 +815,7 @@ SmiPFHandler ( goto Exit; } - if (mCpuSmmRestrictedMemoryAccess && IsSmmCommBufferForbiddenAddress (PFAddress)) { + if (IsSmmCommBufferForbiddenAddress (PFAddress)) { DEBUG ((DEBUG_ERROR, "Access SMM communication forbidden address (0x%lx)!\n", PFAddress)); } } From c8ce84d06785ee7e7a3e1a8ab7c0af42ccbe3aa8 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 2 Sep 2024 12:03:46 +0800 Subject: [PATCH 205/280] UefiCpuPkg/PiSmmCpuDxeSmm: Always save and restore CR2 Following the commit 9f29fbd3, full mapping SMM page table is always created regardless the value of the PcdCpuSmmRestrictedMemoryAccess. Consequently, a page fault (#PF) that triggers an update to the page table occurs only when SmiProfile is enabled. Therefore, it is necessary to save and restore the CR2 register when SmiProfile is configured to be enabled. And the operation of saving and restoring CR2 is considered to be not heavy operation compared to the saving and restoring of CR3. As a result, the condition check for SmiProfile has been removed, and CR2 is now saved and restored unconditionally, without the need for additional condition checks. Signed-off-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index 29b6125dce09..d561dc19663e 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -845,7 +845,7 @@ SmiPFHandler ( } /** - This function reads CR2 register when on-demand paging is enabled. + This function reads CR2 register. @param[out] *Cr2 Pointer to variable to hold CR2 register value. **/ @@ -854,16 +854,11 @@ SaveCr2 ( OUT UINTN *Cr2 ) { - if (!mCpuSmmRestrictedMemoryAccess) { - // - // On-demand paging is enabled when access to non-SMRAM is not restricted. - // - *Cr2 = AsmReadCr2 (); - } + *Cr2 = AsmReadCr2 (); } /** - This function restores CR2 register when on-demand paging is enabled. + This function restores CR2 register. @param[in] Cr2 Value to write into CR2 register. **/ @@ -872,12 +867,7 @@ RestoreCr2 ( IN UINTN Cr2 ) { - if (!mCpuSmmRestrictedMemoryAccess) { - // - // On-demand paging is enabled when access to non-SMRAM is not restricted. - // - AsmWriteCr2 (Cr2); - } + AsmWriteCr2 (Cr2); } /** From f6eb069e1719a6203814846bd953d85518bc4f21 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 2 Sep 2024 13:51:09 +0800 Subject: [PATCH 206/280] UefiCpuPkg/PiSmmCpuDxeSmm: Deadloop if PFAddr is not supported by system Deadloop if PFAddr is not supported by system, no need check SMM CPU RestrictedMemory access enable or not. Signed-off-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index d561dc19663e..fb1f237c126d 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -726,7 +726,7 @@ SmiPFHandler ( PFAddress = AsmReadCr2 (); - if (mCpuSmmRestrictedMemoryAccess && (PFAddress >= LShiftU64 (1, (mPhysicalAddressBits - 1)))) { + if (PFAddress >= LShiftU64 (1, (mPhysicalAddressBits - 1))) { DumpCpuContext (InterruptType, SystemContext); DEBUG ((DEBUG_ERROR, "Do not support address 0x%lx by processor!\n", PFAddress)); CpuDeadLoop (); From 4f6614fc180c3f24a72ac3234daba8575f13cbad Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 2 Sep 2024 12:22:41 +0800 Subject: [PATCH 207/280] UefiCpuPkg/PiSmmCpuDxeSmm: Correct SetPageTableAttributes func usage SetPageTableAttributes() will use the IfReadOnlyPageTableNeeded() to determine whether it is necessary to set the page table itself to read-only. And IfReadOnlyPageTableNeeded() has already token into account the status of IsRestrictedMemoryAccess(). Therefore, there is no need for an additional call to IsRestrictedMemoryAccess() before calling the SetPageTableAttributes(). Signed-off-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 10 ++++------ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c | 10 ++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index 50aeefb9484e..0ecdd2d8910d 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -95,12 +95,10 @@ PerformRemainingTasks ( SetMemMapAttributes (MemoryAttributesTable); } - if (IsRestrictedMemoryAccess ()) { - // - // Set page table itself to be read-only - // - SetPageTableAttributes (); - } + // + // Set page table itself to be read-only + // + SetPageTableAttributes (); // // Configure SMM Code Access Check feature if available. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c index f81389463fc7..6f59b493051a 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c @@ -70,12 +70,10 @@ PerformRemainingTasks ( SetMemMapAttributes (MemoryAttributesTable); } - if (IsRestrictedMemoryAccess ()) { - // - // Set page table itself to be read-only - // - SetPageTableAttributes (); - } + // + // Set page table itself to be read-only + // + SetPageTableAttributes (); // // Measure performance of SmmCpuFeaturesCompleteSmmReadyToLock() from caller side From 633a755d99d8f889c4e3ed74cf558b16e6a67251 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 2 Sep 2024 13:37:51 +0800 Subject: [PATCH 208/280] UefiCpuPkg/PiSmmCpuDxeSmm: Update IfReadOnlyPageTableNeeded After the 9f29fbd3, full mapping SMM page table is always created regardless the value of the PcdCpuSmmRestrictedMemoryAccess. If so, SMM PageTable Attributes can be set to ready-only since there is no need to update it. So, this patch is to remove restricted memory access check when setting the SMM PageTable attributes. Signed-off-by: Jiaxin Wu --- .../PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c index d1cfd72106c0..9c2fe162a992 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c @@ -1486,31 +1486,14 @@ IfReadOnlyPageTableNeeded ( { // // Don't mark page table memory as read-only if - // - no restriction on access to non-SMRAM memory; or // - SMM heap guard feature enabled; or // BIT2: SMM page guard enabled // BIT3: SMM pool guard enabled // - SMM profile feature enabled // - if (!IsRestrictedMemoryAccess () || - ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) || + if (((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) || mSmmProfileEnabled) { - if (sizeof (UINTN) == sizeof (UINT64)) { - // - // Restriction on access to non-SMRAM memory and heap guard could not be enabled at the same time. - // - ASSERT ( - !(IsRestrictedMemoryAccess () && - (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) - ); - - // - // Restriction on access to non-SMRAM memory and SMM profile could not be enabled at the same time. - // - ASSERT (!(IsRestrictedMemoryAccess () && mSmmProfileEnabled)); - } - return FALSE; } From b4820f2d6591357d7e6f35b5e5340300d3be790f Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 2 Sep 2024 14:52:14 +0800 Subject: [PATCH 209/280] UefiCpuPkg/PiSmmCpuDxeSmm: Clean mCpuSmmRestrictedMemoryAccess Currently, mCpuSmmRestrictedMemoryAccess is only used by the IsRestrictedMemoryAccess(). And IsRestrictedMemoryAccess() can consume the PcdCpuSmmRestrictedMemoryAccess directly. Therefore, mCpuSmmRestrictedMemoryAccess can be cleaned to simply the code logic. Signed-off-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index fb1f237c126d..4043e26955c1 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -15,7 +15,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent LIST_ENTRY mPagePool = INITIALIZE_LIST_HEAD_VARIABLE (mPagePool); BOOLEAN m1GPageTableSupport = FALSE; -BOOLEAN mCpuSmmRestrictedMemoryAccess; X86_ASSEMBLY_PATCH_LABEL gPatch5LevelPagingNeeded; /** @@ -207,10 +206,9 @@ SmmInitPageTable ( // InitializeSpinLock (mPFLock); - mCpuSmmRestrictedMemoryAccess = PcdGetBool (PcdCpuSmmRestrictedMemoryAccess); - m1GPageTableSupport = Is1GPageSupport (); - m5LevelPagingNeeded = Is5LevelPagingNeeded (); - mPhysicalAddressBits = CalculateMaximumSupportAddress (m5LevelPagingNeeded); + m1GPageTableSupport = Is1GPageSupport (); + m5LevelPagingNeeded = Is5LevelPagingNeeded (); + mPhysicalAddressBits = CalculateMaximumSupportAddress (m5LevelPagingNeeded); PatchInstructionX86 (gPatch5LevelPagingNeeded, m5LevelPagingNeeded, 1); if (m5LevelPagingNeeded) { mPagingMode = m1GPageTableSupport ? Paging5Level1GB : Paging5Level; @@ -220,7 +218,6 @@ SmmInitPageTable ( DEBUG ((DEBUG_INFO, "5LevelPaging Needed - %d\n", m5LevelPagingNeeded)); DEBUG ((DEBUG_INFO, "1GPageTable Support - %d\n", m1GPageTableSupport)); - DEBUG ((DEBUG_INFO, "PcdCpuSmmRestrictedMemoryAccess - %d\n", mCpuSmmRestrictedMemoryAccess)); DEBUG ((DEBUG_INFO, "PhysicalAddressBits - %d\n", mPhysicalAddressBits)); // @@ -881,5 +878,5 @@ IsRestrictedMemoryAccess ( VOID ) { - return mCpuSmmRestrictedMemoryAccess; + return PcdGetBool (PcdCpuSmmRestrictedMemoryAccess); } From b437b5ca4c1a6725897dfd0740de6ef20cacd226 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 2 Sep 2024 15:22:00 +0800 Subject: [PATCH 210/280] UefiCpuPkg/PiSmmCpuDxeSmm: Remove RestrictedMemoryAccess check for MM CPU The PcdCpuSmmRestrictedMemoryAccess is declared as either a dynamic or fixed PCD. It is not recommended for use in the MM CPU driver. Furthermore, IsRestrictedMemoryAccess() is only needed for SMM. Therefor, there is no need for MM to consume the PcdCpuSmmRestrictedMemoryAccess. So, this patch is to add the SMM specific file for its own functions, with the change, the dependency of the MM CPU driver on PcdCpuSmmRestrictedMemoryAccess can be removed. Signed-off-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 14 ------------ .../PiSmmCpuDxeSmm/Ia32/SmmFuncsArchDxeSmm.c | 22 +++++++++++++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 2 ++ .../PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf | 3 --- UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 14 ------------ .../PiSmmCpuDxeSmm/X64/SmmFuncsArchDxeSmm.c | 22 +++++++++++++++++++ 6 files changed, 46 insertions(+), 31 deletions(-) create mode 100644 UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArchDxeSmm.c create mode 100644 UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArchDxeSmm.c diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c index 1294485c60ae..e1ce36bf7863 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c @@ -229,17 +229,3 @@ RestoreCr2 ( { return; } - -/** - Return whether access to non-SMRAM is restricted. - - @retval TRUE Access to non-SMRAM is restricted. - @retval FALSE Access to non-SMRAM is not restricted. -**/ -BOOLEAN -IsRestrictedMemoryAccess ( - VOID - ) -{ - return TRUE; -} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArchDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArchDxeSmm.c new file mode 100644 index 000000000000..21f7992fd815 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArchDxeSmm.c @@ -0,0 +1,22 @@ +/** @file + +Copyright (c) 2024, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuCommon.h" + +/** + Return whether access to non-SMRAM is restricted. + + @retval TRUE Access to non-SMRAM is restricted. + @retval FALSE Access to non-SMRAM is not restricted. +**/ +BOOLEAN +IsRestrictedMemoryAccess ( + VOID + ) +{ + return TRUE; +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf index d8eda7825ff2..8c4be7e5883d 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -56,6 +56,7 @@ Ia32/SmiEntry.nasm Ia32/SmiException.nasm Ia32/Cet.nasm + Ia32/SmmFuncsArchDxeSmm.c [Sources.X64] X64/PageTbl.c @@ -65,6 +66,7 @@ X64/SmiEntry.nasm X64/SmiException.nasm X64/Cet.nasm + X64/SmmFuncsArchDxeSmm.c [Packages] MdePkg/MdePkg.dec diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf index 13b8ce17bd95..d0ae5e709d2c 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf @@ -131,6 +131,3 @@ [Depex] TRUE - -[Pcd.X64] - gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmRestrictedMemoryAccess ## CONSUMES diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index 4043e26955c1..160e33b4ed6a 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -866,17 +866,3 @@ RestoreCr2 ( { AsmWriteCr2 (Cr2); } - -/** - Return whether access to non-SMRAM is restricted. - - @retval TRUE Access to non-SMRAM is restricted. - @retval FALSE Access to non-SMRAM is not restricted. -**/ -BOOLEAN -IsRestrictedMemoryAccess ( - VOID - ) -{ - return PcdGetBool (PcdCpuSmmRestrictedMemoryAccess); -} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArchDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArchDxeSmm.c new file mode 100644 index 000000000000..e812a433125a --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArchDxeSmm.c @@ -0,0 +1,22 @@ +/** @file + +Copyright (c) 2024, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuCommon.h" + +/** + Return whether access to non-SMRAM is restricted. + + @retval TRUE Access to non-SMRAM is restricted. + @retval FALSE Access to non-SMRAM is not restricted. +**/ +BOOLEAN +IsRestrictedMemoryAccess ( + VOID + ) +{ + return PcdGetBool (PcdCpuSmmRestrictedMemoryAccess); +} From 043615ae8b0df9635b509643fe1d5cedb6e1a64d Mon Sep 17 00:00:00 2001 From: Ceping Sun Date: Thu, 29 Aug 2024 21:21:48 -0400 Subject: [PATCH 211/280] MdePkg/BaseLib: Add NULL version Tdx functions for other architectures Currently, the NULL version Tdx functions are only built for Ia32. In BaseLib, the others architectures also need such NULL version Tdx functions. Cc: Liming Gao Cc: Michael D Kinney Cc: Zhiguang Liu Cc: Gerd Hoffmann Cc: Jiewen Yao Cc: Min Xu Signed-off-by: Ceping Sun --- MdePkg/Include/Library/BaseLib.h | 4 ---- MdePkg/Library/BaseLib/BaseLib.inf | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index eb817f131f53..9658026d9c60 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -5259,8 +5259,6 @@ SpeculationBarrier ( VOID ); -#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) - /** The TDCALL instruction causes a VM exit to the Intel TDX module. It is used to call guest-side Intel TDX functions, either local or a TD exit @@ -5323,8 +5321,6 @@ TdIsEnabled ( VOID ); -#endif - #if defined (MDE_CPU_X64) // // The page size for the PVALIDATE instruction diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf index e3336c5dfb48..317d32cf68a4 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -339,6 +339,7 @@ Ebc/SpeculationBarrier.c Unaligned.c Math64.c + IntelTdxNull.c [Sources.ARM] Arm/InternalSwitchStack.c @@ -364,6 +365,7 @@ Arm/CpuBreakpoint.S | GCC Arm/MemoryFence.S | GCC Arm/SpeculationBarrier.S | GCC + IntelTdxNull.c [Sources.AARCH64] Arm/InternalSwitchStack.c @@ -391,6 +393,7 @@ AArch64/SpeculationBarrier.asm | MSFT AArch64/ArmReadCntPctReg.asm | MSFT AArch64/ArmReadIdAA64Isar0Reg.asm | MSFT + IntelTdxNull.c [Sources.RISCV64] Math64.c @@ -412,6 +415,7 @@ RiscV64/ReadTimer.S | GCC RiscV64/RiscVMmu.S | GCC RiscV64/SpeculationBarrier.S | GCC + IntelTdxNull.c [Sources.LOONGARCH64] Math64.c @@ -432,6 +436,7 @@ LoongArch64/ExceptionBase.S | GCC LoongArch64/Cpucfg.S | GCC LoongArch64/ReadStableCounter.S | GCC + IntelTdxNull.c [Packages] MdePkg/MdePkg.dec From e5715711a41b3a323b1605e41e5875d377e7c9c2 Mon Sep 17 00:00:00 2001 From: Ceping Sun Date: Tue, 7 May 2024 06:33:57 +0800 Subject: [PATCH 212/280] OvmfPkg/QemuFwCfgS3Lib: Disable S3 detection in TDVF Refer to the section 2.1 of tdx-virtual-firmware-design-guide spec, APCI S3 is not supported in TDVF. Therefore, TDVF should not read the S3 status via fw_cfg and always set it as unsupported. spec: https://cdrdv2.intel.com/v1/dl/getContent/733585 Cc: Erdem Aktas Cc: Jiewen Yao Cc: Min Xu Cc: Gerd Hoffmann Cc: Elena Reshetova Signed-off-by: Ceping Sun --- OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c index 270f0503367c..e0c21461ce0e 100644 --- a/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c +++ b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c @@ -7,6 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ +#include #include #include @@ -32,6 +33,10 @@ QemuFwCfgS3Enabled ( UINTN FwCfgSize; UINT8 SystemStates[6]; + if (TdIsEnabled ()) { + return FALSE; + } + Status = QemuFwCfgFindFile ("etc/system-states", &FwCfgItem, &FwCfgSize); if ((Status != RETURN_SUCCESS) || (FwCfgSize != sizeof SystemStates)) { return FALSE; From 3885a3edad618861168fe7081027867f1753ed42 Mon Sep 17 00:00:00 2001 From: Mike Beaton Date: Sun, 8 Sep 2024 11:33:43 +0100 Subject: [PATCH 213/280] NetworkPkg/DxeNetLib: Update misleading comment Commit 6862b9d538d96363635677198899e1669e591259 makes more explicit the previous logic of the code anyway, which is that it is (and was) only a fatal error if all secure algorithms fail. However the comment updated by this commit seems somewhat incompatible with that change, and even with the previous code (which operated as now, just logging different error messages). This updates the comment to be more compatible with how the code operates. Signed-off-by: Mike Beaton --- NetworkPkg/Library/DxeNetLib/DxeNetLib.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/NetworkPkg/Library/DxeNetLib/DxeNetLib.c b/NetworkPkg/Library/DxeNetLib/DxeNetLib.c index 4dfbe91a5554..cf875d7af350 100644 --- a/NetworkPkg/Library/DxeNetLib/DxeNetLib.c +++ b/NetworkPkg/Library/DxeNetLib/DxeNetLib.c @@ -133,10 +133,16 @@ GLOBAL_REMOVE_IF_UNREFERENCED VLAN_DEVICE_PATH mNetVlanDevicePathTemplate = { // These represent UEFI SPEC defined algorithms that should be supported by // the RNG protocol and are generally considered secure. // -// The order of the algorithms in this array is important. This order is the order -// in which the algorithms will be tried by the RNG protocol. -// If your platform needs to use a specific algorithm for the random number generator, -// then you should place that algorithm first in the array. +// Assuming that PcdEnforceSecureRngAlgorithms is TRUE (the default) then +// only the algorithms defined here will be used by the network stack, and +// none of these being available will result in an error condition (even if +// some other RNG implementation is available). +// +// If PcdEnforceSecureRngAlgorithms is FALSE this list is not consulted, +// and the first available RNG algorithm is used. +// +// If your platform needs to use a specific algorithm for the random number +// generator, then you should modify this array. // GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID *mSecureHashAlgorithms[] = { &gEfiRngAlgorithmSp80090Ctr256Guid, // SP800-90A DRBG CTR using AES-256 From 61f9695f20a575085d0579a0d3efc41b322ce1ac Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Wed, 4 Sep 2024 10:02:09 -0700 Subject: [PATCH 214/280] BaseTools: Remove Pip BaseTools BaseTools was moved out to a separate repo and consumed as a pip module by edk2 CI. This process has not led to the desired goals of doing so, so this patch removes the pip based BaseTools from edk2 CI. The original goal of moving BaseTools to a pip module was primarily to speed up the development process, as the old edk2 mailing list was slow. However, with edk2 moving to PRs, it now actually slows the BaseTools development process to have to do a PR in another repo, publish the module, and then make a PR in edk2 to consume the new BaseTools. It also holds up using the features in a new BaseTools in other PRs. There were other goals of moving, such as allowing projects to use the BaseTools outside of edk2. This can still be accomplished outside of this PR, this PR simply stops edk2 CI from using the pip module. Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Oliver Smith-Denny --- .pytool/CISettings.py | 27 --------- BaseTools/BinPipWrappers/PosixLike/AmlToC | 14 ----- BaseTools/BinPipWrappers/PosixLike/BPDG | 12 ---- .../BinPipWrappers/PosixLike/BrotliCompress | 60 ------------------- BaseTools/BinPipWrappers/PosixLike/DevicePath | 29 --------- BaseTools/BinPipWrappers/PosixLike/Ecc | 13 ---- BaseTools/BinPipWrappers/PosixLike/EfiRom | 29 --------- BaseTools/BinPipWrappers/PosixLike/GenCrc32 | 29 --------- BaseTools/BinPipWrappers/PosixLike/GenDepex | 12 ---- BaseTools/BinPipWrappers/PosixLike/GenFds | 12 ---- BaseTools/BinPipWrappers/PosixLike/GenFfs | 29 --------- BaseTools/BinPipWrappers/PosixLike/GenFv | 29 --------- BaseTools/BinPipWrappers/PosixLike/GenFw | 29 --------- .../BinPipWrappers/PosixLike/GenPatchPcdTable | 12 ---- BaseTools/BinPipWrappers/PosixLike/GenSec | 29 --------- .../BinPipWrappers/PosixLike/GenerateCapsule | 12 ---- .../BinPipWrappers/PosixLike/LzmaCompress | 29 --------- .../BinPipWrappers/PosixLike/LzmaF86Compress | 19 ------ .../BinPipWrappers/PosixLike/PatchPcdValue | 12 ---- BaseTools/BinPipWrappers/PosixLike/Pkcs7Sign | 12 ---- .../PosixLike/Rsa2048Sha256GenerateKeys | 12 ---- .../PosixLike/Rsa2048Sha256Sign | 12 ---- BaseTools/BinPipWrappers/PosixLike/Split | 29 --------- BaseTools/BinPipWrappers/PosixLike/TargetTool | 12 ---- .../BinPipWrappers/PosixLike/TianoCompress | 29 --------- BaseTools/BinPipWrappers/PosixLike/Trim | 13 ---- BaseTools/BinPipWrappers/PosixLike/UPT | 12 ---- BaseTools/BinPipWrappers/PosixLike/VfrCompile | 29 --------- BaseTools/BinPipWrappers/PosixLike/VolInfo | 29 --------- BaseTools/BinPipWrappers/PosixLike/build | 12 ---- .../PosixLike/posix_path_env.yaml | 11 ---- .../BinPipWrappers/WindowsLike/AmlToC.bat | 3 - BaseTools/BinPipWrappers/WindowsLike/BPDG.bat | 3 - BaseTools/BinPipWrappers/WindowsLike/Ecc.bat | 3 - .../BinPipWrappers/WindowsLike/GenDepex.bat | 3 - .../BinPipWrappers/WindowsLike/GenFds.bat | 3 - .../WindowsLike/GenPatchPcdTable.bat | 3 - .../WindowsLike/GenerateCapsule.bat | 1 - .../WindowsLike/PatchPcdValue.bat | 3 - .../BinPipWrappers/WindowsLike/Pkcs7Sign.bat | 3 - .../WindowsLike/Rsa2048Sha256GenerateKeys.bat | 1 - .../WindowsLike/Rsa2048Sha256Sign.bat | 3 - .../BinPipWrappers/WindowsLike/Split.bat | 3 - .../BinPipWrappers/WindowsLike/TargetTool.bat | 3 - BaseTools/BinPipWrappers/WindowsLike/Trim.bat | 3 - BaseTools/BinPipWrappers/WindowsLike/UPT.bat | 3 - .../BinPipWrappers/WindowsLike/build.bat | 3 - .../WindowsLike/win_build_tools_path_env.yaml | 11 ---- BaseTools/BuildEnv | 11 +--- BaseTools/Scripts/PatchCheck.py | 1 - BaseTools/Source/Python/README.md | 29 --------- BaseTools/toolsetup.bat | 16 ----- pip-requirements.txt | 1 - 53 files changed, 1 insertion(+), 761 deletions(-) delete mode 100755 BaseTools/BinPipWrappers/PosixLike/AmlToC delete mode 100755 BaseTools/BinPipWrappers/PosixLike/BPDG delete mode 100755 BaseTools/BinPipWrappers/PosixLike/BrotliCompress delete mode 100755 BaseTools/BinPipWrappers/PosixLike/DevicePath delete mode 100755 BaseTools/BinPipWrappers/PosixLike/Ecc delete mode 100755 BaseTools/BinPipWrappers/PosixLike/EfiRom delete mode 100755 BaseTools/BinPipWrappers/PosixLike/GenCrc32 delete mode 100755 BaseTools/BinPipWrappers/PosixLike/GenDepex delete mode 100755 BaseTools/BinPipWrappers/PosixLike/GenFds delete mode 100755 BaseTools/BinPipWrappers/PosixLike/GenFfs delete mode 100755 BaseTools/BinPipWrappers/PosixLike/GenFv delete mode 100755 BaseTools/BinPipWrappers/PosixLike/GenFw delete mode 100755 BaseTools/BinPipWrappers/PosixLike/GenPatchPcdTable delete mode 100755 BaseTools/BinPipWrappers/PosixLike/GenSec delete mode 100755 BaseTools/BinPipWrappers/PosixLike/GenerateCapsule delete mode 100755 BaseTools/BinPipWrappers/PosixLike/LzmaCompress delete mode 100755 BaseTools/BinPipWrappers/PosixLike/LzmaF86Compress delete mode 100755 BaseTools/BinPipWrappers/PosixLike/PatchPcdValue delete mode 100755 BaseTools/BinPipWrappers/PosixLike/Pkcs7Sign delete mode 100755 BaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256GenerateKeys delete mode 100755 BaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256Sign delete mode 100755 BaseTools/BinPipWrappers/PosixLike/Split delete mode 100755 BaseTools/BinPipWrappers/PosixLike/TargetTool delete mode 100755 BaseTools/BinPipWrappers/PosixLike/TianoCompress delete mode 100755 BaseTools/BinPipWrappers/PosixLike/Trim delete mode 100755 BaseTools/BinPipWrappers/PosixLike/UPT delete mode 100755 BaseTools/BinPipWrappers/PosixLike/VfrCompile delete mode 100755 BaseTools/BinPipWrappers/PosixLike/VolInfo delete mode 100755 BaseTools/BinPipWrappers/PosixLike/build delete mode 100644 BaseTools/BinPipWrappers/PosixLike/posix_path_env.yaml delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/AmlToC.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/BPDG.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/Ecc.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/GenDepex.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/GenFds.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/GenPatchPcdTable.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/GenerateCapsule.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/PatchPcdValue.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/Pkcs7Sign.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256GenerateKeys.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256Sign.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/Split.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/TargetTool.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/Trim.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/UPT.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/build.bat delete mode 100644 BaseTools/BinPipWrappers/WindowsLike/win_build_tools_path_env.yaml delete mode 100644 BaseTools/Source/Python/README.md diff --git a/.pytool/CISettings.py b/.pytool/CISettings.py index 314758da32e3..e14b77d4e29e 100644 --- a/.pytool/CISettings.py +++ b/.pytool/CISettings.py @@ -37,7 +37,6 @@ def __init__(self): self.ActualTargets = [] self.ActualArchitectures = [] self.ActualToolChainTag = "" - self.UseBuiltInBaseTools = None self.ActualScopes = None # ####################################################################################### # @@ -45,10 +44,6 @@ def __init__(self): # ####################################################################################### # def AddCommandLineOptions(self, parserObj): - group = parserObj.add_mutually_exclusive_group() - group.add_argument("-force_piptools", "--fpt", dest="force_piptools", action="store_true", default=False, help="Force the system to use pip tools") - group.add_argument("-no_piptools", "--npt", dest="no_piptools", action="store_true", default=False, help="Force the system to not use pip tools") - try: codeql_helpers.add_command_line_option(parserObj) except NameError: @@ -56,10 +51,6 @@ def AddCommandLineOptions(self, parserObj): def RetrieveCommandLineOptions(self, args): super().RetrieveCommandLineOptions(args) - if args.force_piptools: - self.UseBuiltInBaseTools = True - if args.no_piptools: - self.UseBuiltInBaseTools = False try: self.codeql = codeql_helpers.is_codeql_enabled_on_command_line(args) @@ -176,24 +167,6 @@ def GetActiveScopes(self): self.ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "") - is_linux = GetHostInfo().os.upper() == "LINUX" - - if self.UseBuiltInBaseTools is None: - is_linux = GetHostInfo().os.upper() == "LINUX" - # try and import the pip module for basetools - try: - import edk2basetools - self.UseBuiltInBaseTools = True - except ImportError: - self.UseBuiltInBaseTools = False - pass - - if self.UseBuiltInBaseTools == True: - scopes += ('pipbuild-unix',) if is_linux else ('pipbuild-win',) - logging.warning("Using Pip Tools based BaseTools") - else: - logging.warning("Falling back to using in-tree BaseTools") - try: scopes += codeql_helpers.get_scopes(self.codeql) diff --git a/BaseTools/BinPipWrappers/PosixLike/AmlToC b/BaseTools/BinPipWrappers/PosixLike/AmlToC deleted file mode 100755 index 1dd28e966288..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/AmlToC +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -exe=$(basename "$full_cmd") - -export PYTHONPATH="$dir/../../Source/Python${PYTHONPATH:+:"$PYTHONPATH"}" -exec "${python_exe:-python}" "$dir/../../Source/Python/$exe/$exe.py" "$@" diff --git a/BaseTools/BinPipWrappers/PosixLike/BPDG b/BaseTools/BinPipWrappers/PosixLike/BPDG deleted file mode 100755 index a08cbd8de5c5..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/BPDG +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -cmd=${full_cmd##*/} - -exec "${python_exe:-python}" -m edk2basetools.$cmd.EccMain "$@" diff --git a/BaseTools/BinPipWrappers/PosixLike/BrotliCompress b/BaseTools/BinPipWrappers/PosixLike/BrotliCompress deleted file mode 100755 index 426f2a2ef196..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/BrotliCompress +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env bash -# -# This script will exec Brotli tool with -e/-d options. -# -# Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
-# SPDX-License-Identifier: BSD-2-Clause-Patent -# -QLT="-q 9 -w 22" -ARGS= - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -cmd=${full_cmd##*/} - -while test $# -gt 0 -do - case $1 in - -e) - ;; - -d) - ARGS+="$1 " - ;; - -o|-g) - ARGS+="$1 $2 " - shift - ;; - -q) - QLT="$1 $2 " - shift - ;; - *) - ARGS+="$1 " - ;; - esac - shift -done - - -if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] -then - exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" -elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] -then - if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] - then - echo "BaseTools C Tool binary was not found ($cmd)" - echo "You may need to run:" - echo " make -C $EDK_TOOLS_PATH/Source/C" - else - exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" $QLT $ARGS - fi -elif [ -e "$dir/../../Source/C/bin/$cmd" ] -then - exec "$dir/../../Source/C/bin/$cmd" $QLT $ARGS -else - echo "Unable to find the real '$cmd' to run" - echo "This message was printed by" - echo " $0" - exit 127 -fi diff --git a/BaseTools/BinPipWrappers/PosixLike/DevicePath b/BaseTools/BinPipWrappers/PosixLike/DevicePath deleted file mode 100755 index 0945d86d9209..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/DevicePath +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -cmd=${full_cmd##*/} - -if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] -then - exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" -elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] -then - if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] - then - echo "BaseTools C Tool binary was not found ($cmd)" - echo "You may need to run:" - echo " make -C $EDK_TOOLS_PATH/Source/C" - else - exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@" - fi -elif [ -e "$dir/../../Source/C/bin/$cmd" ] -then - exec "$dir/../../Source/C/bin/$cmd" "$@" -else - echo "Unable to find the real '$cmd' to run" - echo "This message was printed by" - echo " $0" - exit 127 -fi - diff --git a/BaseTools/BinPipWrappers/PosixLike/Ecc b/BaseTools/BinPipWrappers/PosixLike/Ecc deleted file mode 100755 index 598728915095..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/Ecc +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -cmd=${full_cmd##*/} - -export PYTHONPATH="$dir/../../Source/Python${PYTHONPATH:+:"$PYTHONPATH"}" -exec "${python_exe:-python}" -m $cmd.EccMain "$@" diff --git a/BaseTools/BinPipWrappers/PosixLike/EfiRom b/BaseTools/BinPipWrappers/PosixLike/EfiRom deleted file mode 100755 index 0945d86d9209..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/EfiRom +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -cmd=${full_cmd##*/} - -if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] -then - exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" -elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] -then - if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] - then - echo "BaseTools C Tool binary was not found ($cmd)" - echo "You may need to run:" - echo " make -C $EDK_TOOLS_PATH/Source/C" - else - exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@" - fi -elif [ -e "$dir/../../Source/C/bin/$cmd" ] -then - exec "$dir/../../Source/C/bin/$cmd" "$@" -else - echo "Unable to find the real '$cmd' to run" - echo "This message was printed by" - echo " $0" - exit 127 -fi - diff --git a/BaseTools/BinPipWrappers/PosixLike/GenCrc32 b/BaseTools/BinPipWrappers/PosixLike/GenCrc32 deleted file mode 100755 index 0945d86d9209..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/GenCrc32 +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -cmd=${full_cmd##*/} - -if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] -then - exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" -elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] -then - if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] - then - echo "BaseTools C Tool binary was not found ($cmd)" - echo "You may need to run:" - echo " make -C $EDK_TOOLS_PATH/Source/C" - else - exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@" - fi -elif [ -e "$dir/../../Source/C/bin/$cmd" ] -then - exec "$dir/../../Source/C/bin/$cmd" "$@" -else - echo "Unable to find the real '$cmd' to run" - echo "This message was printed by" - echo " $0" - exit 127 -fi - diff --git a/BaseTools/BinPipWrappers/PosixLike/GenDepex b/BaseTools/BinPipWrappers/PosixLike/GenDepex deleted file mode 100755 index df75e43f9ec1..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/GenDepex +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -cmd=${full_cmd##*/} - -exec "${python_exe:-python}" -m edk2basetools.AutoGen.$cmd "$@" diff --git a/BaseTools/BinPipWrappers/PosixLike/GenFds b/BaseTools/BinPipWrappers/PosixLike/GenFds deleted file mode 100755 index b27e84eaa210..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/GenFds +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -cmd=${full_cmd##*/} - -exec "${python_exe:-python}" -m edk2basetools.$cmd "$@" diff --git a/BaseTools/BinPipWrappers/PosixLike/GenFfs b/BaseTools/BinPipWrappers/PosixLike/GenFfs deleted file mode 100755 index 0945d86d9209..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/GenFfs +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -cmd=${full_cmd##*/} - -if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] -then - exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" -elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] -then - if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] - then - echo "BaseTools C Tool binary was not found ($cmd)" - echo "You may need to run:" - echo " make -C $EDK_TOOLS_PATH/Source/C" - else - exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@" - fi -elif [ -e "$dir/../../Source/C/bin/$cmd" ] -then - exec "$dir/../../Source/C/bin/$cmd" "$@" -else - echo "Unable to find the real '$cmd' to run" - echo "This message was printed by" - echo " $0" - exit 127 -fi - diff --git a/BaseTools/BinPipWrappers/PosixLike/GenFv b/BaseTools/BinPipWrappers/PosixLike/GenFv deleted file mode 100755 index 0945d86d9209..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/GenFv +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -cmd=${full_cmd##*/} - -if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] -then - exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" -elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] -then - if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] - then - echo "BaseTools C Tool binary was not found ($cmd)" - echo "You may need to run:" - echo " make -C $EDK_TOOLS_PATH/Source/C" - else - exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@" - fi -elif [ -e "$dir/../../Source/C/bin/$cmd" ] -then - exec "$dir/../../Source/C/bin/$cmd" "$@" -else - echo "Unable to find the real '$cmd' to run" - echo "This message was printed by" - echo " $0" - exit 127 -fi - diff --git a/BaseTools/BinPipWrappers/PosixLike/GenFw b/BaseTools/BinPipWrappers/PosixLike/GenFw deleted file mode 100755 index 0945d86d9209..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/GenFw +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -cmd=${full_cmd##*/} - -if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] -then - exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" -elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] -then - if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] - then - echo "BaseTools C Tool binary was not found ($cmd)" - echo "You may need to run:" - echo " make -C $EDK_TOOLS_PATH/Source/C" - else - exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@" - fi -elif [ -e "$dir/../../Source/C/bin/$cmd" ] -then - exec "$dir/../../Source/C/bin/$cmd" "$@" -else - echo "Unable to find the real '$cmd' to run" - echo "This message was printed by" - echo " $0" - exit 127 -fi - diff --git a/BaseTools/BinPipWrappers/PosixLike/GenPatchPcdTable b/BaseTools/BinPipWrappers/PosixLike/GenPatchPcdTable deleted file mode 100755 index 9d143c7fc6c2..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/GenPatchPcdTable +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -cmd=${full_cmd##*/} - -exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@" diff --git a/BaseTools/BinPipWrappers/PosixLike/GenSec b/BaseTools/BinPipWrappers/PosixLike/GenSec deleted file mode 100755 index 0945d86d9209..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/GenSec +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -cmd=${full_cmd##*/} - -if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] -then - exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" -elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] -then - if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] - then - echo "BaseTools C Tool binary was not found ($cmd)" - echo "You may need to run:" - echo " make -C $EDK_TOOLS_PATH/Source/C" - else - exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@" - fi -elif [ -e "$dir/../../Source/C/bin/$cmd" ] -then - exec "$dir/../../Source/C/bin/$cmd" "$@" -else - echo "Unable to find the real '$cmd' to run" - echo "This message was printed by" - echo " $0" - exit 127 -fi - diff --git a/BaseTools/BinPipWrappers/PosixLike/GenerateCapsule b/BaseTools/BinPipWrappers/PosixLike/GenerateCapsule deleted file mode 100755 index 366a268802c4..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/GenerateCapsule +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -cmd=${full_cmd##*/} - -exec "${python_exe:-python}" -m edk2basetools.Capsule.$cmd "$@" diff --git a/BaseTools/BinPipWrappers/PosixLike/LzmaCompress b/BaseTools/BinPipWrappers/PosixLike/LzmaCompress deleted file mode 100755 index 0945d86d9209..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/LzmaCompress +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -cmd=${full_cmd##*/} - -if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] -then - exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" -elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] -then - if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] - then - echo "BaseTools C Tool binary was not found ($cmd)" - echo "You may need to run:" - echo " make -C $EDK_TOOLS_PATH/Source/C" - else - exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@" - fi -elif [ -e "$dir/../../Source/C/bin/$cmd" ] -then - exec "$dir/../../Source/C/bin/$cmd" "$@" -else - echo "Unable to find the real '$cmd' to run" - echo "This message was printed by" - echo " $0" - exit 127 -fi - diff --git a/BaseTools/BinPipWrappers/PosixLike/LzmaF86Compress b/BaseTools/BinPipWrappers/PosixLike/LzmaF86Compress deleted file mode 100755 index b55352ae4c79..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/LzmaF86Compress +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash -# -# This script will exec LzmaCompress tool with --f86 option that enables converter for x86 code. -# -# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
-# Copyright (c) 2012, Intel Corporation. All rights reserved.
-# SPDX-License-Identifier: BSD-2-Clause-Patent -# - -for arg; do - case $arg in - -e|-d) - set -- "$@" --f86 - break - ;; - esac -done - -exec LzmaCompress "$@" diff --git a/BaseTools/BinPipWrappers/PosixLike/PatchPcdValue b/BaseTools/BinPipWrappers/PosixLike/PatchPcdValue deleted file mode 100755 index 9d143c7fc6c2..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/PatchPcdValue +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -cmd=${full_cmd##*/} - -exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@" diff --git a/BaseTools/BinPipWrappers/PosixLike/Pkcs7Sign b/BaseTools/BinPipWrappers/PosixLike/Pkcs7Sign deleted file mode 100755 index 9d143c7fc6c2..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/Pkcs7Sign +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -cmd=${full_cmd##*/} - -exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@" diff --git a/BaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256GenerateKeys b/BaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256GenerateKeys deleted file mode 100755 index aca2f3a6fe2a..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256GenerateKeys +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -cmd=${full_cmd##*/} - -exec "${python_exe:-python}" -m edk2basetools.Rsa2048Sha256Sign.$cmd "$@" diff --git a/BaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256Sign b/BaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256Sign deleted file mode 100755 index ead26cb3694f..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256Sign +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -cmd=${full_cmd##*/} - -exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@" \ No newline at end of file diff --git a/BaseTools/BinPipWrappers/PosixLike/Split b/BaseTools/BinPipWrappers/PosixLike/Split deleted file mode 100755 index 0945d86d9209..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/Split +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -cmd=${full_cmd##*/} - -if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] -then - exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" -elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] -then - if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] - then - echo "BaseTools C Tool binary was not found ($cmd)" - echo "You may need to run:" - echo " make -C $EDK_TOOLS_PATH/Source/C" - else - exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@" - fi -elif [ -e "$dir/../../Source/C/bin/$cmd" ] -then - exec "$dir/../../Source/C/bin/$cmd" "$@" -else - echo "Unable to find the real '$cmd' to run" - echo "This message was printed by" - echo " $0" - exit 127 -fi - diff --git a/BaseTools/BinPipWrappers/PosixLike/TargetTool b/BaseTools/BinPipWrappers/PosixLike/TargetTool deleted file mode 100755 index 9d143c7fc6c2..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/TargetTool +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -cmd=${full_cmd##*/} - -exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@" diff --git a/BaseTools/BinPipWrappers/PosixLike/TianoCompress b/BaseTools/BinPipWrappers/PosixLike/TianoCompress deleted file mode 100755 index 0945d86d9209..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/TianoCompress +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -cmd=${full_cmd##*/} - -if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] -then - exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" -elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] -then - if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] - then - echo "BaseTools C Tool binary was not found ($cmd)" - echo "You may need to run:" - echo " make -C $EDK_TOOLS_PATH/Source/C" - else - exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@" - fi -elif [ -e "$dir/../../Source/C/bin/$cmd" ] -then - exec "$dir/../../Source/C/bin/$cmd" "$@" -else - echo "Unable to find the real '$cmd' to run" - echo "This message was printed by" - echo " $0" - exit 127 -fi - diff --git a/BaseTools/BinPipWrappers/PosixLike/Trim b/BaseTools/BinPipWrappers/PosixLike/Trim deleted file mode 100755 index 0bd14ee03872..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/Trim +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -cmd=$(basename "$full_cmd") - -exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@" - diff --git a/BaseTools/BinPipWrappers/PosixLike/UPT b/BaseTools/BinPipWrappers/PosixLike/UPT deleted file mode 100755 index ead26cb3694f..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/UPT +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -cmd=${full_cmd##*/} - -exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@" \ No newline at end of file diff --git a/BaseTools/BinPipWrappers/PosixLike/VfrCompile b/BaseTools/BinPipWrappers/PosixLike/VfrCompile deleted file mode 100755 index 0945d86d9209..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/VfrCompile +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -cmd=${full_cmd##*/} - -if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] -then - exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" -elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] -then - if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] - then - echo "BaseTools C Tool binary was not found ($cmd)" - echo "You may need to run:" - echo " make -C $EDK_TOOLS_PATH/Source/C" - else - exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@" - fi -elif [ -e "$dir/../../Source/C/bin/$cmd" ] -then - exec "$dir/../../Source/C/bin/$cmd" "$@" -else - echo "Unable to find the real '$cmd' to run" - echo "This message was printed by" - echo " $0" - exit 127 -fi - diff --git a/BaseTools/BinPipWrappers/PosixLike/VolInfo b/BaseTools/BinPipWrappers/PosixLike/VolInfo deleted file mode 100755 index 0945d86d9209..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/VolInfo +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -cmd=${full_cmd##*/} - -if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] -then - exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" -elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] -then - if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] - then - echo "BaseTools C Tool binary was not found ($cmd)" - echo "You may need to run:" - echo " make -C $EDK_TOOLS_PATH/Source/C" - else - exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@" - fi -elif [ -e "$dir/../../Source/C/bin/$cmd" ] -then - exec "$dir/../../Source/C/bin/$cmd" "$@" -else - echo "Unable to find the real '$cmd' to run" - echo "This message was printed by" - echo " $0" - exit 127 -fi - diff --git a/BaseTools/BinPipWrappers/PosixLike/build b/BaseTools/BinPipWrappers/PosixLike/build deleted file mode 100755 index 9d143c7fc6c2..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/build +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -#python `dirname $0`/RunToolFromSource.py `basename $0` $* - -# If a ${PYTHON_COMMAND} command is available, use it in preference to python -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then - python_exe=${PYTHON_COMMAND} -fi - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -cmd=${full_cmd##*/} - -exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@" diff --git a/BaseTools/BinPipWrappers/PosixLike/posix_path_env.yaml b/BaseTools/BinPipWrappers/PosixLike/posix_path_env.yaml deleted file mode 100644 index eb1db9eb2511..000000000000 --- a/BaseTools/BinPipWrappers/PosixLike/posix_path_env.yaml +++ /dev/null @@ -1,11 +0,0 @@ -## @file -# Set this folder on the path for all linux builds -# -# Copyright (c) Microsoft Corporation. -# SPDX-License-Identifier: BSD-2-Clause-Patent -## -{ - "scope": "pipbuild-unix", - "override_id": "binwrappers", - "flags": ["set_path"] -} diff --git a/BaseTools/BinPipWrappers/WindowsLike/AmlToC.bat b/BaseTools/BinPipWrappers/WindowsLike/AmlToC.bat deleted file mode 100644 index d347d6484467..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/AmlToC.bat +++ /dev/null @@ -1,3 +0,0 @@ -@setlocal -@set ToolName=%~n0% -@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/BPDG.bat b/BaseTools/BinPipWrappers/WindowsLike/BPDG.bat deleted file mode 100644 index d347d6484467..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/BPDG.bat +++ /dev/null @@ -1,3 +0,0 @@ -@setlocal -@set ToolName=%~n0% -@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/Ecc.bat b/BaseTools/BinPipWrappers/WindowsLike/Ecc.bat deleted file mode 100644 index 16a0a799a43b..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/Ecc.bat +++ /dev/null @@ -1,3 +0,0 @@ -@setlocal -@set ToolName=%~n0% -@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.EccMain %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/GenDepex.bat b/BaseTools/BinPipWrappers/WindowsLike/GenDepex.bat deleted file mode 100644 index 481b5ac47d24..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/GenDepex.bat +++ /dev/null @@ -1,3 +0,0 @@ -@setlocal -@set ToolName=%~n0% -@%PYTHON_COMMAND% -m edk2basetools.AutoGen.%ToolName% %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/GenFds.bat b/BaseTools/BinPipWrappers/WindowsLike/GenFds.bat deleted file mode 100644 index d347d6484467..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/GenFds.bat +++ /dev/null @@ -1,3 +0,0 @@ -@setlocal -@set ToolName=%~n0% -@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/GenPatchPcdTable.bat b/BaseTools/BinPipWrappers/WindowsLike/GenPatchPcdTable.bat deleted file mode 100644 index d347d6484467..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/GenPatchPcdTable.bat +++ /dev/null @@ -1,3 +0,0 @@ -@setlocal -@set ToolName=%~n0% -@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/GenerateCapsule.bat b/BaseTools/BinPipWrappers/WindowsLike/GenerateCapsule.bat deleted file mode 100644 index 34c43ac7fc99..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/GenerateCapsule.bat +++ /dev/null @@ -1 +0,0 @@ -@%PYTHON_COMMAND% -m edk2basetools.Capsule.GenerateCapsule %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/PatchPcdValue.bat b/BaseTools/BinPipWrappers/WindowsLike/PatchPcdValue.bat deleted file mode 100644 index d347d6484467..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/PatchPcdValue.bat +++ /dev/null @@ -1,3 +0,0 @@ -@setlocal -@set ToolName=%~n0% -@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/Pkcs7Sign.bat b/BaseTools/BinPipWrappers/WindowsLike/Pkcs7Sign.bat deleted file mode 100644 index d347d6484467..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/Pkcs7Sign.bat +++ /dev/null @@ -1,3 +0,0 @@ -@setlocal -@set ToolName=%~n0% -@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256GenerateKeys.bat b/BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256GenerateKeys.bat deleted file mode 100644 index cdc2e3ea373d..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256GenerateKeys.bat +++ /dev/null @@ -1 +0,0 @@ -@%PYTHON_COMMAND% -m edk2basetools.Rsa2048Sha256Sign.Rsa2048Sha256GenerateKeys %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256Sign.bat b/BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256Sign.bat deleted file mode 100644 index d347d6484467..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256Sign.bat +++ /dev/null @@ -1,3 +0,0 @@ -@setlocal -@set ToolName=%~n0% -@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/Split.bat b/BaseTools/BinPipWrappers/WindowsLike/Split.bat deleted file mode 100644 index d347d6484467..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/Split.bat +++ /dev/null @@ -1,3 +0,0 @@ -@setlocal -@set ToolName=%~n0% -@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/TargetTool.bat b/BaseTools/BinPipWrappers/WindowsLike/TargetTool.bat deleted file mode 100644 index d347d6484467..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/TargetTool.bat +++ /dev/null @@ -1,3 +0,0 @@ -@setlocal -@set ToolName=%~n0% -@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/Trim.bat b/BaseTools/BinPipWrappers/WindowsLike/Trim.bat deleted file mode 100644 index d347d6484467..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/Trim.bat +++ /dev/null @@ -1,3 +0,0 @@ -@setlocal -@set ToolName=%~n0% -@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/UPT.bat b/BaseTools/BinPipWrappers/WindowsLike/UPT.bat deleted file mode 100644 index d347d6484467..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/UPT.bat +++ /dev/null @@ -1,3 +0,0 @@ -@setlocal -@set ToolName=%~n0% -@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/build.bat b/BaseTools/BinPipWrappers/WindowsLike/build.bat deleted file mode 100644 index d347d6484467..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/build.bat +++ /dev/null @@ -1,3 +0,0 @@ -@setlocal -@set ToolName=%~n0% -@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %* diff --git a/BaseTools/BinPipWrappers/WindowsLike/win_build_tools_path_env.yaml b/BaseTools/BinPipWrappers/WindowsLike/win_build_tools_path_env.yaml deleted file mode 100644 index 9fdbe1bcb06b..000000000000 --- a/BaseTools/BinPipWrappers/WindowsLike/win_build_tools_path_env.yaml +++ /dev/null @@ -1,11 +0,0 @@ -## @file -# Add this folder to the path on Windows -# -# Copyright (c) Microsoft Corporation. -# SPDX-License-Identifier: BSD-2-Clause-Patent -## -{ - "scope": "pipbuild-win", - "override_id": "binwrappers", - "flags": ["set_path"] -} diff --git a/BaseTools/BuildEnv b/BaseTools/BuildEnv index bd6235d74fa7..1d9526bdfc11 100755 --- a/BaseTools/BuildEnv +++ b/BaseTools/BuildEnv @@ -198,16 +198,7 @@ AddEdkToolsToPath() { EDK_TOOLS_PATH_BIN=`GetEdkToolsPathBinDirectory` - # check if the edk2basetools pip package is available - if $PYTHON_COMMAND -c "import edk2basetools" > /dev/null 2>&1; then - # if it is, use the pip version of the wrappers - echo "Using Pip Basetools" - AddDirToStartOfPath $EDK_TOOLS_PATH/BinPipWrappers/PosixLike - else - echo "Using EDK2 in-source Basetools" - AddDirToStartOfPath $EDK_TOOLS_PATH/BinWrappers/PosixLike - fi - + AddDirToStartOfPath $EDK_TOOLS_PATH/BinWrappers/PosixLike AddDirToStartOfPath $EDK_TOOLS_PATH_BIN diff --git a/BaseTools/Scripts/PatchCheck.py b/BaseTools/Scripts/PatchCheck.py index d797ac80c15f..83d679518845 100755 --- a/BaseTools/Scripts/PatchCheck.py +++ b/BaseTools/Scripts/PatchCheck.py @@ -395,7 +395,6 @@ def run(self): self.force_notabs = False if self.filename.endswith('.sh') or \ self.filename.startswith('BaseTools/BinWrappers/PosixLike/') or \ - self.filename.startswith('BaseTools/BinPipWrappers/PosixLike/') or \ self.filename == 'BaseTools/BuildEnv': # # Do not enforce CR/LF line endings for linux shell scripts. diff --git a/BaseTools/Source/Python/README.md b/BaseTools/Source/Python/README.md deleted file mode 100644 index 8c4d9e73bbe2..000000000000 --- a/BaseTools/Source/Python/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# Edk2 Basetools - -This folder has traditionally held the source of Python based tools used by EDK2. -The official repo this source has moved to https://github.com/tianocore/edk2-basetools. -This folder will remain in the tree until the next stable release (expected 202102). -There is a new folder under Basetools `BinPipWrappers` that uses the pip module rather than this tree for Basetools. -By adding the scope `pipbuild-win` or `pipbuild-unix` (depending on your host system), the SDE will use the -`BinPipWrappers` instead of the regular `BinWrappers`. - -## Why Move It? - -The discussion is on the mailing list. The RFC is here: https://edk2.groups.io/g/rfc/topic/74009714#270 -The benefits allow for the Basetools project to be used separately from EDK2 itself as well as offering it in a -globally accessible manner. -This makes it much easier to build a module using Basetools. -Separating the Basetools into their own repo allows for easier CI and contribution process. -Additional pros, cons, and process can be found on the mailing list. - -## How Do I Install It? - -By default, EDK2 is tied to and tested with a specific version of the Basetools through `pip-requirements.txt`. -You can simply run: - -```bash -pip install -r pip-requirements.txt -``` - -This will install the required module, thought we strongly suggest setting up a virtual environment. -Additionally, you can also install a local clone of the Basetools as well as a specific git commit. diff --git a/BaseTools/toolsetup.bat b/BaseTools/toolsetup.bat index 5b1070f1e45b..bdbc052c2168 100755 --- a/BaseTools/toolsetup.bat +++ b/BaseTools/toolsetup.bat @@ -350,28 +350,12 @@ if %ERRORLEVEL% NEQ 0 ( endlocal -%PYTHON_COMMAND% -c "import edk2basetools" >NUL 2>NUL -if %ERRORLEVEL% EQU 0 ( - goto use_pip_basetools -) else ( - REM reset ERRORLEVEL - type nul>nul - goto use_builtin_basetools -) - -:use_builtin_basetools @echo Using EDK2 in-source Basetools if defined BASETOOLS_PYTHON_SOURCE goto print_python_info set "PATH=%BASE_TOOLS_PATH%\BinWrappers\WindowsLike;%PATH%" set PYTHONPATH=%BASE_TOOLS_PATH%\Source\Python;%PYTHONPATH% goto print_python_info -:use_pip_basetools - @echo Using Pip Basetools - set "PATH=%BASE_TOOLS_PATH%\BinPipWrappers\WindowsLike;%PATH%" - set PYTHONPATH=%BASE_TOOLS_PATH%\Source\Python;%PYTHONPATH% - goto print_python_info - :print_python_info echo PATH = %PATH% echo. diff --git a/pip-requirements.txt b/pip-requirements.txt index f9fb9e130bad..c8de90fc2bd1 100644 --- a/pip-requirements.txt +++ b/pip-requirements.txt @@ -14,7 +14,6 @@ edk2-pytool-library~=0.21.9 edk2-pytool-extensions~=0.27.10 -edk2-basetools==0.1.53 antlr4-python3-runtime>=4.7.1 lcov-cobertura==2.0.2 regex==2024.7.24 From b1ce2e1b67ff3b2478739976e952ac719010f019 Mon Sep 17 00:00:00 2001 From: Vishal Oliyil Kunnil Date: Mon, 9 Sep 2024 17:21:14 -0700 Subject: [PATCH 215/280] ArmPkg/ArmPsciMpServices: GetProcessorInfo copies incorrect structure GetProcessorInfo copies CpuData instead of CpuData.Info. The OUT parameter ProcessorInfoBuffer is of type EFI_PROCESSOR_INFORMATION, not CPU_AP_DATA. Fix it to copy the correct member CpuData.Info. Signed-off-by: Vishal Oliyil Kunnil --- ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.c b/ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.c index e7f422351347..6d075df5c1f0 100644 --- a/ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.c +++ b/ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.c @@ -340,7 +340,7 @@ GetProcessorInfo ( CopyMem ( ProcessorInfoBuffer, - &mCpuMpData.CpuData[ProcessorIndex], + &mCpuMpData.CpuData[ProcessorIndex].Info, sizeof (EFI_PROCESSOR_INFORMATION) ); return EFI_SUCCESS; From 1328938560be440f25c122bcf6635af210291a4e Mon Sep 17 00:00:00 2001 From: Mike Beaton Date: Mon, 9 Sep 2024 16:55:23 +0100 Subject: [PATCH 216/280] MdeModulePkg/VariableRuntimeDxe: Fix VariablePolicyProtocol PRODUCES If we search the codebase for &gEdkiiVariablePolicyProtocolGuid we can find two drivers which install this policy: VariableRuntimeDxe (installed in VariableDxe.c) and VariableSmmRuntimeDxe (installed in VariablePolicySmmDxe.c). The .inf file for VariableRuntimeDxe incorrectly lists the protocol as CONSUMES in the comment, so change this to PRODUCES. Signed-off-by: Mike Beaton --- .../Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf index f90ec70b77cb..b5e8bf606771 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf @@ -84,7 +84,7 @@ gEfiVariableWriteArchProtocolGuid ## PRODUCES gEfiVariableArchProtocolGuid ## PRODUCES gEdkiiVariableLockProtocolGuid ## PRODUCES - gEdkiiVariablePolicyProtocolGuid ## CONSUMES + gEdkiiVariablePolicyProtocolGuid ## PRODUCES gEdkiiVarCheckProtocolGuid ## PRODUCES [Guids] From 9a4088777fbe7941664ad9bb2bd78446d223cbf9 Mon Sep 17 00:00:00 2001 From: Abdul Lateef Attar Date: Sat, 31 Aug 2024 09:19:30 +0000 Subject: [PATCH 217/280] .pytool/EccCheck: Trim leading path to modified directory The code changes in the patch is for trimming the leading path to the modified directory in the .pytool/EccCheck script. This is necessary when running Ecc on other repositories, such as edk2-platforms, where the platform package is located in a subfolder, like Platform/AMD/AmdPlatformPkg. The EccCheck script checks for modified directories and expects them to start with the package name. # # Skip directory names that do not start with the package being scanned. # if file_dir.split('/')[0] != pkg: continue However, if the package name is in a subfolder, the "git diff" command gives a relative path, like Platform/AMD, which causes the condition to be false. "M Platform/AMD/AmdPlatformPkg/Universal/LogoDxe/Logo.c" As a result, EccCheck does not happen on modified files. To fix this issue, the leading path needs to be trimmed so that it starts from the directory name. This change will not affect the existing check for the edk2 repository, where all package names are at the first level directory. Cc: Sean Brogan Cc: Joey Vagedes Cc: Michael D Kinney Cc: Liming Gao Signed-off-by: Abdul Lateef Attar --- .pytool/Plugin/EccCheck/EccCheck.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.pytool/Plugin/EccCheck/EccCheck.py b/.pytool/Plugin/EccCheck/EccCheck.py index 7235fcb55cea..0002143f1aa6 100644 --- a/.pytool/Plugin/EccCheck/EccCheck.py +++ b/.pytool/Plugin/EccCheck/EccCheck.py @@ -182,6 +182,11 @@ def GetModifyDir(self, pkg: str, temp_diff_output: str) -> List[str]: # file_dir = os.path.dirname(file_path[-1]) # + # strip the prefix path till the package name + # + if pkg in file_dir: + file_dir = file_dir[file_dir.find(pkg):] + # # Skip directory names that do not start with the package being scanned. # if file_dir.split('/')[0] != pkg: From 14c9ba1a2ca64137de148968823dc20988dcaa4c Mon Sep 17 00:00:00 2001 From: Zhiguang Liu Date: Tue, 18 Jun 2024 16:13:12 +0800 Subject: [PATCH 218/280] IntelFsp2Pkg: Support FSP API to save and restore page table A potential issue may happen when FSP creates/changes page table while bootloader doesn't expect page table being changed in FSP. Current, FSP API support to save/restore stack, IDT and general purpose registers. Following the same pattern, add save/restore page table support to solve this issue. Note that this feature only impacts FSP API mode, and is controlled by PCD PcdFspSaveRestorePageTableEnable. For compatibility, the PCD default value is set as FALSE. Signed-off-by: Zhiguang Liu --- IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf | 1 + IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf | 1 + .../FspSecCore/Ia32/Fsp24ApiEntryM.nasm | 30 +++- .../FspSecCore/Ia32/FspApiEntryM.nasm | 30 +++- .../FspSecCore/X64/Fsp24ApiEntryM.nasm | 33 ++++- IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm | 33 ++++- IntelFsp2Pkg/IntelFsp2Pkg.dec | 8 ++ .../Library/BaseFspCommonLib/FspCommonLib.c | 31 ++-- .../BaseFspSwitchStackLib.inf | 4 +- .../BaseFspSwitchStackLib/Ia32/Stack.nasm | 132 ++++++++++++++++++ .../BaseFspSwitchStackLib/X64/Stack.nasm | 109 ++++++++++++++- 11 files changed, 382 insertions(+), 30 deletions(-) diff --git a/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf b/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf index 762d485bab04..40ff9f22f7c4 100644 --- a/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf +++ b/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf @@ -69,6 +69,7 @@ gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage ## CONSUMES gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxInterruptSupported ## CONSUMES gIntelFsp2PkgTokenSpaceGuid.PcdFspPrivateTemporaryRamSize ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdFspSaveRestorePageTableEnable ## CONSUMES [Ppis] gEfiTemporaryRamSupportPpiGuid ## PRODUCES diff --git a/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf b/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf index 3acf4f6f9dc4..ac572a61687f 100644 --- a/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf +++ b/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf @@ -68,6 +68,7 @@ gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage ## CONSUMES gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxInterruptSupported ## CONSUMES gIntelFsp2PkgTokenSpaceGuid.PcdFspPrivateTemporaryRamSize ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdFspSaveRestorePageTableEnable ## CONSUMES [Ppis] gEfiTemporaryRamSupportPpiGuid ## PRODUCES diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm index 5fa5c035692a..e9bf0cbed205 100644 --- a/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm +++ b/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm @@ -13,6 +13,7 @@ extern ASM_PFX(PcdGet32(PcdTemporaryRamBase)) extern ASM_PFX(PcdGet32(PcdFspTemporaryRamSize)) extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage)) +extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable)) struc FSPM_UPD_COMMON ; FSP_UPD_HEADER { @@ -64,7 +65,7 @@ extern ASM_PFX(AsmGetFspInfoHeader) extern ASM_PFX(FspMultiPhaseMemInitApiHandler) STACK_SAVED_EAX_OFFSET EQU 4 * 7 ; size of a general purpose register * eax index -API_PARAM1_OFFSET EQU 34h ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call] +API_PARAM1_OFFSET EQU 44h ; ApiParam1 [ sub esp,8 + push cr0/cr3/cr4/EFER + pushad + pushfd + push eax + call] FSP_HEADER_IMGBASE_OFFSET EQU 1Ch FSP_HEADER_CFGREG_OFFSET EQU 24h @@ -153,6 +154,33 @@ NotMultiPhaseMemoryInitApi: cli pushad + ; + ; Allocate 4x4 bytes on the stack. + ; + sub esp, 16 + cmp byte [dword ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))], 0 + jz SkipPagetableSave + + add esp, 16 + ; Save EFER MSR lower 32 bits + push ecx + push eax + mov ecx, 0xC0000080 + rdmsr + mov edx, eax + pop eax + pop ecx + push edx + + ; Save CR registers + mov edx, cr4 + push edx + mov edx, cr3 + push edx + mov edx, cr0 + push edx +SkipPagetableSave: + ; Reserve 8 bytes for IDT save/restore sub esp, 8 sidt [esp] diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm index 861cce4d01a1..b1623063ef1b 100644 --- a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm +++ b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm @@ -13,6 +13,7 @@ extern ASM_PFX(PcdGet32(PcdTemporaryRamBase)) extern ASM_PFX(PcdGet32(PcdFspTemporaryRamSize)) extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage)) +extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable)) struc FSPM_UPD_COMMON ; FSP_UPD_HEADER { @@ -62,7 +63,7 @@ extern ASM_PFX(FspApiCommon) extern ASM_PFX(AsmGetFspBaseAddress) extern ASM_PFX(AsmGetFspInfoHeader) -API_PARAM1_OFFSET EQU 34h ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call] +API_PARAM1_OFFSET EQU 44h ; ApiParam1 [ sub esp,8 + push cr0/cr3/cr4/EFER +pushad + pushfd + push eax + call] FSP_HEADER_IMGBASE_OFFSET EQU 1Ch FSP_HEADER_CFGREG_OFFSET EQU 24h @@ -124,6 +125,33 @@ ASM_PFX(FspApiCommonContinue): cli pushad + ; + ; Allocate 4x4 bytes on the stack. + ; + sub esp, 16 + cmp byte [dword ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))], 0 + jz SkipPagetableSave + + add esp, 16 + ; Save EFER MSR lower 32-bit + push ecx + push eax + mov ecx, 0xC0000080 + rdmsr + mov edx, eax + pop eax + pop ecx + push edx + + ; Save CR registers + mov edx, cr4 + push edx + mov edx, cr3 + push edx + mov edx, cr0 + push edx + +SkipPagetableSave: ; Reserve 8 bytes for IDT save/restore sub esp, 8 sidt [esp] diff --git a/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm index a3b38e458597..3066156bcf97 100644 --- a/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm +++ b/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm @@ -4,7 +4,7 @@ ; Copyright (c) 2022, Intel Corporation. All rights reserved.
; SPDX-License-Identifier: BSD-2-Clause-Patent ;; - + DEFAULT REL SECTION .text %include "PushPopRegsNasm.inc" @@ -13,6 +13,7 @@ ; Following are fixed PCDs ; extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage)) +extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable)) struc FSPM_UPD_COMMON_FSP24 ; FSP_UPD_HEADER { @@ -142,6 +143,36 @@ NotMultiPhaseMemoryInitApi: cli PUSHA_64 + ; + ; Allocate 4x8 bytes on the stack. + ; + sub rsp, 32 + lea rdx, [ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))] + mov dl, byte [rdx] + cmp dl, 0 + jz SkipPagetableSave + + add rsp, 32 + ; Save EFER MSR + push rcx + push rax + mov rcx, 0xC0000080 + rdmsr + shl rdx, 0x20 + or rdx, rax + pop rax + pop rcx + push rdx + + ; Save CR registers + mov rdx, cr4 + push rdx + mov rdx, cr3 + push rdx + mov rdx, cr0 + push rdx +SkipPagetableSave: + ; Reserve 16 bytes for IDT save/restore sub rsp, 16 sidt [rsp] diff --git a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm index 2d2f75b1f049..b0b6b6a4aad4 100644 --- a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm +++ b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm @@ -4,7 +4,7 @@ ; Copyright (c) 2022, Intel Corporation. All rights reserved.
; SPDX-License-Identifier: BSD-2-Clause-Patent ;; - + DEFAULT REL SECTION .text %include "PushPopRegsNasm.inc" @@ -13,6 +13,7 @@ ; Following are fixed PCDs ; extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage)) +extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable)) struc FSPM_UPD_COMMON_FSP24 ; FSP_UPD_HEADER { @@ -110,6 +111,36 @@ ASM_PFX(FspApiCommonContinue): cli PUSHA_64 + ; + ; Allocate 4x8 bytes on the stack. + ; + sub rsp, 32 + lea rdx, [ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))] + mov dl, byte [rdx] + cmp dl, 0 + jz SkipPagetableSave + + add rsp, 32 + ; Save EFER MSR + push rcx + push rax + mov rcx, 0xC0000080 + rdmsr + shl rdx, 0x20 + or rdx, rax + pop rax + pop rcx + push rdx + + ; Save CR registers + mov rdx, cr4 + push rdx + mov rdx, cr3 + push rdx + mov rdx, cr0 + push rdx +SkipPagetableSave: + ; Reserve 16 bytes for IDT save/restore sub rsp, 16 sidt [rsp] diff --git a/IntelFsp2Pkg/IntelFsp2Pkg.dec b/IntelFsp2Pkg/IntelFsp2Pkg.dec index d1c3d3ee7b90..8fe6b64f9971 100644 --- a/IntelFsp2Pkg/IntelFsp2Pkg.dec +++ b/IntelFsp2Pkg/IntelFsp2Pkg.dec @@ -114,6 +114,14 @@ # gIntelFsp2PkgTokenSpaceGuid.PcdFspPrivateTemporaryRamSize |0x00000000|UINT32|0x10000006 +[PcdsFeatureFlag] + # + # Indicates if the FSP will save and restore page table. Only works in FSP API mode + # TRUE - FSP will save and restore page table + # FALSE - FSP will not save and restore page table + # + gIntelFsp2PkgTokenSpaceGuid.PcdFspSaveRestorePageTableEnable |FALSE|BOOLEAN|0x10000007 + [PcdsFixedAtBuild,PcdsDynamic,PcdsDynamicEx] gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedMemoryLength |0x00100000|UINT32|0x46530000 gIntelFsp2PkgTokenSpaceGuid.PcdBootLoaderEntry |0xFFFFFFE4|UINT32|0x46530100 diff --git a/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c index 54dbf546c360..3ecc5bd265b2 100644 --- a/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c +++ b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c @@ -15,21 +15,14 @@ #pragma pack(1) -// -// API Parameter +0x34 -// API return address +0x30 -// -// push FspInfoHeader +0x2C -// pushfd +0x28 -// cli -// pushad +0x24 -// sub esp, 8 +0x00 -// sidt fword ptr [esp] -// typedef struct { UINT16 IdtrLimit; UINT32 IdtrBase; UINT16 Reserved; + UINT32 Cr0; + UINT32 Cr3; + UINT32 Cr4; + UINT32 Efer; // lower 32-bit of EFER since only NXE bit (BIT11) need to be restored. UINT32 Registers[8]; // General Purpose Registers: Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx and Eax UINT16 Flags[2]; UINT32 FspInfoHeader; @@ -37,20 +30,12 @@ typedef struct { UINT32 ApiParam[2]; } CONTEXT_STACK; -// -// API return address +0xB8 -// Reserved +0xB0 -// push API Parameter2 +0xA8 -// push API Parameter1 +0xA0 -// push FspInfoHeader +0x98 -// pushfq +0x90 -// cli -// PUSHA_64 +0x10 -// sub rsp, 16 +0x00 -// sidt [rsp] -// typedef struct { UINT64 Idtr[2]; // IDTR Limit - bit0:bi15, IDTR Base - bit16:bit79 + UINT64 Cr0; + UINT64 Cr3; + UINT64 Cr4; + UINT64 Efer; UINT64 Registers[16]; // General Purpose Registers: RDI, RSI, RBP, RSP, RBX, RDX, RCX, RAX, and R15 to R8 UINT32 Flags[2]; UINT64 FspInfoHeader; diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf index 6909aec651b0..0194c2e9554b 100644 --- a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf +++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf @@ -32,5 +32,5 @@ BaseLib IoLib - - +[Pcd] + gIntelFsp2PkgTokenSpaceGuid.PcdFspSaveRestorePageTableEnable diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm index 6599901906bf..d13842451ca8 100644 --- a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm +++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm @@ -12,6 +12,12 @@ SECTION .text extern ASM_PFX(SwapStack) +extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable)) + +; Page table related bits in CR0/CR4/EFER +%define CR0_PG_MASK 0x80010000 ; CR0.PG and CR0.WP +%define CR4_PG_MASK 0x10B0 ; CR4.PSE, CR4.PAE, CR4.PGE and CR4.LA57 +%define EFER_PG_MASK 0x800 ; EFER.NXE ;------------------------------------------------------------------------------ ; UINT32 @@ -50,6 +56,34 @@ ASM_PFX(FspSwitchStack): pushfd cli pushad + + ; + ; Allocate 4x4 bytes on the stack. + ; + sub esp, 16 + cmp byte [dword ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))], 0 + jz SkipPagetableSave + + add esp, 16 + ; Save EFER MSR lower 32 bits + push ecx + push eax + mov ecx, 0xC0000080 + rdmsr + mov edx, eax + pop eax + pop ecx + push edx + + ; Save CR registers + mov eax, cr4 + push eax + mov eax, cr3 + push eax + mov eax, cr0 + push eax +SkipPagetableSave: + sub esp, 8 sidt [esp] @@ -61,6 +95,104 @@ ASM_PFX(FspSwitchStack): ; Restore previous contexts lidt [esp] add esp, 8 + + cmp byte [dword ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))], 0 + jz SkipPagetableRestore + ; [esp] stores new cr0 + ; [esp+4] stores new cr3 + ; [esp+8] stores new cr4 + ; [esp+12] stores new Efer + ; + ; When new EFER.NXE == 1, the restore flow is: EFER --> CRx + ; Otherwise: CRx --> EFER + ; When new CR0.PG == 1, the restore flow for CRx is: CR3 --> CR4 --> CR0 + ; Otherwise, the restore flow is: CR0 --> CR3 --> CR4 + ; + ; If NXE bit is changed to 1, change NXE before CR register + ; This is because Nx bit in page table entry in new CR3 will be invalid + ; if updating CR3 before EFER MSR. + ; + mov eax, [esp+12] + bt eax, 11 + jnc SkipEferLabel1 + + ; Restore EFER MSR + mov ecx, 0xC0000080 + rdmsr + and eax, ~EFER_PG_MASK + mov ebx, [esp+12] + and ebx, EFER_PG_MASK + or eax, ebx + wrmsr + +SkipEferLabel1: + + ; + ; if new cr0 is to disable page table, change CR0 before CR3/CR4 + ; + mov eax, [esp] + bt eax, 31 + jc SkipCr0Label1 + + ; Restore CR0 + mov edx, cr0 + and edx, ~CR0_PG_MASK + mov eax, [esp] + and eax, CR0_PG_MASK + or edx, eax + mov cr0, edx + +SkipCr0Label1: + + ; Restore CR3/CR4 + mov eax, [esp+4] + mov cr3, eax + + mov edx, cr4 + and edx, ~CR4_PG_MASK + mov eax, [esp+8] + and eax, CR4_PG_MASK + or edx, eax + mov cr4, edx + + ; + ; if new cr0 is to enable page table, change CR0 after CR3/CR4 + ; + mov eax, [esp] + bt eax, 31 + jnc SkipCr0Label2 + + ; Restore CR0 + mov edx, cr0 + and edx, ~CR0_PG_MASK + mov eax, [esp] + and eax, CR0_PG_MASK + or edx, eax + mov cr0, edx + +SkipCr0Label2: + ; + ; If NXE bit is changed to 0, change NXE after than CR regiser + ; + mov eax, [esp+12] + bt eax, 11 + jc SkipEferLabel2 + + ; Restore EFER MSR + mov ecx, 0xC0000080 + rdmsr + and eax, ~EFER_PG_MASK + mov ebx, [esp+12] + and ebx, EFER_PG_MASK + or eax, ebx + wrmsr + +SkipEferLabel2: +SkipPagetableRestore: + + ; pop page table related registers. + add esp, 16 + popad popfd add esp, 4 diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm index e3a7cf002fe6..f40df51ab4ad 100644 --- a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm +++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm @@ -8,12 +8,18 @@ ; Switch the stack from temporary memory to permanent memory. ; ;------------------------------------------------------------------------------ - + DEFAULT REL SECTION .text %include "PushPopRegsNasm.inc" +; Page table related bits in CR0/CR4/EFER +%define CR0_PG_MASK 0x80010000 ; CR0.PG and CR0.WP +%define CR4_PG_MASK 0x10B0 ; CR4.PSE, CR4.PAE, CR4.PGE and CR4.LA57 +%define EFER_PG_MASK 0x800 ; EFER.NXE + extern ASM_PFX(SwapStack) +extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable)) ;------------------------------------------------------------------------------ ; UINT32 @@ -55,6 +61,37 @@ ASM_PFX(FspSwitchStack): pushfq cli PUSHA_64 + + ; + ; Allocate 4x8 bytes on the stack. + ; + sub rsp, 32 + lea rdx, [ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))] + mov dl, byte [rdx] + cmp dl, 0 + jz SkipPagetableSave + + add rsp, 32 + ; Save EFER MSR + push rcx + push rax + mov rcx, 0xC0000080 + rdmsr + shl rdx, 0x20 + or rdx, rax + pop rax + pop rcx + push rdx + + ; Save CR registers + mov rdx, cr4 + push rdx + mov rdx, cr3 + push rdx + mov rdx, cr0 + push rdx +SkipPagetableSave: + sub rsp, 16 sidt [rsp] @@ -68,6 +105,76 @@ ASM_PFX(FspSwitchStack): ; Restore previous contexts lidt [rsp] add rsp, 16 + + lea rax, [ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))] + mov al, byte [rax] + cmp al, 0 + jz SkipPagetableRestore + ; [rsp] stores new cr0 + ; [rsp+8] stores new cr3 + ; [rsp+16] stores new cr4 + ; [rsp+24] stores new Efer + ; + ; When new EFER.NXE == 1, the restore flow is: EFER --> CRx + ; Otherwise: CRx --> EFER + ; + ; If NXE bit is changed to 1, change NXE before CR register + ; This is because Nx bit in page table entry in new CR3 will be invalid + ; if updating CR3 before EFER MSR. + ; + mov rax, [rsp + 24] + bt rax, 11 + jnc SkipEferLabel1 + + ; Restore EFER MSR + mov ecx, 0xC0000080 + rdmsr + and eax, ~EFER_PG_MASK + mov ebx, [rsp + 24] + and ebx, EFER_PG_MASK + or eax, ebx + wrmsr + +SkipEferLabel1: + + mov rbx, [rsp] + mov rdx, cr0 + and rdx, ~CR0_PG_MASK + and rbx, CR0_PG_MASK + or rdx, rbx + mov cr0, rdx + + mov rbx, [rsp + 8] + mov cr3, rbx + + mov rbx, [rsp + 16] + mov rdx, cr4 + and rdx, ~CR4_PG_MASK + and rbx, CR4_PG_MASK + or rdx, rbx + mov cr4, rdx + + ; + ; If NXE bit is changed to 0, change NXE after than CR regiser + ; + mov rax, [rsp + 24] + bt rax, 11 + jc SkipEferLabel2 + + ; Restore EFER MSR + mov ecx, 0xC0000080 + rdmsr + and eax, ~EFER_PG_MASK + mov ebx, [rsp + 24] + and ebx, EFER_PG_MASK + or eax, ebx + wrmsr + +SkipEferLabel2: +SkipPagetableRestore: + ; pop page table related registers. + add rsp, 32 + POPA_64 popfq add rsp, 32 ; FspInfoHeader + ApiParam[2] + Reserved QWORD From 58b4bf7b7e526cec295bfbc6caa4a5cf223a1c53 Mon Sep 17 00:00:00 2001 From: Hongbin1 Zhang Date: Thu, 29 Aug 2024 09:52:05 +0800 Subject: [PATCH 219/280] StandaloneMmPkg/MmIpl: Correct unblocked memory regions attribute When CPU smm profile feature was enabled, unblocked memory should not set logging attribute when building resource HOB. Signed-off-by: Hongbin1 Zhang Cc: Jiewen Yao Cc: Ray Ni Cc: Star Zeng Cc: Jiaxin Wu Cc: Wei6 Xu Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Supreeth Venkatesh --- .../StandaloneMmIplPei/MmFoundationHob.c | 114 +++++++++++++----- 1 file changed, 87 insertions(+), 27 deletions(-) diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c index b13d4f688f00..a0f8d1f14f7d 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c @@ -450,6 +450,44 @@ MmIplBuildResourceHobForUnblockedRegion ( *HobBufferSize = UsedSize; } +/** + Collect unblock memory regions. + + @param[in, out] MemoryRegion Pointer to unblock memory regions. + @param[in, out] MemoryRegionCount Count of unblock memory regions. +**/ +VOID +CollectUnblockMemoryRegions ( + IN OUT MM_IPL_MEMORY_REGION *MemoryRegion, + IN OUT UINTN *MemoryRegionCount + ) +{ + UINTN Index; + EFI_HOB_GENERIC_HEADER *GuidHob; + MM_UNBLOCK_REGION *UnblockRegion; + + ASSERT (MemoryRegionCount != NULL); + ASSERT (*MemoryRegionCount == 0 || MemoryRegion != NULL); + + Index = 0; + // + // Collect unblock memory ranges + // + GuidHob = GetFirstGuidHob (&gMmUnblockRegionHobGuid); + while (GuidHob != NULL) { + if (Index < *MemoryRegionCount) { + UnblockRegion = GET_GUID_HOB_DATA (GuidHob); + MemoryRegion[Index].Base = UnblockRegion->PhysicalStart; + MemoryRegion[Index].Length = EFI_PAGES_TO_SIZE (UnblockRegion->NumberOfPages); + } + + Index++; + GuidHob = GetNextGuidHob (&gMmUnblockRegionHobGuid, GET_NEXT_HOB (GuidHob)); + } + + *MemoryRegionCount = Index; +} + /** Create MMIO memory map according to platform HOB. @@ -564,16 +602,15 @@ MmIplCalculateMaximumSupportAddress ( /** Build resource HOB to cover [0, PhysicalAddressBits length] by excluding - all Mmram ranges, MM Profile data and MMIO ranges. - - @param[in] HobBuffer The pointer of new HOB buffer. - @param[in, out] HobBufferSize The available size of the HOB buffer when as input. - The used size of when as output. - @param[in] PlatformHobList Platform HOB list. - @param[in] PlatformHobSize Platform HOB size. - @param[in] Block Pointer of MMRAM descriptor block. - @param[in] MmProfileDataHob Pointer to MM profile data HOB. - + all Mmram ranges, MM Profile data, Unblock memory ranges and MMIO ranges. + + @param[in] HobBuffer The pointer of new HOB buffer. + @param[in, out] HobBufferSize The available size of the HOB buffer when as input. + The used size of when as output. + @param[in] PlatformHobList Platform HOB list. + @param[in] PlatformHobSize Platform HOB size. + @param[in] Block Pointer of MMRAM descriptor block. + @param[in] MmProfileDataHob Pointer to MM profile data HOB. **/ VOID MmIplBuildResourceHobForAllSystemMemory ( @@ -593,6 +630,7 @@ MmIplBuildResourceHobForAllSystemMemory ( UINT64 MaxAddress; MM_IPL_MEMORY_REGION *MemoryRegions; MM_IPL_MEMORY_REGION SortBuffer; + UINTN UnblockRegionCount; MaxAddress = LShiftU64 (1, MmIplCalculateMaximumSupportAddress ()); @@ -605,9 +643,16 @@ MmIplBuildResourceHobForAllSystemMemory ( } // - // Allocate buffer for platform memory regions, MM Profile data, MMRam ranges, an extra terminator. + // Get the count of platform memory regions + // + UnblockRegionCount = 0; + CollectUnblockMemoryRegions (NULL, &UnblockRegionCount); + + // + // Allocate buffer for platform memory regions, unblock memory regions, + // MM Profile data, MMRam ranges, an extra terminator. // - Count = PlatformRegionCount + Block->NumberOfMmReservedRegions + ((MmProfileDataHob != NULL) ? 1 : 0) + 1; + Count = PlatformRegionCount + UnblockRegionCount + Block->NumberOfMmReservedRegions + ((MmProfileDataHob != NULL) ? 1 : 0) + 1; MemoryRegions = AllocatePages (EFI_SIZE_TO_PAGES (Count * sizeof (*MemoryRegions))); ASSERT (MemoryRegions != NULL); if (MemoryRegions == NULL) { @@ -629,24 +674,31 @@ MmIplBuildResourceHobForAllSystemMemory ( CollectPlatformMemoryRegions (PlatformHobList, PlatformHobSize, MemoryRegions, &PlatformRegionCount); } + // + // Collect unblock memory regions + // + if (UnblockRegionCount != 0) { + CollectUnblockMemoryRegions (&MemoryRegions[PlatformRegionCount], &UnblockRegionCount); + } + // // Collect SMRAM regions // for (Index = 0; Index < Block->NumberOfMmReservedRegions; Index++) { - MemoryRegions[PlatformRegionCount + Index].Base = Block->Descriptor[Index].CpuStart; - MemoryRegions[PlatformRegionCount + Index].Length = Block->Descriptor[Index].PhysicalSize; + MemoryRegions[PlatformRegionCount + UnblockRegionCount + Index].Base = Block->Descriptor[Index].CpuStart; + MemoryRegions[PlatformRegionCount + UnblockRegionCount + Index].Length = Block->Descriptor[Index].PhysicalSize; } // // Collect MM profile database region // if (MmProfileDataHob != NULL) { - MemoryRegions[PlatformRegionCount + Block->NumberOfMmReservedRegions].Base = MmProfileDataHob->AllocDescriptor.MemoryBaseAddress; - MemoryRegions[PlatformRegionCount + Block->NumberOfMmReservedRegions].Length = MmProfileDataHob->AllocDescriptor.MemoryLength; + MemoryRegions[PlatformRegionCount + UnblockRegionCount + Block->NumberOfMmReservedRegions].Base = MmProfileDataHob->AllocDescriptor.MemoryBaseAddress; + MemoryRegions[PlatformRegionCount + UnblockRegionCount + Block->NumberOfMmReservedRegions].Length = MmProfileDataHob->AllocDescriptor.MemoryLength; } // - // Build system memory resource HOBs excluding platform memory regions, SMRAM regions, MmProfile database. + // Build system memory resource HOBs excluding platform memory regions, SMRAM regions, MmProfile database, Unblocked memory regions. // QuickSort (MemoryRegions, Count, sizeof (*MemoryRegions), MemoryRegionBaseAddressCompare, &SortBuffer); UsedSize = 0; @@ -843,24 +895,32 @@ CreateMmFoundationHobList ( UsedSize += HobLength; } + // + // Build resource HOB for unblocked region + // HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); - if (PcdGetBool (PcdCpuSmmRestrictedMemoryAccess)) { - // - // Only unblocked memory regions are accessible - // - MmIplBuildResourceHobForUnblockedRegion (FoundationHobList + UsedSize, &HobLength); - } else { + MmIplBuildResourceHobForUnblockedRegion (FoundationHobList + UsedSize, &HobLength); + UsedSize += HobLength; + + if (!PcdGetBool (PcdCpuSmmRestrictedMemoryAccess)) { // // All system memory (DRAM) is accessible. // When SMM Profile is enabled: - // * Access to regions reported from MmPlatformHobProducerLib do not require logging. + // * Access to regions included all Mmram ranges, MM Profile data, Unblock memory ranges and MMIO ranges do not require logging. // * Access to other system memory requires logging. // - MmIplBuildResourceHobForAllSystemMemory (FoundationHobList + UsedSize, &HobLength, PlatformHobList, PlatformHobSize, Block, MmProfileDataHob); + HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); + MmIplBuildResourceHobForAllSystemMemory ( + FoundationHobList + UsedSize, + &HobLength, + PlatformHobList, + PlatformHobSize, + Block, + MmProfileDataHob + ); + UsedSize += HobLength; } - UsedSize += HobLength; - if (*FoundationHobSize < UsedSize) { Status = RETURN_BUFFER_TOO_SMALL; } else { From 589304e67fbfcbb7c250d1a3031ef23c4fb8a41b Mon Sep 17 00:00:00 2001 From: yhsu3 Date: Sun, 8 Sep 2024 17:45:54 +0800 Subject: [PATCH 220/280] Support Report Status Code in the UefiPxe driver. Report PXE error status via Status Code, with this design, it will be flexible to register a status code handler via gEfiRscHandlerProtocolGuid to output the customized error code to other telemetry service. The subclass code is `EFI_IO_BUS_IP_NETWORK` Signed-off-by: Ethan Hsu --- NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c | 7 +++++++ NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c | 7 +++++++ NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h | 1 + NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf | 1 + 4 files changed, 16 insertions(+) diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c b/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c index f22a151e256d..0af791dc5f58 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c @@ -1268,5 +1268,12 @@ PxeBcLoadBootFile ( AsciiPrint ("\n PXE-E99: Unexpected network error.\n"); } + REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( + EFI_ERROR_CODE, + (EFI_STATUS_CODE_VALUE)(EFI_IO_BUS_IP_NETWORK | EFI_OEM_SPECIFIC | ((EFI_STATUS_CODE_VALUE)(Status & 0x1F))), + (VOID *)&(PxeBcMode->UsingIpv6), + sizeof (PxeBcMode->UsingIpv6) + ); + return Status; } diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c index 0a4baf6f90e8..e29647447184 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c @@ -72,6 +72,13 @@ EfiPxeBcStart ( return EFI_UNSUPPORTED; } + REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( + EFI_PROGRESS_CODE, + EFI_IO_BUS_IP_NETWORK | EFI_IOB_PC_RECONFIG, + (VOID *)&(Mode->UsingIpv6), + sizeof (Mode->UsingIpv6) + ); + if (Mode->UsingIpv6) { AsciiPrint ("\n>>Start PXE over IPv6"); // diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h index 732889f23d16..cdb9b3448094 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h @@ -48,6 +48,7 @@ #include #include #include +#include typedef struct _PXEBC_PRIVATE_DATA PXEBC_PRIVATE_DATA; typedef struct _PXEBC_PRIVATE_PROTOCOL PXEBC_PRIVATE_PROTOCOL; diff --git a/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf b/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf index 3371c150be13..d5aba1376ac0 100644 --- a/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf +++ b/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf @@ -62,6 +62,7 @@ DpcLib DevicePathLib PcdLib + ReportStatusCodeLib [Protocols] ## TO_START From f2557032d61e7a6bf1eb76eca5e836e7de991b8a Mon Sep 17 00:00:00 2001 From: Mike Beaton Date: Mon, 9 Sep 2024 12:53:23 +0100 Subject: [PATCH 221/280] NetworkPkg/MnpDxe: Convert TX buffer allocation messages to DEBUG_VERBOSE Under normal operation, some 30 or so of these lines logged as DEBUG_INFO on first transmit. This is not relevant information for users of the driver, so convert these messages to VERBOSE. Signed-off-by: Mike Beaton --- NetworkPkg/MnpDxe/MnpConfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NetworkPkg/MnpDxe/MnpConfig.c b/NetworkPkg/MnpDxe/MnpConfig.c index 93587d53aa75..d0e3f823d279 100644 --- a/NetworkPkg/MnpDxe/MnpConfig.c +++ b/NetworkPkg/MnpDxe/MnpConfig.c @@ -234,7 +234,7 @@ MnpAddFreeTxBuf ( break; } - DEBUG ((DEBUG_INFO, "MnpAddFreeTxBuf: Add TxBufWrap %p, TxBuf %p\n", TxBufWrap, TxBufWrap->TxBuf)); + DEBUG ((DEBUG_VERBOSE, "MnpAddFreeTxBuf: Add TxBufWrap %p, TxBuf %p\n", TxBufWrap, TxBufWrap->TxBuf)); TxBufWrap->Signature = MNP_TX_BUF_WRAP_SIGNATURE; TxBufWrap->InUse = FALSE; InsertTailList (&MnpDeviceData->FreeTxBufList, &TxBufWrap->WrapEntry); From dadd8c7a95bab7e17aaa0d5bbd6c40eaf461d434 Mon Sep 17 00:00:00 2001 From: Jason1 Lin Date: Thu, 15 Aug 2024 18:05:32 +0800 Subject: [PATCH 222/280] MdeModulePkg/DxeCapsuleLibFmp: Change the Event Notify to Cache ESRT Table REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4831 In this patch introduced the below changes, [1] Add the event of system resource table installed callback. - Register the event in DxeRuntimeCapsuleLibConstructor () - Unregister the event in DxeRuntimeCapsuleLibDestructor () [2] Migrate the event to update the module variable to cache ESRT table from ReadyToBoot to system resource table installed. [3] Add the condition to free the pool of buffer when the "mEsrtTable" is not NULL. Co-authored-by: Dakota Chiang Signed-off-by: Jason1 Lin --- .../DxeCapsuleLibFmp/DxeCapsuleRuntime.c | 60 ++++++++++++++++--- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c index 855b7a60fc23..9bea682bee4c 100644 --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c @@ -1,7 +1,7 @@ /** @file Capsule library runtime support. - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
+ Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2024, Ampere Computing LLC. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -23,6 +23,7 @@ extern EFI_SYSTEM_RESOURCE_TABLE *mEsrtTable; EFI_EVENT mDxeRuntimeCapsuleLibVirtualAddressChangeEvent = NULL; +EFI_EVENT mDxeRuntimeCapsuleLibSystemResourceTableEvent = NULL; EFI_EVENT mDxeRuntimeCapsuleLibReadyToBootEvent = NULL; extern BOOLEAN mDxeCapsuleLibReadyToBootEvent; @@ -44,16 +45,16 @@ DxeCapsuleLibVirtualAddressChangeEvent ( } /** - Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. + Notify function for event of system resource table installation. - @param[in] Event The Event that is being processed. - @param[in] Context The Event Context. + @param[in] Event The Event that is being processed. + @param[in] Context The Event Context. **/ STATIC VOID EFIAPI -DxeCapsuleLibReadyToBootEventNotify ( +DxeCapsuleLibSystemResourceTableInstallEventNotify ( IN EFI_EVENT Event, IN VOID *Context ) @@ -78,6 +79,14 @@ DxeCapsuleLibReadyToBootEventNotify ( // If no Esrt table installed in Configure Table // if (Index < gST->NumberOfTableEntries) { + // + // Free the pool to remove the cached ESRT table. + // + if (mEsrtTable != NULL) { + FreePool ((VOID *)mEsrtTable); + mEsrtTable = NULL; + } + // // Search Esrt to check given capsule is qualified // @@ -95,12 +104,28 @@ DxeCapsuleLibReadyToBootEventNotify ( // mEsrtTable->FwResourceCountMax = mEsrtTable->FwResourceCount; } +} +/** + Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. + + @param[in] Event The Event that is being processed. + @param[in] Context The Event Context. + +**/ +STATIC +VOID +EFIAPI +DxeCapsuleLibReadyToBootEventNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ mDxeCapsuleLibReadyToBootEvent = TRUE; } /** - The constructor function hook VirtualAddressChange event to use ESRT table as capsule routing table. + The constructor function for the file of DxeCapsuleRuntime. @param ImageHandle The firmware allocated handle for the EFI image. @param SystemTable A pointer to the EFI System Table. @@ -130,7 +155,20 @@ DxeRuntimeCapsuleLibConstructor ( ASSERT_EFI_ERROR (Status); // - // Register notify function to cache the FMP capsule GUIDs at ReadyToBoot. + // Register notify function to cache the FMP capsule GUIDs when system resource table installed. + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + DxeCapsuleLibSystemResourceTableInstallEventNotify, + NULL, + &gEfiSystemResourceTableGuid, + &mDxeRuntimeCapsuleLibSystemResourceTableEvent + ); + ASSERT_EFI_ERROR (Status); + + // + // Register notify function to indicate the event is signaled at ReadyToBoot. // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, @@ -146,7 +184,7 @@ DxeRuntimeCapsuleLibConstructor ( } /** - The destructor function closes the VirtualAddressChange event. + The destructor function for the file of DxeCapsuleRuntime. @param ImageHandle The firmware allocated handle for the EFI image. @param SystemTable A pointer to the EFI System Table. @@ -168,6 +206,12 @@ DxeRuntimeCapsuleLibDestructor ( Status = gBS->CloseEvent (mDxeRuntimeCapsuleLibVirtualAddressChangeEvent); ASSERT_EFI_ERROR (Status); + // + // Close the system resource table installed event. + // + Status = gBS->CloseEvent (mDxeRuntimeCapsuleLibSystemResourceTableEvent); + ASSERT_EFI_ERROR (Status); + // // Close the ReadyToBoot event. // From 03c8ec6ce29e47abca2b598bba9a05ddd87afc17 Mon Sep 17 00:00:00 2001 From: Jason1 Lin Date: Wed, 28 Aug 2024 17:36:11 +0800 Subject: [PATCH 223/280] MdeModulePkg/DxeCapsuleLibFmp: Check BootService Status to Use ESRT Cache - In c36414b131dfd0a1ca51f10f87a18955bc110ff2 change, it was introduced the ReadyToBoot event check to prevent the boot service got called in runtime to cause the issue. - In this patch introduced the ExitBootService event to replace it. It would be better to base on the BootService status to decide the source of ESRT table. - Based on the BootService availability to decide, - Exit : Use cache ESRT table in IF-condition - Not Exit: Use boot service to locate protocol in ELSE-condition Co-authored-by: Dakota Chiang Signed-off-by: Jason1 Lin --- .../Library/DxeCapsuleLibFmp/DxeCapsuleLib.c | 28 +++++++------------ .../DxeCapsuleLibFmp/DxeCapsuleRuntime.c | 22 +++++++-------- .../DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf | 4 +-- 3 files changed, 23 insertions(+), 31 deletions(-) diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c index 8befbae1de07..edf927649ff1 100644 --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c @@ -10,7 +10,7 @@ ValidateFmpCapsule(), and DisplayCapsuleImage() receives untrusted input and performs basic validation. - Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2024, Ampere Computing LLC. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -49,7 +49,7 @@ EFI_EVENT mDxeCapsuleLibEndOfDxeEvent = NULL; EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL *mFmpProgress = NULL; -BOOLEAN mDxeCapsuleLibReadyToBootEvent = FALSE; +BOOLEAN mDxeCapsuleLibIsExitBootService = FALSE; /** Initialize capsule related variables. @@ -1396,25 +1396,17 @@ IsNestedFmpCapsule ( EFI_SYSTEM_RESOURCE_ENTRY Entry; EsrtGuidFound = FALSE; - if (mEsrtTable != NULL) { - EsrtEntry = (EFI_SYSTEM_RESOURCE_ENTRY *)(mEsrtTable + 1); - for (Index = 0; Index < mEsrtTable->FwResourceCount; Index++, EsrtEntry++) { - if (CompareGuid (&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) { - EsrtGuidFound = TRUE; - break; + if (mDxeCapsuleLibIsExitBootService) { + if (mEsrtTable != NULL) { + EsrtEntry = (EFI_SYSTEM_RESOURCE_ENTRY *)(mEsrtTable + 1); + for (Index = 0; Index < mEsrtTable->FwResourceCount; Index++, EsrtEntry++) { + if (CompareGuid (&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) { + EsrtGuidFound = TRUE; + break; + } } } } else { - if (mDxeCapsuleLibReadyToBootEvent) { - // - // The ESRT table (mEsrtTable) in the Configuration Table would be located - // at the ReadyToBoot event if it exists. Hence, it should return here to - // avoid a crash due to calling gBS->LocateProtocol () at runtime in case - // there is no ERST table installed. - // - return FALSE; - } - // // Check ESRT protocol // diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c index 9bea682bee4c..34dc595dc8a4 100644 --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c @@ -22,10 +22,10 @@ #include extern EFI_SYSTEM_RESOURCE_TABLE *mEsrtTable; +extern BOOLEAN mDxeCapsuleLibIsExitBootService; EFI_EVENT mDxeRuntimeCapsuleLibVirtualAddressChangeEvent = NULL; EFI_EVENT mDxeRuntimeCapsuleLibSystemResourceTableEvent = NULL; -EFI_EVENT mDxeRuntimeCapsuleLibReadyToBootEvent = NULL; -extern BOOLEAN mDxeCapsuleLibReadyToBootEvent; +EFI_EVENT mDxeRuntimeCapsuleLibExitBootServiceEvent = NULL; /** Convert EsrtTable physical address to virtual address. @@ -107,7 +107,7 @@ DxeCapsuleLibSystemResourceTableInstallEventNotify ( } /** - Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. + Notify function for event of exit boot service. @param[in] Event The Event that is being processed. @param[in] Context The Event Context. @@ -116,12 +116,12 @@ DxeCapsuleLibSystemResourceTableInstallEventNotify ( STATIC VOID EFIAPI -DxeCapsuleLibReadyToBootEventNotify ( +DxeCapsuleLibExitBootServiceEventNotify ( IN EFI_EVENT Event, IN VOID *Context ) { - mDxeCapsuleLibReadyToBootEvent = TRUE; + mDxeCapsuleLibIsExitBootService = TRUE; } /** @@ -168,15 +168,15 @@ DxeRuntimeCapsuleLibConstructor ( ASSERT_EFI_ERROR (Status); // - // Register notify function to indicate the event is signaled at ReadyToBoot. + // Register notify function to indicate the event is signaled at ExitBootService. // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, - DxeCapsuleLibReadyToBootEventNotify, + DxeCapsuleLibExitBootServiceEventNotify, NULL, - &gEfiEventReadyToBootGuid, - &mDxeRuntimeCapsuleLibReadyToBootEvent + &gEfiEventExitBootServicesGuid, + &mDxeRuntimeCapsuleLibExitBootServiceEvent ); ASSERT_EFI_ERROR (Status); @@ -213,9 +213,9 @@ DxeRuntimeCapsuleLibDestructor ( ASSERT_EFI_ERROR (Status); // - // Close the ReadyToBoot event. + // Close the ExitBootService event. // - Status = gBS->CloseEvent (mDxeRuntimeCapsuleLibReadyToBootEvent); + Status = gBS->CloseEvent (mDxeRuntimeCapsuleLibExitBootServiceEvent); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf index bf56f4623f80..ef1fa57c5182 100644 --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf @@ -3,7 +3,7 @@ # # Capsule library instance for DXE_RUNTIME_DRIVER module types. # -# Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -66,7 +66,7 @@ gEfiCapsuleReportGuid gEfiCapsuleVendorGuid ## SOMETIMES_CONSUMES ## Variable:L"CapsuleUpdateData" gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event - gEfiEventReadyToBootGuid ## CONSUMES ## Event + gEfiEventExitBootServicesGuid ## CONSUMES ## Event gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event gEdkiiCapsuleOnDiskNameGuid ## SOMETIMES_CONSUMES ## GUID From e41e728c1640d5f3c5c24c31e088bf34f2fde197 Mon Sep 17 00:00:00 2001 From: Ashraf Ali Date: Fri, 6 Sep 2024 20:42:42 +0530 Subject: [PATCH 224/280] Refactor SetMemWrapper to reduce binary size Moved SetMemN API to a separate file to eliminate unnecessary inclusion of InternalMemSetMem64 and InternalMemSetMem32 APIs in driver binary. When the compiler linking the Object files it may not remove all the unused from NASM OBJs. This change is to reorganize the C files to minimize the impact of the NASM behavior resulting is code size reduction. Signed-off-by: Ashraf Ali --- .../Library/BaseMemoryLib/BaseMemoryLib.inf | 1 + MdePkg/Library/BaseMemoryLib/SetMemNWrapper.c | 54 +++++++++++++++++++ MdePkg/Library/BaseMemoryLib/SetMemWrapper.c | 36 +------------ .../BaseMemoryLibMmx/BaseMemoryLibMmx.inf | 1 + .../Library/BaseMemoryLibMmx/SetMemNWrapper.c | 54 +++++++++++++++++++ .../Library/BaseMemoryLibMmx/SetMemWrapper.c | 36 +------------ .../BaseMemoryLibOptDxe.inf | 1 + .../BaseMemoryLibOptDxe/SetMemNWrapper.c | 54 +++++++++++++++++++ .../BaseMemoryLibOptDxe/SetMemWrapper.c | 36 +------------ .../BaseMemoryLibOptPei.inf | 1 + .../BaseMemoryLibOptPei/SetMemNWrapper.c | 54 +++++++++++++++++++ .../BaseMemoryLibOptPei/SetMemWrapper.c | 36 +------------ .../BaseMemoryLibRepStr.inf | 1 + .../BaseMemoryLibRepStr/SetMemNWrapper.c | 54 +++++++++++++++++++ .../BaseMemoryLibRepStr/SetMemWrapper.c | 36 +------------ .../BaseMemoryLibSse2/BaseMemoryLibSse2.inf | 1 + .../BaseMemoryLibSse2/SetMemNWrapper.c | 54 +++++++++++++++++++ .../Library/BaseMemoryLibSse2/SetMemWrapper.c | 36 +------------ MdePkg/Library/UefiMemoryLib/SetMemNWrapper.c | 54 +++++++++++++++++++ MdePkg/Library/UefiMemoryLib/SetMemWrapper.c | 36 +------------ .../Library/UefiMemoryLib/UefiMemoryLib.inf | 2 +- 21 files changed, 392 insertions(+), 246 deletions(-) create mode 100644 MdePkg/Library/BaseMemoryLib/SetMemNWrapper.c create mode 100644 MdePkg/Library/BaseMemoryLibMmx/SetMemNWrapper.c create mode 100644 MdePkg/Library/BaseMemoryLibOptDxe/SetMemNWrapper.c create mode 100644 MdePkg/Library/BaseMemoryLibOptPei/SetMemNWrapper.c create mode 100644 MdePkg/Library/BaseMemoryLibRepStr/SetMemNWrapper.c create mode 100644 MdePkg/Library/BaseMemoryLibSse2/SetMemNWrapper.c create mode 100644 MdePkg/Library/UefiMemoryLib/SetMemNWrapper.c diff --git a/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf b/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf index e84a2c7ee5da..eac88cf713f8 100644 --- a/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf +++ b/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf @@ -32,6 +32,7 @@ ScanMem8Wrapper.c ZeroMemWrapper.c CompareMemWrapper.c + SetMemNWrapper.c SetMem64Wrapper.c SetMem32Wrapper.c SetMem16Wrapper.c diff --git a/MdePkg/Library/BaseMemoryLib/SetMemNWrapper.c b/MdePkg/Library/BaseMemoryLib/SetMemNWrapper.c new file mode 100644 index 000000000000..8a7cfca63bdf --- /dev/null +++ b/MdePkg/Library/BaseMemoryLib/SetMemNWrapper.c @@ -0,0 +1,54 @@ +/** @file + SetMemN() implementation. + + The following BaseMemoryLib instances contain the same copy of this file: + + BaseMemoryLib + BaseMemoryLibMmx + BaseMemoryLibSse2 + BaseMemoryLibRepStr + BaseMemoryLibOptDxe + BaseMemoryLibOptPei + PeiMemoryLib + UefiMemoryLib + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MemLibInternals.h" + +/** + Fills a target buffer with a value that is size UINTN, and returns the target buffer. + + This function fills Length bytes of Buffer with the UINTN sized value specified by + Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length + bytes of Buffer. + + If Length > 0 and Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + If Buffer is not aligned on a UINTN boundary, then ASSERT(). + If Length is not aligned on a UINTN boundary, then ASSERT(). + + @param Buffer The pointer to the target buffer to fill. + @param Length The number of bytes in Buffer to fill. + @param Value The value with which to fill Length bytes of Buffer. + + @return Buffer. + +**/ +VOID * +EFIAPI +SetMemN ( + OUT VOID *Buffer, + IN UINTN Length, + IN UINTN Value + ) +{ + if (sizeof (UINTN) == sizeof (UINT64)) { + return SetMem64 (Buffer, Length, (UINT64)Value); + } else { + return SetMem32 (Buffer, Length, (UINT32)Value); + } +} diff --git a/MdePkg/Library/BaseMemoryLib/SetMemWrapper.c b/MdePkg/Library/BaseMemoryLib/SetMemWrapper.c index 39ec8cb0db2e..31f8bd495785 100644 --- a/MdePkg/Library/BaseMemoryLib/SetMemWrapper.c +++ b/MdePkg/Library/BaseMemoryLib/SetMemWrapper.c @@ -1,5 +1,5 @@ /** @file - SetMem() and SetMemN() implementation. + SetMem() implementation. The following BaseMemoryLib instances contain the same copy of this file: @@ -49,37 +49,3 @@ SetMem ( return InternalMemSetMem (Buffer, Length, Value); } - -/** - Fills a target buffer with a value that is size UINTN, and returns the target buffer. - - This function fills Length bytes of Buffer with the UINTN sized value specified by - Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length - bytes of Buffer. - - If Length > 0 and Buffer is NULL, then ASSERT(). - If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - If Buffer is not aligned on a UINTN boundary, then ASSERT(). - If Length is not aligned on a UINTN boundary, then ASSERT(). - - @param Buffer The pointer to the target buffer to fill. - @param Length The number of bytes in Buffer to fill. - @param Value The value with which to fill Length bytes of Buffer. - - @return Buffer. - -**/ -VOID * -EFIAPI -SetMemN ( - OUT VOID *Buffer, - IN UINTN Length, - IN UINTN Value - ) -{ - if (sizeof (UINTN) == sizeof (UINT64)) { - return SetMem64 (Buffer, Length, (UINT64)Value); - } else { - return SetMem32 (Buffer, Length, (UINT32)Value); - } -} diff --git a/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf b/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf index 18fc5875e24a..2f37c69d6e32 100644 --- a/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf +++ b/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf @@ -36,6 +36,7 @@ ScanMem8Wrapper.c ZeroMemWrapper.c CompareMemWrapper.c + SetMemNWrapper.c SetMem64Wrapper.c SetMem32Wrapper.c SetMem16Wrapper.c diff --git a/MdePkg/Library/BaseMemoryLibMmx/SetMemNWrapper.c b/MdePkg/Library/BaseMemoryLibMmx/SetMemNWrapper.c new file mode 100644 index 000000000000..8a7cfca63bdf --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibMmx/SetMemNWrapper.c @@ -0,0 +1,54 @@ +/** @file + SetMemN() implementation. + + The following BaseMemoryLib instances contain the same copy of this file: + + BaseMemoryLib + BaseMemoryLibMmx + BaseMemoryLibSse2 + BaseMemoryLibRepStr + BaseMemoryLibOptDxe + BaseMemoryLibOptPei + PeiMemoryLib + UefiMemoryLib + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MemLibInternals.h" + +/** + Fills a target buffer with a value that is size UINTN, and returns the target buffer. + + This function fills Length bytes of Buffer with the UINTN sized value specified by + Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length + bytes of Buffer. + + If Length > 0 and Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + If Buffer is not aligned on a UINTN boundary, then ASSERT(). + If Length is not aligned on a UINTN boundary, then ASSERT(). + + @param Buffer The pointer to the target buffer to fill. + @param Length The number of bytes in Buffer to fill. + @param Value The value with which to fill Length bytes of Buffer. + + @return Buffer. + +**/ +VOID * +EFIAPI +SetMemN ( + OUT VOID *Buffer, + IN UINTN Length, + IN UINTN Value + ) +{ + if (sizeof (UINTN) == sizeof (UINT64)) { + return SetMem64 (Buffer, Length, (UINT64)Value); + } else { + return SetMem32 (Buffer, Length, (UINT32)Value); + } +} diff --git a/MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c b/MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c index 39ec8cb0db2e..31f8bd495785 100644 --- a/MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c +++ b/MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c @@ -1,5 +1,5 @@ /** @file - SetMem() and SetMemN() implementation. + SetMem() implementation. The following BaseMemoryLib instances contain the same copy of this file: @@ -49,37 +49,3 @@ SetMem ( return InternalMemSetMem (Buffer, Length, Value); } - -/** - Fills a target buffer with a value that is size UINTN, and returns the target buffer. - - This function fills Length bytes of Buffer with the UINTN sized value specified by - Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length - bytes of Buffer. - - If Length > 0 and Buffer is NULL, then ASSERT(). - If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - If Buffer is not aligned on a UINTN boundary, then ASSERT(). - If Length is not aligned on a UINTN boundary, then ASSERT(). - - @param Buffer The pointer to the target buffer to fill. - @param Length The number of bytes in Buffer to fill. - @param Value The value with which to fill Length bytes of Buffer. - - @return Buffer. - -**/ -VOID * -EFIAPI -SetMemN ( - OUT VOID *Buffer, - IN UINTN Length, - IN UINTN Value - ) -{ - if (sizeof (UINTN) == sizeof (UINT64)) { - return SetMem64 (Buffer, Length, (UINT64)Value); - } else { - return SetMem32 (Buffer, Length, (UINT32)Value); - } -} diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf b/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf index 6a7fa9a5652a..ed10b2e8fa1c 100644 --- a/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf +++ b/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf @@ -92,6 +92,7 @@ ScanMem8Wrapper.c ZeroMemWrapper.c CompareMemWrapper.c + SetMemNWrapper.c SetMem64Wrapper.c SetMem32Wrapper.c SetMem16Wrapper.c diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/SetMemNWrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/SetMemNWrapper.c new file mode 100644 index 000000000000..8a7cfca63bdf --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibOptDxe/SetMemNWrapper.c @@ -0,0 +1,54 @@ +/** @file + SetMemN() implementation. + + The following BaseMemoryLib instances contain the same copy of this file: + + BaseMemoryLib + BaseMemoryLibMmx + BaseMemoryLibSse2 + BaseMemoryLibRepStr + BaseMemoryLibOptDxe + BaseMemoryLibOptPei + PeiMemoryLib + UefiMemoryLib + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MemLibInternals.h" + +/** + Fills a target buffer with a value that is size UINTN, and returns the target buffer. + + This function fills Length bytes of Buffer with the UINTN sized value specified by + Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length + bytes of Buffer. + + If Length > 0 and Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + If Buffer is not aligned on a UINTN boundary, then ASSERT(). + If Length is not aligned on a UINTN boundary, then ASSERT(). + + @param Buffer The pointer to the target buffer to fill. + @param Length The number of bytes in Buffer to fill. + @param Value The value with which to fill Length bytes of Buffer. + + @return Buffer. + +**/ +VOID * +EFIAPI +SetMemN ( + OUT VOID *Buffer, + IN UINTN Length, + IN UINTN Value + ) +{ + if (sizeof (UINTN) == sizeof (UINT64)) { + return SetMem64 (Buffer, Length, (UINT64)Value); + } else { + return SetMem32 (Buffer, Length, (UINT32)Value); + } +} diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c index 39ec8cb0db2e..31f8bd495785 100644 --- a/MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c +++ b/MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c @@ -1,5 +1,5 @@ /** @file - SetMem() and SetMemN() implementation. + SetMem() implementation. The following BaseMemoryLib instances contain the same copy of this file: @@ -49,37 +49,3 @@ SetMem ( return InternalMemSetMem (Buffer, Length, Value); } - -/** - Fills a target buffer with a value that is size UINTN, and returns the target buffer. - - This function fills Length bytes of Buffer with the UINTN sized value specified by - Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length - bytes of Buffer. - - If Length > 0 and Buffer is NULL, then ASSERT(). - If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - If Buffer is not aligned on a UINTN boundary, then ASSERT(). - If Length is not aligned on a UINTN boundary, then ASSERT(). - - @param Buffer The pointer to the target buffer to fill. - @param Length The number of bytes in Buffer to fill. - @param Value The value with which to fill Length bytes of Buffer. - - @return Buffer. - -**/ -VOID * -EFIAPI -SetMemN ( - OUT VOID *Buffer, - IN UINTN Length, - IN UINTN Value - ) -{ - if (sizeof (UINTN) == sizeof (UINT64)) { - return SetMem64 (Buffer, Length, (UINT64)Value); - } else { - return SetMem32 (Buffer, Length, (UINT32)Value); - } -} diff --git a/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf b/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf index 43c2cc2a0a9b..7e3136961cd5 100644 --- a/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf +++ b/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf @@ -33,6 +33,7 @@ ScanMem8Wrapper.c ZeroMemWrapper.c CompareMemWrapper.c + SetMemNWrapper.c SetMem64Wrapper.c SetMem32Wrapper.c SetMem16Wrapper.c diff --git a/MdePkg/Library/BaseMemoryLibOptPei/SetMemNWrapper.c b/MdePkg/Library/BaseMemoryLibOptPei/SetMemNWrapper.c new file mode 100644 index 000000000000..8a7cfca63bdf --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibOptPei/SetMemNWrapper.c @@ -0,0 +1,54 @@ +/** @file + SetMemN() implementation. + + The following BaseMemoryLib instances contain the same copy of this file: + + BaseMemoryLib + BaseMemoryLibMmx + BaseMemoryLibSse2 + BaseMemoryLibRepStr + BaseMemoryLibOptDxe + BaseMemoryLibOptPei + PeiMemoryLib + UefiMemoryLib + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MemLibInternals.h" + +/** + Fills a target buffer with a value that is size UINTN, and returns the target buffer. + + This function fills Length bytes of Buffer with the UINTN sized value specified by + Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length + bytes of Buffer. + + If Length > 0 and Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + If Buffer is not aligned on a UINTN boundary, then ASSERT(). + If Length is not aligned on a UINTN boundary, then ASSERT(). + + @param Buffer The pointer to the target buffer to fill. + @param Length The number of bytes in Buffer to fill. + @param Value The value with which to fill Length bytes of Buffer. + + @return Buffer. + +**/ +VOID * +EFIAPI +SetMemN ( + OUT VOID *Buffer, + IN UINTN Length, + IN UINTN Value + ) +{ + if (sizeof (UINTN) == sizeof (UINT64)) { + return SetMem64 (Buffer, Length, (UINT64)Value); + } else { + return SetMem32 (Buffer, Length, (UINT32)Value); + } +} diff --git a/MdePkg/Library/BaseMemoryLibOptPei/SetMemWrapper.c b/MdePkg/Library/BaseMemoryLibOptPei/SetMemWrapper.c index 39ec8cb0db2e..31f8bd495785 100644 --- a/MdePkg/Library/BaseMemoryLibOptPei/SetMemWrapper.c +++ b/MdePkg/Library/BaseMemoryLibOptPei/SetMemWrapper.c @@ -1,5 +1,5 @@ /** @file - SetMem() and SetMemN() implementation. + SetMem() implementation. The following BaseMemoryLib instances contain the same copy of this file: @@ -49,37 +49,3 @@ SetMem ( return InternalMemSetMem (Buffer, Length, Value); } - -/** - Fills a target buffer with a value that is size UINTN, and returns the target buffer. - - This function fills Length bytes of Buffer with the UINTN sized value specified by - Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length - bytes of Buffer. - - If Length > 0 and Buffer is NULL, then ASSERT(). - If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - If Buffer is not aligned on a UINTN boundary, then ASSERT(). - If Length is not aligned on a UINTN boundary, then ASSERT(). - - @param Buffer The pointer to the target buffer to fill. - @param Length The number of bytes in Buffer to fill. - @param Value The value with which to fill Length bytes of Buffer. - - @return Buffer. - -**/ -VOID * -EFIAPI -SetMemN ( - OUT VOID *Buffer, - IN UINTN Length, - IN UINTN Value - ) -{ - if (sizeof (UINTN) == sizeof (UINT64)) { - return SetMem64 (Buffer, Length, (UINT64)Value); - } else { - return SetMem32 (Buffer, Length, (UINT32)Value); - } -} diff --git a/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf b/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf index 59983d0a0c5b..4dad964a97c1 100644 --- a/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf +++ b/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf @@ -33,6 +33,7 @@ ScanMem8Wrapper.c ZeroMemWrapper.c CompareMemWrapper.c + SetMemNWrapper.c SetMem64Wrapper.c SetMem32Wrapper.c SetMem16Wrapper.c diff --git a/MdePkg/Library/BaseMemoryLibRepStr/SetMemNWrapper.c b/MdePkg/Library/BaseMemoryLibRepStr/SetMemNWrapper.c new file mode 100644 index 000000000000..8a7cfca63bdf --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibRepStr/SetMemNWrapper.c @@ -0,0 +1,54 @@ +/** @file + SetMemN() implementation. + + The following BaseMemoryLib instances contain the same copy of this file: + + BaseMemoryLib + BaseMemoryLibMmx + BaseMemoryLibSse2 + BaseMemoryLibRepStr + BaseMemoryLibOptDxe + BaseMemoryLibOptPei + PeiMemoryLib + UefiMemoryLib + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MemLibInternals.h" + +/** + Fills a target buffer with a value that is size UINTN, and returns the target buffer. + + This function fills Length bytes of Buffer with the UINTN sized value specified by + Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length + bytes of Buffer. + + If Length > 0 and Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + If Buffer is not aligned on a UINTN boundary, then ASSERT(). + If Length is not aligned on a UINTN boundary, then ASSERT(). + + @param Buffer The pointer to the target buffer to fill. + @param Length The number of bytes in Buffer to fill. + @param Value The value with which to fill Length bytes of Buffer. + + @return Buffer. + +**/ +VOID * +EFIAPI +SetMemN ( + OUT VOID *Buffer, + IN UINTN Length, + IN UINTN Value + ) +{ + if (sizeof (UINTN) == sizeof (UINT64)) { + return SetMem64 (Buffer, Length, (UINT64)Value); + } else { + return SetMem32 (Buffer, Length, (UINT32)Value); + } +} diff --git a/MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c b/MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c index 39ec8cb0db2e..31f8bd495785 100644 --- a/MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c +++ b/MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c @@ -1,5 +1,5 @@ /** @file - SetMem() and SetMemN() implementation. + SetMem() implementation. The following BaseMemoryLib instances contain the same copy of this file: @@ -49,37 +49,3 @@ SetMem ( return InternalMemSetMem (Buffer, Length, Value); } - -/** - Fills a target buffer with a value that is size UINTN, and returns the target buffer. - - This function fills Length bytes of Buffer with the UINTN sized value specified by - Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length - bytes of Buffer. - - If Length > 0 and Buffer is NULL, then ASSERT(). - If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - If Buffer is not aligned on a UINTN boundary, then ASSERT(). - If Length is not aligned on a UINTN boundary, then ASSERT(). - - @param Buffer The pointer to the target buffer to fill. - @param Length The number of bytes in Buffer to fill. - @param Value The value with which to fill Length bytes of Buffer. - - @return Buffer. - -**/ -VOID * -EFIAPI -SetMemN ( - OUT VOID *Buffer, - IN UINTN Length, - IN UINTN Value - ) -{ - if (sizeof (UINTN) == sizeof (UINT64)) { - return SetMem64 (Buffer, Length, (UINT64)Value); - } else { - return SetMem32 (Buffer, Length, (UINT32)Value); - } -} diff --git a/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf b/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf index 69a29a1b7da3..fbc1a7b6cf1f 100644 --- a/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf +++ b/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf @@ -32,6 +32,7 @@ ScanMem8Wrapper.c ZeroMemWrapper.c CompareMemWrapper.c + SetMemNWrapper.c SetMem64Wrapper.c SetMem32Wrapper.c SetMem16Wrapper.c diff --git a/MdePkg/Library/BaseMemoryLibSse2/SetMemNWrapper.c b/MdePkg/Library/BaseMemoryLibSse2/SetMemNWrapper.c new file mode 100644 index 000000000000..8a7cfca63bdf --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibSse2/SetMemNWrapper.c @@ -0,0 +1,54 @@ +/** @file + SetMemN() implementation. + + The following BaseMemoryLib instances contain the same copy of this file: + + BaseMemoryLib + BaseMemoryLibMmx + BaseMemoryLibSse2 + BaseMemoryLibRepStr + BaseMemoryLibOptDxe + BaseMemoryLibOptPei + PeiMemoryLib + UefiMemoryLib + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MemLibInternals.h" + +/** + Fills a target buffer with a value that is size UINTN, and returns the target buffer. + + This function fills Length bytes of Buffer with the UINTN sized value specified by + Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length + bytes of Buffer. + + If Length > 0 and Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + If Buffer is not aligned on a UINTN boundary, then ASSERT(). + If Length is not aligned on a UINTN boundary, then ASSERT(). + + @param Buffer The pointer to the target buffer to fill. + @param Length The number of bytes in Buffer to fill. + @param Value The value with which to fill Length bytes of Buffer. + + @return Buffer. + +**/ +VOID * +EFIAPI +SetMemN ( + OUT VOID *Buffer, + IN UINTN Length, + IN UINTN Value + ) +{ + if (sizeof (UINTN) == sizeof (UINT64)) { + return SetMem64 (Buffer, Length, (UINT64)Value); + } else { + return SetMem32 (Buffer, Length, (UINT32)Value); + } +} diff --git a/MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c b/MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c index 39ec8cb0db2e..31f8bd495785 100644 --- a/MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c +++ b/MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c @@ -1,5 +1,5 @@ /** @file - SetMem() and SetMemN() implementation. + SetMem() implementation. The following BaseMemoryLib instances contain the same copy of this file: @@ -49,37 +49,3 @@ SetMem ( return InternalMemSetMem (Buffer, Length, Value); } - -/** - Fills a target buffer with a value that is size UINTN, and returns the target buffer. - - This function fills Length bytes of Buffer with the UINTN sized value specified by - Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length - bytes of Buffer. - - If Length > 0 and Buffer is NULL, then ASSERT(). - If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - If Buffer is not aligned on a UINTN boundary, then ASSERT(). - If Length is not aligned on a UINTN boundary, then ASSERT(). - - @param Buffer The pointer to the target buffer to fill. - @param Length The number of bytes in Buffer to fill. - @param Value The value with which to fill Length bytes of Buffer. - - @return Buffer. - -**/ -VOID * -EFIAPI -SetMemN ( - OUT VOID *Buffer, - IN UINTN Length, - IN UINTN Value - ) -{ - if (sizeof (UINTN) == sizeof (UINT64)) { - return SetMem64 (Buffer, Length, (UINT64)Value); - } else { - return SetMem32 (Buffer, Length, (UINT32)Value); - } -} diff --git a/MdePkg/Library/UefiMemoryLib/SetMemNWrapper.c b/MdePkg/Library/UefiMemoryLib/SetMemNWrapper.c new file mode 100644 index 000000000000..8a7cfca63bdf --- /dev/null +++ b/MdePkg/Library/UefiMemoryLib/SetMemNWrapper.c @@ -0,0 +1,54 @@ +/** @file + SetMemN() implementation. + + The following BaseMemoryLib instances contain the same copy of this file: + + BaseMemoryLib + BaseMemoryLibMmx + BaseMemoryLibSse2 + BaseMemoryLibRepStr + BaseMemoryLibOptDxe + BaseMemoryLibOptPei + PeiMemoryLib + UefiMemoryLib + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MemLibInternals.h" + +/** + Fills a target buffer with a value that is size UINTN, and returns the target buffer. + + This function fills Length bytes of Buffer with the UINTN sized value specified by + Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length + bytes of Buffer. + + If Length > 0 and Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + If Buffer is not aligned on a UINTN boundary, then ASSERT(). + If Length is not aligned on a UINTN boundary, then ASSERT(). + + @param Buffer The pointer to the target buffer to fill. + @param Length The number of bytes in Buffer to fill. + @param Value The value with which to fill Length bytes of Buffer. + + @return Buffer. + +**/ +VOID * +EFIAPI +SetMemN ( + OUT VOID *Buffer, + IN UINTN Length, + IN UINTN Value + ) +{ + if (sizeof (UINTN) == sizeof (UINT64)) { + return SetMem64 (Buffer, Length, (UINT64)Value); + } else { + return SetMem32 (Buffer, Length, (UINT32)Value); + } +} diff --git a/MdePkg/Library/UefiMemoryLib/SetMemWrapper.c b/MdePkg/Library/UefiMemoryLib/SetMemWrapper.c index 1d54a8afe19e..df1247d4524e 100644 --- a/MdePkg/Library/UefiMemoryLib/SetMemWrapper.c +++ b/MdePkg/Library/UefiMemoryLib/SetMemWrapper.c @@ -1,5 +1,5 @@ /** @file - SetMem() and SetMemN() implementation. + SetMem() implementation. The following BaseMemoryLib instances contain the same copy of this file: @@ -49,37 +49,3 @@ SetMem ( return InternalMemSetMem (Buffer, Length, Value); } - -/** - Fills a target buffer with a value that is size UINTN, and returns the target buffer. - - This function fills Length bytes of Buffer with the UINTN sized value specified by - Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length - bytes of Buffer. - - If Length > 0 and Buffer is NULL, then ASSERT(). - If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - If Buffer is not aligned on a UINTN boundary, then ASSERT(). - If Length is not aligned on a UINTN boundary, then ASSERT(). - - @param Buffer The pointer to the target buffer to fill. - @param Length The number of bytes in Buffer to fill. - @param Value The value with which to fill Length bytes of Buffer. - - @return Buffer. - -**/ -VOID * -EFIAPI -SetMemN ( - OUT VOID *Buffer, - IN UINTN Length, - IN UINTN Value - ) -{ - if (sizeof (UINTN) == sizeof (UINT64)) { - return SetMem64 (Buffer, Length, (UINT64)Value); - } else { - return SetMem32 (Buffer, Length, (UINT32)Value); - } -} diff --git a/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.inf b/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.inf index 2556225e1d20..35dff7a4c3d6 100644 --- a/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.inf +++ b/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.inf @@ -32,6 +32,7 @@ ScanMem8Wrapper.c ZeroMemWrapper.c CompareMemWrapper.c + SetMemNWrapper.c SetMem64Wrapper.c SetMem32Wrapper.c SetMem16Wrapper.c @@ -47,7 +48,6 @@ [Packages] MdePkg/MdePkg.dec - [LibraryClasses] BaseLib UefiBootServicesTableLib From bacee5113e813520b92babf0fc6f5914cdfc9fab Mon Sep 17 00:00:00 2001 From: Nhi Pham Date: Mon, 9 Sep 2024 14:22:22 +0700 Subject: [PATCH 225/280] MdePkg/IpmiNetFnGroupExtension.h: Enforce structure alignment The natural aligmenent seems to be failed on some cases. So, this patch intends to add the pack(1) to ensure the structure aligned with a one-byte boundary. Signed-off-by: Nhi Pham --- MdePkg/Include/IndustryStandard/IpmiNetFnGroupExtension.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MdePkg/Include/IndustryStandard/IpmiNetFnGroupExtension.h b/MdePkg/Include/IndustryStandard/IpmiNetFnGroupExtension.h index aa242efcbbff..b821ad51e39f 100644 --- a/MdePkg/Include/IndustryStandard/IpmiNetFnGroupExtension.h +++ b/MdePkg/Include/IndustryStandard/IpmiNetFnGroupExtension.h @@ -4,6 +4,12 @@ Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.
Copyright (c) 2024, Ampere Computing LLC. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + - Arm Server Base Manageability Requirements (SBMR) Specification + Revision 2.0d, Section F + https://developer.arm.com/documentation/den0069 + **/ #ifndef _IPMI_NET_FN_GROUP_EXTENSION_H_ @@ -27,6 +33,7 @@ /// https://developer.arm.com/documentation/den0069 /// +#pragma pack(1) // // Definitions for send progress code command // @@ -85,5 +92,6 @@ typedef struct { UINT8 DefiningBody; IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_FORMAT BootProgressCode; } IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_GET_RESPONSE; +#pragma pack() #endif From babccb841dbb39de2b4485bdb63dcc5bb6122bd8 Mon Sep 17 00:00:00 2001 From: Ken Lautner Date: Fri, 23 Aug 2024 17:41:49 -0700 Subject: [PATCH 226/280] MdeModulePkg: Enable Data Terminal at end of serial When a Serial device resets, the Modem Control Register Data Terminal Ready and Request to Send need to be cleared also. Otherwise the registers will be left in their previous state, and the connected device will not be able to transmit data. Signed-off-by: Kenneth Lautner --- MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c index aafa65f44c6d..fa1038ed43c0 100644 --- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c +++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c @@ -95,6 +95,10 @@ TerminalConInReset ( ); } + if (!EFI_ERROR (Status)) { + Status = TerminalDevice->SerialIo->SetControl (TerminalDevice->SerialIo, EFI_SERIAL_DATA_TERMINAL_READY|EFI_SERIAL_REQUEST_TO_SEND); + } + return Status; } From dfc242c2dda2010faf99beaf7fd2009bf4287444 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Thu, 5 Sep 2024 10:03:59 +0100 Subject: [PATCH 227/280] MdePkg/Acpi65.h: Add RAS2 table defs and signature as in ACPI 6.5 Add EFI_ACPI_RAS2_PCC_DESCRIPTOR, EFI_ACPI_6_5_RAS2_FEATURE_TABLE and EFI_ACPI_6_5_ACPI_RAS2_FEATURE_TABLE_SIGNATURE. Signed-off-by: Carsten Haitzler --- MdePkg/Include/IndustryStandard/Acpi65.h | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/MdePkg/Include/IndustryStandard/Acpi65.h b/MdePkg/Include/IndustryStandard/Acpi65.h index 42a9aaf860e2..62d2fac1bfb6 100644 --- a/MdePkg/Include/IndustryStandard/Acpi65.h +++ b/MdePkg/Include/IndustryStandard/Acpi65.h @@ -1056,6 +1056,26 @@ typedef struct { #define EFI_ACPI_6_5_RASF_PATROL_SCRUB_COMMAND_START_PATROL_SCRUBBER 0x02 #define EFI_ACPI_6_5_RASF_PATROL_SCRUB_COMMAND_STOP_PATROL_SCRUBBER 0x03 +/// +/// ACPI RAS2 PCC Descriptor +/// +typedef struct { + UINT8 PccId; + UINT8 Reserved[2]; + UINT8 RasFeatureType; + UINT32 Instance; +} EFI_ACPI_RAS2_PCC_DESCRIPTOR; + +/// +/// ACPI RAS2 Feature Table definition. +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT16 Reserved; + UINT16 PccCount; + // EFI_ACPI_RAS2_PCC_DESCRIPTOR Descriptors[PccCount]; +} EFI_ACPI_6_5_RAS2_FEATURE_TABLE; + /// /// Memory Power State Table definition. /// @@ -3121,6 +3141,11 @@ typedef struct { /// #define EFI_ACPI_6_5_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('P', 'S', 'D', 'T') +/// +/// "RAS2" ACPI RAS2 Feature Table +/// +#define EFI_ACPI_6_5_ACPI_RAS2_FEATURE_TABLE_SIGNATURE SIGNATURE_32('R', 'A', 'S', '2') + /// /// "RASF" ACPI RAS Feature Table /// From 1197fb3383ddbe53d764cb9b3583c1738ac62a18 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Thu, 29 Aug 2024 15:06:08 +0100 Subject: [PATCH 228/280] ShellPkg/AcpiView: RAS2 Parser Add a new parser for the RAS2 Table as specified in ACPI6.5 Signed-off-by: Carsten Haitzler --- .../UefiShellAcpiViewCommandLib/AcpiParser.h | 23 ++++ .../Parsers/Ras2/Ras2Parser.c | 118 ++++++++++++++++++ .../UefiShellAcpiViewCommandLib.c | 1 + .../UefiShellAcpiViewCommandLib.inf | 1 + 4 files changed, 143 insertions(+) create mode 100644 ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ras2/Ras2Parser.c diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h index 6427ea7d8a5d..32816242fc23 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h @@ -1006,6 +1006,29 @@ ParseAcpiPptt ( IN UINT8 AcpiTableRevision ); +/** + This function parses the ACPI RAS2 table. + When trace is enabled this function parses the RAS2 table and + traces the ACPI table fields. + + This function parses the RAS2 ACPI table along with PCC Entries + + This function also performs validation of the ACPI table fields. + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiRas2 ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ); + /** This function parses the ACPI RSDP table. diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ras2/Ras2Parser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ras2/Ras2Parser.c new file mode 100644 index 000000000000..9c61b96817ab --- /dev/null +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ras2/Ras2Parser.c @@ -0,0 +1,118 @@ +/** @file + RAS2 table parser + + Copyright (c) 2024, Arm Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.5 Specification - August 2022 +**/ + +#include +#include +#include +#include "AcpiParser.h" +#include "AcpiView.h" + +// Maximum Memory Domain matrix print size. +#define MAX_MEMORY_DOMAIN_TARGET_PRINT_MATRIX 10 + +// Local variables +STATIC CONST UINT16 *Ras2PccDescriptors; + +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +/** + An ACPI_PARSER array describing the ACPI RAS2 Table. +*/ +STATIC CONST ACPI_PARSER Ras2Parser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo), + { L"Reserved", 2, 36, L"0x%x", NULL, NULL, NULL, NULL }, + { L"PCC Descriptors", 2, 38, L"%d", NULL, (VOID **)&Ras2PccDescriptors, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the RAS2 PCC ID Entry +*/ +STATIC CONST ACPI_PARSER Ras2StructurePccDescriptor[] = { + { L"PCC ID", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 1, 1, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Feature Type", 1, 3, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Instance", 4, 4, L"0x%x", NULL, NULL, NULL, NULL } +}; + +STATIC +VOID +DumpPccEntry ( + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "PCC Descriptor Entry", + Ptr, + Length, + PARSER_PARAMS (Ras2StructurePccDescriptor) + ); +} + +/** + This function parses the ACPI RAS2 table. + When trace is enabled this function parses the RAS2 table and + traces the ACPI table fields. + + This function parses the following RAS2 structures: + - Pcc Instries + - Entry Pcc ID + - Entry Feature Type + - Entry Pcc Instance + + This function also performs validation of the ACPI table fields. + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiRas2 ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + UINT32 Offset; + + if (!Trace) { + return; + } + + // Parse ACPI Header + RAS2 "fixed" fields + Offset = ParseAcpi ( + Trace, + 0, + "RAS2", + Ptr, + AcpiTableLength, + PARSER_PARAMS (Ras2Parser) + ); + + // Table is too small to contain data + if (Offset >= AcpiTableLength) { + return; + } + + // Loop over rest of table for PCC Entries and dump them + while (Offset <= (AcpiTableLength - sizeof (EFI_ACPI_RAS2_PCC_DESCRIPTOR))) { + DumpPccEntry ( + Ptr + Offset, + sizeof (EFI_ACPI_RAS2_PCC_DESCRIPTOR) + ); + Offset += sizeof (EFI_ACPI_RAS2_PCC_DESCRIPTOR); + } // while +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c index 4f4254ac40d5..5e73a3909543 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c @@ -71,6 +71,7 @@ ACPI_TABLE_PARSER ParserList[] = { ParseAcpiPcct }, { EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE, ParseAcpiPptt }, + { EFI_ACPI_6_5_ACPI_RAS2_FEATURE_TABLE_SIGNATURE, ParseAcpiRas2 }, { RSDP_TABLE_INFO, ParseAcpiRsdp }, { EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE, ParseAcpiSlit }, { EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, ParseAcpiSpcr }, diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf index 54dddd0ee26d..7ef8b0afb7b2 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf @@ -50,6 +50,7 @@ Parsers/Pcct/PcctParser.h Parsers/Pptt/PpttParser.c Parsers/Pptt/PpttParser.h + Parsers/Ras2/Ras2Parser.c Parsers/Rsdp/RsdpParser.c Parsers/Slit/SlitParser.c Parsers/Spcr/SpcrParser.c From fe6b6feca7b6012278a432226a56f0836ad1c457 Mon Sep 17 00:00:00 2001 From: Xianglai Li Date: Wed, 11 Sep 2024 16:58:53 +0800 Subject: [PATCH 229/280] OvmfPkg/LoongArchVirt: Modify loongarch uefi firmware size After the loongarch flash block size is changed from 128K to 256K, qemu requires that the UEFI firmware size be aligned with the flash block size(256K). Otherwise, the firmware cannot be loaded, Use the following code to resolve the old firmware loading problem: mv QEMU_EFI.fd QEMU_EFI.fd-bak cat QEMU_EFI.fd-bak /dev/zero | head -c 16m > ./QEMU_EFI.fd mv QEMU_VARS.fd QEMU_VARS.fd-bak cat QEMU_VARS.fd-bak /dev/zero | head -c 16m > ./QEMU_VARS.fd For the new firmware, we refer to other architecture UEFI and set the UEFI firmware size to align with the flash block size(256K). So for this patch, we set the UEFI firmware size to 256K alignment. Cc: Bibo Mao Cc: Chao Li Signed-off-by: Xianglai Li --- OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc b/OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc index 22373bec6a43..6d68a9e3a60e 100644 --- a/OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc +++ b/OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc @@ -15,18 +15,8 @@ DEFINE FW_BLOCKS = 0x400 DEFINE FW_SIZE = 0x400000 ############################################################################ -#Flash code layout -#Set Sec size in flash -DEFINE SECFV_SIZE = 0x00010000 - -#Set Pei size in flash -DEFINE PEIFV_SIZE = 0x00040000 - -#Set Dxe size in flash -DEFINE DXEFV_SIZE = 0x00350000 - #Set FVMAIN size -DEFINE FVMAIN_SIZE = $(SECFV_SIZE) + $(PEIFV_SIZE) +$(DXEFV_SIZE) +DEFINE FVMAIN_SIZE = $(FW_SIZE) #Set Memory layout DEFINE SEC_PEI_TEMP_RAM_BASE = 0x10000 From 656665d289b355ada71ad718759200c44c655264 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 6 Aug 2024 15:22:34 -0700 Subject: [PATCH 230/280] ArmPkg: CompilerIntrinsicsLib: Use AsmMacroIoLibV8.h for AARCH64 ASM AArch64/ashlti3.S was using AsmMacroIoLib.h which is the ARM version of these definitions. AsmMacroIoLibV8.h is the AARCH64 version of these defintions. This patch moves that file to use the proper arch file. Signed-off-by: Oliver Smith-Denny --- ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S b/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S index 79a7b3514c57..c2e20069b4e2 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__ashlti3) # return if shift is 0 From 734e71f428a4fdac5d82ae9c093911053356f6ff Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 6 Aug 2024 15:19:23 -0700 Subject: [PATCH 231/280] MdePkg: Move AsmMacroIoLib*.h from ArmPkg AsmMacroIoLib.h and AsmMacroIoLibV8.h are used by the CompilerIntrinsicsLib, which is moving to MdePkg. These functions provide standard definitions for ARM/AARCH64 assembly code, respectively, and so are moved to the arch directories in MdePkg to avoid MdePkg having a dependency on ArmPkg. Now that the files are in Arm/ and AArch64/ directories, the filenames are changed to AsmMacroLib.h as we can distinguish the architecture from the path. AsmMacroIoLib.inc is unused and so is removed. Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Oliver Smith-Denny --- .../Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S | 2 +- ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S | 2 +- ArmPkg/Drivers/ArmPsciMpServicesDxe/MpFuncs.S | 2 +- ArmPkg/Include/AsmMacroIoLib.inc | 33 ------------------- .../AArch64/ExceptionSupport.S | 2 +- ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S | 2 +- ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S | 2 +- .../ArmLib/AArch64/AArch64ArchTimerSupport.S | 2 +- .../Library/ArmLib/AArch64/AArch64Support.S | 2 +- ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S | 2 +- .../Library/ArmLib/AArch64/ArmLibSupportV8.S | 2 +- ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S | 2 +- ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S | 2 +- .../ArmLib/Arm/ArmV7ArchTimerSupport.S | 2 +- ArmPkg/Library/ArmLib/Arm/ArmV7Support.S | 2 +- .../ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S | 2 +- .../ArmMmuLib/Arm/ArmMmuLibV7Support.S | 2 +- .../ArmMonitorLib/AArch64/ArmMonitorLib.S | 2 +- .../Library/ArmMonitorLib/Arm/ArmMonitorLib.S | 2 +- ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S | 2 +- ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S | 2 +- ArmPkg/Library/ArmSvcLib/AArch64/ArmSvc.S | 2 +- .../CompilerIntrinsicsLib/AArch64/ashlti3.S | 2 +- .../CompilerIntrinsicsLib/Arm/ashldi3.S | 2 +- .../CompilerIntrinsicsLib/Arm/ashrdi3.S | 2 +- .../CompilerIntrinsicsLib/Arm/clzsi2.S | 2 +- .../CompilerIntrinsicsLib/Arm/ctzsi2.S | 2 +- .../CompilerIntrinsicsLib/Arm/divdi3.S | 2 +- .../CompilerIntrinsicsLib/Arm/divsi3.S | 2 +- .../Library/CompilerIntrinsicsLib/Arm/lasr.S | 2 +- .../CompilerIntrinsicsLib/Arm/ldivmod.S | 2 +- .../Library/CompilerIntrinsicsLib/Arm/llsl.S | 2 +- .../Library/CompilerIntrinsicsLib/Arm/llsr.S | 2 +- .../CompilerIntrinsicsLib/Arm/lshrdi3.S | 2 +- .../CompilerIntrinsicsLib/Arm/memmove.S | 2 +- .../CompilerIntrinsicsLib/Arm/moddi3.S | 2 +- .../CompilerIntrinsicsLib/Arm/modsi3.S | 2 +- .../CompilerIntrinsicsLib/Arm/muldi3.S | 2 +- .../CompilerIntrinsicsLib/Arm/switch16.S | 2 +- .../CompilerIntrinsicsLib/Arm/switch32.S | 2 +- .../CompilerIntrinsicsLib/Arm/switch8.S | 2 +- .../CompilerIntrinsicsLib/Arm/switchu8.S | 2 +- .../CompilerIntrinsicsLib/Arm/ucmpdi2.S | 2 +- .../CompilerIntrinsicsLib/Arm/udivdi3.S | 2 +- .../CompilerIntrinsicsLib/Arm/udivmoddi4.S | 2 +- .../CompilerIntrinsicsLib/Arm/udivsi3.S | 2 +- .../CompilerIntrinsicsLib/Arm/umoddi3.S | 2 +- .../CompilerIntrinsicsLib/Arm/umodsi3.S | 2 +- .../Library/CompilerIntrinsicsLib/Arm/uread.S | 2 +- .../CompilerIntrinsicsLib/Arm/uwrite.S | 2 +- .../Library/SemihostLib/AArch64/GccSemihost.S | 2 +- ArmPkg/Library/SemihostLib/Arm/GccSemihost.S | 2 +- .../AArch64/ArmPlatformHelper.S | 2 +- .../Arm/ArmPlatformHelper.S | 2 +- .../PeilessSec/AArch64/ModuleEntryPoint.S | 2 +- .../PeilessSec/Arm/ModuleEntryPoint.S | 2 +- ArmPlatformPkg/Sec/AArch64/Exception.S | 2 +- ArmPlatformPkg/Sec/AArch64/Helper.S | 2 +- ArmPlatformPkg/Sec/AArch64/ModuleEntryPoint.S | 2 +- ArmPlatformPkg/Sec/AArch64/SwitchStack.S | 2 +- ArmPlatformPkg/Sec/Arm/Exception.S | 2 +- ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S | 2 +- ArmPlatformPkg/Sec/Arm/SwitchStack.S | 2 +- .../AArch64/ArmPlatformHelper.S | 2 +- ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S | 2 +- ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S | 2 +- .../Include/AArch64/AsmMacroLib.h | 0 .../Include/Arm/AsmMacroLib.h | 0 68 files changed, 65 insertions(+), 98 deletions(-) delete mode 100644 ArmPkg/Include/AsmMacroIoLib.inc rename ArmPkg/Include/AsmMacroIoLibV8.h => MdePkg/Include/AArch64/AsmMacroLib.h (100%) rename ArmPkg/Include/AsmMacroIoLib.h => MdePkg/Include/Arm/AsmMacroLib.h (100%) diff --git a/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S b/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S index 7316502d2351..504f026a1d00 100644 --- a/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S +++ b/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S @@ -5,7 +5,7 @@ # # -#include +#include #if !defined(__clang__) diff --git a/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S b/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S index 8c43a613dc57..33c0a5846414 100644 --- a/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S +++ b/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S @@ -5,7 +5,7 @@ # # -#include +#include #include // For the moment we assume this will run in SVC mode on ARMv7 diff --git a/ArmPkg/Drivers/ArmPsciMpServicesDxe/MpFuncs.S b/ArmPkg/Drivers/ArmPsciMpServicesDxe/MpFuncs.S index f73edc1792d0..7a52a406e7bb 100644 --- a/ArmPkg/Drivers/ArmPsciMpServicesDxe/MpFuncs.S +++ b/ArmPkg/Drivers/ArmPsciMpServicesDxe/MpFuncs.S @@ -7,7 +7,7 @@ .text .align 3 -#include +#include #include #include diff --git a/ArmPkg/Include/AsmMacroIoLib.inc b/ArmPkg/Include/AsmMacroIoLib.inc deleted file mode 100644 index 66b8d3d33bca..000000000000 --- a/ArmPkg/Include/AsmMacroIoLib.inc +++ /dev/null @@ -1,33 +0,0 @@ -;%HEADER% -;/** @file -; Macros to work around lack of Apple support for LDR register, =expr -; -; Copyright (c) 2009, Apple Inc. All rights reserved.
-; Copyright (c) 2011-2012, ARM Ltd. All rights reserved.
-; -; SPDX-License-Identifier: BSD-2-Clause-Patent -; -;**/ - - - MACRO - adrll $Reg, $Symbol - add $Reg, pc, #-8 - RELOC R_ARM_ALU_PC_G0_NC, $Symbol - add $Reg, $Reg, #-4 - RELOC R_ARM_ALU_PC_G1_NC, $Symbol - add $Reg, $Reg, #0 - RELOC R_ARM_ALU_PC_G2, $Symbol - MEND - - MACRO - ldrl $Reg, $Symbol - add $Reg, pc, #-8 - RELOC R_ARM_ALU_PC_G0_NC, $Symbol - add $Reg, $Reg, #-4 - RELOC R_ARM_ALU_PC_G1_NC, $Symbol - ldr $Reg, [$Reg, #0] - RELOC R_ARM_LDR_PC_G2, $Symbol - MEND - - END diff --git a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S index de9d3316de92..5dc6899773ef 100644 --- a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S @@ -9,7 +9,7 @@ #include #include -#include +#include #include // for exception type definitions /* diff --git a/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S b/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S index 39d956a02261..57c2d7588554 100644 --- a/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S +++ b/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S @@ -6,7 +6,7 @@ // // -#include +#include ASM_FUNC(ArmCallHvc) // Push x0 on the stack - The stack must always be quad-word aligned diff --git a/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S index 0a5a959196bc..9676529c1763 100644 --- a/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S +++ b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S @@ -6,7 +6,7 @@ // // -#include +#include .arch_extension virt diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S b/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S index 574e0d593320..be6f073c4894 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S @@ -7,7 +7,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(ArmReadCntFrq) mrs x0, cntfrq_el0 // Read CNTFRQ diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S index 1ec868ee1243..19c77d31b5e0 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S @@ -10,7 +10,7 @@ #------------------------------------------------------------------------------ #include -#include +#include .set CTRL_M_BIT, (1 << 0) .set CTRL_A_BIT, (1 << 1) diff --git a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S index ec34200d4dba..d35730704d42 100644 --- a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S +++ b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S @@ -8,7 +8,7 @@ # #------------------------------------------------------------------------------ -#include +#include .set DAIF_RD_FIQ_BIT, (1 << 6) .set DAIF_RD_IRQ_BIT, (1 << 7) diff --git a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S index 0ae75e4cb9f9..145980566421 100644 --- a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S +++ b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S @@ -8,7 +8,7 @@ # #------------------------------------------------------------------------------ -#include +#include .set MPIDR_U_BIT, (30) .set MPIDR_U_MASK, (1 << MPIDR_U_BIT) diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S b/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S index 7e032dd07c13..86635cc093ee 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S +++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S @@ -8,7 +8,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(ArmReadMidr) mrc p15,0,R0,c0,c0,0 diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S index d843f91dfca8..d207876a2198 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S +++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S @@ -8,7 +8,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(ArmIsMpCore) mrc p15,0,R0,c0,c0,5 diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.S b/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.S index 7abaa79639ff..2ad9b480d195 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.S +++ b/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.S @@ -7,7 +7,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(ArmReadCntFrq) mrc p15, 0, r0, c14, c0, 0 @ Read CNTFRQ diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S b/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S index 1f396adffc11..70b27da70c65 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S +++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S @@ -8,7 +8,7 @@ # #------------------------------------------------------------------------------ -#include +#include .set DC_ON, (0x1<<2) .set IC_ON, (0x1<<12) diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S index 0332cf7ce15c..97204141541c 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include .set CTRL_M_BIT, (1 << 0) diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibV7Support.S b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibV7Support.S index a97e3fabb22d..05f553aba6ff 100644 --- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibV7Support.S +++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibV7Support.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include .text .align 2 diff --git a/ArmPkg/Library/ArmMonitorLib/AArch64/ArmMonitorLib.S b/ArmPkg/Library/ArmMonitorLib/AArch64/ArmMonitorLib.S index a99adf00ade0..6ca1be5ba8d8 100644 --- a/ArmPkg/Library/ArmMonitorLib/AArch64/ArmMonitorLib.S +++ b/ArmPkg/Library/ArmMonitorLib/AArch64/ArmMonitorLib.S @@ -5,7 +5,7 @@ // // -#include +#include /** Monitor call. diff --git a/ArmPkg/Library/ArmMonitorLib/Arm/ArmMonitorLib.S b/ArmPkg/Library/ArmMonitorLib/Arm/ArmMonitorLib.S index 9029059cf4a4..f3605cb8d93c 100644 --- a/ArmPkg/Library/ArmMonitorLib/Arm/ArmMonitorLib.S +++ b/ArmPkg/Library/ArmMonitorLib/Arm/ArmMonitorLib.S @@ -5,7 +5,7 @@ // // -#include +#include /** Monitor call. diff --git a/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S b/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S index 4a8c2a8f59ea..a4443a41fe6c 100644 --- a/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S +++ b/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S @@ -5,7 +5,7 @@ // // -#include +#include ASM_FUNC(ArmCallSmc) // Push x0 on the stack - The stack must always be quad-word aligned diff --git a/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S b/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S index d218e7e70952..4b3d0db69715 100644 --- a/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S +++ b/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S @@ -5,7 +5,7 @@ // // -#include +#include .arch_extension sec diff --git a/ArmPkg/Library/ArmSvcLib/AArch64/ArmSvc.S b/ArmPkg/Library/ArmSvcLib/AArch64/ArmSvc.S index bdba9d7fe941..6bcb10e88ad7 100644 --- a/ArmPkg/Library/ArmSvcLib/AArch64/ArmSvc.S +++ b/ArmPkg/Library/ArmSvcLib/AArch64/ArmSvc.S @@ -5,7 +5,7 @@ // // -#include +#include .text .align 3 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S b/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S index c2e20069b4e2..77348a0cff7a 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__ashlti3) # return if shift is 0 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S index dee659b66320..f5f14509c5e9 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__ashldi3) cmp r2, #31 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S index d60c1c64fe36..855497e7d1e4 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__ashrdi3) cmp r2, #31 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S index 493392a9f9e2..54a7f3cd8350 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__clzsi2) @ frame_needed = 1, uses_anonymous_args = 0 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S index 5b21ec749e4c..d1ff500d5dc5 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__ctzsi2) uxth r3, r0 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S index f809a7dfeff9..c1c3c77b25dc 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__divdi3) @ args = 0, pretend = 0, frame = 0 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S index 45c0fcc3f759..eb4c30f6a220 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__divsi3) eor r3, r0, r0, asr #31 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.S index feeea9edd12a..27201de4bef8 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include # #UINT64 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S index 9f4dddad798d..15c99c5099e8 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S @@ -6,7 +6,7 @@ // //------------------------------------------------------------------------------ -#include +#include // // A pair of (unsigned) long longs is returned in {{r0, r1}, {r2, r3}}, diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S index cc63a15b3cf6..d0a4acd8bda4 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include # #VOID diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S index 246d5651e8d9..af6fd27028d1 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include #VOID #EFIAPI diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S index 829d8deb07b6..288573c855d3 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__lshrdi3) cmp r2, #31 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S index f9f1932c6dea..d8588d3d98eb 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include # VOID # EFIAPI diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S index faf077dc6bd6..e208f8fd2837 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__moddi3) stmfd sp!, {r4, r5, r7, lr} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S index b3299851bd8b..d67f88f717a7 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__modsi3) stmfd sp!, {r4, r5, r7, lr} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S index adee64782e56..6fdc527ecce5 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__muldi3) stmfd sp!, {r4, r5, r6, r7, lr} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S index e6d55673cb69..32870878b32a 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S @@ -7,7 +7,7 @@ #**/ # -#include +#include .syntax unified diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S index fbf72dd5f10b..040d65d6dc27 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S @@ -7,7 +7,7 @@ #**/ # -#include +#include .syntax unified diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S index aea048f4fba2..08fec9a8a0f2 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S @@ -7,7 +7,7 @@ #**/ # -#include +#include .syntax unified diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S index 22aeacdecaaf..a94b368ef911 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S @@ -7,7 +7,7 @@ #**/ # -#include +#include .syntax unified diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S index 681e3cf6e9c5..8d199fb0e288 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__ucmpdi2) stmfd sp!, {r4, r5, r8, lr} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S index 505ae545f10a..ccb6f6c6c0f9 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__udivdi3) stmfd sp!, {r7, lr} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S index a74db6fad193..edee8fc33687 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include .syntax unified diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S index e1f7da782af6..100a6a00d899 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include .syntax unified diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S index 3f26e2c5c81b..b22a785e0823 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__umoddi3) stmfd sp!, {r7, lr} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S index b48b25b7dce5..ee548afe17da 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(__umodsi3) stmfd sp!, {r4, r5, r7, lr} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.S index e8a1dbad8692..132975c6a146 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include # #UINT32 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.S index 9432ac431799..2c56ba3e063b 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.S +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include # #UINT32 diff --git a/ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S b/ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S index a44307563933..10ecbcade62e 100644 --- a/ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S +++ b/ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S @@ -7,7 +7,7 @@ # #------------------------------------------------------------------------------ -#include +#include ASM_FUNC(GccSemihostCall) hlt #0xf000 diff --git a/ArmPkg/Library/SemihostLib/Arm/GccSemihost.S b/ArmPkg/Library/SemihostLib/Arm/GccSemihost.S index d6f81ec2c957..da02a1f1cf0b 100644 --- a/ArmPkg/Library/SemihostLib/Arm/GccSemihost.S +++ b/ArmPkg/Library/SemihostLib/Arm/GccSemihost.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include /* Semihosting operation request mechanism diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S b/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S index 1eeb7fed6f19..873729343cfa 100644 --- a/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S +++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S @@ -5,7 +5,7 @@ // // -#include +#include #include ASM_FUNC(ArmPlatformPeiBootAction) diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/Arm/ArmPlatformHelper.S b/ArmPlatformPkg/Library/ArmPlatformLibNull/Arm/ArmPlatformHelper.S index 342d6d5e0a9d..0e11c34af5d1 100644 --- a/ArmPlatformPkg/Library/ArmPlatformLibNull/Arm/ArmPlatformHelper.S +++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/Arm/ArmPlatformHelper.S @@ -5,7 +5,7 @@ // // -#include +#include #include ASM_FUNC(ArmPlatformPeiBootAction) diff --git a/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S index efb6c5ade946..7263ee9374d1 100644 --- a/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S +++ b/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S @@ -5,7 +5,7 @@ // // -#include +#include ASM_FUNC(_ModuleEntryPoint) // Do early platform specific actions diff --git a/ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S b/ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S index ab5b023fa974..fc28939afe48 100644 --- a/ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S +++ b/ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S @@ -5,7 +5,7 @@ // // -#include +#include #include diff --git a/ArmPlatformPkg/Sec/AArch64/Exception.S b/ArmPlatformPkg/Sec/AArch64/Exception.S index d0d6bc44f78c..433761e3eb72 100644 --- a/ArmPlatformPkg/Sec/AArch64/Exception.S +++ b/ArmPlatformPkg/Sec/AArch64/Exception.S @@ -6,7 +6,7 @@ # #include -#include +#include #include #include diff --git a/ArmPlatformPkg/Sec/AArch64/Helper.S b/ArmPlatformPkg/Sec/AArch64/Helper.S index 9b81b96a4949..c784c4a1cd45 100644 --- a/ArmPlatformPkg/Sec/AArch64/Helper.S +++ b/ArmPlatformPkg/Sec/AArch64/Helper.S @@ -5,7 +5,7 @@ # #======================================================================================= -#include +#include #include // Setup EL1 while in EL1 diff --git a/ArmPlatformPkg/Sec/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/Sec/AArch64/ModuleEntryPoint.S index 7addae6cffd3..154be1111d09 100644 --- a/ArmPlatformPkg/Sec/AArch64/ModuleEntryPoint.S +++ b/ArmPlatformPkg/Sec/AArch64/ModuleEntryPoint.S @@ -5,7 +5,7 @@ // // -#include +#include ASM_FUNC(_ModuleEntryPoint) // Do early platform specific actions diff --git a/ArmPlatformPkg/Sec/AArch64/SwitchStack.S b/ArmPlatformPkg/Sec/AArch64/SwitchStack.S index 308b8764fc69..707404043578 100644 --- a/ArmPlatformPkg/Sec/AArch64/SwitchStack.S +++ b/ArmPlatformPkg/Sec/AArch64/SwitchStack.S @@ -8,7 +8,7 @@ # #------------------------------------------------------------------------------ -#include +#include #/** # This allows the caller to switch the stack and return diff --git a/ArmPlatformPkg/Sec/Arm/Exception.S b/ArmPlatformPkg/Sec/Arm/Exception.S index 956ae8471459..364b51260424 100644 --- a/ArmPlatformPkg/Sec/Arm/Exception.S +++ b/ArmPlatformPkg/Sec/Arm/Exception.S @@ -5,7 +5,7 @@ # # -#include +#include #include #include diff --git a/ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S b/ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S index b3c67234e9c9..1207497dc709 100644 --- a/ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S +++ b/ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S @@ -5,7 +5,7 @@ // // -#include +#include ASM_FUNC(_ModuleEntryPoint) // Do early platform specific actions diff --git a/ArmPlatformPkg/Sec/Arm/SwitchStack.S b/ArmPlatformPkg/Sec/Arm/SwitchStack.S index d64772b8edbf..028ee26e89e4 100644 --- a/ArmPlatformPkg/Sec/Arm/SwitchStack.S +++ b/ArmPlatformPkg/Sec/Arm/SwitchStack.S @@ -6,7 +6,7 @@ # #------------------------------------------------------------------------------ -#include +#include #/** # This allows the caller to switch the stack and return diff --git a/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S b/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S index bdb460c7ee7b..f20395c38b7d 100644 --- a/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S +++ b/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S @@ -5,7 +5,7 @@ // // -#include +#include .macro mov_i, reg:req, imm:req movz \reg, :abs_g1:\imm diff --git a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S index fc06c28daaf4..06a0020f250c 100644 --- a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S +++ b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S @@ -6,7 +6,7 @@ // // -#include +#include ASM_FUNC(_ModuleEntryPoint) // diff --git a/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S index f0536c65eb52..cfb5de864fb9 100644 --- a/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S +++ b/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S @@ -6,7 +6,7 @@ // // -#include +#include ASM_FUNC(_ModuleEntryPoint) // Do early platform specific actions diff --git a/ArmPkg/Include/AsmMacroIoLibV8.h b/MdePkg/Include/AArch64/AsmMacroLib.h similarity index 100% rename from ArmPkg/Include/AsmMacroIoLibV8.h rename to MdePkg/Include/AArch64/AsmMacroLib.h diff --git a/ArmPkg/Include/AsmMacroIoLib.h b/MdePkg/Include/Arm/AsmMacroLib.h similarity index 100% rename from ArmPkg/Include/AsmMacroIoLib.h rename to MdePkg/Include/Arm/AsmMacroLib.h From 8f74b95a21cf106fa4eb4932e22b404c57297ba2 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Mon, 5 Aug 2024 10:25:07 -0700 Subject: [PATCH 232/280] MdePkg: Move CompilerIntrinsicsLib from ArmPkg As per the emailed RFC in https://edk2.groups.io/g/devel/topic/rfc_move/107675828, this patch moves CompilerIntrinsicsLib from ArmPkg to MdePkg as this library provides compiler intrinsics, which are industry standard. This aligns with the goal of integrating ArmPkg into existing packages: https://bugzilla.tianocore.org/show_bug.cgi?id=4121. The newly placed CompilerIntrinsicsLib is added to MdeLibs.dsc.inc as every DSC that builds ARM/AARCH64 needs this library added. The old location is removed from every DSC in edk2 in this commit also to not break bisectability with minimal hoop jumping. Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Oliver Smith-Denny --- ArmPkg/ArmPkg.dsc | 3 --- ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc | 1 - ArmPlatformPkg/ArmPlatformPkg.dsc | 1 - ArmVirtPkg/ArmVirt.dsc.inc | 6 ------ CryptoPkg/CryptoPkg.dsc | 7 ------- CryptoPkg/CryptoPkgMbedTls.dsc | 8 -------- DynamicTablesPkg/DynamicTablesPkg.dsc | 1 - EmbeddedPkg/EmbeddedPkg.dsc | 1 - FatPkg/FatPkg.dsc | 1 - FmpDevicePkg/FmpDevicePkg.dsc | 8 -------- MdeModulePkg/MdeModulePkg.dsc | 7 ------- .../Library/CompilerIntrinsicsLib/AArch64/Atomics.S | 0 .../Library/CompilerIntrinsicsLib/AArch64/ashlti3.S | 0 .../Library/CompilerIntrinsicsLib/Arm/ashldi3.S | 0 .../Library/CompilerIntrinsicsLib/Arm/ashrdi3.S | 0 .../Library/CompilerIntrinsicsLib/Arm/clzsi2.S | 0 .../Library/CompilerIntrinsicsLib/Arm/ctzsi2.S | 0 .../Library/CompilerIntrinsicsLib/Arm/div.S | 0 .../Library/CompilerIntrinsicsLib/Arm/div.asm | 0 .../Library/CompilerIntrinsicsLib/Arm/divdi3.S | 0 .../Library/CompilerIntrinsicsLib/Arm/divsi3.S | 0 .../Library/CompilerIntrinsicsLib/Arm/lasr.S | 0 .../Library/CompilerIntrinsicsLib/Arm/ldivmod.S | 0 .../Library/CompilerIntrinsicsLib/Arm/ldivmod.asm | 0 .../Library/CompilerIntrinsicsLib/Arm/llsl.S | 0 .../Library/CompilerIntrinsicsLib/Arm/llsr.S | 0 .../Library/CompilerIntrinsicsLib/Arm/llsr.asm | 0 .../Library/CompilerIntrinsicsLib/Arm/lshrdi3.S | 0 .../Library/CompilerIntrinsicsLib/Arm/memmove.S | 0 .../Library/CompilerIntrinsicsLib/Arm/moddi3.S | 0 .../Library/CompilerIntrinsicsLib/Arm/modsi3.S | 0 .../Library/CompilerIntrinsicsLib/Arm/muldi3.S | 0 .../Library/CompilerIntrinsicsLib/Arm/mullu.S | 0 .../Library/CompilerIntrinsicsLib/Arm/sourcery.S | 0 .../Library/CompilerIntrinsicsLib/Arm/switch16.S | 0 .../Library/CompilerIntrinsicsLib/Arm/switch32.S | 0 .../Library/CompilerIntrinsicsLib/Arm/switch8.S | 0 .../Library/CompilerIntrinsicsLib/Arm/switchu8.S | 0 .../Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S | 0 .../Library/CompilerIntrinsicsLib/Arm/udivdi3.S | 0 .../Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S | 0 .../Library/CompilerIntrinsicsLib/Arm/udivsi3.S | 0 .../Library/CompilerIntrinsicsLib/Arm/uldiv.S | 0 .../Library/CompilerIntrinsicsLib/Arm/uldiv.asm | 0 .../Library/CompilerIntrinsicsLib/Arm/umoddi3.S | 0 .../Library/CompilerIntrinsicsLib/Arm/umodsi3.S | 0 .../Library/CompilerIntrinsicsLib/Arm/uread.S | 0 .../Library/CompilerIntrinsicsLib/Arm/uwrite.S | 0 .../CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf | 5 ++--- .../Library/CompilerIntrinsicsLib/memcmp_ms.c | 0 .../Library/CompilerIntrinsicsLib/memcpy.c | 0 .../Library/CompilerIntrinsicsLib/memcpy_ms.c | 0 .../Library/CompilerIntrinsicsLib/memmove_ms.c | 0 .../Library/CompilerIntrinsicsLib/memset.c | 0 .../Library/CompilerIntrinsicsLib/memset_ms.c | 0 MdePkg/MdeLibs.dsc.inc | 10 ++++++++++ MdePkg/MdePkg.dsc | 1 + NetworkPkg/NetworkPkg.dsc | 6 ------ NetworkPkg/Test/NetworkPkgHostTest.dsc | 12 ++++-------- PrmPkg/PrmPkg.ci.yaml | 1 - PrmPkg/PrmPkg.dsc | 5 ++--- RedfishPkg/RedfishPkg.dsc | 1 - SecurityPkg/SecurityPkg.dsc | 7 ------- ShellPkg/ShellPkg.dsc | 7 ------- SignedCapsulePkg/SignedCapsulePkg.dsc | 7 ------- StandaloneMmPkg/StandaloneMmPkg.dsc | 1 - .../UnitTestFrameworkPkgTarget.dsc.inc | 7 ------- 67 files changed, 19 insertions(+), 95 deletions(-) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/AArch64/Atomics.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/ashldi3.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/clzsi2.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/div.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/div.asm (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/divdi3.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/divsi3.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/lasr.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/ldivmod.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/llsl.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/llsr.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/llsr.asm (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/memmove.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/moddi3.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/modsi3.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/muldi3.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/mullu.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/sourcery.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/switch16.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/switch32.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/switch8.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/switchu8.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/udivdi3.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/udivsi3.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/uldiv.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/uldiv.asm (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/umoddi3.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/umodsi3.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/uread.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/Arm/uwrite.S (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf (89%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/memcmp_ms.c (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/memcpy.c (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/memcpy_ms.c (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/memmove_ms.c (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/memset.c (100%) rename {ArmPkg => MdePkg}/Library/CompilerIntrinsicsLib/memset_ms.c (100%) diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 910e8589c41c..657e2bc5d5c0 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -101,8 +101,6 @@ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf [LibraryClasses.ARM, LibraryClasses.AARCH64] - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf - # Add support for GCC stack protector NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf @@ -110,7 +108,6 @@ ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf - ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf diff --git a/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc b/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc index 2818ce65db98..4ab7737c83eb 100644 --- a/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc +++ b/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc @@ -43,7 +43,6 @@ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf [Components.common] diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc index 919e4cf80a3a..396d7df1cc58 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg.dsc @@ -73,7 +73,6 @@ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf [LibraryClasses.common.PEIM] diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 04394553044b..35a5a1420a58 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -88,12 +88,6 @@ # Networking Requirements !include NetworkPkg/NetworkLibs.dsc.inc - # - # It is not possible to prevent the ARM compiler from inserting calls to intrinsic functions. - # This library provides the instrinsic functions such a compiler may generate calls to. - # - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf - # Add support for GCC stack protector NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc index f08808d5d18e..344f158a768e 100644 --- a/CryptoPkg/CryptoPkg.dsc +++ b/CryptoPkg/CryptoPkg.dsc @@ -117,13 +117,6 @@ [LibraryClasses.ARM, LibraryClasses.AARCH64] ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf - # - # It is not possible to prevent the ARM compiler for generic intrinsic functions. - # This library provides the instrinsic functions generate by a given compiler. - # [LibraryClasses.ARM, LibraryClasses.AARCH64] and NULL mean link this library - # into all ARM and AARCH64 images. - # - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf # Add support for stack protector NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf diff --git a/CryptoPkg/CryptoPkgMbedTls.dsc b/CryptoPkg/CryptoPkgMbedTls.dsc index c97b28c0b5dd..a429606efe35 100644 --- a/CryptoPkg/CryptoPkgMbedTls.dsc +++ b/CryptoPkg/CryptoPkgMbedTls.dsc @@ -52,14 +52,6 @@ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf [LibraryClasses.ARM, LibraryClasses.AARCH64] - # - # It is not possible to prevent the ARM compiler for generic intrinsic functions. - # This library provides the instrinsic functions generate by a given compiler. - # [LibraryClasses.ARM, LibraryClasses.AARCH64] and NULL mean link this library - # into all ARM and AARCH64 images. - # - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf - # Add support for stack protector NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf diff --git a/DynamicTablesPkg/DynamicTablesPkg.dsc b/DynamicTablesPkg/DynamicTablesPkg.dsc index cf06f0731a23..e4302f6b32dc 100644 --- a/DynamicTablesPkg/DynamicTablesPkg.dsc +++ b/DynamicTablesPkg/DynamicTablesPkg.dsc @@ -35,7 +35,6 @@ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf [LibraryClasses.ARM, LibraryClasses.AARCH64] - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc index 67034dd7dc9e..4b8a943839ee 100644 --- a/EmbeddedPkg/EmbeddedPkg.dsc +++ b/EmbeddedPkg/EmbeddedPkg.dsc @@ -127,7 +127,6 @@ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf # Add support for GCC stack protector NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf diff --git a/FatPkg/FatPkg.dsc b/FatPkg/FatPkg.dsc index 076b57797220..b97fe9a3dede 100644 --- a/FatPkg/FatPkg.dsc +++ b/FatPkg/FatPkg.dsc @@ -57,7 +57,6 @@ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf [LibraryClasses.ARM, LibraryClasses.AARCH64] - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf ################################################################################################### diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc index f9f26c54bb79..8d2b490503a0 100644 --- a/FmpDevicePkg/FmpDevicePkg.dsc +++ b/FmpDevicePkg/FmpDevicePkg.dsc @@ -73,14 +73,6 @@ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf [LibraryClasses.ARM, LibraryClasses.AARCH64] - # - # It is not possible to prevent the ARM compiler for generic intrinsic functions. - # This library provides the intrinsic functions generate by a given compiler. - # [LibraryClasses.ARM, LibraryClasses.AARCH64] and NULL mean link this library - # into all ARM and AARCH64 images. - # - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf - # Add support for stack protector NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 8c864fe1838e..4317d09fff63 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -184,13 +184,6 @@ [LibraryClasses.ARM, LibraryClasses.AARCH64] LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf - # - # It is not possible to prevent ARM compiler calls to generic intrinsic functions. - # This library provides the instrinsic functions generated by a given compiler. - # [LibraryClasses.ARM] and NULL mean link this library into all ARM images. - # - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf - # # Since software stack checking may be heuristically enabled by the compiler # include BaseStackCheckLib unconditionally. diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S b/MdePkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S rename to MdePkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S b/MdePkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S rename to MdePkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/div.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/div.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm b/MdePkg/Library/CompilerIntrinsicsLib/Arm/div.asm similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/div.asm diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/lasr.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/lasr.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/llsl.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/llsl.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/llsr.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/llsr.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm b/MdePkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/memmove.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/memmove.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/mullu.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/mullu.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/switch16.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/switch16.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/switch32.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/switch32.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/switch8.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/switch8.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm b/MdePkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/uread.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/uread.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/uwrite.S similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.S rename to MdePkg/Library/CompilerIntrinsicsLib/Arm/uwrite.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf b/MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf similarity index 89% rename from ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf rename to MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf index 054e68130730..ac48b4624653 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf +++ b/MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf @@ -10,9 +10,9 @@ #**/ [Defines] - INF_VERSION = 0x00010005 + INF_VERSION = 1.29 BASE_NAME = CompilerIntrinsicsLib - FILE_GUID = 855274FA-3575-4C20-9709-C031DC5589FA + FILE_GUID = 2A6B451F-B99D-47B1-8F29-D805433C62E0 MODULE_TYPE = BASE VERSION_STRING = 1.0 LIBRARY_CLASS = CompilerIntrinsicsLib @@ -70,7 +70,6 @@ [Packages] MdePkg/MdePkg.dec - ArmPkg/ArmPkg.dec [BuildOptions] MSFT:*_*_*_CC_FLAGS = /GL- diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memcmp_ms.c b/MdePkg/Library/CompilerIntrinsicsLib/memcmp_ms.c similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/memcmp_ms.c rename to MdePkg/Library/CompilerIntrinsicsLib/memcmp_ms.c diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memcpy.c b/MdePkg/Library/CompilerIntrinsicsLib/memcpy.c similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/memcpy.c rename to MdePkg/Library/CompilerIntrinsicsLib/memcpy.c diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memcpy_ms.c b/MdePkg/Library/CompilerIntrinsicsLib/memcpy_ms.c similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/memcpy_ms.c rename to MdePkg/Library/CompilerIntrinsicsLib/memcpy_ms.c diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memmove_ms.c b/MdePkg/Library/CompilerIntrinsicsLib/memmove_ms.c similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/memmove_ms.c rename to MdePkg/Library/CompilerIntrinsicsLib/memmove_ms.c diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memset.c b/MdePkg/Library/CompilerIntrinsicsLib/memset.c similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/memset.c rename to MdePkg/Library/CompilerIntrinsicsLib/memset.c diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memset_ms.c b/MdePkg/Library/CompilerIntrinsicsLib/memset_ms.c similarity index 100% rename from ArmPkg/Library/CompilerIntrinsicsLib/memset_ms.c rename to MdePkg/Library/CompilerIntrinsicsLib/memset_ms.c diff --git a/MdePkg/MdeLibs.dsc.inc b/MdePkg/MdeLibs.dsc.inc index a8c8f4ef3639..e40ff7d95e04 100644 --- a/MdePkg/MdeLibs.dsc.inc +++ b/MdePkg/MdeLibs.dsc.inc @@ -20,3 +20,13 @@ SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf + +[LibraryClasses.ARM, LibraryClasses.AARCH64] + # + # It is not possible to prevent the ARM/AARCH64 compilers from inserting generic intrinsic functions. + # This library provides the intrinsic functions generated by these compilers. + # + # Linking this here as a null library will cause all ARM/AARCH64 files to link against it and have + # definitions for the intrinsic functions. + # + NULL|MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 109224c527f7..ebcd79864d4f 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -194,6 +194,7 @@ [Components.ARM, Components.AARCH64] MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf + MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf [Components.RISCV64] MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc index 808c6bffce2c..4c3737440da6 100644 --- a/NetworkPkg/NetworkPkg.dsc +++ b/NetworkPkg/NetworkPkg.dsc @@ -72,12 +72,6 @@ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf [LibraryClasses.ARM, LibraryClasses.AARCH64] - # - # It is not possible to prevent ARM compiler calls to generic intrinsic functions. - # This library provides the instrinsic functions generated by a given compiler. - # [LibraryClasses.ARM] and NULL mean link this library into all ARM images. - # - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc index 1772afb05815..a17a7d00216c 100644 --- a/NetworkPkg/Test/NetworkPkgHostTest.dsc +++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc @@ -83,21 +83,17 @@ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf + [LibraryClasses.common.UEFI_APPLICATION] DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf + [LibraryClasses.ARM, LibraryClasses.AARCH64] - # - # It is not possible to prevent ARM compiler calls to generic intrinsic functions. - # This library provides the instrinsic functions generated by a given compiler. - # [LibraryClasses.ARM] and NULL mean link this library into all ARM images. - # -!if $(TOOL_CHAIN_TAG) != VS2017 and $(TOOL_CHAIN_TAG) != VS2015 and $(TOOL_CHAIN_TAG) != VS2019 - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf -!endif NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf + [LibraryClasses.ARM] RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf + [LibraryClasses.RISCV64] RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf diff --git a/PrmPkg/PrmPkg.ci.yaml b/PrmPkg/PrmPkg.ci.yaml index b4b5aad67fbd..a55abd221662 100644 --- a/PrmPkg/PrmPkg.ci.yaml +++ b/PrmPkg/PrmPkg.ci.yaml @@ -49,7 +49,6 @@ ## options defined .pytool/Plugin/DependencyCheck "DependencyCheck": { "AcceptableDependencies": [ - "ArmPkg/ArmPkg.dec", "MdeModulePkg/MdeModulePkg.dec", "MdePkg/MdePkg.dec", "PrmPkg/PrmPkg.dec", diff --git a/PrmPkg/PrmPkg.dsc b/PrmPkg/PrmPkg.dsc index 677100504584..3e9126c32115 100644 --- a/PrmPkg/PrmPkg.dsc +++ b/PrmPkg/PrmPkg.dsc @@ -18,6 +18,8 @@ DEFINE PLATFORM_PACKAGE = $(PLATFORM_NAME)Pkg +!include MdePkg/MdeLibs.dsc.inc + [LibraryClasses.common] # # EDK II Packages @@ -42,7 +44,6 @@ MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf [LibraryClasses.AARCH64] - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf [LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.UEFI_APPLICATION] @@ -149,8 +150,6 @@ $(PLATFORM_PACKAGE)/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf [Components.AARCH64] - ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf - # Add support for GCC stack protector MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc index b0150043a9c6..b4c025831471 100644 --- a/RedfishPkg/RedfishPkg.dsc +++ b/RedfishPkg/RedfishPkg.dsc @@ -56,7 +56,6 @@ # # This library provides the instrinsic functions generated by a given compiler. # - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index 70981da36109..bc991410a1f9 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -90,13 +90,6 @@ MemLibWrapper|SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.inf [LibraryClasses.ARM, LibraryClasses.AARCH64] - # - # It is not possible to prevent the ARM compiler for generic intrinsic functions. - # This library provides the intrinsic functions generate by a given compiler. - # And NULL mean link this library into all ARM images. - # - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf - # Add support for GCC stack protector NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf diff --git a/ShellPkg/ShellPkg.dsc b/ShellPkg/ShellPkg.dsc index 720288e2f55c..a8ae1deaae14 100644 --- a/ShellPkg/ShellPkg.dsc +++ b/ShellPkg/ShellPkg.dsc @@ -66,13 +66,6 @@ ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf [LibraryClasses.ARM,LibraryClasses.AARCH64] - # - # It is not possible to prevent the ARM compiler for generic intrinsic functions. - # This library provides the instrinsic functions generate by a given compiler. - # [LibraryClasses.ARM] and NULL mean link this library into all ARM images. - # - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf - # Add support for GCC stack protector NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf diff --git a/SignedCapsulePkg/SignedCapsulePkg.dsc b/SignedCapsulePkg/SignedCapsulePkg.dsc index 4c656666e981..e3e62d03f6a4 100644 --- a/SignedCapsulePkg/SignedCapsulePkg.dsc +++ b/SignedCapsulePkg/SignedCapsulePkg.dsc @@ -99,13 +99,6 @@ ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf [LibraryClasses.AARCH64, LibraryClasses.ARM] - # - # It is not possible to prevent the ARM compiler for generic intrinsic functions. - # This library provides the instrinsic functions generate by a given compiler. - # And NULL mean link this library into all ARM images. - # - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf - # Add support for GCC stack protector NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc index 02ab3d749e40..34a7e55cbc79 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -79,7 +79,6 @@ CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf PeCoffExtraActionLib|StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf [LibraryClasses.common.MM_CORE_STANDALONE] diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc index 1a059ed4aad2..06c40f24f2ad 100644 --- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc +++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc @@ -46,13 +46,6 @@ NULL|UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf [LibraryClasses.ARM, LibraryClasses.AARCH64] - # - # It is not possible to prevent ARM compiler calls to generic intrinsic functions. - # This library provides the instrinsic functions generated by a given compiler. - # [LibraryClasses.ARM] and NULL mean link this library into all ARM images. - # - NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf - # # Since software stack checking may be heuristically enabled by the compiler # include BaseStackCheckLib unconditionally. From af60615f0ef5f5d5ab3f9cea3215e07b8c73b600 Mon Sep 17 00:00:00 2001 From: Mike Beaton Date: Sat, 24 Aug 2024 09:13:37 +0100 Subject: [PATCH 233/280] NetworkPkg: Fix unable to build OVMF with -D NETWORK_ENABLE=0 https://bugzilla.tianocore.org/show_bug.cgi?id=4829 7f17a15 (2024/02/22) "OvmfPkg: Shell*.inc: allow building without network support" breaks building OVMF with `-D NETWORK_ENABLE=0`. Before this commit we could build OVMF e.g. with the following command in the OvmfPkg directory: ./build.sh -D NETWORK_ENABLE=0 After the commit the same command fails early with: /home/user/OpenSource/edk2/OvmfPkg/OvmfPkgX64.dsc(15): error F001: Pcd (gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections) defined in DSC is not declared in DEC files referenced in INF files in FDF. Arch: ['X64'] This commit conditionally removes the undefined Pcd reference in NetworkPkg which is part of this issue. Similar changes are needed in separate commits for OvmfPkg (and for ArmVirtPkg, since the issue also exists there, although masked by another issue). Signed-off-by: Mike Beaton --- NetworkPkg/NetworkPcds.dsc.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NetworkPkg/NetworkPcds.dsc.inc b/NetworkPkg/NetworkPcds.dsc.inc index f874b382efc3..c6299ad6ed0f 100644 --- a/NetworkPkg/NetworkPcds.dsc.inc +++ b/NetworkPkg/NetworkPcds.dsc.inc @@ -11,6 +11,6 @@ # ## -!if $(NETWORK_ALLOW_HTTP_CONNECTIONS) == TRUE +!if ($(NETWORK_ENABLE) == TRUE) AND ($(NETWORK_ALLOW_HTTP_CONNECTIONS) == TRUE) gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections|TRUE !endif From 14d7ae94bc1d3367703a674b862748cb117b71c8 Mon Sep 17 00:00:00 2001 From: Mike Beaton Date: Sat, 24 Aug 2024 09:18:10 +0100 Subject: [PATCH 234/280] OvmfPkg: Fix unable to build OVMF with -D NETWORK_ENABLE=0 https://bugzilla.tianocore.org/show_bug.cgi?id=4829 7f17a15 (2024/02/22) "OvmfPkg: Shell*.inc: allow building without network support" breaks building OVMF with `-D NETWORK_ENABLE=0`. Before this commit we could build OVMF e.g. with the following command in the OvmfPkg directory: ./build.sh -D NETWORK_ENABLE=0 After the commit the same command fails early with: /home/user/OpenSource/edk2/OvmfPkg/OvmfPkgX64.dsc(15): error F001: Pcd (gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections) defined in DSC is not declared in DEC files referenced in INF files in FDF. Arch: ['X64'] The problem applies in Intel OvmfPkg platforms. Additionally, it applies in various other OvmfPkg platforms, but is masked buy another issue; namely that these platforms incorrectly still include some network packages when most are disabled. (A fix for that issue has previously been made, in OvmfPkg Intel platforms only, by d933ec1 followed by 7f17a15 .) This commit conditionally removes the undefined Pcd references in all OvmfPkg platforms which are now affected by this issue, and in all those which would be affected as and when the other issue mentioned above is fixed. Signed-off-by: Mike Beaton --- OvmfPkg/CloudHv/CloudHvX64.dsc | 2 ++ OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc | 2 ++ OvmfPkg/Microvm/MicrovmX64.dsc | 2 ++ OvmfPkg/OvmfPkgIa32.dsc | 2 ++ OvmfPkg/OvmfPkgIa32X64.dsc | 2 ++ OvmfPkg/OvmfPkgX64.dsc | 2 ++ OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc | 2 ++ 7 files changed, 14 insertions(+) diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc index 0ad495545c8f..3dcefb189623 100644 --- a/OvmfPkg/CloudHv/CloudHvX64.dsc +++ b/OvmfPkg/CloudHv/CloudHvX64.dsc @@ -632,9 +632,11 @@ !include OvmfPkg/Include/Dsc/OvmfTpmPcds.dsc.inc +!if $(NETWORK_ENABLE) == TRUE # IPv4 and IPv6 PXE Boot support. gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01 gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01 +!endif # Set ConfidentialComputing defaults gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr|0 diff --git a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc index 29c945b0ee34..9064058bc510 100644 --- a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc +++ b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc @@ -417,8 +417,10 @@ # # IPv4 and IPv6 PXE Boot support. # +!if $(NETWORK_ENABLE) == TRUE gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport | 0x01 gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport | 0x01 +!endif # # SMBIOS entry point version diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc index 3b2312ddbcc7..1196ba98c90e 100644 --- a/OvmfPkg/Microvm/MicrovmX64.dsc +++ b/OvmfPkg/Microvm/MicrovmX64.dsc @@ -647,9 +647,11 @@ gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00 +!if $(NETWORK_ENABLE) == TRUE # IPv4 and IPv6 PXE Boot support. gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01 gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01 +!endif # Set ConfidentialComputing defaults gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr|0 diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 974ab6236211..3f68d4d63b72 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -658,9 +658,11 @@ !include OvmfPkg/Include/Dsc/OvmfTpmPcds.dsc.inc +!if $(NETWORK_ENABLE) == TRUE # IPv4 and IPv6 PXE Boot support. gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01 gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01 +!endif # Set ConfidentialComputing defaults gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr|0 diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index c0e3210a8340..67730b0f90b8 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -676,9 +676,11 @@ gEfiMdePkgTokenSpaceGuid.PcdFSBClock|1000000000 [PcdsDynamicDefault.X64] +!if $(NETWORK_ENABLE) == TRUE # IPv4 and IPv6 PXE Boot support. gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01 gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01 +!endif [PcdsDynamicHii] !include OvmfPkg/Include/Dsc/OvmfTpmPcdsHii.dsc.inc diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index efb0eedb0459..f4ff2e321a09 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -690,9 +690,11 @@ !include OvmfPkg/Include/Dsc/OvmfTpmPcds.dsc.inc +!if $(NETWORK_ENABLE) == TRUE # IPv4 and IPv6 PXE Boot support. gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01 gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01 +!endif # Set ConfidentialComputing defaults gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr|0 diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc index e0ed6fb9bcd8..63d896587b4a 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc +++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc @@ -217,11 +217,13 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0 +!if $(NETWORK_ENABLE) == TRUE # # IPv4 and IPv6 PXE Boot support. # gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01 gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01 +!endif # # TPM2 support From bb403511d412959aaa3733a8235257190d63b3ad Mon Sep 17 00:00:00 2001 From: Mike Beaton Date: Sat, 24 Aug 2024 09:25:09 +0100 Subject: [PATCH 235/280] ArmVirtPkg: Fix unable to build with -D NETWORK_ENABLE=0 https://bugzilla.tianocore.org/show_bug.cgi?id=4829 7f17a15 (2024/02/22) "OvmfPkg: Shell*.inc: allow building without network support" breaks building OVMF with `-D NETWORK_ENABLE=0`. Before this commit we could build OVMF e.g. with the following command in the OvmfPkg directory: ./build.sh -D NETWORK_ENABLE=0 After the commit the same command fails early with: /home/user/OpenSource/edk2/OvmfPkg/OvmfPkgX64.dsc(15): error F001: Pcd (gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections) defined in DSC is not declared in DEC files referenced in INF files in FDF. Arch: ['X64'] This problem also applies in the ArmVirtPkg platforms which are modified here, but is currently masked by another issue, namely that these platforms incorrectly still include some network packages when most are disabled. (A fix for this was previously applied, for OvmfPkg Intel platforms only, by d933ec1 followed by 7f17a15 .) This commit was created at the same time as the commits resolving this issue in NetworkPkg and OvmfPkg. It makes conditional the Pcd references in ArmVirtPkg platforms which will become references to undefined Pcds as and when the other issue mentioned above is fixed. Signed-off-by: Mike Beaton --- ArmVirtPkg/ArmVirtQemu.dsc | 2 ++ ArmVirtPkg/ArmVirtQemuKernel.dsc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 56512594ad59..6826edab93a3 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -299,11 +299,13 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0 gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE +!if $(NETWORK_ENABLE) == TRUE # # IPv4 and IPv6 PXE Boot support. # gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01 gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01 +!endif # # TPM2 support diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc index f4fb8ee69ee7..c5fdcfd9c72a 100644 --- a/ArmVirtPkg/ArmVirtQemuKernel.dsc +++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc @@ -260,11 +260,13 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0 gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE +!if $(NETWORK_ENABLE) == TRUE # # IPv4 and IPv6 PXE Boot support. # gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01 gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01 +!endif ################################################################################ # From bec02ea9de6ae8aec4a645b56424d7be999fe23f Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 12 Sep 2024 11:22:00 +0200 Subject: [PATCH 236/280] MdePkg/ArmLib: Drop routines that maintain the entire D-cache Cache maintenance on the D-cache hierarchy as a whole is not supported by the ARM architecture, so drop the routines from ArmLib that pretend to implement it. Signed-off-by: Ard Biesheuvel --- MdePkg/Include/Library/ArmLib.h | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/MdePkg/Include/Library/ArmLib.h b/MdePkg/Include/Library/ArmLib.h index 6a1503a7e5ba..087cddfb76c3 100644 --- a/MdePkg/Include/Library/ArmLib.h +++ b/MdePkg/Include/Library/ArmLib.h @@ -180,24 +180,6 @@ ArmIsMpCore ( VOID ); -VOID -EFIAPI -ArmInvalidateDataCache ( - VOID - ); - -VOID -EFIAPI -ArmCleanInvalidateDataCache ( - VOID - ); - -VOID -EFIAPI -ArmCleanDataCache ( - VOID - ); - VOID EFIAPI ArmInvalidateInstructionCache ( From 6706fe6e239253e45b28147e06f71dd68a374007 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 12 Sep 2024 10:36:29 +0200 Subject: [PATCH 237/280] ArmPkg/ArmLib: Drop set/way Dcache operations Cache maintenance operations by set/way are not broadcast, and operate on individual architected caches, making them suitable only for en/disabling cache levels, which is the job of secure firmware, to be carried out while the CPU in question is not taking part in the cache coherency protocol. Managing the clean/dirty state of a memory range can only be done using cache maintenance by virtual address. So drop the set/way handling from ArmLib for ARM and AARCH64, as there is no context where it can be used correctly from EDK2. Signed-off-by: Ard Biesheuvel --- ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c | 55 -------------- ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h | 27 ------- .../Library/ArmLib/AArch64/AArch64Support.S | 75 ------------------- ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c | 55 -------------- ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h | 27 ------- ArmPkg/Library/ArmLib/Arm/ArmV7Support.S | 67 ----------------- 6 files changed, 306 deletions(-) diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c index 6739f5c37d38..53b202ff34a8 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c @@ -18,61 +18,6 @@ #include "AArch64Lib.h" #include "ArmLibPrivate.h" -VOID -AArch64DataCacheOperation ( - IN AARCH64_CACHE_OPERATION DataCacheOperation - ) -{ - UINTN SavedInterruptState; - - SavedInterruptState = ArmGetInterruptState (); - ArmDisableInterrupts (); - - AArch64AllDataCachesOperation (DataCacheOperation); - - ArmDataSynchronizationBarrier (); - - if (SavedInterruptState) { - ArmEnableInterrupts (); - } -} - -VOID -EFIAPI -ArmInvalidateDataCache ( - VOID - ) -{ - ASSERT (!ArmMmuEnabled ()); - - ArmDataSynchronizationBarrier (); - AArch64DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay); -} - -VOID -EFIAPI -ArmCleanInvalidateDataCache ( - VOID - ) -{ - ASSERT (!ArmMmuEnabled ()); - - ArmDataSynchronizationBarrier (); - AArch64DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay); -} - -VOID -EFIAPI -ArmCleanDataCache ( - VOID - ) -{ - ASSERT (!ArmMmuEnabled ()); - - ArmDataSynchronizationBarrier (); - AArch64DataCacheOperation (ArmCleanDataCacheEntryBySetWay); -} - /** Check whether the CPU supports the GIC system register interface (any version) diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h index 6380a019ddc5..7127a768ef8e 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h @@ -11,33 +11,6 @@ #ifndef AARCH64_LIB_H_ #define AARCH64_LIB_H_ -typedef VOID (*AARCH64_CACHE_OPERATION)( - UINTN - ); - -VOID -AArch64AllDataCachesOperation ( - IN AARCH64_CACHE_OPERATION DataCacheOperation - ); - -VOID -EFIAPI -ArmInvalidateDataCacheEntryBySetWay ( - IN UINTN SetWayFormat - ); - -VOID -EFIAPI -ArmCleanDataCacheEntryBySetWay ( - IN UINTN SetWayFormat - ); - -VOID -EFIAPI -ArmCleanInvalidateDataCacheEntryBySetWay ( - IN UINTN SetWayFormat - ); - UINTN EFIAPI ArmReadIdAA64Dfr0 ( diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S index 19c77d31b5e0..66daa27fb401 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S @@ -43,22 +43,6 @@ ASM_FUNC(ArmCleanInvalidateDataCacheEntryByMVA) dc civac, x0 // Clean and invalidate single data cache line ret - -ASM_FUNC(ArmInvalidateDataCacheEntryBySetWay) - dc isw, x0 // Invalidate this line - ret - - -ASM_FUNC(ArmCleanInvalidateDataCacheEntryBySetWay) - dc cisw, x0 // Clean and Invalidate this line - ret - - -ASM_FUNC(ArmCleanDataCacheEntryBySetWay) - dc csw, x0 // Clean this line - ret - - ASM_FUNC(ArmInvalidateInstructionCache) ic iallu // Invalidate entire instruction cache dsb sy @@ -257,65 +241,6 @@ ASM_FUNC(ArmDisableBranchPrediction) ret -ASM_FUNC(AArch64AllDataCachesOperation) -// We can use regs 0-7 and 9-15 without having to save/restore. -// Save our link register on the stack. - The stack must always be quad-word aligned - stp x29, x30, [sp, #-16]! - mov x29, sp - mov x1, x0 // Save Function call in x1 - mrs x6, clidr_el1 // Read EL1 CLIDR - and x3, x6, #0x7000000 // Mask out all but Level of Coherency (LoC) - lsr x3, x3, #23 // Left align cache level value - the level is shifted by 1 to the - // right to ease the access to CSSELR and the Set/Way operation. - cbz x3, L_Finished // No need to clean if LoC is 0 - mov x10, #0 // Start clean at cache level 0 - -Loop1: - add x2, x10, x10, lsr #1 // Work out 3x cachelevel for cache info - lsr x12, x6, x2 // bottom 3 bits are the Cache type for this level - and x12, x12, #7 // get those 3 bits alone - cmp x12, #2 // what cache at this level? - b.lt L_Skip // no cache or only instruction cache at this level - msr csselr_el1, x10 // write the Cache Size selection register with current level (CSSELR) - isb // isb to sync the change to the CacheSizeID reg - mrs x12, ccsidr_el1 // reads current Cache Size ID register (CCSIDR) - and x2, x12, #0x7 // extract the line length field - add x2, x2, #4 // add 4 for the line length offset (log2 16 bytes) - mov x4, #0x400 - sub x4, x4, #1 - and x4, x4, x12, lsr #3 // x4 is the max number on the way size (right aligned) - clz w5, w4 // w5 is the bit position of the way size increment - mov x7, #0x00008000 - sub x7, x7, #1 - and x7, x7, x12, lsr #13 // x7 is the max number of the index size (right aligned) - -Loop2: - mov x9, x4 // x9 working copy of the max way size (right aligned) - -Loop3: - lsl x11, x9, x5 - orr x0, x10, x11 // factor in the way number and cache number - lsl x11, x7, x2 - orr x0, x0, x11 // factor in the index number - - blr x1 // Goto requested cache operation - - subs x9, x9, #1 // decrement the way number - b.ge Loop3 - subs x7, x7, #1 // decrement the index - b.ge Loop2 -L_Skip: - add x10, x10, #2 // increment the cache number - cmp x3, x10 - b.gt Loop1 - -L_Finished: - dsb sy - isb - ldp x29, x30, [sp], #0x10 - ret - - ASM_FUNC(ArmDataMemoryBarrier) dmb sy ret diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c index 6acc4d3e7cc5..dd1e8c5930c2 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c +++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c @@ -18,61 +18,6 @@ #include "ArmV7Lib.h" #include "ArmLibPrivate.h" -VOID -ArmV7DataCacheOperation ( - IN ARM_V7_CACHE_OPERATION DataCacheOperation - ) -{ - UINTN SavedInterruptState; - - SavedInterruptState = ArmGetInterruptState (); - ArmDisableInterrupts (); - - ArmV7AllDataCachesOperation (DataCacheOperation); - - ArmDataSynchronizationBarrier (); - - if (SavedInterruptState) { - ArmEnableInterrupts (); - } -} - -VOID -EFIAPI -ArmInvalidateDataCache ( - VOID - ) -{ - ASSERT (!ArmMmuEnabled ()); - - ArmDataSynchronizationBarrier (); - ArmV7DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay); -} - -VOID -EFIAPI -ArmCleanInvalidateDataCache ( - VOID - ) -{ - ASSERT (!ArmMmuEnabled ()); - - ArmDataSynchronizationBarrier (); - ArmV7DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay); -} - -VOID -EFIAPI -ArmCleanDataCache ( - VOID - ) -{ - ASSERT (!ArmMmuEnabled ()); - - ArmDataSynchronizationBarrier (); - ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay); -} - /** Check whether the CPU supports the GIC system register interface (any version) diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h index 404ff92c4e06..548be5cf28b0 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h +++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h @@ -23,33 +23,6 @@ #define ID_MMFR0_SHR_IMP_HW_COHERENT 1 #define ID_MMFR0_SHR_IGNORED 0xf -typedef VOID (*ARM_V7_CACHE_OPERATION)( - UINT32 - ); - -VOID -ArmV7AllDataCachesOperation ( - IN ARM_V7_CACHE_OPERATION DataCacheOperation - ); - -VOID -EFIAPI -ArmInvalidateDataCacheEntryBySetWay ( - IN UINTN SetWayFormat - ); - -VOID -EFIAPI -ArmCleanDataCacheEntryBySetWay ( - IN UINTN SetWayFormat - ); - -VOID -EFIAPI -ArmCleanInvalidateDataCacheEntryBySetWay ( - IN UINTN SetWayFormat - ); - /** Reads the ID_MMFR4 register. @return The contents of the ID_MMFR4 register. diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S b/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S index 70b27da70c65..0bfb5f1c9971 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S +++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S @@ -42,20 +42,6 @@ ASM_FUNC(ArmCleanInvalidateDataCacheEntryByMVA) bx lr -ASM_FUNC(ArmInvalidateDataCacheEntryBySetWay) - mcr p15, 0, r0, c7, c6, 2 @ Invalidate this line - bx lr - - -ASM_FUNC(ArmCleanInvalidateDataCacheEntryBySetWay) - mcr p15, 0, r0, c7, c14, 2 @ Clean and Invalidate this line - bx lr - - -ASM_FUNC(ArmCleanDataCacheEntryBySetWay) - mcr p15, 0, r0, c7, c10, 2 @ Clean this line - bx lr - ASM_FUNC(ArmInvalidateInstructionCache) mcr p15,0,R0,c7,c5,0 @Invalidate entire instruction cache dsb @@ -171,59 +157,6 @@ ASM_FUNC(ArmSetHighVectors) isb bx LR -ASM_FUNC(ArmV7AllDataCachesOperation) - stmfd SP!,{r4-r12, LR} - mov R1, R0 @ Save Function call in R1 - mrc p15, 1, R6, c0, c0, 1 @ Read CLIDR - ands R3, R6, #0x7000000 @ Mask out all but Level of Coherency (LoC) - mov R3, R3, LSR #23 @ Cache level value (naturally aligned) - beq L_Finished - mov R10, #0 - -Loop1: - add R2, R10, R10, LSR #1 @ Work out 3xcachelevel - mov R12, R6, LSR R2 @ bottom 3 bits are the Cache type for this level - and R12, R12, #7 @ get those 3 bits alone - cmp R12, #2 - blt L_Skip @ no cache or only instruction cache at this level - mcr p15, 2, R10, c0, c0, 0 @ write the Cache Size selection register (CSSELR) // OR in 1 for Instruction - isb @ isb to sync the change to the CacheSizeID reg - mrc p15, 1, R12, c0, c0, 0 @ reads current Cache Size ID register (CCSIDR) - and R2, R12, #0x7 @ extract the line length field - add R2, R2, #4 @ add 4 for the line length offset (log2 16 bytes) -@ ldr R4, =0x3FF - mov R4, #0x400 - sub R4, R4, #1 - ands R4, R4, R12, LSR #3 @ R4 is the max number on the way size (right aligned) - clz R5, R4 @ R5 is the bit position of the way size increment -@ ldr R7, =0x00007FFF - mov R7, #0x00008000 - sub R7, R7, #1 - ands R7, R7, R12, LSR #13 @ R7 is the max number of the index size (right aligned) - -Loop2: - mov R9, R4 @ R9 working copy of the max way size (right aligned) - -Loop3: - orr R0, R10, R9, LSL R5 @ factor in the way number and cache number into R11 - orr R0, R0, R7, LSL R2 @ factor in the index number - - blx R1 - - subs R9, R9, #1 @ decrement the way number - bge Loop3 - subs R7, R7, #1 @ decrement the index - bge Loop2 -L_Skip: - add R10, R10, #2 @ increment the cache number - cmp R3, R10 - bgt Loop1 - -L_Finished: - dsb - ldmfd SP!, {r4-r12, lr} - bx LR - ASM_FUNC(ArmDataMemoryBarrier) dmb bx LR From 837bb626613eb6ae2d9c647b39dc2784a6586c2d Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Wed, 28 Aug 2024 09:39:45 -0700 Subject: [PATCH 238/280] NetworkPkg: PxeBcDhcp6GoogleTest: Fix Stack Smashing Unit Test PxeBcDhcp6GoogleTest's MultipleDnsEntries test started to fail with stack cookies added for host applications. Debugging this showed that the test was attempting to copy two UINT16s to a UINT8 Data[1] array allocated on the stack. This was moved to a heap based allocation for a UINT32 to accommodate the proper size. After this fix, the unit test passed with stack cookies enabled. Signed-off-by: Oliver Smith-Denny --- .../GoogleTest/PxeBcDhcp6GoogleTest.cpp | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp index 61736ff79e83..e529bc6daf1d 100644 --- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp +++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp @@ -290,15 +290,9 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptUnderflowTest) { // Test Description // Test that we can handle recursive dns (multiple dns entries) TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) { - EFI_DHCP6_PACKET_OPTION Option = { 0 }; + EFI_DHCP6_PACKET_OPTION *Option = NULL; PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL; - Private.SelectIndex = 1; // SelectIndex is 1-based - Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6; - Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option; - // Setup the DHCPv6 offer packet - Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID; - EFI_IPv6_ADDRESS addresses[2] = { // 2001:db8:85a3::8a2e:370:7334 { 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 }, @@ -306,7 +300,18 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) { { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x78, 0x91, 0xc3, 0xec, 0xd7, 0x4f, 0xf9 } }; - CopyMem (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, &addresses, sizeof (addresses)); + Option = (EFI_DHCP6_PACKET_OPTION *)AllocatePool (sizeof (*Option) + sizeof (addresses)); + if (Option == NULL) { + ASSERT_NE (Option, nullptr); + } + + Private.SelectIndex = 1; // SelectIndex is 1-based + Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6; + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = Option; + // Setup the DHCPv6 offer packet + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID; + + CopyMem (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, addresses, sizeof (addresses)); Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (sizeof (addresses)); @@ -327,6 +332,10 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) { if (Private.DnsServer) { FreePool (Private.DnsServer); } + + if (Option) { + FreePool (Option); + } } /////////////////////////////////////////////////////////////////////////////// From 26c381801126527943b08ee1cff4133dfcfd3d77 Mon Sep 17 00:00:00 2001 From: Bret Barkelew Date: Thu, 28 Jan 2021 03:33:13 +0000 Subject: [PATCH 239/280] UnitTestFrameworkPkg: Move common includes to their own file Previously, the UnitTestFrameworkPkgHost.dsc.inc included the entire UnitTestFrameworkPkgTarget.dsc.inc file. This is unnecessary for most configurations, so copy the relevant common components to a separate file. This is required for stack cookies so that we can have stack cookies on target based test apps but not on host base test apps. Signed-off-by: Oliver Smith-Denny --- .../UnitTestFrameworkPkgCommon.dsc.inc | 22 +++++++++++++++++++ .../UnitTestFrameworkPkgHost.dsc.inc | 2 +- .../UnitTestFrameworkPkgTarget.dsc.inc | 13 ++--------- 3 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 UnitTestFrameworkPkg/UnitTestFrameworkPkgCommon.dsc.inc diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgCommon.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgCommon.dsc.inc new file mode 100644 index 000000000000..0de6e4362bf4 --- /dev/null +++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgCommon.dsc.inc @@ -0,0 +1,22 @@ +## @file +# UnitTestFrameworkPkg DSC include file for host and target based test DSC +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[LibraryClasses] + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + UnitTestPersistenceLib|UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf + UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + +[PcdsFixedAtBuild] + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17 + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED + GCC:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED + XCODE:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc index 83d3205b636c..0747229d0597 100644 --- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc +++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc @@ -6,7 +6,7 @@ # ## -!include UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc +!include UnitTestFrameworkPkg/UnitTestFrameworkPkgCommon.dsc.inc [LibraryClasses.common.HOST_APPLICATION] BaseLib|MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc index 06c40f24f2ad..fdec9c6e0026 100644 --- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc +++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc @@ -6,6 +6,8 @@ # ## +!include UnitTestFrameworkPkg/UnitTestFrameworkPkgCommon.dsc.inc + [LibraryClasses] # # Entry point @@ -15,15 +17,12 @@ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf BaseLib|MdePkg/Library/BaseLib/BaseLib.inf - BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf - PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf - PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf @@ -59,11 +58,3 @@ [LibraryClasses.common.UEFI_APPLICATION] UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.inf - -[PcdsFixedAtBuild] - gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17 - -[BuildOptions] - MSFT:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED - GCC:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED - XCODE:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED From 3a9da5f329ab9683bffc451502a2f0680568a71f Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Fri, 14 Jun 2024 13:20:29 -0700 Subject: [PATCH 240/280] MdePkg: Add Stack Cookie Interrupt Vector PCD This patch adds a PCD allowing a platform to specify the interrupt vector to trigger on a stack check failure. On x86, this is an offset into the IDT. On ARM/AARCH64, this triggers a software interrupt that can be decoded to indicate this was a stack check failure. Signed-off-by: Oliver Smith-Denny --- MdePkg/MdePkg.dec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index d36bd2eda37e..8d5947fc9e9a 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -2259,6 +2259,9 @@ # @Prompt Speculation Barrier Type. gEfiMdePkgTokenSpaceGuid.PcdSpeculationBarrierType|0x01|UINT8|0x30001018 + ## This PCD specifies the interrupt vector for stack cookie check failures + gEfiMdePkgTokenSpaceGuid.PcdStackCookieExceptionVector|0x42|UINT8|0x30001019 + [PcdsFixedAtBuild,PcdsPatchableInModule] ## Indicates the maximum length of unicode string used in the following # BaseLib functions: StrLen(), StrSize(), StrCmp(), StrnCmp(), StrCpy(), StrnCpy()

From ac43bbacdef18a6fea6d978e096326ec0805885d Mon Sep 17 00:00:00 2001 From: Taylor Beebe Date: Tue, 27 Aug 2024 14:31:48 -0700 Subject: [PATCH 241/280] MdePkg: Create Stack Check Null Libs Add Null libs for Stack Check and Stack Check Failure Hook Lib that allow a platform to opt out of stack checks and the stack check failure hook lib. StackCheckLib allows implementation (or in this case null implementation) of stack checks on binaries. There is a Host Application specific version of this null lib because MSVC host applications must not be linked against our lib (so the file here is a no-op but that doesn't cause the build system to fail the build for not building a file for MSVC) as it links against the MSVC C runtime lib that provides the stack cookie definitions. GCC host applications do not link against such a C runtime lib and must be linked against our version. StackCheckFailureHookLib lets a platform do custom functionality when a stack check failure occurs (such as log it to a platform defined mechanism). The null lib simply returns. Signed-off-by: Oliver Smith-Denny --- .../Library/StackCheckFailureHookLib.h | 26 ++++++++++++ .../StackCheckFailureHook.c | 25 +++++++++++ .../StackCheckFailureHookLibNull.inf | 20 +++++++++ .../IA32/StackCheckFunctionsMsvc.nasm | 21 ++++++++++ .../StackCheckLibHostApplicationMsvc.c | 13 ++++++ .../StackCheckLibNull/StackCheckLibNull.inf | 41 +++++++++++++++++++ .../StackCheckLibNull/StackCheckLibNullGcc.c | 23 +++++++++++ .../StackCheckLibNullHostApplication.inf | 34 +++++++++++++++ .../StackCheckLibNull/StackCheckLibNullMsvc.c | 10 +++++ .../X64/StackCheckFunctionsMsvc.nasm | 21 ++++++++++ MdePkg/MdeLibs.dsc.inc | 6 +++ MdePkg/MdePkg.ci.yaml | 4 +- MdePkg/MdePkg.dec | 4 ++ MdePkg/MdePkg.dsc | 3 ++ MdePkg/Test/MdePkgHostTest.dsc | 2 + 15 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 MdePkg/Include/Library/StackCheckFailureHookLib.h create mode 100644 MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHook.c create mode 100644 MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf create mode 100644 MdePkg/Library/StackCheckLibNull/IA32/StackCheckFunctionsMsvc.nasm create mode 100644 MdePkg/Library/StackCheckLibNull/StackCheckLibHostApplicationMsvc.c create mode 100644 MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf create mode 100644 MdePkg/Library/StackCheckLibNull/StackCheckLibNullGcc.c create mode 100644 MdePkg/Library/StackCheckLibNull/StackCheckLibNullHostApplication.inf create mode 100644 MdePkg/Library/StackCheckLibNull/StackCheckLibNullMsvc.c create mode 100644 MdePkg/Library/StackCheckLibNull/X64/StackCheckFunctionsMsvc.nasm diff --git a/MdePkg/Include/Library/StackCheckFailureHookLib.h b/MdePkg/Include/Library/StackCheckFailureHookLib.h new file mode 100644 index 000000000000..f0657ddfa084 --- /dev/null +++ b/MdePkg/Include/Library/StackCheckFailureHookLib.h @@ -0,0 +1,26 @@ +/** @file + Library provides a hook called when a stack cookie check fails. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef STACK_COOKIE_FAILURE_HOOK_LIB_H_ +#define STACK_COOKIE_FAILURE_HOOK_LIB_H_ + +#include + +/** + This function gets called when a compiler generated stack cookie fails. This allows a platform to hook this + call and perform any required actions/telemetry at that time. + + @param FailureAddress The address of the function that failed the stack cookie check. + +**/ +VOID +EFIAPI +StackCheckFailureHook ( + VOID *FailureAddress + ); + +#endif diff --git a/MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHook.c b/MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHook.c new file mode 100644 index 000000000000..0a258e4773eb --- /dev/null +++ b/MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHook.c @@ -0,0 +1,25 @@ +/** @file + Library provides a hook called when a stack cookie check fails. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include + +/** + This function gets called when a compiler generated stack cookie fails. This allows a platform to hook this + call and perform any required actions/telemetry at that time. + + @param FailureAddress The address of the function that failed the stack cookie check. + +**/ +VOID +EFIAPI +StackCheckFailureHook ( + VOID *FailureAddress + ) +{ + return; +} diff --git a/MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf b/MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf new file mode 100644 index 000000000000..300073a7e7b9 --- /dev/null +++ b/MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf @@ -0,0 +1,20 @@ +## @file +# Library provides a hook called when a stack cookie check fails. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = StackCheckFailureHookLibNull + FILE_GUID = 9ca2587c-d1f2-451a-989a-d49a9a0a613e + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = StackCheckFailureHookLib + +[Sources] + StackCheckFailureHook.c + +[Packages] + MdePkg/MdePkg.dec diff --git a/MdePkg/Library/StackCheckLibNull/IA32/StackCheckFunctionsMsvc.nasm b/MdePkg/Library/StackCheckLibNull/IA32/StackCheckFunctionsMsvc.nasm new file mode 100644 index 000000000000..510d500847a8 --- /dev/null +++ b/MdePkg/Library/StackCheckLibNull/IA32/StackCheckFunctionsMsvc.nasm @@ -0,0 +1,21 @@ +;------------------------------------------------------------------------------ +; IA32/StackCheckFunctionsMsvc.nasm +; +; Copyright (c) Microsoft Corporation. +; SPDX-License-Identifier: BSD-2-Clause-Patent +;------------------------------------------------------------------------------ + + DEFAULT REL + SECTION .text + +global ASM_PFX(__report_rangecheckfailure) +ASM_PFX(__report_rangecheckfailure): + ret + +global ASM_PFX(__GSHandlerCheck) +ASM_PFX(__GSHandlerCheck): + ret + +global @__security_check_cookie@4 +@__security_check_cookie@4: + ret diff --git a/MdePkg/Library/StackCheckLibNull/StackCheckLibHostApplicationMsvc.c b/MdePkg/Library/StackCheckLibNull/StackCheckLibHostApplicationMsvc.c new file mode 100644 index 000000000000..6af9891c3907 --- /dev/null +++ b/MdePkg/Library/StackCheckLibNull/StackCheckLibHostApplicationMsvc.c @@ -0,0 +1,13 @@ +/** @file + This file is empty to allow host applications + to use the MSVC C runtime lib that provides + stack cookie definitions without breaking the + build. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +extern VOID *__security_cookie; diff --git a/MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf b/MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf new file mode 100644 index 000000000000..bb42833d02df --- /dev/null +++ b/MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf @@ -0,0 +1,41 @@ +## @file +# Null library instance for StackCheckLib which can be included +# when a build needs to include stack check functions but does +# not want to generate stack check failures. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = StackCheckLibNull + FILE_GUID = f6ef2763-ca3b-4c6f-a931-2a48de3ce352 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = StackCheckLib + +[Sources] + StackCheckLibNullGcc.c | GCC + StackCheckLibNullMsvc.c | MSFT + +[Sources.IA32] + IA32/StackCheckFunctionsMsvc.nasm | MSFT + +[Sources.X64] + X64/StackCheckFunctionsMsvc.nasm | MSFT + +[Packages] + MdePkg/MdePkg.dec + +[BuildOptions] + # We cannot build the MSVC version with /GL (whole program optimization) because we run into linker error + # LNK1237, which is a failure to link against a symbol from a library compiled with /GL. The whole program + # optimization tries to do away with references to this symbol. The solution is to not compile the stack + # check libs with /GL + MSFT:*_*_*_CC_FLAGS = /GL- + + # We cannot build the GCC version with LTO (link time optimization) because we run into linker errors where + # the stack cookie variable has been optimized away, as it looks to GCC like the variable is not used, because + # the compiler inserts the usage. + GCC:*_*_*_CC_FLAGS = -fno-lto diff --git a/MdePkg/Library/StackCheckLibNull/StackCheckLibNullGcc.c b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullGcc.c new file mode 100644 index 000000000000..cc30632761ea --- /dev/null +++ b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullGcc.c @@ -0,0 +1,23 @@ +/** @file + Defines the stack cookie variable for GCC and Clang compilers. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +VOID *__stack_chk_guard = (VOID *)(UINTN)0x0; + +/** + This function gets called when a gcc/clang generated stack cookie fails. This implementation does nothing when + a stack cookie failure occurs. + +**/ +VOID +EFIAPI +__stack_chk_fail ( + VOID + ) +{ +} diff --git a/MdePkg/Library/StackCheckLibNull/StackCheckLibNullHostApplication.inf b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullHostApplication.inf new file mode 100644 index 000000000000..3e898263c2ac --- /dev/null +++ b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullHostApplication.inf @@ -0,0 +1,34 @@ +## @file +# Null library instance for StackCheckLib which can be included +# when a build needs to include stack check functions but does +# not want to generate stack check failures. This instance is used +# for HOST_APPLICATIONS specifically, as MSVC host applications link +# to the C runtime lib that contains the stack cookie definitions, so +# must link to a completely null version of this lib, whereas GCC host +# host applications do not link to a C runtime lib that contains the stack +# cookie definitions, so we must link against our version. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = StackCheckLibNullHostApplication + FILE_GUID = 7EBE7BD1-0D92-4609-89AA-6EA3815CB844 + MODULE_TYPE = HOST_APPLICATION + VERSION_STRING = 1.0 + LIBRARY_CLASS = StackCheckLib|HOST_APPLICATION + +[Sources] + StackCheckLibHostApplicationMsvc.c | MSFT + StackCheckLibNullGcc.c | GCC + +[Packages] + MdePkg/MdePkg.dec + +[BuildOptions] + # We cannot build the GCC version with LTO (link time optimization) because we run into linker errors where + # the stack cookie variable has been optimized away, as it looks to GCC like the variable is not used, because + # the compiler inserts the usage. We do not worry about the MSVC version here as it is a no-op. + GCC:*_*_*_CC_FLAGS = -fno-lto diff --git a/MdePkg/Library/StackCheckLibNull/StackCheckLibNullMsvc.c b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullMsvc.c new file mode 100644 index 000000000000..ba9a4e6f3ceb --- /dev/null +++ b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullMsvc.c @@ -0,0 +1,10 @@ +/** @file + Defines the stack cookie variable for GCC, Clang and MSVC compilers. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +VOID *__security_cookie = (VOID *)(UINTN)0x0; diff --git a/MdePkg/Library/StackCheckLibNull/X64/StackCheckFunctionsMsvc.nasm b/MdePkg/Library/StackCheckLibNull/X64/StackCheckFunctionsMsvc.nasm new file mode 100644 index 000000000000..f4639a03d2ea --- /dev/null +++ b/MdePkg/Library/StackCheckLibNull/X64/StackCheckFunctionsMsvc.nasm @@ -0,0 +1,21 @@ +;------------------------------------------------------------------------------ +; X64/StackCheckFunctionsMsvc.nasm +; +; Copyright (c) Microsoft Corporation. +; SPDX-License-Identifier: BSD-2-Clause-Patent +;------------------------------------------------------------------------------ + + DEFAULT REL + SECTION .text + +global ASM_PFX(__report_rangecheckfailure) +ASM_PFX(__report_rangecheckfailure): + ret + +global ASM_PFX(__GSHandlerCheck) +ASM_PFX(__GSHandlerCheck): + ret + +global ASM_PFX(__security_check_cookie) +ASM_PFX(__security_check_cookie): + ret diff --git a/MdePkg/MdeLibs.dsc.inc b/MdePkg/MdeLibs.dsc.inc index e40ff7d95e04..4e3858edb627 100644 --- a/MdePkg/MdeLibs.dsc.inc +++ b/MdePkg/MdeLibs.dsc.inc @@ -30,3 +30,9 @@ # definitions for the intrinsic functions. # NULL|MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf + +# Stack Cookies cannot be generically applied to SEC modules because they may not define _ModuleEntryPoint and when we +# link a library in, we have to be able to define the entry point. SEC modules that do define _ModuleEntryPoint can +# apply a library class override to get StackCheckLibNull.inf +[LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM, LibraryClasses.common.DXE_CORE, LibraryClasses.common.SMM_CORE, LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_SMM_DRIVER, LibraryClasses.common.MM_STANDALONE, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf diff --git a/MdePkg/MdePkg.ci.yaml b/MdePkg/MdePkg.ci.yaml index f2d81af080ee..cebccba59d29 100644 --- a/MdePkg/MdePkg.ci.yaml +++ b/MdePkg/MdePkg.ci.yaml @@ -61,7 +61,9 @@ "7007", "_EFI_SPI_NOR_FLASH_PROTOCOL", "7007", "_EFI_SPI_HC_PROTOCOL", "8002", "aligned (", - "4002", "_ReturnAddress" + "4002", "_ReturnAddress", + "8005", "__security_cookie", + "8006", "__stack_chk_fail" ], ## Both file path and directory path are accepted. "IgnoreFiles": [ diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 8d5947fc9e9a..b542d6d83235 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -303,6 +303,10 @@ # TraceHubDebugSysTLib|Include/Library/TraceHubDebugSysTLib.h + ## @libraryclass Provides a hook called when a stack cookie check fails. + # + StackCheckFailureHookLib|Include/Library/StackCheckFailureHookLib.h + [LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64] ## @libraryclass Provides services to generate random number. # diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index ebcd79864d4f..f410a89a00f2 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -139,6 +139,9 @@ MdePkg/Library/JedecJep106Lib/JedecJep106Lib.inf MdePkg/Library/BaseFdtLib/BaseFdtLib.inf + MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf + MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [Components.IA32, Components.X64, Components.ARM, Components.AARCH64] # # Add UEFI Target Based Unit Tests diff --git a/MdePkg/Test/MdePkgHostTest.dsc b/MdePkg/Test/MdePkgHostTest.dsc index 6a85d02236a0..1351d191575e 100644 --- a/MdePkg/Test/MdePkgHostTest.dsc +++ b/MdePkg/Test/MdePkgHostTest.dsc @@ -47,3 +47,5 @@ MdePkg/Test/Mock/Library/GoogleTest/MockPeiServicesLib/MockPeiServicesLib.inf MdePkg/Test/Mock/Library/GoogleTest/MockHobLib/MockHobLib.inf MdePkg/Test/Mock/Library/GoogleTest/MockFdtLib/MockFdtLib.inf + + MdePkg/Library/StackCheckLibNull/StackCheckLibNullHostApplication.inf From 5000568969995293b529f49ea43726e2d0a9dcab Mon Sep 17 00:00:00 2001 From: Taylor Beebe Date: Tue, 27 Aug 2024 14:34:35 -0700 Subject: [PATCH 242/280] MdePkg: Create Stack Check Lib StackCheckLib contains the required functionality for initializing the stack cookie value, checking the value, and triggering an interrupt when a mismatch occurs. The stack cookie is a random value placed on the stack between the stack variables and the return address so that continuously writing past the stack variables will cause the stack cookie to be overwritten. Before the function returns, the stack cookie value will be checked and if there is a mismatch then StackCheckLib handles the failure. Because UEFI doesn't use the C runtime libraries provided by MSVC, the stack check code is written in assembly within this library. GCC and Clang compilers have built-in support for stack cookie checking, so this library only handles failures. Signed-off-by: Oliver Smith-Denny --- .../AArch64/StackCookieInterrupt.S | 21 +++ .../AArch64/StackCookieInterrupt.asm | 25 ++++ .../StackCheckLib/Arm/StackCookieInterrupt.S | 21 +++ .../Arm/StackCookieInterrupt.asm | 25 ++++ .../StackCheckLib/IA32/CheckCookieMsvc.nasm | 43 ++++++ .../IA32/StackCookieInterrupt.nasm | 23 ++++ MdePkg/Library/StackCheckLib/Readme.md | 126 ++++++++++++++++++ .../StackCheckLib/StackCheckLibCommonGcc.c | 38 ++++++ .../StackCheckLib/StackCheckLibCommonMsvc.c | 40 ++++++ .../StackCheckLib/StackCheckLibStaticInit.inf | 58 ++++++++ .../StackCheckLib/X64/CheckCookieMsvc.nasm | 43 ++++++ MdePkg/MdePkg.dsc | 1 + 12 files changed, 464 insertions(+) create mode 100644 MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.S create mode 100644 MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.asm create mode 100644 MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.S create mode 100644 MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.asm create mode 100644 MdePkg/Library/StackCheckLib/IA32/CheckCookieMsvc.nasm create mode 100644 MdePkg/Library/StackCheckLib/IA32/StackCookieInterrupt.nasm create mode 100644 MdePkg/Library/StackCheckLib/Readme.md create mode 100644 MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c create mode 100644 MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c create mode 100644 MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf create mode 100644 MdePkg/Library/StackCheckLib/X64/CheckCookieMsvc.nasm diff --git a/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.S b/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.S new file mode 100644 index 000000000000..bce13643e3d2 --- /dev/null +++ b/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.S @@ -0,0 +1,21 @@ +//------------------------------------------------------------------------------ +// AArch64/StackCookieInterrupt.S +// +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: BSD-2-Clause-Patent +//------------------------------------------------------------------------------ + + .text + +//------------------------------------------------------------------------------ +// Calls an interrupt using the vector specified by PcdStackCookieExceptionVector +// +// VOID +// TriggerStackCookieInterrupt ( +// VOID +// ); +//------------------------------------------------------------------------------ +.global ASM_PFX(TriggerStackCookieInterrupt) +ASM_PFX(TriggerStackCookieInterrupt): + svc FixedPcdGet8 (PcdStackCookieExceptionVector) + ret diff --git a/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.asm b/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.asm new file mode 100644 index 000000000000..ff5ee35acce8 --- /dev/null +++ b/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.asm @@ -0,0 +1,25 @@ +;------------------------------------------------------------------------------ +; AArch64/StackCookieInterrupt.asm +; +; Copyright (c) Microsoft Corporation. +; SPDX-License-Identifier: BSD-2-Clause-Patent +;------------------------------------------------------------------------------ + + EXPORT TriggerStackCookieInterrupt + + AREA |.text|, CODE, READONLY + +;------------------------------------------------------------------------------ +; Calls an interrupt using the vector specified by PcdStackCookieExceptionVector +; +; VOID +; TriggerStackCookieInterrupt ( +; VOID +; ); +;------------------------------------------------------------------------------ +TriggerStackCookieInterrupt PROC + SVC FixedPcdGet8 (PcdStackCookieExceptionVector) + RET +TriggerStackCookieInterrupt ENDP + + END diff --git a/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.S b/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.S new file mode 100644 index 000000000000..1f10bb8aea52 --- /dev/null +++ b/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.S @@ -0,0 +1,21 @@ +//------------------------------------------------------------------------------ +// Arm/StackCookieInterrupt.S +// +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: BSD-2-Clause-Patent +//------------------------------------------------------------------------------ + + .text + +//------------------------------------------------------------------------------ +// Calls an interrupt using the vector specified by PcdStackCookieExceptionVector +// +// VOID +// TriggerStackCookieInterrupt ( +// VOID +// ); +//------------------------------------------------------------------------------ +.global ASM_PFX(TriggerStackCookieInterrupt) +ASM_PFX(TriggerStackCookieInterrupt): + swi FixedPcdGet8 (PcdStackCookieExceptionVector) + bx lr diff --git a/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.asm b/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.asm new file mode 100644 index 000000000000..f1b1e539438a --- /dev/null +++ b/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.asm @@ -0,0 +1,25 @@ +;------------------------------------------------------------------------------ +; Arm/StackCookieInterrupt.asm +; +; Copyright (c) Microsoft Corporation. +; SPDX-License-Identifier: BSD-2-Clause-Patent +;------------------------------------------------------------------------------ + + EXPORT TriggerStackCookieInterrupt + + AREA |.text|, CODE, READONLY + +;------------------------------------------------------------------------------ +; Calls an interrupt using the vector specified by PcdStackCookieExceptionVector +; +; VOID +; TriggerStackCookieInterrupt ( +; VOID +; ); +;------------------------------------------------------------------------------ +TriggerStackCookieInterrupt PROC + SWI FixedPcdGet8 (PcdStackCookieExceptionVector) + BX LR +TriggerStackCookieInterrupt ENDP + + END diff --git a/MdePkg/Library/StackCheckLib/IA32/CheckCookieMsvc.nasm b/MdePkg/Library/StackCheckLib/IA32/CheckCookieMsvc.nasm new file mode 100644 index 000000000000..a52ee90ad9f1 --- /dev/null +++ b/MdePkg/Library/StackCheckLib/IA32/CheckCookieMsvc.nasm @@ -0,0 +1,43 @@ +;------------------------------------------------------------------------------ +; IA32/CheckCookieMsvc.nasm +; +; Copyright (c) Microsoft Corporation. +; SPDX-License-Identifier: BSD-2-Clause-Patent +;------------------------------------------------------------------------------ + + DEFAULT REL + SECTION .text + +extern ASM_PFX(StackCheckFailure) +extern ASM_PFX(__security_cookie) +extern ASM_PFX(CpuDeadLoop) + +; Called when a buffer check fails. This functionality is dependent on MSVC +; C runtime libraries and so is unsupported in UEFI. +global ASM_PFX(__report_rangecheckfailure) +ASM_PFX(__report_rangecheckfailure): + jmp ASM_PFX(CpuDeadLoop) + ret + +; The GS handler is for checking the stack cookie during SEH or +; EH exceptions and is unsupported in UEFI. +global ASM_PFX(__GSHandlerCheck) +ASM_PFX(__GSHandlerCheck): + jmp ASM_PFX(CpuDeadLoop) + ret + +;------------------------------------------------------------------------------ +; Checks the stack cookie value against __security_cookie and calls the +; stack cookie failure handler if there is a mismatch. +; +; VOID +; EFIAPI +; __security_check_cookie ( +; IN UINTN CheckValue +; ); +;------------------------------------------------------------------------------ +global @__security_check_cookie@4 +@__security_check_cookie@4: + cmp ecx, [ASM_PFX(__security_cookie)] + jne ASM_PFX(StackCheckFailure) + ret diff --git a/MdePkg/Library/StackCheckLib/IA32/StackCookieInterrupt.nasm b/MdePkg/Library/StackCheckLib/IA32/StackCookieInterrupt.nasm new file mode 100644 index 000000000000..83a686ddb309 --- /dev/null +++ b/MdePkg/Library/StackCheckLib/IA32/StackCookieInterrupt.nasm @@ -0,0 +1,23 @@ +;------------------------------------------------------------------------------ +; IA32/StackCookieInterrupt.nasm +; +; Copyright (c) Microsoft Corporation. +; SPDX-License-Identifier: BSD-2-Clause-Patent +;------------------------------------------------------------------------------ + + DEFAULT REL + SECTION .text + +;------------------------------------------------------------------------------ +; Checks the stack cookie value against __security_cookie and calls the +; stack cookie failure handler if there is a mismatch. +; +; VOID +; TriggerStackCookieInterrupt ( +; VOID +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(TriggerStackCookieInterrupt) +ASM_PFX(TriggerStackCookieInterrupt): + int FixedPcdGet8 (PcdStackCookieExceptionVector) + ret diff --git a/MdePkg/Library/StackCheckLib/Readme.md b/MdePkg/Library/StackCheckLib/Readme.md new file mode 100644 index 000000000000..636cd047f086 --- /dev/null +++ b/MdePkg/Library/StackCheckLib/Readme.md @@ -0,0 +1,126 @@ +# StackCheckLib + +## Table of Contents + +- [StackCheckLib](#stackchecklib) + - [Table of Contents](#table-of-contents) + - [Introduction and Library Instances](#introduction-and-library-instances) + - [StackCheckLibStaticInit](#stackchecklibstaticinit) + - [StackCheckLibDynamicInit](#stackchecklibdynamicinit) + - [StackCheckLibNull](#stackchecklibnull) + - [How Failures are Handled](#how-failures-are-handled) + - [Debugging Stack Cookie Check Failures](#debugging-stack-cookie-check-failures) + - [Usage](#usage) + +## Introduction and Library Instances + +`StackCheckLib` contains the required functionality for initializing the stack cookie +value, checking the value, and triggering an interrupt when a mismatch occurs. +The stack cookie is a random value placed on the stack between the stack variables +and the return address so that continuously writing past the stack variables will +cause the stack cookie to be overwritten. Before the function returns, the stack +cookie value will be checked and if there is a mismatch then `StackCheckLib` handles +the failure. + +Because UEFI doesn't use the C runtime libraries provided by MSVC, the stack +check code is written in assembly within this library. GCC and Clang compilers +have built-in support for stack cookie checking, so this library only handles failures. + +### StackCheckLibStaticInit + +`StackCheckLibStaticInit` is an instance of `StackCheckLib` which does not update the +stack cookie value for the module at runtime. It's always preferable to use +`StackCheckLibDynamicInit` for improved security but there are cases where the stack +cookie global cannot be written to such as in execute-in-place (XIP) modules and during +the Cache-as-RAM (CAR) phase of the boot process. The stack cookie value is initialized +at compile time via updates to the AutoGen process. Each module will define +`STACK_COOKIE_VALUE` which is used for the module stack cookie value. + +### StackCheckLibDynamicInit + +This section is future work. The below is the proposed instance. + +`StackCheckLibDynamicInit` is an instance of `StackCheckLib` which updates the stack +cookie value for the module at runtime. This is the preferred method for stack cookie +initialization as it provides improved security. The stack cookie value is initialized +at runtime by calling `GetRandomNumber32()` or `GetRandomNumber64()` to generate a random +value via the platform's random number generator protocol. If the random number generator +returns an error, then the value will still have the build-time randomized value to fall +back on. + +### StackCheckLibNull + +`StackCheckLibNull` is an instance of `StackCheckLib` which does not perform any stack +cookie checks. This is useful for modules which will fail if stack cookie checks are +inserted. Of course, this is not recommended for production code. + +## How Failures are Handled + +When a stack cookie check fails, the `StackCheckLib` library will first call into a hook +function `StackCheckFailureHook()` which only has a NULL implementation in edk2. +The NULL implementation will simply print the failure address and return, but a platform +can implement their own instance of this library which can perform additional actions +before the system triggers an interrupt. + +After `StackCheckFailureHook()` returns, the library will trigger an interrupt with +PcdStackCookieExceptionVector. + +- On IA32 and X64 platforms, PcdStackCookieExceptionVector is used as an index into the +Interrupt Descriptor Table. +- On ARM platforms, a software interrupt (`SWI`) is called with the value of +PcdStackCookieExceptionVector. The value can be retrieved by the handler by reading +bits [7:0] of the instruction opcode which will allow the handler to determine if the +interrupt was triggered by the stack cookie check. Reference: +[Arm A64 Instruction Set Architecture Version 2024-3](https://developer.arm.com/documentation/ddi0597/2024-03/Base-Instructions/SVC--Supervisor-Call-?lang=en) +- On AARCH64 platforms, a supervisor call (`SVC`) is called with the value +of PcdStackCookieExceptionVector. This value can similarly be retrieved by the +handler to determine if the interrupt was triggered by the stack cookie check. Reference: +[Arm A64 Instruction Set Architecture Version 2024-3](https://developer.arm.com/documentation/ddi0602/2024-03/Base-Instructions/SVC--Supervisor-Call-?lang=en) + +## Debugging Stack Cookie Check Failures + +Tracking down the origin of stack cookie failures can be difficult. Programmers may attempt +printf debugging to determine which function has an overflow only to find that the failure +disappears on the next boot. This curiosity is usually due to the black-box heuristic used +by compilers to determine where to put stack cookie checks or compiler optimization features +removing the failing check. The address where the failed stack cookie check occurred will +be printed using DebugLib. If .map files are available, the address combined with the image +offset can be used to determine the function which failed. + +GNU-based compilers have the `-fstack-protector-all` flag to force stack cookie checks on +all functions which could create a more consistent environment for debugging assuming an +earlier failure doesn't mask the targeted one and the flash space can accommodate the +increased size. + +The Visual Studio (MSVC) toolchain has the ability to generate `.cod` files during compilation +which interleave C and the generated assembly code. These files will contain the stack cookie +checks and are useful for determining where the checks are placed. To generate these files, +append `/FAcs` to the build options for each target module. The easiest way to do this is to +update the tools_def file so the `___CC_FLAGS` includes `/FAcs`. + +## Usage + +edk2 updated the tools_def to add `/GS` to VS2022 and VS2019 IA32/X64 builds and +`-fstack-protector` to GCC builds. This will cause stack cookie references to be inserted +throughout the code. Every module should have a `StackCheckLib` instances linked to satisfy +these references. So every module doesn't need to add `StackCheckLib` to the LibraryClasses +section of the INF file, `StackCheckLib` instances should be linked as NULL in the platform +DSC fies. The only exception to this is host-based unit tests as they will be compiled with +the runtime libraries which already contain the stack cookie definitions and will collide +with `StackCheckLib`. + +SEC and PEI_CORE modules should always use `StackCheckLibNull` and pre-memory modules +should use `StackCheckLibStaticInit`. All other modules should use `StackCheckLibDynamicInit`. +Below is an **example** of how to link the `StackCheckLib` instances in the platform DSC file +but it may need customization based on the platform's requirements: + +```text +[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + +[LibraryClasses.common.PEIM] + NULL|MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf + +[LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.MM_STANDALONE, LibraryClasses.common.DXE_CORE, LibraryClasses.common.SMM_CORE, LibraryClasses.common.DXE_SMM_DRIVER, LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_SAL_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION] + NULL|MdePkg/Library/StackCheckLib/StackCheckLibDynamicInit.inf +``` diff --git a/MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c b/MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c new file mode 100644 index 000000000000..4146012b905c --- /dev/null +++ b/MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c @@ -0,0 +1,38 @@ +/** @file + Provides the required functionality for handling stack + cookie check failures in GCC. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include +#include +#include + +/** + Triggers an interrupt using the vector specified by PcdStackCookieExceptionVector +**/ +VOID +TriggerStackCookieInterrupt ( + VOID + ); + +VOID *__stack_chk_guard = (VOID *)(UINTN)STACK_COOKIE_VALUE; + +/** + This function gets called when a gcc/clang generated stack cookie fails. This implementation calls into a platform + failure hook lib and then triggers the stack cookie interrupt. + +**/ +VOID +__stack_chk_fail ( + VOID + ) +{ + DEBUG ((DEBUG_ERROR, "Stack cookie check failed at address 0x%llx!\n", RETURN_ADDRESS (0))); + StackCheckFailureHook (RETURN_ADDRESS (0)); + TriggerStackCookieInterrupt (); +} diff --git a/MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c b/MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c new file mode 100644 index 000000000000..406b2d01169b --- /dev/null +++ b/MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c @@ -0,0 +1,40 @@ +/** @file + Provides the required functionality for handling stack + cookie check failures for MSVC. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include +#include +#include + +/** + Triggers an interrupt using the vector specified by PcdStackCookieExceptionVector +**/ +VOID +TriggerStackCookieInterrupt ( + VOID + ); + +VOID *__security_cookie = (VOID *)(UINTN)STACK_COOKIE_VALUE; + +/** + This function gets called when an MSVC generated stack cookie fails. This implementation calls into a platform + failure hook lib and then triggers the stack cookie interrupt. + + @param[in] ActualCookieValue The value that was written onto the stack, corrupting the stack cookie. + +**/ +VOID +StackCheckFailure ( + VOID *ActualCookieValue + ) +{ + DEBUG ((DEBUG_ERROR, "Stack cookie check failed at address 0x%llx!\n", RETURN_ADDRESS (0))); + StackCheckFailureHook (RETURN_ADDRESS (0)); + TriggerStackCookieInterrupt (); +} diff --git a/MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf b/MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf new file mode 100644 index 000000000000..ce8bc11f2bb0 --- /dev/null +++ b/MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf @@ -0,0 +1,58 @@ +## @file +# Provides the required functionality for checking the stack cookie. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = StackCheckLibStaticInit + FILE_GUID = 2b24dc50-e33d-4c9f-8b62-e826f06e483f + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = NULL + +[Sources] + StackCheckLibCommonMsvc.c | MSFT + StackCheckLibCommonGcc.c | GCC + +[Sources.IA32] + IA32/CheckCookieMsvc.nasm | MSFT + +[Sources.X64] + X64/CheckCookieMsvc.nasm | MSFT + +[Sources.IA32, Sources.X64] + IA32/StackCookieInterrupt.nasm + +[Sources.ARM] + Arm/StackCookieInterrupt.S |GCC + Arm/StackCookieInterrupt.asm |MSFT + +[Sources.AARCH64] + AArch64/StackCookieInterrupt.S |GCC + AArch64/StackCookieInterrupt.asm |MSFT + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + StackCheckFailureHookLib + BaseLib + DebugLib + +[FixedPcd] + gEfiMdePkgTokenSpaceGuid.PcdStackCookieExceptionVector + +[BuildOptions] + # We cannot build the MSVC version with /GL (whole program optimization) because we run into linker error + # LNK1237, which is a failure to link against a symbol from a library compiled with /GL. The whole program + # optimization tries to do away with references to this symbol. The solution is to not compile the stack + # check libs with /GL + MSFT:*_*_*_CC_FLAGS = /GL- + + # We cannot build the GCC version with LTO (link time optimization) because we run into linker errors where + # the stack cookie variable has been optimized away, as it looks to GCC like the variable is not used, because + # the compiler inserts the usage. + GCC:*_*_*_CC_FLAGS = -fno-lto diff --git a/MdePkg/Library/StackCheckLib/X64/CheckCookieMsvc.nasm b/MdePkg/Library/StackCheckLib/X64/CheckCookieMsvc.nasm new file mode 100644 index 000000000000..ebc4f75712e1 --- /dev/null +++ b/MdePkg/Library/StackCheckLib/X64/CheckCookieMsvc.nasm @@ -0,0 +1,43 @@ +;------------------------------------------------------------------------------ +; X64/CheckCookieMsvc.nasm +; +; Copyright (c) Microsoft Corporation. +; SPDX-License-Identifier: BSD-2-Clause-Patent +;------------------------------------------------------------------------------ + + DEFAULT REL + SECTION .text + +extern ASM_PFX(StackCheckFailure) +extern ASM_PFX(__security_cookie) +extern ASM_PFX(CpuDeadLoop) + +; Called when a buffer check fails. This functionality is dependent on MSVC +; C runtime libraries and so is unsupported in UEFI. +global ASM_PFX(__report_rangecheckfailure) +ASM_PFX(__report_rangecheckfailure): + jmp ASM_PFX(CpuDeadLoop) + ret + +; The GS handler is for checking the stack cookie during SEH or +; EH exceptions and is unsupported in UEFI. +global ASM_PFX(__GSHandlerCheck) +ASM_PFX(__GSHandlerCheck): + jmp ASM_PFX(CpuDeadLoop) + ret + +;------------------------------------------------------------------------------ +; Checks the stack cookie value against __security_cookie and calls the +; stack cookie failure handler if there is a mismatch. +; +; VOID +; EFIAPI +; __security_check_cookie ( +; IN UINTN CheckValue +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(__security_check_cookie) +ASM_PFX(__security_check_cookie): + cmp rcx, [ASM_PFX(__security_cookie)] + jne ASM_PFX(StackCheckFailure) + ret diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index f410a89a00f2..92809e4a7599 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -141,6 +141,7 @@ MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf [Components.IA32, Components.X64, Components.ARM, Components.AARCH64] # From d1faaa8eae7a3423bbb824750d780a95266affb6 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 23 Jul 2024 15:18:41 -0700 Subject: [PATCH 243/280] ArmPkg: Remove Deprecated Stack Check Lib Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- ArmPkg/ArmPkg.dsc | 8 ++++---- ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 657e2bc5d5c0..041751e36830 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -93,6 +93,10 @@ OemMiscLib|ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf +[LibraryClasses.common.SEC] + # ARM platforms have SEC modules with standard entry points, so we can generically link StackCheckLib + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf @@ -100,10 +104,6 @@ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf -[LibraryClasses.ARM, LibraryClasses.AARCH64] - # Add support for GCC stack protector - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - [Components.common] ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf diff --git a/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc b/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc index 4ab7737c83eb..28ebe68b417e 100644 --- a/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc +++ b/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc @@ -43,7 +43,5 @@ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - [Components.common] ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.inf From acab6dbf8776b0d16d0ae5809321e72186f61449 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 23 Jul 2024 15:19:46 -0700 Subject: [PATCH 244/280] ArmPlatformPkg: Add Null Stack Check Lib Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- ArmPlatformPkg/ArmPlatformPkg.dsc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc index 396d7df1cc58..bfe1b99e8bfb 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg.dsc @@ -73,8 +73,6 @@ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf @@ -88,6 +86,9 @@ MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf + # ARM platforms have SEC modules with standard entry points, so we can generically link StackCheckLib + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.AARCH64.MM_STANDALONE] HobLib|StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf From 02e6c73a99a4157295b85c58d24537c5fe37de05 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 23 Jul 2024 15:21:07 -0700 Subject: [PATCH 245/280] ArmVirtPkg: Add Null Stack Check Lib Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- ArmVirtPkg/ArmVirt.dsc.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 35a5a1420a58..890a056cd018 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -88,9 +88,6 @@ # Networking Requirements !include NetworkPkg/NetworkLibs.dsc.inc - # Add support for GCC stack protector - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - # ARM Architectural Libraries CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf @@ -185,6 +182,9 @@ DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf !endif + # ARM platforms have SEC modules with standard entry points, so we can generically link StackCheckLib + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.PEI_CORE] PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf From c9320adf22948696f1504b24952695ace489448b Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Fri, 14 Jun 2024 13:59:37 -0700 Subject: [PATCH 246/280] CryptoPkg: Add StackCheckLib Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- CryptoPkg/CryptoPkg.dsc | 5 ++--- CryptoPkg/CryptoPkgMbedTls.dsc | 4 ---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc index 344f158a768e..f23fb6f945e1 100644 --- a/CryptoPkg/CryptoPkg.dsc +++ b/CryptoPkg/CryptoPkg.dsc @@ -118,15 +118,14 @@ [LibraryClasses.ARM, LibraryClasses.AARCH64] ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf - # Add support for stack protector - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - [LibraryClasses.ARM] ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf [LibraryClasses.common.SEC] BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf + # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf [LibraryClasses.common.PEIM] PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf diff --git a/CryptoPkg/CryptoPkgMbedTls.dsc b/CryptoPkg/CryptoPkgMbedTls.dsc index a429606efe35..17f41c4f3612 100644 --- a/CryptoPkg/CryptoPkgMbedTls.dsc +++ b/CryptoPkg/CryptoPkgMbedTls.dsc @@ -51,10 +51,6 @@ RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf -[LibraryClasses.ARM, LibraryClasses.AARCH64] - # Add support for stack protector - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - [LibraryClasses.common.PEIM] PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf From 8c21bc715713cc788507aa70d080cf5976ec93af Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 23 Jul 2024 15:33:05 -0700 Subject: [PATCH 247/280] DynamicTablesPkg: Add StackCheckLibNull Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- DynamicTablesPkg/DynamicTablesPkg.dsc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/DynamicTablesPkg/DynamicTablesPkg.dsc b/DynamicTablesPkg/DynamicTablesPkg.dsc index e4302f6b32dc..8cac9d579e37 100644 --- a/DynamicTablesPkg/DynamicTablesPkg.dsc +++ b/DynamicTablesPkg/DynamicTablesPkg.dsc @@ -34,8 +34,11 @@ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf +# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules +[LibraryClasses.common.SEC] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.ARM, LibraryClasses.AARCH64] - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf [Components.common] From e7c0ad366106839842f7b5f40a2f6efd87338b63 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 23 Jul 2024 15:33:51 -0700 Subject: [PATCH 248/280] EmbeddedPkg: Add StackCheckLibNull Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- EmbeddedPkg/EmbeddedPkg.dsc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc index 4b8a943839ee..503d7cc6d506 100644 --- a/EmbeddedPkg/EmbeddedPkg.dsc +++ b/EmbeddedPkg/EmbeddedPkg.dsc @@ -122,15 +122,14 @@ [LibraryClasses.common.SEC] ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf + # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf [LibraryClasses.ARM, LibraryClasses.AARCH64] ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf - # Add support for GCC stack protector - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf ################################################################################ From ae5953dea06e0b79a808168892913f6ada07302d Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 23 Jul 2024 15:34:37 -0700 Subject: [PATCH 249/280] EmulatorPkg: Add StackCheckLibNull Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- EmulatorPkg/EmulatorPkg.dsc | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc index 1c356bc8c732..e4bf3ce4165e 100644 --- a/EmulatorPkg/EmulatorPkg.dsc +++ b/EmulatorPkg/EmulatorPkg.dsc @@ -151,6 +151,8 @@ PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf TimerLib|EmulatorPkg/Library/PeiTimerLib/PeiTimerLib.inf + # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf [LibraryClasses.common.USER_DEFINED, LibraryClasses.common.BASE] DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf @@ -319,13 +321,25 @@ # Emulator, OS WIN application # CLANGPDB is cross OS tool chain. It depends on WIN_HOST_BUILD flag # to build WinHost application. + # + # USER_DEFINED components skip normal NULL lib linking, so we have to link this + # specially here for the libs that have stack guard enabled ## - EmulatorPkg/Win/Host/WinHost.inf + EmulatorPkg/Win/Host/WinHost.inf { + + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + } !else ## # Emulator, OS POSIX application + # + # USER_DEFINED components skip normal NULL lib linking, so we have to link this + # specially here for the libs that have stack guard enabled ## - EmulatorPkg/Unix/Host/Host.inf + EmulatorPkg/Unix/Host/Host.inf { + + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + } !endif !endif From 6f0ba2047114be3eb4439ee4b533e0f8ab96d6e5 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 23 Jul 2024 15:35:18 -0700 Subject: [PATCH 250/280] FatPkg: Add StackCheckLibNull Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- FatPkg/FatPkg.dsc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/FatPkg/FatPkg.dsc b/FatPkg/FatPkg.dsc index b97fe9a3dede..76dddaa6907e 100644 --- a/FatPkg/FatPkg.dsc +++ b/FatPkg/FatPkg.dsc @@ -49,6 +49,10 @@ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf +# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules +[LibraryClasses.common.SEC] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.PEIM] PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf @@ -56,9 +60,6 @@ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf -[LibraryClasses.ARM, LibraryClasses.AARCH64] - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - ################################################################################################### # # Components Section - list of the modules and components that will be processed by compilation From 715a695c3d0c6058efc308a585c15bcbdc8af4c7 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 23 Jul 2024 15:35:58 -0700 Subject: [PATCH 251/280] FmpDevicePkg: Add StackCheckLibNull Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- FmpDevicePkg/FmpDevicePkg.dsc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc index 8d2b490503a0..c38cbc480b72 100644 --- a/FmpDevicePkg/FmpDevicePkg.dsc +++ b/FmpDevicePkg/FmpDevicePkg.dsc @@ -72,9 +72,9 @@ FmpDependencyDeviceLib|FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.inf TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf -[LibraryClasses.ARM, LibraryClasses.AARCH64] - # Add support for stack protector - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf +# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules +[LibraryClasses.common.SEC] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf [LibraryClasses.ARM] ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf From 254e4cfa8ccdaa8aaad1118ca2bd9cba5e72137d Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Mon, 29 Jul 2024 16:06:38 -0700 Subject: [PATCH 252/280] IntelFsp2Pkg: Add StackCheckLibNull Adds the null instance of StackCheckLib to SEC modules Signed-off-by: Oliver Smith-Denny --- IntelFsp2Pkg/IntelFsp2Pkg.dsc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/IntelFsp2Pkg/IntelFsp2Pkg.dsc b/IntelFsp2Pkg/IntelFsp2Pkg.dsc index 991ab014904d..ea61c5d9b447 100644 --- a/IntelFsp2Pkg/IntelFsp2Pkg.dsc +++ b/IntelFsp2Pkg/IntelFsp2Pkg.dsc @@ -46,6 +46,10 @@ FspSecPlatformLib|IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf FspMultiPhaseLib|IntelFsp2Pkg/Library/BaseFspMultiPhaseLib/BaseFspMultiPhaseLib.inf +# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules +[LibraryClasses.common.SEC] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.PEIM, LibraryClasses.common.SEC] PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf From 847561eb53b390d1bc1f1c4df4a109f6e20f7f98 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Mon, 29 Jul 2024 16:07:48 -0700 Subject: [PATCH 253/280] IntelFsp2WrapperPkg: Add StackCheckLib Adds null version of StackCheckLib to SEC modules. Signed-off-by: Oliver Smith-Denny --- IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc index fe621244a61b..f904e6f258fe 100644 --- a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc +++ b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc @@ -57,6 +57,10 @@ Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf +# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules +[LibraryClasses.common.SEC] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.PEIM,LibraryClasses.common.PEI_CORE] PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf From 000b61eff831cbde0818c99c7065bb848c8709e2 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Fri, 14 Jun 2024 13:58:54 -0700 Subject: [PATCH 254/280] MdeModulePkg: Add StackCheckLib Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- MdeModulePkg/MdeModulePkg.dsc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 4317d09fff63..f8204f787553 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -109,6 +109,10 @@ IpmiCommandLib|MdeModulePkg/Library/BaseIpmiCommandLibNull/BaseIpmiCommandLibNull.inf SpiHcPlatformLib|MdeModulePkg/Library/BaseSpiHcPlatformLibNull/BaseSpiHcPlatformLibNull.inf +# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules +[LibraryClasses.common.SEC] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.EBC.PEIM] IoLib|MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf @@ -184,12 +188,6 @@ [LibraryClasses.ARM, LibraryClasses.AARCH64] LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf - # - # Since software stack checking may be heuristically enabled by the compiler - # include BaseStackCheckLib unconditionally. - # - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - [LibraryClasses.EBC, LibraryClasses.RISCV64, LibraryClasses.LOONGARCH64] LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf From fefd0178517ce7424e02c995979834158210b720 Mon Sep 17 00:00:00 2001 From: Taylor Beebe Date: Fri, 14 Jun 2024 14:00:18 -0700 Subject: [PATCH 255/280] NetworkPkg: Add StackCheckLib Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- NetworkPkg/NetworkPkg.dsc | 5 ++++- NetworkPkg/Test/NetworkPkgHostTest.dsc | 3 --- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc index 4c3737440da6..f008790f30f8 100644 --- a/NetworkPkg/NetworkPkg.dsc +++ b/NetworkPkg/NetworkPkg.dsc @@ -62,6 +62,10 @@ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf +# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules +[LibraryClasses.common.SEC] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.UEFI_DRIVER] HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf @@ -72,7 +76,6 @@ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf [LibraryClasses.ARM, LibraryClasses.AARCH64] - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf [LibraryClasses.ARM] diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc index a17a7d00216c..667be9558724 100644 --- a/NetworkPkg/Test/NetworkPkgHostTest.dsc +++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc @@ -88,9 +88,6 @@ DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf -[LibraryClasses.ARM, LibraryClasses.AARCH64] - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - [LibraryClasses.ARM] RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf From 538b10f157b2db2359ed039a4aa0860118ed09dc Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 23 Jul 2024 15:23:21 -0700 Subject: [PATCH 256/280] OvmfPkg: Add StackCheckLibNull Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- OvmfPkg/AmdSev/AmdSevX64.dsc | 3 +++ OvmfPkg/Bhyve/BhyveX64.dsc | 3 +++ OvmfPkg/CloudHv/CloudHvX64.dsc | 3 +++ OvmfPkg/IntelTdx/IntelTdxX64.dsc | 3 +++ OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc | 6 +++--- OvmfPkg/Microvm/MicrovmX64.dsc | 3 +++ OvmfPkg/OvmfPkgIa32.dsc | 1 + OvmfPkg/OvmfPkgIa32X64.dsc | 1 + OvmfPkg/OvmfPkgX64.dsc | 1 + OvmfPkg/OvmfXen.dsc | 1 + OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc | 7 +++---- 11 files changed, 25 insertions(+), 7 deletions(-) diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc index 40553c00198d..1f5837d6e723 100644 --- a/OvmfPkg/AmdSev/AmdSevX64.dsc +++ b/OvmfPkg/AmdSev/AmdSevX64.dsc @@ -232,6 +232,9 @@ CcExitLib|OvmfPkg/Library/CcExitLib/SecCcExitLib.inf MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf + # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.PEI_CORE] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc index 0689d6442f69..2f5fb46a2e67 100644 --- a/OvmfPkg/Bhyve/BhyveX64.dsc +++ b/OvmfPkg/Bhyve/BhyveX64.dsc @@ -256,6 +256,9 @@ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf + # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.PEI_CORE] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc index 3dcefb189623..1a8d3c4911cf 100644 --- a/OvmfPkg/CloudHv/CloudHvX64.dsc +++ b/OvmfPkg/CloudHv/CloudHvX64.dsc @@ -269,6 +269,9 @@ CcExitLib|OvmfPkg/Library/CcExitLib/SecCcExitLib.inf MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf + # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.PEI_CORE] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc index fc1332598e24..fbda01bd7582 100644 --- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc +++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc @@ -240,6 +240,9 @@ PeilessStartupLib|OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf CcProbeLib|OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf + # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.DXE_CORE] HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf diff --git a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc index 9064058bc510..755892737b12 100644 --- a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc +++ b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc @@ -102,9 +102,6 @@ TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf !endif - # For stack protector support - NULL | MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - BaseLib | MdePkg/Library/BaseLib/BaseLib.inf SafeIntLib | MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf TimeBaseLib | EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf @@ -197,6 +194,9 @@ PlatformHookLib | OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf CpuExceptionHandlerLib | UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf + # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules + NULL | MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.PEI_CORE] PcdLib | MdePkg/Library/PeiPcdLib/PeiPcdLib.inf HobLib | MdePkg/Library/PeiHobLib/PeiHobLib.inf diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc index 1196ba98c90e..6fe8dfd2880e 100644 --- a/OvmfPkg/Microvm/MicrovmX64.dsc +++ b/OvmfPkg/Microvm/MicrovmX64.dsc @@ -277,6 +277,9 @@ CcExitLib|OvmfPkg/Library/CcExitLib/SecCcExitLib.inf MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf + # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.PEI_CORE] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 3f68d4d63b72..5e2086eb3309 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -686,6 +686,7 @@ OvmfPkg/Sec/SecMain.inf { NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf } # diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 67730b0f90b8..ef04ae21a734 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -699,6 +699,7 @@ OvmfPkg/Sec/SecMain.inf { NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf } # diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index f4ff2e321a09..e7fc7a9410f2 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -720,6 +720,7 @@ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf NULL|OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf } # diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc index f6846c20ff40..ac7d18196909 100644 --- a/OvmfPkg/OvmfXen.dsc +++ b/OvmfPkg/OvmfXen.dsc @@ -525,6 +525,7 @@ OvmfPkg/Sec/SecMain.inf { NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf } # diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc index 30e51790aca1..9cf743c842bc 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc +++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc @@ -76,10 +76,6 @@ TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf !endif - - # Add support for GCC stack protector - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - # RISC-V Architectural Libraries CpuExceptionHandlerLib|UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf RiscVSbiLib|MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf @@ -156,6 +152,9 @@ PrePiHobListPointerLib|OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf + # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.DXE_CORE] PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf From a275f1018607e5571384b756f92dbdae3cf84c83 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Mon, 29 Jul 2024 16:55:41 -0700 Subject: [PATCH 257/280] PcAtChipsetPkg: Add StackCheckLib Add Null implementation of StackCheckLib. Signed-off-by: Oliver Smith-Denny --- PcAtChipsetPkg/PcAtChipsetPkg.dsc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PcAtChipsetPkg/PcAtChipsetPkg.dsc b/PcAtChipsetPkg/PcAtChipsetPkg.dsc index 2f02ecf6fd11..73f8198f68fd 100644 --- a/PcAtChipsetPkg/PcAtChipsetPkg.dsc +++ b/PcAtChipsetPkg/PcAtChipsetPkg.dsc @@ -45,6 +45,10 @@ ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf +# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules +[LibraryClasses.common.SEC] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [Components] PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf From e4c3c3eb65daa557dac40b4c68cc3589cd674986 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 23 Jul 2024 15:24:54 -0700 Subject: [PATCH 258/280] PrmPkg: Add StackCheckLibNull Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- PrmPkg/PrmPkg.dsc | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/PrmPkg/PrmPkg.dsc b/PrmPkg/PrmPkg.dsc index 3e9126c32115..8eeb393cd19c 100644 --- a/PrmPkg/PrmPkg.dsc +++ b/PrmPkg/PrmPkg.dsc @@ -40,12 +40,13 @@ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf +# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules +[LibraryClasses.common.SEC] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.IA32, LibraryClasses.X64] MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf -[LibraryClasses.AARCH64] - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - [LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.UEFI_APPLICATION] # # EDK II Packages @@ -149,10 +150,6 @@ # $(PLATFORM_PACKAGE)/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf -[Components.AARCH64] - # Add support for GCC stack protector - MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - [BuildOptions] # Force deprecated interfaces off *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES From 78d5d274707c90a73781341fb0ffa440348a34c4 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 23 Jul 2024 15:27:48 -0700 Subject: [PATCH 259/280] RedfishPkg: Add StackCheckLibNull Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- RedfishPkg/RedfishPkg.dsc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc index b4c025831471..97f20597d244 100644 --- a/RedfishPkg/RedfishPkg.dsc +++ b/RedfishPkg/RedfishPkg.dsc @@ -52,11 +52,11 @@ IpmiLib|MdeModulePkg/Library/BaseIpmiLibNull/BaseIpmiLibNull.inf IpmiCommandLib|MdeModulePkg/Library/BaseIpmiCommandLibNull/BaseIpmiCommandLibNull.inf +# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules +[LibraryClasses.common.SEC] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.ARM, LibraryClasses.AARCH64] - # - # This library provides the instrinsic functions generated by a given compiler. - # - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf [Components] From 7ca87dcc6a4611278af26200e555220ae67fd6c6 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 23 Jul 2024 15:28:43 -0700 Subject: [PATCH 260/280] SecurityPkg: Add StackCheckLibNull Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- SecurityPkg/SecurityPkg.dsc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index bc991410a1f9..f6a3f49f12aa 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -89,10 +89,11 @@ PlatformLibWrapper|SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.inf MemLibWrapper|SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.inf -[LibraryClasses.ARM, LibraryClasses.AARCH64] - # Add support for GCC stack protector - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf +# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules +[LibraryClasses.common.SEC] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf +[LibraryClasses.ARM, LibraryClasses.AARCH64] ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf ArmTrngLib|MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.inf From ce347727a04bfa8db43fc809771f42fcb7f630dd Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 23 Jul 2024 15:29:27 -0700 Subject: [PATCH 261/280] SignedCapsulePkg: Add StackCheckLibNull Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- SignedCapsulePkg/SignedCapsulePkg.dsc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SignedCapsulePkg/SignedCapsulePkg.dsc b/SignedCapsulePkg/SignedCapsulePkg.dsc index e3e62d03f6a4..1217d24b8adc 100644 --- a/SignedCapsulePkg/SignedCapsulePkg.dsc +++ b/SignedCapsulePkg/SignedCapsulePkg.dsc @@ -95,13 +95,13 @@ PlatformFlashAccessLib|SignedCapsulePkg/Library/PlatformFlashAccessLibNull/PlatformFlashAccessLibNull.inf RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf +# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules +[LibraryClasses.common.SEC] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.ARM] ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf -[LibraryClasses.AARCH64, LibraryClasses.ARM] - # Add support for GCC stack protector - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - [LibraryClasses.ARM] RngLib|MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf From 2e8fb6b406b962fdc0d0920f28c4fa1389696579 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Fri, 14 Jun 2024 14:03:11 -0700 Subject: [PATCH 262/280] ShellPkg: Add StackCheckLib Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- ShellPkg/ShellPkg.dsc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ShellPkg/ShellPkg.dsc b/ShellPkg/ShellPkg.dsc index a8ae1deaae14..029a22fc7997 100644 --- a/ShellPkg/ShellPkg.dsc +++ b/ShellPkg/ShellPkg.dsc @@ -65,9 +65,9 @@ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf -[LibraryClasses.ARM,LibraryClasses.AARCH64] - # Add support for GCC stack protector - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf +# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules +[LibraryClasses.common.SEC] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf [PcdsFixedAtBuild] gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF From d7a0a7ae4a87022c9938a42a00a523c276be4fa2 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Mon, 29 Jul 2024 16:56:31 -0700 Subject: [PATCH 263/280] SourceLevelDebugPkg: Add StackCheckLib Add null implementation of StackCheckLib Signed-off-by: Oliver Smith-Denny --- SourceLevelDebugPkg/SourceLevelDebugPkg.dsc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc b/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc index 986dd5a769d3..1b9a99b6ab57 100644 --- a/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc +++ b/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc @@ -52,6 +52,10 @@ !endif !endif +# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules +[LibraryClasses.common.SEC] + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.PEIM] PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf From 7b4b1d2bd3f1c3fb7b8a2f72bac08a4eeb9c3a6e Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Fri, 14 Jun 2024 14:03:47 -0700 Subject: [PATCH 264/280] StandaloneMmPkg: Add StackCheckLib Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny --- StandaloneMmPkg/StandaloneMmPkg.dsc | 2 -- 1 file changed, 2 deletions(-) diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc index 34a7e55cbc79..51dd134ef9da 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -79,8 +79,6 @@ CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf PeCoffExtraActionLib|StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - [LibraryClasses.common.MM_CORE_STANDALONE] HobLib|StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf From dfc397133bc88de5589c93645eda320eb4aefefb Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Mon, 29 Jul 2024 14:52:19 -0700 Subject: [PATCH 265/280] UefiCpuPkg: Add StackCheckLib SecCore and SecCoreNative require StackCheckLib and so the NULL instance is linked against them here. Signed-off-by: Oliver Smith-Denny --- UefiCpuPkg/UefiCpuPkg.dsc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 6459ba8f1ab2..f173bba87e4b 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -173,8 +173,14 @@ UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf - UefiCpuPkg/SecCore/SecCore.inf - UefiCpuPkg/SecCore/SecCoreNative.inf + UefiCpuPkg/SecCore/SecCore.inf { + + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + } + UefiCpuPkg/SecCore/SecCoreNative.inf { + + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + } UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf { From 17744fc9ce655e3ffcbaa358c039c38831f385f2 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Mon, 29 Jul 2024 16:57:18 -0700 Subject: [PATCH 266/280] UefiPayloadPkg: Add StackCheckLib Add null implementation of StackCheckLib Signed-off-by: Oliver Smith-Denny --- UefiPayloadPkg/UefiPayloadPkg.dsc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 9a73c7fd80aa..3c0f2d699b0b 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -352,6 +352,9 @@ SerialPortLib|UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf !endif + # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + [LibraryClasses.common.DXE_CORE] DxeHobListLib|UefiPayloadPkg/Library/DxeHobListLibNull/DxeHobListLibNull.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf From 5e07b970940ec1bdbcbec01e733b20532c0b547c Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Fri, 14 Jun 2024 14:05:14 -0700 Subject: [PATCH 267/280] UnitTestFrameworkPkg: Add StackCheckLib Add StackCheckLib for Target and Host based unit tests. Host based unit tests are treated specially, because MSVC built host based unit tests use the MSVC C runtime lib to provide the stack cookie definitions, but GCC built host based unit tests use our implementation, as we do not link against a C runtime lib that provides the definitions. Signed-off-by: Oliver Smith-Denny --- UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc | 1 + UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc | 8 +------- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc index 0747229d0597..c56db1819c40 100644 --- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc +++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc @@ -23,6 +23,7 @@ UefiBootServicesTableLib|UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.inf PeiServicesTablePointerLib|UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.inf NULL|UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.inf + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNullHostApplication.inf [BuildOptions] MSFT:*_*_*_CC_FLAGS = /MT diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc index fdec9c6e0026..c0c546db5371 100644 --- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc +++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc @@ -28,6 +28,7 @@ UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf UnitTestPersistenceLib|UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf + NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf [LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM] NULL|UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf @@ -44,13 +45,6 @@ [LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION] NULL|UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf -[LibraryClasses.ARM, LibraryClasses.AARCH64] - # - # Since software stack checking may be heuristically enabled by the compiler - # include BaseStackCheckLib unconditionally. - # - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf From cac0955658cb591d4629bf90aaa542a66e25be55 Mon Sep 17 00:00:00 2001 From: Taylor Beebe Date: Fri, 14 Jun 2024 14:07:33 -0700 Subject: [PATCH 268/280] BaseTools: Update Stack Cookie Logic This patch updates the GenC logic to generate a random stack cookie value for the stack check libraries. These random values improve security for modules which cannot update the global intrinsics. If the stack cookie value is randomized in the AutoGen.h file each build, the build system will determine the module/library must be rebuilt causing effectively a clean build every time. This also makes binary reproducibility impossible. This patch updates the early build scripts to create 32 and 64-bit JSON files in the build output directory which each contain 100 randomized stack cookie values for each bitwidth. If the JSON files are already present, then they are not recreated which allows them to be stored and moved to other builds for binary reproducibility. Because they are in the build directory, a clean build will cause the values to be regenerated. The logic which creates AutoGen.h will read these JSON files and use a hash of the module GUID (the hash seed is fixed in Basetools) to index into the array of stack cookie values for the module bitwidth. This model is necessary because there isn't thread-consistent data so we cannot use a locking mechanism to ensure only one thread is writing to the stack cookie files at a time. With this model, the build threads only need to read from the files. Signed-off-by: Oliver Smith-Denny --- BaseTools/Source/Python/AutoGen/GenC.py | 31 ++++++++++++++++++++ BaseTools/Source/Python/Common/GlobalData.py | 3 +- BaseTools/Source/Python/build/build.py | 21 +++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py index 5ad10cee2898..86991e7675de 100755 --- a/BaseTools/Source/Python/AutoGen/GenC.py +++ b/BaseTools/Source/Python/AutoGen/GenC.py @@ -21,6 +21,9 @@ from .GenPcdDb import CreatePcdDatabaseCode from .IdfClassObject import * +import json +import secrets + ## PCD type string gItemTypeStringDatabase = { TAB_PCDS_FEATURE_FLAG : TAB_PCDS_FIXED_AT_BUILD, @@ -2039,6 +2042,34 @@ def CreateFooterCode(Info, AutoGenC, AutoGenH): def CreateCode(Info, AutoGenC, AutoGenH, StringH, UniGenCFlag, UniGenBinBuffer, StringIdf, IdfGenCFlag, IdfGenBinBuffer): CreateHeaderCode(Info, AutoGenC, AutoGenH) + # The only 32 bit archs we have are IA32 and ARM, everything else is 64 bit + Bitwidth = 32 if Info.Arch == 'IA32' or Info.Arch == 'ARM' else 64 + + if GlobalData.gStackCookieValues64 == [] and os.path.exists(os.path.join(Info.PlatformInfo.BuildDir, "StackCookieValues64.json")): + with open (os.path.join(Info.PlatformInfo.BuildDir, "StackCookieValues64.json"), "r") as file: + GlobalData.gStackCookieValues64 = json.load(file) + if GlobalData.gStackCookieValues32 == [] and os.path.exists(os.path.join(Info.PlatformInfo.BuildDir, "StackCookieValues32.json")): + with open (os.path.join(Info.PlatformInfo.BuildDir, "StackCookieValues32.json"), "r") as file: + GlobalData.gStackCookieValues32 = json.load(file) + + try: + if Bitwidth == 32: + CookieValue = int(GlobalData.gStackCookieValues32[hash(Info.Guid) % len(GlobalData.gStackCookieValues32)]) + else: + CookieValue = int(GlobalData.gStackCookieValues64[hash(Info.Guid) % len(GlobalData.gStackCookieValues64)]) + except: + EdkLogger.warn("build", "Failed to get Stack Cookie Value List! Generating random value.", ExtraData="[%s]" % str(Info)) + if Bitwidth == 32: + CookieValue = secrets.randbelow (0xFFFFFFFF) + else: + CookieValue = secrets.randbelow (0xFFFFFFFFFFFFFFFF) + + AutoGenH.Append(( + '#define STACK_COOKIE_VALUE 0x%XULL\n' % CookieValue + if Bitwidth == 64 else + '#define STACK_COOKIE_VALUE 0x%X\n' % CookieValue + )) + CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH) CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH) CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH) diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Source/Python/Common/GlobalData.py index 11849e863f53..dd5316d2831e 100755 --- a/BaseTools/Source/Python/Common/GlobalData.py +++ b/BaseTools/Source/Python/Common/GlobalData.py @@ -122,4 +122,5 @@ gSikpAutoGenCache = set() # Common lock for the file access in multiple process AutoGens file_lock = None - +gStackCookieValues32 = [] +gStackCookieValues64 = [] diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py index 51fb1f433eb7..ce1bb8712693 100755 --- a/BaseTools/Source/Python/build/build.py +++ b/BaseTools/Source/Python/build/build.py @@ -28,6 +28,8 @@ from linecache import getlines from subprocess import Popen,PIPE, STDOUT from collections import OrderedDict, defaultdict +import json +import secrets from AutoGen.PlatformAutoGen import PlatformAutoGen from AutoGen.ModuleAutoGen import ModuleAutoGen @@ -282,6 +284,22 @@ def LaunchCommand(Command, WorkingDir,ModuleAuto = None): iau.CreateDepsTarget() return "%dms" % (int(round((time.time() - BeginTime) * 1000))) +def GenerateStackCookieValues(): + if GlobalData.gBuildDirectory == "": + return + + # Check if the 32 bit values array needs to be created + if not os.path.exists(os.path.join(GlobalData.gBuildDirectory, "StackCookieValues32.json")): + StackCookieValues32 = [secrets.randbelow(0xFFFFFFFF) for _ in range(0, 100)] + with open (os.path.join(GlobalData.gBuildDirectory, "StackCookieValues32.json"), "w") as file: + json.dump(StackCookieValues32, file) + + # Check if the 64 bit values array needs to be created + if not os.path.exists(os.path.join(GlobalData.gBuildDirectory, "StackCookieValues64.json")): + StackCookieValues64 = [secrets.randbelow(0xFFFFFFFFFFFFFFFF) for _ in range(0, 100)] + with open (os.path.join(GlobalData.gBuildDirectory, "StackCookieValues64.json"), "w") as file: + json.dump(StackCookieValues64, file) + ## The smallest unit that can be built in multi-thread build mode # # This is the base class of build unit. The "Obj" parameter must provide @@ -1794,6 +1812,7 @@ def _BuildPlatform(self): self.UniFlag, self.Progress ) + GenerateStackCookieValues() self.Fdf = Wa.FdfFile self.LoadFixAddress = Wa.Platform.LoadFixAddress self.BuildReport.AddPlatformReport(Wa) @@ -1897,6 +1916,7 @@ def _BuildModule(self): self.Progress, self.ModuleFile ) + GenerateStackCookieValues() self.Fdf = Wa.FdfFile self.LoadFixAddress = Wa.Platform.LoadFixAddress Wa.CreateMakeFile(False) @@ -2147,6 +2167,7 @@ def PerformAutoGen(self,BuildTarget,ToolChain): self.UniFlag, self.Progress ) + GenerateStackCookieValues() self.Fdf = Wa.FdfFile self.LoadFixAddress = Wa.Platform.LoadFixAddress self.BuildReport.AddPlatformReport(Wa) From f53f029122d4493e9db95e2424dd8f067f247661 Mon Sep 17 00:00:00 2001 From: Taylor Beebe Date: Fri, 14 Jun 2024 14:09:54 -0700 Subject: [PATCH 269/280] BaseTools: Add Stack Cookie Support to MSVC and GCC IA32/X64/ARM/AARCH64 This patch directs MSVC and GCC to build stack cookie support into binaries. Signed-off-by: Oliver Smith-Denny --- BaseTools/Conf/tools_def.template | 65 ++++++++++++++++--------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index c2c24ca98c19..87f035a56e64 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -21,8 +21,9 @@ # - Add GCC and GCCNOLTO # - Deprecate GCC48, GCC49 and GCC5. # 3.01 - Add toolchain for VS2022 +# 3.02 - Enable stack cookies for IA32, X64, ARM, and AARCH64 builds for GCC and MSVC # -#!VERSION=3.01 +#!VERSION=3.02 IDENTIFIER = Default TOOL_CHAIN_CONF @@ -635,9 +636,9 @@ NOOPT_VS2017_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF *_VS2019_IA32_PP_PATH = DEF(VS2019_BIN_IA32)\cl.exe *_VS2019_IA32_ASM_PATH = DEF(VS2019_BIN_IA32)\ml.exe - DEBUG_VS2019_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Gw -RELEASE_VS2019_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw -NOOPT_VS2019_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Od + DEBUG_VS2019_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Gw +RELEASE_VS2019_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw +NOOPT_VS2019_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Od DEBUG_VS2019_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd /Zi RELEASE_VS2019_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd @@ -665,9 +666,9 @@ NOOPT_VS2019_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /O *_VS2019_X64_DLINK_PATH = DEF(VS2019_BIN_X64)\link.exe *_VS2019_X64_ASLDLINK_PATH = DEF(VS2019_BIN_X64)\link.exe - DEBUG_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Gw /volatileMetadata- -RELEASE_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Gw /volatileMetadata- -NOOPT_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Od /volatileMetadata- + DEBUG_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Gw /volatileMetadata- +RELEASE_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Gw /volatileMetadata- +NOOPT_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Od /volatileMetadata- DEBUG_VS2019_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi RELEASE_VS2019_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd @@ -695,9 +696,9 @@ NOOPT_VS2019_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:428 *_VS2019_ARM_ASLPP_PATH = DEF(VS2019_BIN_ARM)\cl.exe *_VS2019_ARM_ASLDLINK_PATH = DEF(VS2019_BIN_ARM)\link.exe - DEBUG_VS2019_ARM_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi- -RELEASE_VS2019_ARM_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi- -NOOPT_VS2019_ARM_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi- + DEBUG_VS2019_ARM_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi- +RELEASE_VS2019_ARM_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi- +NOOPT_VS2019_ARM_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi- DEBUG_VS2019_ARM_ASM_FLAGS = /nologo /g RELEASE_VS2019_ARM_ASM_FLAGS = /nologo @@ -721,9 +722,9 @@ NOOPT_VS2019_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF *_VS2019_AARCH64_ASLPP_PATH = DEF(VS2019_BIN_AARCH64)\cl.exe *_VS2019_AARCH64_ASLDLINK_PATH = DEF(VS2019_BIN_AARCH64)\link.exe - DEBUG_VS2019_AARCH64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi- -RELEASE_VS2019_AARCH64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi- -NOOPT_VS2019_AARCH64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi- + DEBUG_VS2019_AARCH64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi- +RELEASE_VS2019_AARCH64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi- +NOOPT_VS2019_AARCH64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi- DEBUG_VS2019_AARCH64_ASM_FLAGS = /nologo /g RELEASE_VS2019_AARCH64_ASM_FLAGS = /nologo @@ -778,9 +779,9 @@ NOOPT_VS2019_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF *_VS2022_IA32_ASM_PATH = DEF(VS2022_BIN_IA32)\ml.exe *_VS2022_IA32_MAKE_FLAGS = /nologo - DEBUG_VS2022_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Gw -RELEASE_VS2022_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw -NOOPT_VS2022_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Od + DEBUG_VS2022_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Gw +RELEASE_VS2022_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw +NOOPT_VS2022_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Od DEBUG_VS2022_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd /Zi RELEASE_VS2022_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd @@ -808,9 +809,9 @@ NOOPT_VS2022_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /O *_VS2022_X64_DLINK_PATH = DEF(VS2022_BIN_X64)\link.exe *_VS2022_X64_ASLDLINK_PATH = DEF(VS2022_BIN_X64)\link.exe - DEBUG_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Gw /volatileMetadata- -RELEASE_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Gw /volatileMetadata- -NOOPT_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Od /volatileMetadata- + DEBUG_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Gw /volatileMetadata- +RELEASE_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Gw /volatileMetadata- +NOOPT_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Od /volatileMetadata- DEBUG_VS2022_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi RELEASE_VS2022_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd @@ -839,9 +840,9 @@ NOOPT_VS2022_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:428 *_VS2022_ARM_ASLDLINK_PATH = DEF(VS2022_BIN_ARM)\link.exe *_VS2022_ARM_MAKE_FLAGS = /nologo - DEBUG_VS2022_ARM_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi- -RELEASE_VS2022_ARM_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi- -NOOPT_VS2022_ARM_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi- + DEBUG_VS2022_ARM_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi- +RELEASE_VS2022_ARM_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi- +NOOPT_VS2022_ARM_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi- DEBUG_VS2022_ARM_ASM_FLAGS = /nologo /g RELEASE_VS2022_ARM_ASM_FLAGS = /nologo @@ -866,9 +867,9 @@ NOOPT_VS2022_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF *_VS2022_AARCH64_ASLDLINK_PATH = DEF(VS2022_BIN_AARCH64)\link.exe *_VS2022_AARCH64_MAKE_FLAGS = /nologo - DEBUG_VS2022_AARCH64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi- -RELEASE_VS2022_AARCH64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi- -NOOPT_VS2022_AARCH64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi- + DEBUG_VS2022_AARCH64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi- +RELEASE_VS2022_AARCH64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi- +NOOPT_VS2022_AARCH64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi- DEBUG_VS2022_AARCH64_ASM_FLAGS = /nologo /g RELEASE_VS2022_AARCH64_ASM_FLAGS = /nologo @@ -894,11 +895,13 @@ NOOPT_*_*_OBJCOPY_ADDDEBUGFLAG = --add-gnu-debuglink="$(DEBUG_DIR)/$(MODULE_ *_*_*_DTCPP_PATH = DEF(DTCPP_BIN) *_*_*_DTC_PATH = DEF(DTC_BIN) -DEFINE GCC_ALL_CC_FLAGS = -g -Os -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -fno-common -DEFINE GCC_ARM_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -mabi=aapcs -fno-short-enums -funsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -Wno-address -mthumb -fno-pic -fno-pie +# All supported GCC archs except LOONGARCH64 support -mstack-protector-guard=global, so set that on everything except LOONGARCH64 +DEFINE GCC_ALL_CC_FLAGS = -g -Os -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -fno-common -fstack-protector +DEFINE GCC_IA32_X64_CC_FLAGS = -mstack-protector-guard=global +DEFINE GCC_ARM_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -mabi=aapcs -fno-short-enums -funsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -Wno-address -mthumb -fno-pic -fno-pie -mstack-protector-guard=global DEFINE GCC_LOONGARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mabi=lp64d -fno-asynchronous-unwind-tables -Wno-address -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections DEFINE GCC_ARM_CC_XIPFLAGS = -mno-unaligned-access -DEFINE GCC_AARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -fno-short-enums -fverbose-asm -funsigned-char -ffunction-sections -fdata-sections -Wno-address -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pic -fno-pie -ffixed-x18 +DEFINE GCC_AARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -fno-short-enums -fverbose-asm -funsigned-char -ffunction-sections -fdata-sections -Wno-address -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pic -fno-pie -ffixed-x18 -mstack-protector-guard=global DEFINE GCC_AARCH64_CC_XIPFLAGS = -mstrict-align -mgeneral-regs-only DEFINE GCC_RISCV64_CC_XIPFLAGS = -mstrict-align -mgeneral-regs-only DEFINE GCC_DLINK_FLAGS_COMMON = -nostdlib --pie @@ -935,8 +938,8 @@ DEFINE GCC_DEPS_FLAGS = -MMD -MF $@.deps DEFINE GCC48_ALL_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -ffunction-sections -fdata-sections -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings DEFINE GCC48_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x20 -DEFINE GCC48_IA32_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) -m32 -march=i586 -malign-double -fno-stack-protector -D EFI32 -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer -DEFINE GCC48_X64_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer +DEFINE GCC48_IA32_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m32 -march=i586 -malign-double -D EFI32 -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer +DEFINE GCC48_X64_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer DEFINE GCC48_IA32_X64_ASLDLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable DEFINE GCC48_IA32_X64_DLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive DEFINE GCC48_IA32_DLINK2_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0x220 DEF(GCC_DLINK2_FLAGS_COMMON) @@ -945,7 +948,7 @@ DEFINE GCC48_X64_DLINK2_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0x228 DEF DEFINE GCC48_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEFINE GCC48_ARM_ASM_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_ASM_FLAGS) -mlittle-endian DEFINE GCC48_AARCH64_ASM_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_ASM_FLAGS) -mlittle-endian -DEFINE GCC48_ARM_CC_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_ARM_CC_FLAGS) -fstack-protector -mword-relocations +DEFINE GCC48_ARM_CC_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_ARM_CC_FLAGS) -mword-relocations DEFINE GCC48_ARM_CC_XIPFLAGS = DEF(GCC_ARM_CC_XIPFLAGS) DEFINE GCC48_AARCH64_CC_FLAGS = $(PLATFORM_FLAGS) -mcmodel=large DEF(GCC_AARCH64_CC_FLAGS) DEFINE GCC48_AARCH64_CC_XIPFLAGS = DEF(GCC_AARCH64_CC_XIPFLAGS) From a9b38305b64ef5997d0ba5f7d2797a75edd1f9ef Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Tue, 23 Jul 2024 16:07:25 -0700 Subject: [PATCH 270/280] MdePkg: Remove Old Stack Check Lib Implementation Now that the new stack check lib implementation is being used everywhere, remove the old one. Signed-off-by: Oliver Smith-Denny --- .../BaseStackCheckLib/BaseStackCheckGcc.c | 50 ------------------- .../BaseStackCheckLib/BaseStackCheckLib.inf | 39 --------------- .../BaseStackCheckLib/BaseStackCheckLib.uni | 16 ------ .../BaseStackCheckLib/BaseStackCheckNull.c | 9 ---- MdePkg/MdePkg.dsc | 1 - 5 files changed, 115 deletions(-) delete mode 100644 MdePkg/Library/BaseStackCheckLib/BaseStackCheckGcc.c delete mode 100644 MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf delete mode 100644 MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.uni delete mode 100644 MdePkg/Library/BaseStackCheckLib/BaseStackCheckNull.c diff --git a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckGcc.c b/MdePkg/Library/BaseStackCheckLib/BaseStackCheckGcc.c deleted file mode 100644 index ea168841b617..000000000000 --- a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckGcc.c +++ /dev/null @@ -1,50 +0,0 @@ -/** @file - Base Stack Check library for GCC/clang. - - Use -fstack-protector-all compiler flag to make the compiler insert the - __stack_chk_guard "canary" value into the stack and check the value prior - to exiting the function. If the "canary" is overwritten __stack_chk_fail() - is called. This is GCC specific code. - - Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. - Copyright (c) 2012, Apple Inc. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include -#include -#include - -/// "canary" value that is inserted by the compiler into the stack frame. -VOID *__stack_chk_guard = (VOID *)0x0AFF; - -// If ASLR was enabled we could use -// void (*__stack_chk_guard)(void) = __stack_chk_fail; - -/** - Error path for compiler generated stack "canary" value check code. If the - stack canary has been overwritten this function gets called on exit of the - function. -**/ -VOID -__stack_chk_fail ( - VOID - ) -{ - UINT8 DebugPropertyMask; - - DEBUG ((DEBUG_ERROR, "STACK FAULT: Buffer Overflow at 0x%p.\n", RETURN_ADDRESS (0))); - - // - // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings even if - // BaseDebugLibNull is in use. - // - DebugPropertyMask = PcdGet8 (PcdDebugPropertyMask); - if ((DebugPropertyMask & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) { - CpuBreakpoint (); - } else if ((DebugPropertyMask & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) { - CpuDeadLoop (); - } -} diff --git a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf b/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf deleted file mode 100644 index b827645d72b9..000000000000 --- a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf +++ /dev/null @@ -1,39 +0,0 @@ -## @file -# Stack Check Library -# -# Stack Check Library -# -# Copyright (c) 2014, ARM Ltd. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = BaseStackCheckLib - MODULE_UNI_FILE = BaseStackCheckLib.uni - FILE_GUID = 5f6579f7-b648-4fdb-9f19-4c17e27e8eff - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = NULL - - -# -# VALID_ARCHITECTURES = ARM AARCH64 -# - -[Sources] - BaseStackCheckGcc.c | GCC - BaseStackCheckNull.c | MSFT - -[Packages] - MdePkg/MdePkg.dec - -[LibraryClasses] - BaseLib - DebugLib - -[Pcd] - gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask ## CONSUMES diff --git a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.uni b/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.uni deleted file mode 100644 index 03b9d7cd5320..000000000000 --- a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.uni +++ /dev/null @@ -1,16 +0,0 @@ -// /** @file -// Stack Check Library -// -// Stack Check Library -// -// Copyright (c) 2014, ARM Ltd. All rights reserved.
-// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Stack Check Library" - -#string STR_MODULE_DESCRIPTION #language en-US "Stack Check Library" - diff --git a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckNull.c b/MdePkg/Library/BaseStackCheckLib/BaseStackCheckNull.c deleted file mode 100644 index 32932002fa13..000000000000 --- a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckNull.c +++ /dev/null @@ -1,9 +0,0 @@ -/** @file - This file is purely empty as a work around for BaseStackCheck to pass MSVC build. - - Copyright (c) 2018, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -extern int __BaseStackCheckNull; diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 92809e4a7599..0f00172be100 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -197,7 +197,6 @@ [Components.ARM, Components.AARCH64] MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf - MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf [Components.RISCV64] From 964c22b8ea3b1c497fed0547f29e8338be26040a Mon Sep 17 00:00:00 2001 From: Ken Lautner Date: Wed, 28 Aug 2024 10:55:09 -0700 Subject: [PATCH 271/280] MdeModulePkg: Fix buffer overflow in MergeMemoryMap Check that the next map entry is valid before dereferencing to merge the guard pages. If the final entry is at the end of a page with no valid page following it, then this can cause an access violation. Signed-off-by: Kenneth Lautner --- MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c index 58b947423a0e..a11c455ab598 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c @@ -395,11 +395,14 @@ MergeMemoryMap ( NewMemoryMapEntry = MemoryMap; MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + *MemoryMapSize); while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { - CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); + CopyMem (NewMemoryMapEntry, MemoryMapEntry, DescriptorSize); NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); do { - MergeGuardPages (NewMemoryMapEntry, NextMemoryMapEntry->PhysicalStart); + if ((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) { + MergeGuardPages (NewMemoryMapEntry, NextMemoryMapEntry->PhysicalStart); + } + MemoryBlockLength = LShiftU64 (NewMemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT); if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) && (NewMemoryMapEntry->Type == NextMemoryMapEntry->Type) && From 52621088222cc6655069c4d63a2ecba5b1555d18 Mon Sep 17 00:00:00 2001 From: Leandro Becker Date: Tue, 27 Aug 2024 12:16:00 -0300 Subject: [PATCH 272/280] MdePkg/Http11.h: Add HTTP header definitions. Added HTTP header definitions for the following headers: "Content-Range", "Last-Modified" and "If-Unmodified-Since" Signed-off-by: Leandro Gustavo Biss Becker --- MdePkg/Include/IndustryStandard/Http11.h | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/MdePkg/Include/IndustryStandard/Http11.h b/MdePkg/Include/IndustryStandard/Http11.h index 2137ef1f1ac3..7636a9e92562 100644 --- a/MdePkg/Include/IndustryStandard/Http11.h +++ b/MdePkg/Include/IndustryStandard/Http11.h @@ -248,6 +248,34 @@ /// #define HTTP_EXPECT_100_CONTINUE "100-continue" +/// +/// Content-Range Response Header +/// The Content-Range response HTTP header indicates where in a +/// full body message a partial message belongs. +/// +#define HTTP_HEADER_CONTENT_RANGE "Content-Range" + +/// +/// Last-Modified Response Header +/// The Last-Modified response HTTP header contains a date and time when +/// the origin server believes the resource was last modified. It is used +/// as a validator to determine if the resource is the same as the +/// previously stored one. Less accurate than an ETag header, +/// it is a fallback mechanism. Conditional requests containing +/// If-Modified-Since or If-Unmodified-Since headers make use of this field. +/// +#define HTTP_HEADER_LAST_MODIFIED "Last-Modified" + +/// +/// If Unmodified Since Request Header +/// Makes the request for the resource conditional: the server will send +/// the requested resource or accept it in the case of a POST or another +/// non-safe method only if the resource has not been modified after the +/// date specified by this HTTP header. If the resource has been modified +/// after the specified date, the response will be a 412 Precondition Failed error. +/// +#define HTTP_HEADER_IF_UNMODIFIED_SINCE "If-Unmodified-Since" + #pragma pack() #endif From 69139e39bc9bd7410ee71a830b812fb74d21bdb4 Mon Sep 17 00:00:00 2001 From: Leandro Becker Date: Tue, 27 Aug 2024 12:17:10 -0300 Subject: [PATCH 273/280] NetworkPkg/HttpBootDxe: Resume an interrupted boot file download. When the boot file download operation is interrupted for some reason, HttpBootDxe will use HTTP Range header to try resume the download operation reusing the bytes downloaded so far. Signed-off-by: Leandro Gustavo Biss Becker --- NetworkPkg/HttpBootDxe/HttpBootClient.c | 182 +++++++++++++++++++++++- NetworkPkg/HttpBootDxe/HttpBootClient.h | 1 + NetworkPkg/HttpBootDxe/HttpBootDxe.h | 2 + NetworkPkg/HttpBootDxe/HttpBootDxe.inf | 6 +- NetworkPkg/HttpBootDxe/HttpBootImpl.c | 73 ++++++++-- NetworkPkg/NetworkPkg.dec | 10 ++ 6 files changed, 252 insertions(+), 22 deletions(-) diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.c b/NetworkPkg/HttpBootDxe/HttpBootClient.c index 40f64fcb6bf8..858e7c21034c 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootClient.c +++ b/NetworkPkg/HttpBootDxe/HttpBootClient.c @@ -923,6 +923,9 @@ HttpBootGetBootFileCallback ( BufferSize has been updated with the size needed to complete the request. @retval EFI_ACCESS_DENIED The server needs to authenticate the client. + @retval EFI_NOT_READY Data transfer has timed-out, call HttpBootGetBootFile again to resume + the download operation using HTTP Range headers. + @retval EFI_UNSUPPORTED Some HTTP response header is not supported. @retval Others Unexpected error happened. **/ @@ -955,6 +958,10 @@ HttpBootGetBootFile ( CHAR8 BaseAuthValue[80]; EFI_HTTP_HEADER *HttpHeader; CHAR8 *Data; + UINTN HeadersCount; + BOOLEAN ResumingOperation; + CHAR8 *ContentRangeResponseValue; + CHAR8 RangeValue[64]; ASSERT (Private != NULL); ASSERT (Private->HttpCreated); @@ -985,6 +992,16 @@ HttpBootGetBootFile ( } } + // Check if this is a previous download that has failed and need to be resumed + if ((!HeaderOnly) && + (Private->PartialTransferredSize > 0) && + (Private->BootFileSize == *BufferSize)) + { + ResumingOperation = TRUE; + } else { + ResumingOperation = FALSE; + } + // // Not found in cache, try to download it through HTTP. // @@ -1014,8 +1031,23 @@ HttpBootGetBootFile ( // Accept // User-Agent // [Authorization] + // [Range] + // [If-Match]|[If-Unmodified-Since] // - HttpIoHeader = HttpIoCreateHeader ((Private->AuthData != NULL) ? 4 : 3); + HeadersCount = 3; + if (Private->AuthData != NULL) { + HeadersCount++; + } + + if (ResumingOperation) { + HeadersCount++; + if (Private->LastModifiedOrEtag) { + HeadersCount++; + } + } + + HttpIoHeader = HttpIoCreateHeader (HeadersCount); + if (HttpIoHeader == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ERROR_2; @@ -1097,6 +1129,62 @@ HttpBootGetBootFile ( } } + // + // Add HTTP header field 5 (optional): Range + // + if (ResumingOperation) { + // Resuming a failed download. Prepare the HTTP Range Header + Status = AsciiSPrint ( + RangeValue, + sizeof (RangeValue), + "bytes=%lu-%lu", + Private->PartialTransferredSize, + Private->BootFileSize - 1 + ); + if (EFI_ERROR (Status)) { + goto ERROR_3; + } + + Status = HttpIoSetHeader (HttpIoHeader, "Range", RangeValue); + if (EFI_ERROR (Status)) { + goto ERROR_3; + } + + DEBUG ( + (DEBUG_WARN | DEBUG_INFO, + "HttpBootGetBootFile: Resuming failed download. Range: %a\n", + RangeValue) + ); + + // + // Add HTTP header field 6 (optional): If-Match or If-Unmodified-Since + // + if (Private->LastModifiedOrEtag) { + if (Private->LastModifiedOrEtag[0] == '"') { + // An ETag value starts with " + DEBUG ( + (DEBUG_WARN | DEBUG_INFO, + "HttpBootGetBootFile: If-Match=%a\n", + Private->LastModifiedOrEtag) + ); + // Add If-Match header with the ETag value got from the first request. + Status = HttpIoSetHeader (HttpIoHeader, HTTP_HEADER_IF_MATCH, Private->LastModifiedOrEtag); + } else { + DEBUG ( + (DEBUG_WARN | DEBUG_INFO, + "HttpBootGetBootFile: If-Unmodified-Since=%a\n", + Private->LastModifiedOrEtag) + ); + // Add If-Unmodified-Since header with the timestamp value (Last-Modified) got from the first request. + Status = HttpIoSetHeader (HttpIoHeader, HTTP_HEADER_IF_UNMODIFIED_SINCE, Private->LastModifiedOrEtag); + } + + if (EFI_ERROR (Status)) { + goto ERROR_3; + } + } + } + // // 2.2 Build the rest of HTTP request info. // @@ -1245,6 +1333,62 @@ HttpBootGetBootFile ( Cache->ImageType = *ImageType; } + // Cache ETag or Last-Modified response header value to + // be used when resuming an interrupted download. + HttpHeader = HttpFindHeader ( + ResponseData->HeaderCount, + ResponseData->Headers, + HTTP_HEADER_ETAG + ); + if (HttpHeader == NULL) { + HttpHeader = HttpFindHeader ( + ResponseData->HeaderCount, + ResponseData->Headers, + HTTP_HEADER_LAST_MODIFIED + ); + } + + if (HttpHeader) { + if (Private->LastModifiedOrEtag) { + FreePool (Private->LastModifiedOrEtag); + } + + Private->LastModifiedOrEtag = AllocateCopyPool (AsciiStrSize (HttpHeader->FieldValue), HttpHeader->FieldValue); + } + + // + // 3.2.2 Validate the range response. If operation is being resumed, + // server must respond with Content-Range. + // + if (ResumingOperation) { + HttpHeader = HttpFindHeader ( + ResponseData->HeaderCount, + ResponseData->Headers, + HTTP_HEADER_CONTENT_RANGE + ); + if ((HttpHeader == NULL) || + (AsciiStrnCmp (HttpHeader->FieldValue, "bytes", 5) != 0)) + { + Status = EFI_UNSUPPORTED; + goto ERROR_5; + } + + // Gets the total size of ranged data (Content-Range: -/) + // and check if it remains the same + ContentRangeResponseValue = AsciiStrStr (HttpHeader->FieldValue, "/"); + if (ContentRangeResponseValue == NULL) { + Status = EFI_INVALID_PARAMETER; + goto ERROR_5; + } + + ContentRangeResponseValue++; + ContentLength = AsciiStrDecimalToUintn (ContentRangeResponseValue); + if (ContentLength != *BufferSize) { + Status = EFI_INVALID_PARAMETER; + goto ERROR_5; + } + } + // // 3.3 Init a message-body parser from the header information. // @@ -1295,10 +1439,15 @@ HttpBootGetBootFile ( // In identity transfer-coding there is no need to parse the message body, // just download the message body to the user provided buffer directly. // + if (ResumingOperation && ((ContentLength + Private->PartialTransferredSize) > *BufferSize)) { + Status = EFI_INVALID_PARAMETER; + goto ERROR_6; + } + ReceivedSize = 0; while (ReceivedSize < ContentLength) { - ResponseBody.Body = (CHAR8 *)Buffer + ReceivedSize; - ResponseBody.BodyLength = *BufferSize - ReceivedSize; + ResponseBody.Body = (CHAR8 *)Buffer + (ReceivedSize + Private->PartialTransferredSize); + ResponseBody.BodyLength = *BufferSize - (ReceivedSize + Private->PartialTransferredSize); Status = HttpIoRecvResponse ( &Private->HttpIo, FALSE, @@ -1309,6 +1458,20 @@ HttpBootGetBootFile ( Status = ResponseBody.Status; } + if ((Status == EFI_TIMEOUT) || (Status == EFI_DEVICE_ERROR)) { + // For EFI_TIMEOUT and EFI_DEVICE_ERROR errors, we may resume the operation. + // We will not check if server sent Accept-Ranges header, because some back-ends + // do not report this header, even when supporting it. Know example: CloudFlare CDN Cache. + Private->PartialTransferredSize = ReceivedSize; + DEBUG ( + ( + DEBUG_WARN | DEBUG_INFO, + "HttpBootGetBootFile: Transfer error. Bytes transferred so far: %lu.\n", + ReceivedSize + ) + ); + } + goto ERROR_6; } @@ -1326,6 +1489,9 @@ HttpBootGetBootFile ( } } } + + // download completed, there is no more partial data + Private->PartialTransferredSize = 0; } else { // // In "chunked" transfer-coding mode, so we need to parse the received @@ -1385,9 +1551,13 @@ HttpBootGetBootFile ( // // 3.5 Message-body receive & parse is completed, we should be able to get the file size now. // - Status = HttpGetEntityLength (Parser, &ContentLength); - if (EFI_ERROR (Status)) { - goto ERROR_6; + if (!ResumingOperation) { + Status = HttpGetEntityLength (Parser, &ContentLength); + if (EFI_ERROR (Status)) { + goto ERROR_6; + } + } else { + ContentLength = Private->BootFileSize; } if (*BufferSize < ContentLength) { diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.h b/NetworkPkg/HttpBootDxe/HttpBootClient.h index 86a28bc91aa2..406eefb54298 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootClient.h +++ b/NetworkPkg/HttpBootDxe/HttpBootClient.h @@ -108,6 +108,7 @@ HttpBootCreateHttpIo ( BufferSize has been updated with the size needed to complete the request. @retval EFI_ACCESS_DENIED The server needs to authenticate the client. + @retval EFI_UNSUPPORTED Some HTTP response header is not supported. @retval Others Unexpected error happened. **/ diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.h b/NetworkPkg/HttpBootDxe/HttpBootDxe.h index 5ff8ad4698b2..193235dabbfc 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDxe.h +++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.h @@ -214,6 +214,8 @@ struct _HTTP_BOOT_PRIVATE_DATA { CHAR8 *BootFileUri; VOID *BootFileUriParser; UINTN BootFileSize; + UINTN PartialTransferredSize; + CHAR8 *LastModifiedOrEtag; BOOLEAN NoGateway; HTTP_BOOT_IMAGE_TYPE ImageType; diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.inf b/NetworkPkg/HttpBootDxe/HttpBootDxe.inf index cffa642a4bf7..3f87e58a14a9 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDxe.inf +++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.inf @@ -95,8 +95,10 @@ gEfiAdapterInfoUndiIpv6SupportGuid ## SOMETIMES_CONSUMES ## GUID [Pcd] - gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections ## CONSUMES - gEfiNetworkPkgTokenSpaceGuid.PcdHttpIoTimeout ## CONSUMES + gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections ## CONSUMES + gEfiNetworkPkgTokenSpaceGuid.PcdHttpIoTimeout ## CONSUMES + gEfiNetworkPkgTokenSpaceGuid.PcdMaxHttpResumeRetries ## CONSUMES + gEfiNetworkPkgTokenSpaceGuid.PcdHttpDelayBetweenResumeRetries ## CONSUMES [UserExtensions.TianoCore."ExtraFiles"] HttpBootDxeExtra.uni diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.c b/NetworkPkg/HttpBootDxe/HttpBootImpl.c index fa27941f8050..4f84e59a2183 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c +++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c @@ -304,6 +304,7 @@ HttpBootGetBootFileCaller ( { HTTP_GET_BOOT_FILE_STATE State; EFI_STATUS Status; + UINT32 Retries; if (Private->BootFileSize == 0) { State = GetBootFileHead; @@ -370,13 +371,40 @@ HttpBootGetBootFileCaller ( // // Load the boot file into Buffer // - Status = HttpBootGetBootFile ( - Private, - FALSE, - BufferSize, - Buffer, - ImageType - ); + for (Retries = 1; Retries <= PcdGet32 (PcdMaxHttpResumeRetries); Retries++) { + Status = HttpBootGetBootFile ( + Private, + FALSE, + BufferSize, + Buffer, + ImageType + ); + if (!EFI_ERROR (Status) || + ((Status != EFI_TIMEOUT) && (Status != EFI_DEVICE_ERROR))) + { + break; + } + + // + // HttpBootGetBootFile returned EFI_TIMEOUT or EFI_DEVICE_ERROR. + // We may attempt to resume the interrupted download. + // + + Private->HttpCreated = FALSE; + HttpIoDestroyIo (&Private->HttpIo); + Status = HttpBootCreateHttpIo (Private); + if (EFI_ERROR (Status)) { + break; + } + + DEBUG ((DEBUG_WARN | DEBUG_INFO, "HttpBootGetBootFileCaller: NBP file download interrupted, will try to resume the operation.\n")); + gBS->Stall (1000 * 1000 * PcdGet32 (PcdHttpDelayBetweenResumeRetries)); + } + + if (EFI_ERROR (Status) && (Retries >= PcdGet32 (PcdMaxHttpResumeRetries))) { + DEBUG ((DEBUG_ERROR, "HttpBootGetBootFileCaller: Error downloading NBP file, even after trying to resume %d times.\n", Retries)); + } + return Status; case GetBootFileError: @@ -522,12 +550,13 @@ HttpBootStop ( ZeroMem (&Private->StationIp, sizeof (EFI_IP_ADDRESS)); ZeroMem (&Private->SubnetMask, sizeof (EFI_IP_ADDRESS)); ZeroMem (&Private->GatewayIp, sizeof (EFI_IP_ADDRESS)); - Private->Port = 0; - Private->BootFileUri = NULL; - Private->BootFileUriParser = NULL; - Private->BootFileSize = 0; - Private->SelectIndex = 0; - Private->SelectProxyType = HttpOfferTypeMax; + Private->Port = 0; + Private->BootFileUri = NULL; + Private->BootFileUriParser = NULL; + Private->BootFileSize = 0; + Private->SelectIndex = 0; + Private->SelectProxyType = HttpOfferTypeMax; + Private->PartialTransferredSize = 0; if (!Private->UsingIpv6) { // @@ -577,6 +606,11 @@ HttpBootStop ( Private->FilePathUriParser = NULL; } + if (Private->LastModifiedOrEtag != NULL) { + FreePool (Private->LastModifiedOrEtag); + Private->LastModifiedOrEtag = NULL; + } + ZeroMem (Private->OfferBuffer, sizeof (Private->OfferBuffer)); Private->OfferNum = 0; ZeroMem (Private->OfferCount, sizeof (Private->OfferCount)); @@ -765,7 +799,8 @@ HttpBootCallback ( if (Data != NULL) { HttpMessage = (EFI_HTTP_MESSAGE *)Data; if ((HttpMessage->Data.Request->Method == HttpMethodGet) && - (HttpMessage->Data.Request->Url != NULL)) + (HttpMessage->Data.Request->Url != NULL) && + (Private->PartialTransferredSize == 0)) { Print (L"\n URI: %s\n", HttpMessage->Data.Request->Url); } @@ -797,6 +832,16 @@ HttpBootCallback ( } } + // If download was resumed, do not change progress variables + HttpHeader = HttpFindHeader ( + HttpMessage->HeaderCount, + HttpMessage->Headers, + HTTP_HEADER_CONTENT_RANGE + ); + if (HttpHeader) { + break; + } + HttpHeader = HttpFindHeader ( HttpMessage->HeaderCount, HttpMessage->Headers, diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec index 7c4289b77b21..29fc0c046c5b 100644 --- a/NetworkPkg/NetworkPkg.dec +++ b/NetworkPkg/NetworkPkg.dec @@ -104,6 +104,16 @@ # @Prompt Max size of total HTTP chunk transfer. the default value is 12MB. gEfiNetworkPkgTokenSpaceGuid.PcdMaxHttpChunkTransfer|0x0C00000|UINT32|0x0000000E + ## The maximum number of retries while attempting to resume an + # interrupted HTTP download using a HTTP Range request header. + # @Prompt Max number of HTTP download resume retries. Default value is 5. + gEfiNetworkPkgTokenSpaceGuid.PcdMaxHttpResumeRetries|0x00000005|UINT32|0x00000012 + + ## Delay in seconds between each attempt to resume an + # interrupted HTTP download. + # @Prompt Delay in seconds between each HTTP resume retry. Default value is 2s. + gEfiNetworkPkgTokenSpaceGuid.PcdHttpDelayBetweenResumeRetries|0x00000002|UINT32|0x00000013 + [PcdsFixedAtBuild, PcdsPatchableInModule] ## Indicates whether HTTP connections (i.e., unsecured) are permitted or not. # TRUE - HTTP connections are allowed. Both the "https://" and "http://" URI schemes are permitted. From 5c8bdb190f6dd79f38ef6191754c9a26892f8d26 Mon Sep 17 00:00:00 2001 From: Chun-Yi Lee Date: Thu, 12 Sep 2024 14:32:05 +0800 Subject: [PATCH 274/280] MdePkg DebugLib: Enable FILE NAME as DEBUG ASSERT for GCC12 Using __FILE_NAME__ is useful for reducing the size of debug image and it's also good for reproducable builds. The gcc-12 also supported this macro. Ref: https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=1a9b3f04c11eb467a8dc504a37dad57a371a0d4c This patch removed the checking of __clang__ when using __FILE_NAME__. References: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42579 Signed-off-by: Chun-Yi Lee --- MdePkg/Include/Library/DebugLib.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MdePkg/Include/Library/DebugLib.h b/MdePkg/Include/Library/DebugLib.h index 0db3b78ec86d..fc5c83463d4a 100644 --- a/MdePkg/Include/Library/DebugLib.h +++ b/MdePkg/Include/Library/DebugLib.h @@ -342,13 +342,13 @@ UnitTestDebugAssert ( #if defined (_ASSERT) #undef _ASSERT #endif - #if defined (__clang__) && defined (__FILE_NAME__) + #if defined (__FILE_NAME__) #define _ASSERT(Expression) UnitTestDebugAssert (__FILE_NAME__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) #else #define _ASSERT(Expression) UnitTestDebugAssert (__FILE__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) #endif #else - #if defined (__clang__) && defined (__FILE_NAME__) + #if defined (__FILE_NAME__) #define _ASSERT(Expression) DebugAssert (__FILE_NAME__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) #else #define _ASSERT(Expression) DebugAssert (__FILE__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) From bc02b255a83dbad98aa63a86b2cee82f1205e2e0 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Thu, 29 Aug 2024 16:31:45 +0200 Subject: [PATCH 275/280] MdePkg: Move PcdEnforceSecureRngAlgorithms from NetworkPkg The PcdEnforceSecureRngAlgorithms Pcd enforces the use of RNG algorithms defined by the UEFI spec. To re-use the Pcd in other packages and have a generic mean to control the usage of unsecure algorithms, move the Pcd to the MdePkg. Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Pierre Gondois --- MdePkg/MdePkg.dec | 6 ++++++ NetworkPkg/Library/DxeNetLib/DxeNetLib.inf | 2 +- NetworkPkg/NetworkPkg.dec | 6 ------ 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index b542d6d83235..624f62636092 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -2266,6 +2266,12 @@ ## This PCD specifies the interrupt vector for stack cookie check failures gEfiMdePkgTokenSpaceGuid.PcdStackCookieExceptionVector|0x42|UINT8|0x30001019 + ## Enforces the use of Secure UEFI spec defined RNG algorithms. + # TRUE - Enforce the use of Secure UEFI spec defined RNG algorithms. + # FALSE - Do not enforce and depend on the default implementation of RNG algorithm from the provider. + # @Prompt Enforce the use of Secure UEFI spec defined RNG algorithms. + gEfiMdePkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms|TRUE|BOOLEAN|0x1000000D + [PcdsFixedAtBuild,PcdsPatchableInModule] ## Indicates the maximum length of unicode string used in the following # BaseLib functions: StrLen(), StrSize(), StrCmp(), StrnCmp(), StrCpy(), StrnCpy()

diff --git a/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf b/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf index a8f534a29358..54dcb97e578d 100644 --- a/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf +++ b/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf @@ -67,7 +67,7 @@ gEfiRngProtocolGuid ## CONSUMES [FixedPcd] - gEfiNetworkPkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms ## CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms ## CONSUMES [Depex] gEfiRngProtocolGuid diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec index 29fc0c046c5b..5db7aa137a23 100644 --- a/NetworkPkg/NetworkPkg.dec +++ b/NetworkPkg/NetworkPkg.dec @@ -141,12 +141,6 @@ # @Prompt Indicates whether SnpDxe creates event for ExitBootServices() call. gEfiNetworkPkgTokenSpaceGuid.PcdSnpCreateExitBootServicesEvent|TRUE|BOOLEAN|0x1000000C - ## Enforces the use of Secure UEFI spec defined RNG algorithms for all network connections. - # TRUE - Enforce the use of Secure UEFI spec defined RNG algorithms. - # FALSE - Do not enforce and depend on the default implementation of RNG algorithm from the provider. - # @Prompt Enforce the use of Secure UEFI spec defined RNG algorithms. - gEfiNetworkPkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms|TRUE|BOOLEAN|0x1000000D - [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] ## IPv6 DHCP Unique Identifier (DUID) Type configuration (From RFCs 3315 and 6355). # 01 = DUID Based on Link-layer Address Plus Time [DUID-LLT] From c04c4534c4a5093c116b0670c34d11df9440dd7b Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Tue, 3 Sep 2024 18:04:39 +0200 Subject: [PATCH 276/280] MdePkg/DxeRngLib: Refactor Rng algorithm selection Add a library constructor which: - locate the RNG prototocol and keep a reference to it in order to avoid locating it multiple times (for each random number generation) - check which secure algorithm is available on the platform. This avoids to try each secure algorithm until finding one available for each random number generation call. Signed-off-by: Pierre Gondois --- MdePkg/Library/DxeRngLib/DxeRngLib.c | 187 +++++++++++++++++++++---- MdePkg/Library/DxeRngLib/DxeRngLib.inf | 2 + 2 files changed, 158 insertions(+), 31 deletions(-) diff --git a/MdePkg/Library/DxeRngLib/DxeRngLib.c b/MdePkg/Library/DxeRngLib/DxeRngLib.c index 05c795759b9a..4b4efef0b424 100644 --- a/MdePkg/Library/DxeRngLib/DxeRngLib.c +++ b/MdePkg/Library/DxeRngLib/DxeRngLib.c @@ -1,17 +1,129 @@ /** @file Provides an implementation of the library class RngLib that uses the Rng protocol. - Copyright (c) 2023, Arm Limited. All rights reserved. + Copyright (c) 2023 - 2024, Arm Limited. All rights reserved. Copyright (c) Microsoft Corporation. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include +#include #include +#include #include #include +STATIC EFI_RNG_PROTOCOL *mRngProtocol; +STATIC UINTN mFirstAlgo = MAX_UINTN; + +typedef struct { + /// Guid of the secure algorithm. + EFI_GUID *Guid; + + /// Algorithm name. + CONST CHAR8 *Name; + + /// The algorithm is available for use. + BOOLEAN Available; +} SECURE_RNG_ALGO_ARRAY; + +// +// These represent UEFI SPEC defined algorithms that should be supported by +// the RNG protocol and are generally considered secure. +// +GLOBAL_REMOVE_IF_UNREFERENCED SECURE_RNG_ALGO_ARRAY mSecureHashAlgorithms[] = { + { + &gEfiRngAlgorithmSp80090Ctr256Guid, // SP800-90A DRBG CTR using AES-256 + "DRBG-CTR", + FALSE, + }, + { + &gEfiRngAlgorithmSp80090Hmac256Guid, // SP800-90A DRBG HMAC using SHA-256 + "DRBG-HMAC", + FALSE, + }, + { + &gEfiRngAlgorithmSp80090Hash256Guid, // SP800-90A DRBG Hash using SHA-256 + "DRBG-Hash", + FALSE, + }, + { + &gEfiRngAlgorithmRaw, // Raw data from NRBG (or TRNG) + "TRNG", + FALSE, + }, +}; + +/** + Constructor routine to probe the available secure Rng algorithms. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS Success. + @retval EFI_NOT_FOUND Not found. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +DxeRngLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINTN RngArraySize; + UINTN RngArrayCnt; + UINT32 Index; + UINT32 Index1; + EFI_RNG_ALGORITHM *RngArray; + + Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID **)&mRngProtocol); + if (EFI_ERROR (Status) || (mRngProtocol == NULL)) { + DEBUG ((DEBUG_ERROR, "%a: Could not locate RNG protocol, Status = %r\n", __func__, Status)); + return Status; + } + + RngArraySize = 0; + + Status = mRngProtocol->GetInfo (mRngProtocol, &RngArraySize, NULL); + if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) { + return Status; + } else if (RngArraySize == 0) { + return EFI_NOT_FOUND; + } + + RngArrayCnt = RngArraySize / sizeof (*RngArray); + + RngArray = AllocateZeroPool (RngArraySize); + if (RngArray == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = mRngProtocol->GetInfo (mRngProtocol, &RngArraySize, RngArray); + if (EFI_ERROR (Status)) { + goto ExitHandler; + } + + for (Index = 0; Index < RngArrayCnt; Index++) { + for (Index1 = 0; Index1 < ARRAY_SIZE (mSecureHashAlgorithms); Index1++) { + if (CompareGuid (&RngArray[Index], mSecureHashAlgorithms[Index1].Guid)) { + mSecureHashAlgorithms[Index1].Available = TRUE; + if (mFirstAlgo == MAX_UINTN) { + mFirstAlgo = Index1; + } + + break; + } + } + } + +ExitHandler: + FreePool (RngArray); + return Status; +} + /** Routine Description: @@ -32,55 +144,68 @@ GenerateRandomNumberViaNist800Algorithm ( IN UINTN BufferSize ) { - EFI_STATUS Status; - EFI_RNG_PROTOCOL *RngProtocol; - - RngProtocol = NULL; + EFI_STATUS Status; + UINTN Index; + SECURE_RNG_ALGO_ARRAY *Algo; if (Buffer == NULL) { DEBUG ((DEBUG_ERROR, "%a: Buffer == NULL.\n", __func__)); return EFI_INVALID_PARAMETER; } - Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID **)&RngProtocol); - if (EFI_ERROR (Status) || (RngProtocol == NULL)) { - DEBUG ((DEBUG_ERROR, "%a: Could not locate RNG prototocol, Status = %r\n", __func__, Status)); - return Status; - } - - Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Ctr256Guid, BufferSize, Buffer); - DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm CTR-256 - Status = %r\n", __func__, Status)); - if (!EFI_ERROR (Status)) { - return Status; - } - - Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Hmac256Guid, BufferSize, Buffer); - DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm HMAC-256 - Status = %r\n", __func__, Status)); - if (!EFI_ERROR (Status)) { - return Status; + if (mRngProtocol == NULL) { + return EFI_NOT_FOUND; } - Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Hash256Guid, BufferSize, Buffer); - DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm Hash-256 - Status = %r\n", __func__, Status)); - if (!EFI_ERROR (Status)) { - return Status; + // Try the first available algorithm. + if (mFirstAlgo != MAX_UINTN) { + Algo = &mSecureHashAlgorithms[mFirstAlgo]; + Status = mRngProtocol->GetRNG (mRngProtocol, Algo->Guid, BufferSize, Buffer); + DEBUG (( + DEBUG_INFO, + "%a: GetRNG algorithm %a - Status = %r\n", + __func__, + Algo->Name, + Status + )); + if (!EFI_ERROR (Status)) { + return Status; + } + + Index = mFirstAlgo + 1; + } else { + Index = 0; } - Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmRaw, BufferSize, Buffer); - DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm Raw - Status = %r\n", __func__, Status)); - if (!EFI_ERROR (Status)) { - return Status; + // Iterate over other available algorithms. + for ( ; Index < ARRAY_SIZE (mSecureHashAlgorithms); Index++) { + Algo = &mSecureHashAlgorithms[Index]; + if (!Algo->Available) { + continue; + } + + Status = mRngProtocol->GetRNG (mRngProtocol, Algo->Guid, BufferSize, Buffer); + DEBUG (( + DEBUG_INFO, + "%a: GetRNG algorithm %a - Status = %r\n", + __func__, + Algo->Name, + Status + )); + if (!EFI_ERROR (Status)) { + return Status; + } } // If all the other methods have failed, use the default method from the RngProtocol - Status = RngProtocol->GetRNG (RngProtocol, NULL, BufferSize, Buffer); + Status = mRngProtocol->GetRNG (mRngProtocol, NULL, BufferSize, Buffer); DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm default - Status = %r\n", __func__, Status)); if (!EFI_ERROR (Status)) { return Status; } // If we get to this point, we have failed - DEBUG ((DEBUG_ERROR, "%a: GetRNG() failed, staus = %r\n", __func__, Status)); + DEBUG ((DEBUG_ERROR, "%a: GetRNG() failed, Status = %r\n", __func__, Status)); return Status; }// GenerateRandomNumberViaNist800Algorithm() diff --git a/MdePkg/Library/DxeRngLib/DxeRngLib.inf b/MdePkg/Library/DxeRngLib/DxeRngLib.inf index 281fec46502f..ca649585d4cf 100644 --- a/MdePkg/Library/DxeRngLib/DxeRngLib.inf +++ b/MdePkg/Library/DxeRngLib/DxeRngLib.inf @@ -15,6 +15,7 @@ MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 LIBRARY_CLASS = RngLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER + CONSTRUCTOR = DxeRngLibConstructor [Packages] MdePkg/MdePkg.dec @@ -24,6 +25,7 @@ [LibraryClasses] DebugLib + MemoryAllocationLib UefiBootServicesTableLib [Protocols] From 5ed8f64647f57c993ea979db0c7803b949db4262 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Thu, 29 Aug 2024 16:42:33 +0200 Subject: [PATCH 277/280] MdePkg/DxeRngLib: Use PcdEnforceSecureRngAlgorithms for default algorithm Use PcdEnforceSecureRngAlgorithms to allow using the Rng protocol with the default algorithm. All previous call to the Rng protocol are requesting a secure Rng algorithm. Not specifying the Rng algorithm GUID to use is considered unsecure. Signed-off-by: Pierre Gondois --- MdePkg/Library/DxeRngLib/DxeRngLib.c | 12 +++++++----- MdePkg/Library/DxeRngLib/DxeRngLib.inf | 3 +++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/MdePkg/Library/DxeRngLib/DxeRngLib.c b/MdePkg/Library/DxeRngLib/DxeRngLib.c index 4b4efef0b424..17c932d802c7 100644 --- a/MdePkg/Library/DxeRngLib/DxeRngLib.c +++ b/MdePkg/Library/DxeRngLib/DxeRngLib.c @@ -197,11 +197,13 @@ GenerateRandomNumberViaNist800Algorithm ( } } - // If all the other methods have failed, use the default method from the RngProtocol - Status = mRngProtocol->GetRNG (mRngProtocol, NULL, BufferSize, Buffer); - DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm default - Status = %r\n", __func__, Status)); - if (!EFI_ERROR (Status)) { - return Status; + if (!PcdGetBool (PcdEnforceSecureRngAlgorithms)) { + // If all the other methods have failed, use the default method from the RngProtocol + Status = mRngProtocol->GetRNG (mRngProtocol, NULL, BufferSize, Buffer); + DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm default - Status = %r\n", __func__, Status)); + if (!EFI_ERROR (Status)) { + return Status; + } } // If we get to this point, we have failed diff --git a/MdePkg/Library/DxeRngLib/DxeRngLib.inf b/MdePkg/Library/DxeRngLib/DxeRngLib.inf index ca649585d4cf..0eff20d98886 100644 --- a/MdePkg/Library/DxeRngLib/DxeRngLib.inf +++ b/MdePkg/Library/DxeRngLib/DxeRngLib.inf @@ -39,3 +39,6 @@ gEfiRngAlgorithmSp80090Hash256Guid gEfiRngAlgorithmSp80090Hmac256Guid gEfiRngAlgorithmRaw + +[FixedPcd] + gEfiMdePkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms ## CONSUMES From 273f43cec97c48890ddd1ce08de2ca9129a8c348 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Fri, 30 Aug 2024 13:42:52 +0200 Subject: [PATCH 278/280] MdePkg/DxeRngLib: Add gEfiRngAlgorithmArmRndr to the secure algorithms DxeRngLib iterates over a list of secure algorithms before trying to use the default algorithm provided by the Rng protocol. Add gEfiRngAlgorithmArmRndr to this list. The algorithm represented by this GUID is a secure DRBG of an unknown type, implemented by the aarch64 RNDR instruction. On AARCH64 platform, use the RNDR instruction as the first option if it is available. Signed-off-by: Pierre Gondois --- MdePkg/Library/DxeRngLib/DxeRngLib.c | 7 +++++++ MdePkg/Library/DxeRngLib/DxeRngLib.inf | 3 +++ 2 files changed, 10 insertions(+) diff --git a/MdePkg/Library/DxeRngLib/DxeRngLib.c b/MdePkg/Library/DxeRngLib/DxeRngLib.c index 17c932d802c7..3092d3ebcf80 100644 --- a/MdePkg/Library/DxeRngLib/DxeRngLib.c +++ b/MdePkg/Library/DxeRngLib/DxeRngLib.c @@ -33,6 +33,13 @@ typedef struct { // the RNG protocol and are generally considered secure. // GLOBAL_REMOVE_IF_UNREFERENCED SECURE_RNG_ALGO_ARRAY mSecureHashAlgorithms[] = { + #ifdef MDE_CPU_AARCH64 + { + &gEfiRngAlgorithmArmRndr, // unspecified SP800-90A DRBG (through RNDR instr.) + "ARM-RNDR", + FALSE, + }, + #endif { &gEfiRngAlgorithmSp80090Ctr256Guid, // SP800-90A DRBG CTR using AES-256 "DRBG-CTR", diff --git a/MdePkg/Library/DxeRngLib/DxeRngLib.inf b/MdePkg/Library/DxeRngLib/DxeRngLib.inf index 0eff20d98886..f430b12586eb 100644 --- a/MdePkg/Library/DxeRngLib/DxeRngLib.inf +++ b/MdePkg/Library/DxeRngLib/DxeRngLib.inf @@ -40,5 +40,8 @@ gEfiRngAlgorithmSp80090Hmac256Guid gEfiRngAlgorithmRaw +[Guids.AARCH64] + gEfiRngAlgorithmArmRndr + [FixedPcd] gEfiMdePkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms ## CONSUMES From 262ab6259f30203306d8a94de530d08998dab121 Mon Sep 17 00:00:00 2001 From: Mike Beaton Date: Fri, 13 Sep 2024 08:23:17 +0100 Subject: [PATCH 279/280] OvmfPkg/RiscVVirtQemu: Remove non-needed !include line RiscVVirt.dsc.inc includes NetworkPkg/NetworkLibs.dsc.inc. However RiscVVirt.dsc.inc is only ever included by RiscVVirtQemu.dsc, which has already included NetworkPkg/Network.dsc.inc, a general include file which brings in all the required includes for Network features at once, including NetworkPkg/NetworkLibs.dsc.inc. Signed-off-by: Mike Beaton --- OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc | 1 - 1 file changed, 1 deletion(-) diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc index 9cf743c842bc..b5215705545d 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc +++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc @@ -71,7 +71,6 @@ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf # Networking Requirements -!include NetworkPkg/NetworkLibs.dsc.inc !if $(NETWORK_TLS_ENABLE) == TRUE TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf !endif From ec18fa81d311663e24e9b9ad61b90b38862a1ea8 Mon Sep 17 00:00:00 2001 From: Ceping Sun Date: Thu, 29 Aug 2024 07:34:47 +0800 Subject: [PATCH 280/280] OvmfPkg: Use TdInfo instead of fw_cfg to get cpu count in TDVF Currently TDVF gets cpu count information via fw_cfg, but this information can also be retrieved by calling of TdCall.TdInfo. And TdCall is responded by tdx-module which is trust. So, from the security perspective we shall use TdCall.Tdinfo instead of fw_cfg. Cc: Erdem Aktas Cc: Jiewen Yao Cc: Min Xu Cc: Gerd Hoffmann Cc: Elena Reshetova Signed-off-by: Ceping Sun --- OvmfPkg/Library/PlatformInitLib/Platform.c | 15 +++++++++++++++ .../Library/PlatformInitLib/PlatformInitLib.inf | 2 -- OvmfPkg/OvmfPkgIa32.dsc | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/OvmfPkg/Library/PlatformInitLib/Platform.c b/OvmfPkg/Library/PlatformInitLib/Platform.c index c2e0430d2269..10fc17355fac 100644 --- a/OvmfPkg/Library/PlatformInitLib/Platform.c +++ b/OvmfPkg/Library/PlatformInitLib/Platform.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -563,6 +564,20 @@ PlatformMaxCpuCountInitialization ( UINT16 BootCpuCount = 0; UINT32 MaxCpuCount; + if (TdIsEnabled ()) { + BootCpuCount = (UINT16)TdVCpuNum (); + MaxCpuCount = TdMaxVCpuNum (); + + if (BootCpuCount > MaxCpuCount) { + DEBUG ((DEBUG_ERROR, "%a: Failed with BootCpuCount (%d) more than MaxCpuCount(%u) \n", __func__, BootCpuCount, MaxCpuCount)); + ASSERT (FALSE); + } + + PlatformInfoHob->PcdCpuMaxLogicalProcessorNumber = MaxCpuCount; + PlatformInfoHob->PcdCpuBootLogicalProcessorNumber = BootCpuCount; + return; + } + // // Try to fetch the boot CPU count. // diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf index e9c07467bbf0..3e63ef44239a 100644 --- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf +++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf @@ -53,8 +53,6 @@ PcdLib PciLib PeiHardwareInfoLib - -[LibraryClasses.X64] TdxLib [Guids] diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 5e2086eb3309..34f7b9958bda 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -251,6 +251,7 @@ AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf + TdxLib|MdePkg/Library/TdxLib/TdxLib.inf TdxMailboxLib|OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf [LibraryClasses.common.SEC]