diff options
106 files changed, 3323 insertions, 275 deletions
diff --git a/.github/workflows/request-reviews.yml b/.github/workflows/request-reviews.yml index e5db19c..d04901d 100644 --- a/.github/workflows/request-reviews.yml +++ b/.github/workflows/request-reviews.yml @@ -34,7 +34,7 @@ jobs: steps:
- name: Generate Token
id: generate-token
- uses: actions/create-github-app-token@v1
+ uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.TIANOCORE_ASSIGN_REVIEWERS_APPLICATION_ID }}
private-key: ${{ secrets.TIANOCORE_ASSIGN_REVIEWERS_APPLICATION_PRIVATE_KEY }}
diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index 78437b3..edf4567 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -50,14 +50,6 @@ #
ArmMtlLib|Include/Library/ArmMtlLib.h
- ## @libraryclass Provides a System Monitor Call (SMC) interface.
- #
- ArmSmcLib|Include/Library/ArmSmcLib.h
-
- ## @libraryclass Provides a SuperVisor Call (SVC) interface.
- #
- ArmSvcLib|Include/Library/ArmSvcLib.h
-
## @libraryclass Provides a Monitor Call interface that will use the
# default conduit (HVC or SMC).
#
@@ -88,10 +80,6 @@ #
ArmTransferListLib|Include/Library/ArmTransferListLib.h
- ## @libraryclass Provides an interface for a Arm FF-A ABI.
- #
- ArmFfaLib|Include/Library/ArmFfaLib.h
-
## @libraryclass Defines a set of interfaces for the MM core entrypoint for
## AArch64 and ARM.
StandaloneMmCoreEntryPoint|Include/Library/ArmStandaloneMmCoreEntryPoint.h
@@ -105,8 +93,6 @@ gArmMmuReplaceLiveTranslationEntryFuncGuid = { 0xa8b50ff3, 0x08ec, 0x4dd3, {0xbf, 0x04, 0x28, 0xbf, 0x71, 0x75, 0xc7, 0x4a} }
- gArmFfaRxTxBufferInfoGuid = { 0x96fd3d26, 0x6fb1, 0x11ef, { 0x8c, 0x11, 0xf3, 0xc9, 0xc5, 0x02, 0x31, 0xab } }
-
[Protocols.common]
## Arm System Control and Management Interface(SCMI) Base protocol
## ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h
@@ -144,10 +130,6 @@ [PcdsFixedAtBuild.common]
gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE|BOOLEAN|0x00000006
- # This PCD should be a FeaturePcd. But we used this PCD as an '#if' in an ASM file.
- # Using a FeaturePcd make a '(BOOLEAN) casting for its value which is not understood by the preprocessor.
- gArmTokenSpaceGuid.PcdVFPEnabled|0|UINT32|0x00000024
-
gArmTokenSpaceGuid.PcdCpuResetAddress|0x00000000|UINT32|0x00000005
#
@@ -226,6 +208,10 @@ gArmTokenSpaceGuid.PcdFvBaseAddress|0|UINT64|0x0000002D
[PcdsFixedAtBuild.ARM]
+ # This PCD should be a FeaturePcd. But we used this PCD as an '#if' in an ASM file.
+ # Using a FeaturePcd make a '(BOOLEAN) casting for its value which is not understood by the preprocessor.
+ gArmTokenSpaceGuid.PcdVFPEnabled|0|UINT32|0x00000024
+
#
# ARM Security Extension
#
@@ -305,12 +291,6 @@ gArmTokenSpaceGuid.PcdSystemBiosRelease|0xFFFF|UINT16|0x30000058
gArmTokenSpaceGuid.PcdEmbeddedControllerFirmwareRelease|0xFFFF|UINT16|0x30000059
- #
- # Define the conduit to use ArmFfalib.
- # Default PcdFfaLibConduitSmc == TRUE, conduit = SMC
- # If PcdFfaLibConduitSvc == FALSE, conduit = SVC
- gArmTokenSpaceGuid.PcdFfaLibConduitSmc|TRUE|BOOLEAN|0x00000063
-
[PcdsFixedAtBuild.common, PcdsDynamic.common]
# ARM Architectural Timer Interrupt(GIC PPI) numbers
gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|29|UINT32|0x00000035
@@ -401,7 +381,3 @@ # the LinuxBoot payload.
#
gArmTokenSpaceGuid.PcdLinuxBootFileGuid|{0x0}|VOID*|0x0000005C
- gArmTokenSpaceGuid.PcdFfaTxBuffer|0x00|UINT64|0x0000005F
- gArmTokenSpaceGuid.PcdFfaRxBuffer|0x00|UINT64|0x00000060
- gArmTokenSpaceGuid.PcdFfaTxRxPageCount|1|UINT64|0x00000061
- gArmTokenSpaceGuid.PcdFfaExitBootEventRegistered|FALSE|BOOLEAN|0x00000062
diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 9090679..09eafc5 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -68,8 +68,8 @@ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
- ArmSvcLib|ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf
- ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+ ArmSvcLib|MdePkg/Library/ArmSvcLib/ArmSvcLib.inf
+ ArmSmcLib|MdePkg/Library/ArmSmcLib/ArmSmcLib.inf
OpteeLib|ArmPkg/Library/OpteeLib/OpteeLib.inf
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
@@ -85,7 +85,7 @@ ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
ArmTransferListLib|ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf
- ArmFfaLib|ArmPkg/Library/ArmFfaLib/ArmFfaDxeLib.inf
+ ArmFfaLib|MdeModulePkg/Library/ArmFfaLib/ArmFfaDxeLib.inf
ArmMtlLib|ArmPkg/Library/ArmMtlNullLib/ArmMtlNullLib.inf
@@ -97,7 +97,7 @@ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
- ArmFfaLib|ArmPkg/Library/ArmFfaLib/ArmFfaPeiLib.inf
+ ArmFfaLib|MdeModulePkg/Library/ArmFfaLib/ArmFfaPeiLib.inf
[LibraryClasses.common.MM_CORE_STANDALONE]
StandaloneMmCoreEntryPoint|ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.inf
@@ -134,15 +134,8 @@ ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
ArmPkg/Library/ArmHvcLibNull/ArmHvcLibNull.inf
ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf
- ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
- ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf
- ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf
ArmPkg/Library/OpteeLib/OpteeLib.inf
ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf
- ArmPkg/Library/ArmFfaLib/ArmFfaPeiLib.inf
- ArmPkg/Library/ArmFfaLib/ArmFfaDxeLib.inf
- ArmPkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf
- ArmPkg/Library/ArmFfaLib/ArmFfaStandaloneMmLib.inf
ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf index deb4bad..ff8a67d 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf +++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf @@ -65,7 +65,6 @@ gEfiVectorHandoffTableGuid
[Pcd.common]
- gArmTokenSpaceGuid.PcdVFPEnabled
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy
[FeaturePcd.common]
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S index 66daa27..9ad4605 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S @@ -272,16 +272,7 @@ ASM_FUNC(ArmReadVBar) ret
ASM_FUNC(ArmEnableVFP)
- // Check whether floating-point is implemented in the processor.
- mov x1, x30 // Save LR
- bl ArmReadIdAA64Pfr0 // Read EL1 Processor Feature Register (PFR0)
- mov x30, x1 // Restore LR
- ubfx x0, x0, #16, #4 // Extract the FP bits 16:19
- cmp x0, #0xF // Check if FP bits are '1111b',
- // i.e. Floating Point not implemented
- b.eq 4f // Exit when VFP is not implemented.
-
- // FVP is implemented.
+ // FP support is mandated by the UEFI specification, no need to check ID registers
// Make sure VFP exceptions are not trapped (to any exception level).
mrs x0, cpacr_el1 // Read EL1 Coprocessor Access Control Register (CPACR)
orr x0, x0, #CPACR_VFP_BITS // Disable FVP traps to EL1
@@ -292,7 +283,7 @@ ASM_FUNC(ArmEnableVFP) 2:mrs x0, cptr_el2 // Disable VFP traps to EL2
bic x0, x0, x1
msr cptr_el2, x0
-4:ret
+ ret
ASM_FUNC(ArmCallWFI)
diff --git a/ArmPlatformPkg/PeilessSec/AArch64/ArchPeilessSec.c b/ArmPlatformPkg/PeilessSec/AArch64/ArchPeilessSec.c index ccc9cde..22148f0 100644 --- a/ArmPlatformPkg/PeilessSec/AArch64/ArchPeilessSec.c +++ b/ArmPlatformPkg/PeilessSec/AArch64/ArchPeilessSec.c @@ -18,11 +18,6 @@ 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);
diff --git a/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S index c6b7093..5f285f3 100644 --- a/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S +++ b/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S @@ -11,6 +11,10 @@ ASM_FUNC(_ModuleEntryPoint) // Do early platform specific actions
bl ASM_PFX(ArmPlatformPeiBootAction)
+ // Enable Floating Point. This needs to be done before entering C code, which
+ // may use FP/SIMD registers.
+ bl ArmEnableVFP
+
// 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)
diff --git a/ArmPlatformPkg/PeilessSec/Arm/ArchPeilessSec.c b/ArmPlatformPkg/PeilessSec/Arm/ArchPeilessSec.c index 3c3cef6..e2f6f67 100644 --- a/ArmPlatformPkg/PeilessSec/Arm/ArchPeilessSec.c +++ b/ArmPlatformPkg/PeilessSec/Arm/ArchPeilessSec.c @@ -18,8 +18,4 @@ ArchInitialize ( {
// Enable program flow prediction, if supported.
ArmEnableBranchPrediction ();
-
- if (FixedPcdGet32 (PcdVFPEnabled)) {
- ArmEnableVFP ();
- }
}
diff --git a/ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S b/ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S index 6b38b86..9043d86 100644 --- a/ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S +++ b/ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S @@ -13,6 +13,12 @@ ASM_FUNC(_ModuleEntryPoint) // Do early platform specific actions
bl ASM_PFX(ArmPlatformPeiBootAction)
+#if (FixedPcdGet32 (PcdVFPEnabled))
+ // Enable Floating Point. This needs to be done before entering C code, which
+ // may use FP/SIMD registers.
+ bl ArmEnableVFP
+#endif
+
// 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)
diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.inf b/ArmPlatformPkg/PeilessSec/PeilessSec.inf index 7f67adf..e210d01 100644 --- a/ArmPlatformPkg/PeilessSec/PeilessSec.inf +++ b/ArmPlatformPkg/PeilessSec/PeilessSec.inf @@ -70,9 +70,11 @@ gArmTokenSpaceGuid.PcdFdSize
gArmTokenSpaceGuid.PcdFvBaseAddress
gArmTokenSpaceGuid.PcdFvSize
- gArmTokenSpaceGuid.PcdVFPEnabled
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
+[FixedPcd.ARM]
+ gArmTokenSpaceGuid.PcdVFPEnabled
+
[Pcd]
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
diff --git a/ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S b/ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S index 1207497..7cb3de7 100644 --- a/ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S +++ b/ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S @@ -11,6 +11,12 @@ ASM_FUNC(_ModuleEntryPoint) // Do early platform specific actions
bl ASM_PFX(ArmPlatformPeiBootAction)
+#if (FixedPcdGet32 (PcdVFPEnabled))
+ // Enable Floating Point. This needs to be done before entering C code, which
+ // may use FP/SIMD registers.
+ bl ArmEnableVFP
+#endif
+
// Get the top of the primary stacks (and the base of the secondary stacks)
MOV32 (r1, FixedPcdGet64(PcdCPUCoresStackBase) + FixedPcdGet32(PcdCPUCorePrimaryStackSize))
diff --git a/ArmPlatformPkg/Sec/Sec.c b/ArmPlatformPkg/Sec/Sec.c index 9a700e5..4535ae7 100644 --- a/ArmPlatformPkg/Sec/Sec.c +++ b/ArmPlatformPkg/Sec/Sec.c @@ -223,11 +223,6 @@ CEntryPoint ( ASSERT (((UINTN)PeiVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0);
ArmWriteVBar ((UINTN)PeiVectorTable);
- // Enable Floating Point
- if (FixedPcdGet32 (PcdVFPEnabled)) {
- ArmEnableVFP ();
- }
-
// Invoke "ProcessLibraryConstructorList" to have all library constructors
// called.
ProcessLibraryConstructorList ();
diff --git a/ArmPlatformPkg/Sec/Sec.inf b/ArmPlatformPkg/Sec/Sec.inf index b5af19e..a75ce8d 100644 --- a/ArmPlatformPkg/Sec/Sec.inf +++ b/ArmPlatformPkg/Sec/Sec.inf @@ -58,9 +58,11 @@ [FixedPcd]
gArmTokenSpaceGuid.PcdFvBaseAddress
gArmTokenSpaceGuid.PcdFvSize
- gArmTokenSpaceGuid.PcdVFPEnabled
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack
+
+[FixedPcd.ARM]
+ gArmTokenSpaceGuid.PcdVFPEnabled
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index f053f50..18f170e 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -109,7 +109,7 @@ CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf
- ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+ ArmSmcLib|MdePkg/Library/ArmSmcLib/ArmSmcLib.inf
ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf
diff --git a/ArmVirtPkg/ArmVirtCloudHv.dsc b/ArmVirtPkg/ArmVirtCloudHv.dsc index ca1aa13..8b475e2 100644 --- a/ArmVirtPkg/ArmVirtCloudHv.dsc +++ b/ArmVirtPkg/ArmVirtCloudHv.dsc @@ -87,10 +87,6 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
[PcdsFixedAtBuild.common]
-!if $(ARCH) == AARCH64
- gArmTokenSpaceGuid.PcdVFPEnabled|1
-!endif
-
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x4007c000
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000
diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc index 2714593..e5751f9 100644 --- a/ArmVirtPkg/ArmVirtKvmTool.dsc +++ b/ArmVirtPkg/ArmVirtKvmTool.dsc @@ -133,10 +133,6 @@ gArmPlatformTokenSpaceGuid.PcdCoreCount|1
-!if $(ARCH) == AARCH64
- gArmTokenSpaceGuid.PcdVFPEnabled|1
-!endif
-
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 29aa2dc..61463ca 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -246,8 +246,6 @@ # point only, for entry point versions >= 3.0.
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosEntryPointProvideMethod|0x2
- gArmTokenSpaceGuid.PcdVFPEnabled|1
-
[PcdsDynamicDefault.common]
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc index 0dee41c..b08f57e 100644 --- a/ArmVirtPkg/ArmVirtQemuKernel.dsc +++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc @@ -121,10 +121,6 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
[PcdsFixedAtBuild.common]
-!if $(ARCH) == AARCH64
- gArmTokenSpaceGuid.PcdVFPEnabled|1
-!endif
-
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress|0x00000000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|$(FD_SIZE)
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000
diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc index 1df6dca..edf7c93 100644 --- a/ArmVirtPkg/ArmVirtXen.dsc +++ b/ArmVirtPkg/ArmVirtXen.dsc @@ -78,10 +78,6 @@ ################################################################################
[PcdsFixedAtBuild.common]
-!if $(ARCH) == AARCH64
- gArmTokenSpaceGuid.PcdVFPEnabled|1
-!endif
-
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000
# Size of the region used by UEFI in permanent memory (Reserved 64MB)
diff --git a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S index 06a0020..210d2fa 100644 --- a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S +++ b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S @@ -20,11 +20,9 @@ ASM_FUNC(_ModuleEntryPoint) 0:mov x28, x0 // preserve DTB pointer
mov x27, x1 // preserve base of image pointer
-#if (FixedPcdGet32 (PcdVFPEnabled))
// Enable Floating Point. This needs to be done before entering C code, which
// may use FP/SIMD registers.
bl ArmEnableVFP
-#endif
bl ASM_PFX(DiscoverDramFromDt)
diff --git a/ArmVirtPkg/PrePi/Arm/ArchPrePi.c b/ArmVirtPkg/PrePi/Arm/ArchPrePi.c index bb074b8..47ca755 100644 --- a/ArmVirtPkg/PrePi/Arm/ArchPrePi.c +++ b/ArmVirtPkg/PrePi/Arm/ArchPrePi.c @@ -13,8 +13,4 @@ ArchInitialize ( VOID
)
{
- // Enable Floating Point
- if (FixedPcdGet32 (PcdVFPEnabled)) {
- ArmEnableVFP ();
- }
}
diff --git a/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S index cfb5de8..3e94c49 100644 --- a/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S +++ b/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S @@ -12,6 +12,12 @@ ASM_FUNC(_ModuleEntryPoint) // Do early platform specific actions
bl ASM_PFX(ArmPlatformPeiBootAction)
+#if (FixedPcdGet32 (PcdVFPEnabled))
+ // Enable Floating Point. AArch64 uses hardfloat ABI so needs this done before
+ // calling any C code. Arm does not, but let's keep the ports aligned.
+ bl ArmEnableVFP
+#endif
+
// Get ID of this CPU in Multicore system
bl ASM_PFX(ArmReadMpidr)
// Keep a copy of the MpId register value
diff --git a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf index 1f6538a..635b7c1 100755 --- a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf +++ b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf @@ -65,8 +65,6 @@ [FixedPcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
- gArmTokenSpaceGuid.PcdVFPEnabled
-
gArmTokenSpaceGuid.PcdFdSize
gArmTokenSpaceGuid.PcdFvSize
@@ -86,6 +84,9 @@ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+[FixedPcd.ARM]
+ gArmTokenSpaceGuid.PcdVFPEnabled
+
[Pcd]
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
diff --git a/BaseTools/Source/Python/FMMT/core/FvHandler.py b/BaseTools/Source/Python/FMMT/core/FvHandler.py index 7a60760..6d6a9c2 100644 --- a/BaseTools/Source/Python/FMMT/core/FvHandler.py +++ b/BaseTools/Source/Python/FMMT/core/FvHandler.py @@ -248,8 +248,8 @@ class FvHandler: elif len(CompressedData) > len(TargetTree.Data.OriData):
New_Pad_Size = GetPadSize(len(CompressedData), SECTION_COMMON_ALIGNMENT)
self.Remain_New_Free_Space = len(CompressedData) + New_Pad_Size - len(TargetTree.Data.OriData) - len(TargetTree.Data.PadData)
- self.ModifyTest(TargetTree, self.Remain_New_Free_Space)
self.Status = True
+ self.ModifyTest(TargetTree, self.Remain_New_Free_Space)
def ModifyTest(self, ParTree, Needed_Space: int) -> None:
# If have needed space, will find if there have free space in parent tree, meanwhile update the node data.
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py index 7ac3b5b..1bfd137 100644 --- a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py +++ b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py @@ -90,6 +90,16 @@ def GetDeclaredPcd(Platform, BuildDatabase, Arch, Target, Toolchain, additionalP def GetLibraryInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain):
return GetModuleLibInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain,Platform.MetaFile,EdkLogger)
+def GenerateDependencyDump(ConsumedByList, M, Level, Visited):
+ if M in Visited:
+ return []
+ Visited.add(M)
+ Indentation = "\t" * Level
+ DependencyDump = [f"{Indentation}consumed by {M}"]
+ for m in ConsumedByList[M]:
+ DependencyDump.extend(GenerateDependencyDump(ConsumedByList, m, Level + 1, Visited))
+ return DependencyDump
+
def GetModuleLibInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain, FileName = '', EdkLogger = None):
if Module.LibInstances:
return Module.LibInstances
@@ -133,9 +143,11 @@ def GetModuleLibInstances(Module, Platform, BuildDatabase, Arch, Target, Toolcha if LibraryPath is None:
if not Module.LibraryClass:
EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
- "Instance of library class [%s] is not found" % LibraryClassName,
+ f"Instance of library class [{LibraryClassName}] is not found for"
+ f" module [{Module}], [{LibraryClassName}] is:",
File=FileName,
- ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), Arch, str(Module)))
+ ExtraData="\n\t".join(GenerateDependencyDump(ConsumedByList, M, 0, set()))
+ )
else:
return []
diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc index 5cc0bb7..2259c8f 100644 --- a/EmbeddedPkg/EmbeddedPkg.dsc +++ b/EmbeddedPkg/EmbeddedPkg.dsc @@ -124,7 +124,7 @@ ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
[LibraryClasses.ARM, LibraryClasses.AARCH64]
- ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+ ArmSmcLib|MdePkg/Library/ArmSmcLib/ArmSmcLib.inf
SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c index e957cb6..1b2b885 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c @@ -670,13 +670,16 @@ SmmEntryPoint ( IN CONST EFI_SMM_ENTRY_CONTEXT *SmmEntryContext
)
{
- EFI_STATUS Status;
- EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader;
- BOOLEAN InLegacyBoot;
- BOOLEAN IsOverlapped;
- BOOLEAN IsOverUnderflow;
- VOID *CommunicationBuffer;
- UINTN BufferSize;
+ EFI_STATUS Status;
+ EFI_MM_COMMUNICATE_HEADER_V3 *CommunicateHeader;
+ EFI_SMM_COMMUNICATE_HEADER *LegacyCommunicateHeader;
+ BOOLEAN InLegacyBoot;
+ BOOLEAN IsOverlapped;
+ VOID *CommunicationBuffer;
+ UINTN BufferSize;
+ EFI_GUID *CommGuid;
+ VOID *CommData;
+ UINTN CommHeaderSize;
PERF_FUNCTION_BEGIN ();
@@ -730,10 +733,8 @@ SmmEntryPoint ( //
// Check for over or underflows
//
- IsOverUnderflow = EFI_ERROR (SafeUintnSub (BufferSize, OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data), &BufferSize));
-
if (!SmmIsBufferOutsideSmmValid ((UINTN)CommunicationBuffer, BufferSize) ||
- IsOverlapped || IsOverUnderflow)
+ IsOverlapped || (BufferSize < sizeof (EFI_SMM_COMMUNICATE_HEADER)))
{
//
// If CommunicationBuffer is not in valid address scope,
@@ -744,25 +745,50 @@ SmmEntryPoint ( gSmmCorePrivate->CommunicationBuffer = NULL;
gSmmCorePrivate->ReturnStatus = EFI_ACCESS_DENIED;
} else {
- CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)CommunicationBuffer;
- // BufferSize was updated by the SafeUintnSub() call above.
- Status = SmiManage (
- &CommunicateHeader->HeaderGuid,
- NULL,
- CommunicateHeader->Data,
- &BufferSize
- );
+ CommGuid = &((EFI_MM_COMMUNICATE_HEADER_V3 *)CommunicationBuffer)->HeaderGuid;
+ //
+ // Check if the signature matches EFI_MM_COMMUNICATE_HEADER_V3 definition
+ //
+ if (CompareGuid (CommGuid, &gEfiMmCommunicateHeaderV3Guid)) {
+ //
+ // If so, need to make sure the size is at least the size of the header
+ //
+ if (BufferSize < sizeof (EFI_MM_COMMUNICATE_HEADER_V3)) {
+ gSmmCorePrivate->CommunicationBuffer = NULL;
+ gSmmCorePrivate->ReturnStatus = EFI_ACCESS_DENIED;
+ goto AsyncSmi;
+ }
+
+ CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER_V3 *)CommunicationBuffer;
+ CommGuid = &CommunicateHeader->MessageGuid;
+ CommData = CommunicateHeader->MessageData;
+ CommHeaderSize = sizeof (EFI_MM_COMMUNICATE_HEADER_V3);
+ } else {
+ LegacyCommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)CommunicationBuffer;
+ CommGuid = &LegacyCommunicateHeader->HeaderGuid;
+ CommData = LegacyCommunicateHeader->Data;
+ CommHeaderSize = OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
+ }
+
+ BufferSize -= CommHeaderSize;
+ Status = SmiManage (
+ CommGuid,
+ NULL,
+ CommData,
+ &BufferSize
+ );
//
// Update CommunicationBuffer, BufferSize and ReturnStatus
// Communicate service finished, reset the pointer to CommBuffer to NULL
//
- gSmmCorePrivate->BufferSize = BufferSize + OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
+ gSmmCorePrivate->BufferSize = BufferSize + CommHeaderSize;
gSmmCorePrivate->CommunicationBuffer = NULL;
gSmmCorePrivate->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;
}
}
}
+AsyncSmi:
//
// Process Asynchronous SMI sources
//
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf index 75a5934..22a1048 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf @@ -120,6 +120,7 @@ gSmiHandlerProfileGuid
gEdkiiEndOfS3ResumeGuid ## SOMETIMES_PRODUCES ## GUID # Install protocol
gEdkiiS3SmmInitDoneGuid ## SOMETIMES_PRODUCES ## GUID # Install protocol
+ gEfiMmCommunicateHeaderV3Guid ## CONSUMES ## GUID # Communicate header
[UserExtensions.TianoCore."ExtraFiles"]
PiSmmCoreExtra.uni
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c index fbba868..e801b75 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c @@ -11,6 +11,7 @@ #include <Protocol/SmmBase2.h>
#include <Protocol/SmmCommunication.h>
#include <Protocol/MmCommunication2.h>
+#include <Protocol/MmCommunication3.h>
#include <Protocol/SmmAccess2.h>
#include <Protocol/SmmConfiguration.h>
#include <Protocol/SmmControl2.h>
@@ -147,6 +148,37 @@ SmmCommunicationMmCommunicate2 ( );
/**
+ 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_COMMUNICATION3_PROTOCOL instance.
+ @param[in, out] CommBufferPhysical Physical address of the MM communication buffer, of which content must
+ start with EFI_MM_COMMUNICATE_HEADER_V3.
+ @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer, of which content must
+ start with EFI_MM_COMMUNICATE_HEADER_V3.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER CommBufferPhysical was NULL or CommBufferVirtual 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
+MmCommunicationMmCommunicate3 (
+ IN CONST EFI_MM_COMMUNICATION3_PROTOCOL *This,
+ IN OUT VOID *CommBufferPhysical,
+ IN OUT VOID *CommBufferVirtual
+ );
+
+/**
Event notification that is fired every time a gEfiSmmConfigurationProtocol installs.
@param Event The Event that is being processed, not used.
@@ -276,6 +308,13 @@ EFI_MM_COMMUNICATION2_PROTOCOL mMmCommunication2 = { };
//
+// PI 1.9 MM Communication Protocol 3 instance
+//
+EFI_MM_COMMUNICATION3_PROTOCOL mMmCommunication3 = {
+ MmCommunicationMmCommunicate3
+};
+
+//
// SMM Core Private Data structure that contains the data shared between
// the SMM IPL and the SMM Core.
//
@@ -511,10 +550,12 @@ SmmCommunicationCommunicate ( IN OUT UINTN *CommSize OPTIONAL
)
{
- EFI_STATUS Status;
- EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader;
- BOOLEAN OldInSmm;
- UINTN TempCommSize;
+ EFI_STATUS Status;
+ EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader;
+ EFI_MM_COMMUNICATE_HEADER_V3 *CommunicateHeaderV3 = NULL;
+ BOOLEAN OldInSmm;
+ UINTN TempCommSize;
+ UINTN CommHeaderSize;
//
// Check parameters
@@ -524,17 +565,28 @@ SmmCommunicationCommunicate ( }
CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)CommBuffer;
+ if (CompareGuid (&CommunicateHeader->HeaderGuid, &gEfiMmCommunicateHeaderV3Guid)) {
+ CommunicateHeaderV3 = (EFI_MM_COMMUNICATE_HEADER_V3 *)CommBuffer;
+ if (CommunicateHeaderV3->BufferSize < sizeof (EFI_MM_COMMUNICATE_HEADER_V3) + CommunicateHeaderV3->MessageSize) {
+ return EFI_INVALID_PARAMETER;
+ }
- if (CommSize == NULL) {
- TempCommSize = OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength;
+ TempCommSize = (UINTN)CommunicateHeaderV3->BufferSize;
+ CommHeaderSize = sizeof (EFI_MM_COMMUNICATE_HEADER_V3);
} else {
- TempCommSize = *CommSize;
- //
- // CommSize must hold HeaderGuid and MessageLength
- //
- if (TempCommSize < OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)) {
- return EFI_INVALID_PARAMETER;
+ if (CommSize == NULL) {
+ TempCommSize = OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength;
+ } else {
+ TempCommSize = *CommSize;
+ //
+ // CommSize must hold HeaderGuid and MessageLength
+ //
+ if (TempCommSize < OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)) {
+ return EFI_INVALID_PARAMETER;
+ }
}
+
+ CommHeaderSize = OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
}
//
@@ -591,18 +643,22 @@ SmmCommunicationCommunicate ( //
// Before SetVirtualAddressMap(), we are in SMM or SMRAM is open and unlocked, call SmiManage() directly.
//
- TempCommSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
+ TempCommSize -= CommHeaderSize;
Status = gSmmCorePrivate->Smst->SmiManage (
&CommunicateHeader->HeaderGuid,
NULL,
CommunicateHeader->Data,
&TempCommSize
);
- TempCommSize += OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
+ TempCommSize += CommHeaderSize;
if (CommSize != NULL) {
*CommSize = TempCommSize;
}
+ if (CommunicateHeaderV3 != NULL) {
+ CommunicateHeaderV3->BufferSize = TempCommSize;
+ }
+
//
// Restore original InSmm state
//
@@ -652,6 +708,46 @@ SmmCommunicationMmCommunicate2 ( }
/**
+ 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_COMMUNICATION3_PROTOCOL instance.
+ @param[in, out] CommBufferPhysical Physical address of the MM communication buffer, of which content must
+ start with EFI_MM_COMMUNICATE_HEADER_V3.
+ @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer, of which content must
+ start with EFI_MM_COMMUNICATE_HEADER_V3.
+ @param[out] CommSize 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 CommBufferPhysical was NULL or CommBufferVirtual 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
+MmCommunicationMmCommunicate3 (
+ IN CONST EFI_MM_COMMUNICATION3_PROTOCOL *This,
+ IN OUT VOID *CommBufferPhysical,
+ IN OUT VOID *CommBufferVirtual
+ )
+{
+ return SmmCommunicationCommunicate (
+ &mSmmCommunication,
+ CommBufferPhysical,
+ NULL
+ );
+}
+
+/**
Event notification that is fired when GUIDed Event Group is signaled.
@param Event The Event that is being processed, not used.
@@ -1878,6 +1974,8 @@ SmmIplEntry ( &mSmmCommunication,
&gEfiMmCommunication2ProtocolGuid,
&mMmCommunication2,
+ &gEfiMmCommunication3ProtocolGuid,
+ &mMmCommunication3,
NULL
);
ASSERT_EFI_ERROR (Status);
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf index ddeb39c..e983bb2 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf @@ -52,6 +52,7 @@ gEfiSmmBase2ProtocolGuid ## PRODUCES
gEfiSmmCommunicationProtocolGuid ## PRODUCES
gEfiMmCommunication2ProtocolGuid ## PRODUCES
+ gEfiMmCommunication3ProtocolGuid ## PRODUCES
gEfiSmmAccess2ProtocolGuid ## CONSUMES
## NOTIFY
## CONSUMES
@@ -80,6 +81,7 @@ gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event
gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
gLoadFixedAddressConfigurationTableGuid ## SOMETIMES_CONSUMES ## SystemTable
+ gEfiMmCommunicateHeaderV3Guid ## SOMETIMES_CONSUMES ## UNDEFINED # MM communication v3
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressSmmCodePageNumber ## SOMETIMES_CONSUMES
diff --git a/MdeModulePkg/Include/Guid/ArmFfaRxTxBufferInfo.h b/MdeModulePkg/Include/Guid/ArmFfaRxTxBufferInfo.h new file mode 100644 index 0000000..0b8e2b6 --- /dev/null +++ b/MdeModulePkg/Include/Guid/ArmFfaRxTxBufferInfo.h @@ -0,0 +1,31 @@ +/** @file
+ Arm FF-A ns common library Header file
+
+ Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
+ Copyright (c), Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef ARM_FFA_RX_TX_BUFFER_INFO_H_
+#define ARM_FFA_RX_TX_BUFFER_INFO_H_
+
+/**
+ * Guid Hob Data for gArmFfaRxTxBufferInfoGuid Guid Hob.
+ */
+typedef struct ArmFfaRxTxBuffersInfo {
+ /// Tx Buffer Address.
+ VOID *TxBufferAddr;
+
+ /// Tx Buffer Size.
+ UINT64 TxBufferSize;
+
+ /// Rx Buffer Address.
+ VOID *RxBufferAddr;
+
+ /// Rx Buffer Size.
+ UINT64 RxBufferSize;
+} ARM_FFA_RX_TX_BUFFER_INFO;
+
+extern EFI_GUID gArmFfaRxTxBufferInfoGuid;
+
+#endif
diff --git a/ArmPkg/Library/ArmFfaLib/ArmFfaCommon.c b/MdeModulePkg/Library/ArmFfaLib/ArmFfaCommon.c index 8f66a4a..8f66a4a 100644 --- a/ArmPkg/Library/ArmFfaLib/ArmFfaCommon.c +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaCommon.c diff --git a/ArmPkg/Library/ArmFfaLib/ArmFfaCommon.h b/MdeModulePkg/Library/ArmFfaLib/ArmFfaCommon.h index 663d2d3..663d2d3 100644 --- a/ArmPkg/Library/ArmFfaLib/ArmFfaCommon.h +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaCommon.h diff --git a/ArmPkg/Library/ArmFfaLib/ArmFfaDxeLib.c b/MdeModulePkg/Library/ArmFfaLib/ArmFfaDxeLib.c index 4d82844..8751f2f 100644 --- a/ArmPkg/Library/ArmFfaLib/ArmFfaDxeLib.c +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaDxeLib.c @@ -28,6 +28,8 @@ #include <IndustryStandard/ArmFfaSvc.h>
+#include <Guid/ArmFfaRxTxBufferInfo.h>
+
#include "ArmFfaCommon.h"
#include "ArmFfaRxTxMap.h"
diff --git a/ArmPkg/Library/ArmFfaLib/ArmFfaDxeLib.inf b/MdeModulePkg/Library/ArmFfaLib/ArmFfaDxeLib.inf index 96525cf..361ebf6 100644 --- a/ArmPkg/Library/ArmFfaLib/ArmFfaDxeLib.inf +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaDxeLib.inf @@ -24,7 +24,7 @@ [Packages]
MdePkg/MdePkg.dec
- ArmPkg/ArmPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
ArmSmcLib
@@ -35,11 +35,11 @@ HobLib
[Pcd]
- gArmTokenSpaceGuid.PcdFfaLibConduitSmc
- gArmTokenSpaceGuid.PcdFfaTxBuffer
- gArmTokenSpaceGuid.PcdFfaRxBuffer
- gArmTokenSpaceGuid.PcdFfaTxRxPageCount
- gArmTokenSpaceGuid.PcdFfaExitBootEventRegistered
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaLibConduitSmc
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaTxBuffer
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaRxBuffer
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaTxRxPageCount
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaExitBootEventRegistered
[Guids]
gArmFfaRxTxBufferInfoGuid
diff --git a/ArmPkg/Library/ArmFfaLib/ArmFfaPeiLib.c b/MdeModulePkg/Library/ArmFfaLib/ArmFfaPeiLib.c index 8a1d892..e65a3d0 100644 --- a/ArmPkg/Library/ArmFfaLib/ArmFfaPeiLib.c +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaPeiLib.c @@ -29,6 +29,8 @@ #include <IndustryStandard/ArmFfaSvc.h>
+#include <Guid/ArmFfaRxTxBufferInfo.h>
+
#include "ArmFfaCommon.h"
#include "ArmFfaRxTxMap.h"
diff --git a/ArmPkg/Library/ArmFfaLib/ArmFfaPeiLib.inf b/MdeModulePkg/Library/ArmFfaLib/ArmFfaPeiLib.inf index e4ecae0..e3b7dbd 100644 --- a/ArmPkg/Library/ArmFfaLib/ArmFfaPeiLib.inf +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaPeiLib.inf @@ -24,7 +24,7 @@ [Packages]
MdePkg/MdePkg.dec
- ArmPkg/ArmPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
ArmSmcLib
@@ -35,11 +35,11 @@ HobLib
[Pcd]
- gArmTokenSpaceGuid.PcdFfaLibConduitSmc
- gArmTokenSpaceGuid.PcdFfaTxBuffer
- gArmTokenSpaceGuid.PcdFfaRxBuffer
- gArmTokenSpaceGuid.PcdFfaTxRxPageCount
- gArmTokenSpaceGuid.PcdFfaExitBootEventRegistered
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaLibConduitSmc
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaTxBuffer
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaRxBuffer
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaTxRxPageCount
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaExitBootEventRegistered
[Guids]
gArmFfaRxTxBufferInfoGuid
diff --git a/ArmPkg/Library/ArmFfaLib/ArmFfaRxTxMap.c b/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.c index 37d3e80..37d3e80 100644 --- a/ArmPkg/Library/ArmFfaLib/ArmFfaRxTxMap.c +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.c diff --git a/ArmPkg/Library/ArmFfaLib/ArmFfaRxTxMap.h b/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.h index 01db339..6c6bfaa 100644 --- a/ArmPkg/Library/ArmFfaLib/ArmFfaRxTxMap.h +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.h @@ -18,23 +18,6 @@ #define ARM_FFA_RX_TX_MAP_LIB_H_
/**
- * Guid Hob Data for gArmFfaRxTxBufferInfoGuid Guid Hob.
- */
-typedef struct ArmFfaRxTxBuffersInfo {
- /// Tx Buffer Address.
- VOID *TxBufferAddr;
-
- /// Tx Buffer Size.
- UINT64 TxBufferSize;
-
- /// Rx Buffer Address.
- VOID *RxBufferAddr;
-
- /// Rx Buffer Size.
- UINT64 RxBufferSize;
-} ARM_FFA_RX_TX_BUFFER_INFO;
-
-/**
Mapping Rx/Tx buffers.
This function is only called in ArmFfaLibConstructor because
Rx/Tx buffer is registered only once per partition.
diff --git a/ArmPkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf b/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf index a31fa5b..395d1f0 100644 --- a/ArmPkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf @@ -23,7 +23,7 @@ [Packages]
MdePkg/MdePkg.dec
- ArmPkg/ArmPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
ArmSmcLib
@@ -33,4 +33,4 @@ DebugLib
[Pcd]
- gArmTokenSpaceGuid.PcdFfaLibConduitSmc
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaLibConduitSmc
diff --git a/ArmPkg/Library/ArmFfaLib/ArmFfaStandaloneMmLib.c b/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmLib.c index 2d7f834..2d7f834 100644 --- a/ArmPkg/Library/ArmFfaLib/ArmFfaStandaloneMmLib.c +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmLib.c diff --git a/ArmPkg/Library/ArmFfaLib/ArmFfaStandaloneMmLib.inf b/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmLib.inf index bd3ec3f..44679c0 100644 --- a/ArmPkg/Library/ArmFfaLib/ArmFfaStandaloneMmLib.inf +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmLib.inf @@ -23,7 +23,7 @@ [Packages]
MdePkg/MdePkg.dec
- ArmPkg/ArmPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
ArmSmcLib
@@ -33,5 +33,5 @@ DebugLib
[Pcd]
- gArmTokenSpaceGuid.PcdFfaLibConduitSmc
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaLibConduitSmc
diff --git a/MdeModulePkg/Library/BootManagerUiLib/BootManager.c b/MdeModulePkg/Library/BootManagerUiLib/BootManager.c index b752679..c2232e5 100644 --- a/MdeModulePkg/Library/BootManagerUiLib/BootManager.c +++ b/MdeModulePkg/Library/BootManagerUiLib/BootManager.c @@ -7,6 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/
#include "BootManager.h"
+#include <Protocol/LoadedImage.h>
UINT16 mKeyInput;
EFI_GUID mBootManagerGuid = BOOT_MANAGER_FORMSET_GUID;
@@ -493,6 +494,9 @@ UpdateBootManager ( BOOLEAN IsLegacyOption;
BOOLEAN NeedEndOp;
UINTN MaxLen;
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
DeviceType = (UINT16)-1;
@@ -537,6 +541,25 @@ UpdateBootManager ( EndLabel->Number = LABEL_BOOT_OPTION_END;
mKeyInput = 0;
NeedEndOp = FALSE;
+
+ //
+ // Get UiApp FilePath
+ //
+ Status = gBS->HandleProtocol (
+ gImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **)&LoadedImage
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
+ ASSERT (DevicePath != NULL);
+
+ DevicePath = AppendDevicePathNode (
+ DevicePath,
+ LoadedImage->FilePath
+ );
+
for (Index = 0; Index < BootOptionCount; Index++) {
//
// At this stage we are creating a menu entry, thus the Keys are reproduceable
@@ -551,6 +574,13 @@ UpdateBootManager ( }
//
+ // Don't display UiApp within the boot options
+ //
+ if (CompareMem (DevicePath, BootOption[Index].FilePath, GetDevicePathSize (DevicePath)) == 0) {
+ continue;
+ }
+
+ //
// Group the legacy boot option in the sub title created dynamically
//
IsLegacyOption = (BOOLEAN)(
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index aa21365..3698caf 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -494,6 +494,9 @@ ## Include/Guid/DelayedDispatch.h
gEfiDelayedDispatchTableGuid = { 0x4b733449, 0x8eff, 0x488c, { 0x92, 0x1a, 0x15, 0x4a, 0xda, 0x25, 0x18, 0x07 }}
+ ## Include/Guid/ArmFfaRxTxBufferInfo.h
+ gArmFfaRxTxBufferInfoGuid = { 0x96fd3d26, 0x6fb1, 0x11ef, { 0x8c, 0x11, 0xf3, 0xc9, 0xc5, 0x02, 0x31, 0xab } }
+
[Ppis]
## Include/Ppi/FirmwareVolumeShadowPpi.h
gEdkiiPeiFirmwareVolumeShadowPpiGuid = { 0x7dfe756c, 0xed8d, 0x4d77, {0x9e, 0xc4, 0x39, 0x9a, 0x8a, 0x81, 0x51, 0x16 } }
@@ -2281,6 +2284,12 @@ # @Prompt The value is use for Usb Network rate limiting supported.
gEfiMdeModulePkgTokenSpaceGuid.PcdUsbNetworkRateLimitingFactor|100|UINT32|0x10000028
+ ## Define the conduit to use in ArmFfalib.
+ # Default PcdFfaLibConduitSmc == TRUE, conduit = SMC
+ # If PcdFfaLibConduitSvc == FALSE, conduit = SVC
+ # @Prompt Conduit to use in ArmFfaLib.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaLibConduitSmc|TRUE|BOOLEAN|0x10000029
+
[PcdsPatchableInModule]
## Specify memory size with page number for PEI code when
# Loading Module at Fixed Address feature is enabled.
@@ -2359,5 +2368,21 @@ # @Prompt 64bit VPD base address.
gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress64|0x0|UINT64|0x00030006
+ ## This dynamic PCD holds the address of the FFA TX buffer.
+ # @Prompt FFA TX Buffer Address
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaTxBuffer|0x00|UINT64|0x00030009
+
+ ## This dynamic PCD holds the address of the FFA RX buffer.
+ # @Prompt FFA RX Buffer Address
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaRxBuffer|0x00|UINT64|0x0003000A
+
+ ## This dynamic PCD holds the number of pages for the FFA TX/RX buffer.
+ # @Prompt FFA TX/RX Buffer Page Count
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaTxRxPageCount|1|UINT64|0x0003000B
+
+ ## This dynamic PCD holds the information if the FFA exit boot event is registered.
+ # @Prompt FFA Exit Boot Event Registered
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFfaExitBootEventRegistered|FALSE|BOOLEAN|0x0003000C
+
[UserExtensions.TianoCore."ExtraFiles"]
MdeModulePkgExtra.uni
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 4b7f3e4..0c530c7 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -184,6 +184,8 @@ [LibraryClasses.ARM, LibraryClasses.AARCH64]
LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+ ArmSmcLib|MdePkg/Library/ArmSmcLib/ArmSmcLib.inf
+ ArmSvcLib|MdePkg/Library/ArmSvcLib/ArmSvcLib.inf
[LibraryClasses.EBC, LibraryClasses.RISCV64, LibraryClasses.LOONGARCH64]
LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
@@ -532,5 +534,11 @@ [Components.X64]
MdeModulePkg/Universal/CapsulePei/CapsuleX64.inf
+[Components.ARM, Components.AARCH64]
+ MdeModulePkg/Library/ArmFfaLib/ArmFfaPeiLib.inf
+ MdeModulePkg/Library/ArmFfaLib/ArmFfaDxeLib.inf
+ MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf
+ MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmLib.inf
+
[BuildOptions]
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c index a7b7dc7..056a4cb 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c +++ b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c @@ -2014,8 +2014,8 @@ FindTopMenu ( /**
Record the highlight menu and top of screen menu info.
- @param Highlight The menu opton which is highlight.
- @param TopOfScreen The menu opton which is at the top of the form.
+ @param Highlight The menu option which is highlight.
+ @param TopOfScreen The menu option which is at the top of the form.
@param SkipValue The skip line info for the top of screen menu.
**/
@@ -2095,9 +2095,9 @@ UpdateHighlightMenuInfo ( }
/**
- Update attribut for this menu.
+ Update attribute for this menu.
- @param MenuOption The menu opton which this attribut used to.
+ @param MenuOption The menu option which this attribute used to.
@param Highlight Whether this menu will be highlight.
**/
@@ -2130,7 +2130,7 @@ SetDisplayAttribute ( /**
Print string for this menu option.
- @param MenuOption The menu opton which this attribut used to.
+ @param MenuOption The menu option which this attribute used to.
@param Col The column that this string will be print at.
@param Row The row that this string will be print at.
@param String The string which need to print.
@@ -2176,7 +2176,7 @@ DisplayMenuString ( /**
Check whether this menu can has option string.
- @param MenuOption The menu opton which this attribut used to.
+ @param MenuOption The menu option which this attribute used to.
@retval TRUE This menu option can have option string.
@retval FALSE This menu option can't have option string.
@@ -2371,7 +2371,7 @@ FxConfirmPopup ( /**
Print string for this menu option.
- @param MenuOption The menu opton which this attribut used to.
+ @param MenuOption The menu option which this attribute used to.
@param SkipWidth The skip width between the left to the start of the prompt.
@param BeginCol The begin column for one menu.
@param SkipLine The skip line for this menu.
@@ -2904,9 +2904,9 @@ UiDisplayMenu ( case CfRefreshHighLight:
//
- // MenuOption: Last menu option that need to remove hilight
+ // MenuOption: Last menu option that need to remove highlight
// MenuOption is set to NULL in Repaint
- // NewPos: Current menu option that need to hilight
+ // NewPos: Current menu option that need to highlight
//
ControlFlag = CfUpdateHelpString;
@@ -2986,13 +2986,13 @@ UiDisplayMenu ( }
//
- // NewLine means only update highlight menu (remove old highlight and highlith
- // the new one), not need to full repain the form.
+ // NewLine means only update highlight menu (remove old highlight and highlight
+ // the new one), not need to full repaint the form.
//
if (Repaint || NewLine) {
if (IsListEmpty (&gMenuOption)) {
//
- // Don't print anything if no mwnu option.
+ // Don't print anything if no menu option.
//
StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
} else {
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h index 6e26704..a7b15a8 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h +++ b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h @@ -696,8 +696,8 @@ RefreshTimeOutProcess ( /**
Record the highlight menu and top of screen menu info.
- @param Highlight The menu opton which is highlight.
- @param TopOfScreen The menu opton which is at the top of the form.
+ @param Highlight The menu option which is highlight.
+ @param TopOfScreen The menu option which is at the top of the form.
@param SkipValue The skip line info for the top of screen menu.
**/
diff --git a/ArmPkg/Include/IndustryStandard/ArmFfaBootInfo.h b/MdePkg/Include/IndustryStandard/ArmFfaBootInfo.h index aceb69a..aceb69a 100644 --- a/ArmPkg/Include/IndustryStandard/ArmFfaBootInfo.h +++ b/MdePkg/Include/IndustryStandard/ArmFfaBootInfo.h diff --git a/ArmPkg/Include/IndustryStandard/ArmFfaPartInfo.h b/MdePkg/Include/IndustryStandard/ArmFfaPartInfo.h index fcee557..fcee557 100644 --- a/ArmPkg/Include/IndustryStandard/ArmFfaPartInfo.h +++ b/MdePkg/Include/IndustryStandard/ArmFfaPartInfo.h diff --git a/ArmPkg/Include/IndustryStandard/ArmFfaSvc.h b/MdePkg/Include/IndustryStandard/ArmFfaSvc.h index f2b92f8..f2b92f8 100644 --- a/ArmPkg/Include/IndustryStandard/ArmFfaSvc.h +++ b/MdePkg/Include/IndustryStandard/ArmFfaSvc.h diff --git a/ArmPkg/Include/IndustryStandard/ArmStdSmc.h b/MdePkg/Include/IndustryStandard/ArmStdSmc.h index f3d78d8..f3d78d8 100644 --- a/ArmPkg/Include/IndustryStandard/ArmStdSmc.h +++ b/MdePkg/Include/IndustryStandard/ArmStdSmc.h diff --git a/ArmPkg/Include/Library/ArmFfaLib.h b/MdePkg/Include/Library/ArmFfaLib.h index 977f325..977f325 100644 --- a/ArmPkg/Include/Library/ArmFfaLib.h +++ b/MdePkg/Include/Library/ArmFfaLib.h diff --git a/ArmPkg/Include/Library/ArmSmcLib.h b/MdePkg/Include/Library/ArmSmcLib.h index be2f85a..be2f85a 100644 --- a/ArmPkg/Include/Library/ArmSmcLib.h +++ b/MdePkg/Include/Library/ArmSmcLib.h diff --git a/ArmPkg/Include/Library/ArmSvcLib.h b/MdePkg/Include/Library/ArmSvcLib.h index a514e0c..a514e0c 100644 --- a/ArmPkg/Include/Library/ArmSvcLib.h +++ b/MdePkg/Include/Library/ArmSvcLib.h diff --git a/MdePkg/Include/Pi/PiMultiPhase.h b/MdePkg/Include/Pi/PiMultiPhase.h index 1c7332e..5a22ca0 100644 --- a/MdePkg/Include/Pi/PiMultiPhase.h +++ b/MdePkg/Include/Pi/PiMultiPhase.h @@ -111,6 +111,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define EFI_SMRAM_LOCKED EFI_MMRAM_LOCKED
///
+/// MM Communicate header constants
+///
+#define COMMUNICATE_HEADER_V3_GUID \
+ { \
+ 0x68e8c853, 0x2ba9, 0x4dd7, { 0x9a, 0xc0, 0x91, 0xe1, 0x61, 0x55, 0xc9, 0x35 } \
+ }
+
+///
/// Structure describing a MMRAM region and its accessibility attributes.
///
typedef struct {
@@ -156,6 +164,47 @@ typedef struct _EFI_MM_RESERVED_MMRAM_REGION { UINT64 MmramReservedSize;
} EFI_MM_RESERVED_MMRAM_REGION;
+#pragma pack(1)
+
+///
+/// To avoid confusion in interpreting frames, the buffer communicating to MM core through
+/// EFI_MM_COMMUNICATE3 or later should always start with EFI_MM_COMMUNICATE_HEADER_V3.
+///
+typedef struct {
+ ///
+ /// Indicator GUID for MM core that the communication buffer is compliant with this v3 header.
+ /// Must be gEfiMmCommunicateHeaderV3Guid.
+ ///
+ EFI_GUID HeaderGuid;
+ ///
+ /// Describes the size of the entire buffer (in bytes) available for communication, including this communication header.
+ ///
+ UINT64 BufferSize;
+ ///
+ /// Reserved for future use.
+ ///
+ UINT64 Reserved;
+ ///
+ /// Allows for disambiguation of the message format.
+ ///
+ EFI_GUID MessageGuid;
+ ///
+ /// Describes the size of MessageData (in bytes) and does not include the size of the header.
+ ///
+ UINT64 MessageSize;
+ ///
+ /// Designates an array of bytes that is MessageSize in size.
+ ///
+ UINT8 MessageData[];
+} EFI_MM_COMMUNICATE_HEADER_V3;
+
+#pragma pack()
+
+STATIC_ASSERT (
+ (sizeof (EFI_MM_COMMUNICATE_HEADER_V3) == OFFSET_OF (EFI_MM_COMMUNICATE_HEADER_V3, MessageData)), \
+ "sizeof (EFI_MM_COMMUNICATE_HEADER_V3) does not align with the beginning of flexible array MessageData"
+ );
+
typedef enum {
EFI_PCD_TYPE_8,
EFI_PCD_TYPE_16,
@@ -215,4 +264,6 @@ EFI_STATUS IN VOID *ProcedureArgument
);
+extern EFI_GUID gEfiMmCommunicateHeaderV3Guid;
+
#endif
diff --git a/MdePkg/Include/Ppi/MmCommunication3.h b/MdePkg/Include/Ppi/MmCommunication3.h new file mode 100644 index 0000000..fee6b8a --- /dev/null +++ b/MdePkg/Include/Ppi/MmCommunication3.h @@ -0,0 +1,54 @@ +/** @file
+ EFI MM Communication v3 PPI definition.
+
+ This Ppi provides a means of communicating between PEIM and MMI
+ handlers inside of MM.
+
+Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) Microsoft Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_COMMUNICATION3_PPI_H_
+#define MM_COMMUNICATION3_PPI_H_
+
+#include <Pi/PiMultiPhase.h>
+
+#define EFI_PEI_MM_COMMUNICATION3_PPI_GUID \
+ { \
+ 0xe70febf6, 0x13ef, 0x4a21, { 0x89, 0x9e, 0xb2, 0x36, 0xf8, 0x25, 0xff, 0xc9 } \
+ }
+
+typedef struct _EFI_PEI_MM_COMMUNICATION3_PPI EFI_PEI_MM_COMMUNICATION3_PPI;
+
+/**
+ 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_COMMUNICATE3 instance.
+ @param[in, out] CommBuffer A pointer to the buffer to convey into MMRAM.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_MM_COMMUNICATE3)(
+ IN CONST EFI_PEI_MM_COMMUNICATION3_PPI *This,
+ IN OUT VOID *CommBuffer
+ );
+
+///
+/// EFI MM Communication PPI provides runtime services for communicating
+/// between DXE drivers and a registered SMI handler.
+///
+struct _EFI_PEI_MM_COMMUNICATION3_PPI {
+ EFI_PEI_MM_COMMUNICATE3 Communicate;
+};
+
+extern EFI_GUID gEfiPeiMmCommunication3PpiGuid;
+
+#endif
diff --git a/MdePkg/Include/Protocol/MmCommunication3.h b/MdePkg/Include/Protocol/MmCommunication3.h new file mode 100644 index 0000000..337287c --- /dev/null +++ b/MdePkg/Include/Protocol/MmCommunication3.h @@ -0,0 +1,64 @@ +/** @file
+ EFI MM Communication Protocol 3 as defined in the PI 1.9 specification.
+
+ This protocol provides a means of communicating between drivers outside of MM and MMI
+ handlers inside of MM.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2019, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_COMMUNICATION3_H_
+#define MM_COMMUNICATION3_H_
+
+#include <Pi/PiMultiPhase.h>
+
+#define EFI_MM_COMMUNICATION3_PROTOCOL_GUID \
+ { \
+ 0xf7234a14, 0xdf2, 0x46c0, { 0xad, 0x28, 0x90, 0xe6, 0xb8, 0x83, 0xa7, 0x2f } \
+ }
+
+typedef struct _EFI_MM_COMMUNICATION3_PROTOCOL EFI_MM_COMMUNICATION3_PROTOCOL;
+
+/**
+ 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_COMMUNICATION3_PROTOCOL instance.
+ @param[in, out] CommBufferPhysical Physical address of the MM communication buffer, of which content must
+ start with EFI_MM_COMMUNICATE_HEADER_V3.
+ @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer, of which content must
+ start with EFI_MM_COMMUNICATE_HEADER_V3.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER CommBufferPhysical was NULL or CommBufferVirtual was NULL.
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
+ If this error is returned, the MessageSize field
+ in the CommBuffer header, are updated to reflect
+ the maximum payload size the implementation can accommodate.
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter are in address range
+ that cannot be accessed by the MM environment.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MM_COMMUNICATE3)(
+ IN CONST EFI_MM_COMMUNICATION3_PROTOCOL *This,
+ IN OUT VOID *CommBufferPhysical,
+ IN OUT VOID *CommBufferVirtual
+ );
+
+///
+/// EFI MM Communication Protocol provides runtime services for communicating
+/// between DXE drivers and a registered MMI handler.
+///
+struct _EFI_MM_COMMUNICATION3_PROTOCOL {
+ EFI_MM_COMMUNICATE3 Communicate;
+};
+
+extern EFI_GUID gEfiMmCommunication3ProtocolGuid;
+
+#endif
diff --git a/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S b/MdePkg/Library/ArmSmcLib/AArch64/ArmSmc.S index 139bb89..139bb89 100644 --- a/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S +++ b/MdePkg/Library/ArmSmcLib/AArch64/ArmSmc.S diff --git a/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S b/MdePkg/Library/ArmSmcLib/Arm/ArmSmc.S index 4b3d0db..4b3d0db 100644 --- a/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S +++ b/MdePkg/Library/ArmSmcLib/Arm/ArmSmc.S diff --git a/ArmPkg/Library/ArmSmcLib/ArmSmc.c b/MdePkg/Library/ArmSmcLib/ArmSmc.c index 254507e..254507e 100644 --- a/ArmPkg/Library/ArmSmcLib/ArmSmc.c +++ b/MdePkg/Library/ArmSmcLib/ArmSmc.c diff --git a/ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf b/MdePkg/Library/ArmSmcLib/ArmSmcLib.inf index 6ce0ea4..4ae9740 100644 --- a/ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf +++ b/MdePkg/Library/ArmSmcLib/ArmSmcLib.inf @@ -24,4 +24,3 @@ [Packages]
MdePkg/MdePkg.dec
- ArmPkg/ArmPkg.dec
diff --git a/ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.c b/MdePkg/Library/ArmSmcLibNull/ArmSmcLibNull.c index 28514e4..28514e4 100644 --- a/ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.c +++ b/MdePkg/Library/ArmSmcLibNull/ArmSmcLibNull.c diff --git a/ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf b/MdePkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf index 9ce7c9b..de5bbdb 100644 --- a/ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf +++ b/MdePkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf @@ -21,4 +21,3 @@ [Packages]
MdePkg/MdePkg.dec
- ArmPkg/ArmPkg.dec
diff --git a/ArmPkg/Library/ArmSvcLib/AArch64/ArmSvc.S b/MdePkg/Library/ArmSvcLib/AArch64/ArmSvc.S index 814f831..814f831 100644 --- a/ArmPkg/Library/ArmSvcLib/AArch64/ArmSvc.S +++ b/MdePkg/Library/ArmSvcLib/AArch64/ArmSvc.S diff --git a/ArmPkg/Library/ArmSvcLib/Arm/ArmSvc.S b/MdePkg/Library/ArmSvcLib/Arm/ArmSvc.S index e81eb88..e81eb88 100644 --- a/ArmPkg/Library/ArmSvcLib/Arm/ArmSvc.S +++ b/MdePkg/Library/ArmSvcLib/Arm/ArmSvc.S diff --git a/ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf b/MdePkg/Library/ArmSvcLib/ArmSvcLib.inf index ecfbc5d..459b90c 100644 --- a/ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf +++ b/MdePkg/Library/ArmSvcLib/ArmSvcLib.inf @@ -20,5 +20,4 @@ AArch64/ArmSvc.S
[Packages]
- ArmPkg/ArmPkg.dec
MdePkg/MdePkg.dec
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 72fed9a..5159938 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -358,6 +358,18 @@ #
ArmLib|Include/Library/ArmLib.h
+ ## @libraryclass Provides an interface to Arm architecture monitor call functions.
+ #
+ ArmSmcLib|Include/Library/ArmSmcLib.h
+
+ ## @libraryclass Provides an interface to Arm architecture supervisor call functions.
+ #
+ ArmSvcLib|Include/Library/ArmSvcLib.h
+
+ ## @libraryclass Provides an interface to Arm's Firmware Framework for A-profile (FF-A) functions.
+ #
+ ArmFfaLib|Include/Library/ArmFfaLib.h
+
[Guids]
#
# GUID defined in UEFI2.1/UEFI2.0/EFI1.1
@@ -914,6 +926,11 @@ ## Include/Protocol/CcMeasurement.h
gEfiCcFinalEventsTableGuid = { 0xdd4a4648, 0x2de7, 0x4665, { 0x96, 0x4d, 0x21, 0xd9, 0xef, 0x5f, 0xb4, 0x46 }}
+ #
+ # GUID indicates the MM communication data is compliant with v3 communication header.
+ #
+ gEfiMmCommunicateHeaderV3Guid = { 0x68e8c853, 0x2ba9, 0x4dd7, { 0x9a, 0xc0, 0x91, 0xe1, 0x61, 0x55, 0xc9, 0x35 } }
+
[Guids.IA32, Guids.X64]
## Include/Guid/Cper.h
gEfiIa32X64ErrorTypeCacheCheckGuid = { 0xA55701F5, 0xE3EF, 0x43de, { 0xAC, 0x72, 0x24, 0x9B, 0x57, 0x3F, 0xAD, 0x2C }}
@@ -1098,6 +1115,9 @@ ## Include/Ppi/Rng.h
gEfiRngPpiGuid = { 0xeaed0a7e, 0x1a70, 0x4c2b, { 0x85, 0x58, 0x37, 0x17, 0x74, 0x56, 0xd8, 0x06 }}
+ ## Include/Ppi/MmCommunication3.h
+ gEfiPeiMmCommunication3PpiGuid = { 0xe70febf6, 0x13ef, 0x4a21, { 0x89, 0x9e, 0xb2, 0x36, 0xf8, 0x25, 0xff, 0xc9 }}
+
[Protocols]
## Include/Protocol/MemoryAccept.h
gEdkiiMemoryAcceptProtocolGuid = { 0x38c74800, 0x5590, 0x4db4, { 0xa0, 0xf3, 0x67, 0x5d, 0x9b, 0x8e, 0x80, 0x26 }}
@@ -1450,6 +1470,9 @@ ## Include/Protocol/MmCommunication2.h
gEfiMmCommunication2ProtocolGuid = { 0x378daedc, 0xf06b, 0x4446, { 0x83, 0x14, 0x40, 0xab, 0x93, 0x3c, 0x87, 0xa3 }}
+ ## Include/Protocol/MmCommunication3.h
+ gEfiMmCommunication3ProtocolGuid = { 0xf7234a14, 0xdf2, 0x46c0, { 0xad, 0x28, 0x90, 0xe6, 0xb8, 0x83, 0xa7, 0x2f }}
+
#
# Protocols defined in UEFI2.1/UEFI2.0/EFI1.1
#
diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 84730b0..7525573 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -207,6 +207,9 @@ [Components.ARM, Components.AARCH64]
MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+ MdePkg/Library/ArmSmcLib/ArmSmcLib.inf
+ MdePkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf
+ MdePkg/Library/ArmSvcLib/ArmSvcLib.inf
[Components.RISCV64]
MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
diff --git a/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc b/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc index 6170c59..e2543a1 100644 --- a/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc +++ b/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc @@ -45,9 +45,9 @@ DEFINE FW_BLOCKS = 0x200 DEFINE CODE_BASE_ADDRESS = 0xFFE20000
DEFINE CODE_SIZE = 0x001E0000
DEFINE CODE_BLOCKS = 0x1E0
-DEFINE FVMAIN_SIZE = 0x001AC000
-DEFINE SECFV_OFFSET = 0x001CC000
-DEFINE SECFV_SIZE = 0x34000
+DEFINE FVMAIN_SIZE = 0x001BC000
+DEFINE SECFV_OFFSET = 0x001DC000
+DEFINE SECFV_SIZE = 0x24000
!endif
!if $(FD_SIZE_IN_KB) == 4096
diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c index b05da19..2eca39d 100644 --- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c @@ -618,6 +618,7 @@ Done: @param[in] AuthDataSize Size of the Authenticode Signature in bytes.
@retval EFI_UNSUPPORTED Hash algorithm is not supported.
+ @retval EFI_BAD_BUFFER_SIZE AuthData provided is invalid size.
@retval EFI_SUCCESS Hash successfully.
**/
@@ -629,28 +630,28 @@ HashPeImageByType ( {
UINT8 Index;
- for (Index = 0; Index < HASHALG_MAX; Index++) {
+ //
+ // Check the Hash algorithm in PE/COFF Authenticode.
+ // According to PKCS#7 Definition:
+ // SignedData ::= SEQUENCE {
+ // version Version,
+ // digestAlgorithms DigestAlgorithmIdentifiers,
+ // contentInfo ContentInfo,
+ // .... }
+ // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing
+ // This field has the fixed offset (+32) in final Authenticode ASN.1 data.
+ // Fixed offset (+32) is calculated based on two bytes of length encoding.
+ //
+ if ((AuthDataSize > 1) && ((*(AuthData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)) {
//
- // Check the Hash algorithm in PE/COFF Authenticode.
- // According to PKCS#7 Definition:
- // SignedData ::= SEQUENCE {
- // version Version,
- // digestAlgorithms DigestAlgorithmIdentifiers,
- // contentInfo ContentInfo,
- // .... }
- // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing
- // This field has the fixed offset (+32) in final Authenticode ASN.1 data.
- // Fixed offset (+32) is calculated based on two bytes of length encoding.
+ // Only support two bytes of Long Form of Length Encoding.
//
- if ((*(AuthData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE) {
- //
- // Only support two bytes of Long Form of Length Encoding.
- //
- continue;
- }
+ return EFI_BAD_BUFFER_SIZE;
+ }
+ for (Index = 0; Index < HASHALG_MAX; Index++) {
if (AuthDataSize < 32 + mHash[Index].OidLength) {
- return EFI_UNSUPPORTED;
+ continue;
}
if (CompareMem (AuthData + 32, mHash[Index].OidValue, mHash[Index].OidLength) == 0) {
diff --git a/SecurityPkg/SecurityFixes.yaml b/SecurityPkg/SecurityFixes.yaml index b4006b4..06b597a 100644 --- a/SecurityPkg/SecurityFixes.yaml +++ b/SecurityPkg/SecurityFixes.yaml @@ -40,3 +40,18 @@ CVE_2022_36764: - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c
links:
- https://bugzilla.tianocore.org/show_bug.cgi?id=4118
+CVE_2024_38797:
+ commit-titles:
+ - "SecurityPkg: Out of bound read in HashPeImageByType()"
+ - "SecurityPkg: Improving HashPeImageByType () logic"
+ - "SecurityPkg: Improving SecureBootConfigImpl:HashPeImageByType () logic"
+ cve: CVE-2024-38797
+ date_reported: 2024-06-04 12:00 UTC
+ description: Out of bound read in HashPeImageByType()
+ note:
+ files_impacted:
+ - SecurityPkg\Library\DxeImageVerificationLib\DxeImageVerificationLib.c
+ - SecurityPkg\VariableAuthenticated\SecureBootConfigDxe\SecureBootConfigImpl.c
+ links:
+ - https://bugzilla.tianocore.org/show_bug.cgi?id=2214
+ - https://github.com/tianocore/edk2/security/advisories/GHSA-4wjw-6xmf-44xf
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c index d4dc4e1..d262904 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c @@ -2105,30 +2105,35 @@ HashPeImageByType ( {
UINT8 Index;
WIN_CERTIFICATE_EFI_PKCS *PkcsCertData;
+ UINT32 PkcsCertSize;
PkcsCertData = (WIN_CERTIFICATE_EFI_PKCS *)(mImageBase + mSecDataDir->Offset);
+ PkcsCertSize = mSecDataDir->SizeOfCert;
- for (Index = 0; Index < HASHALG_MAX; Index++) {
+ //
+ // Check the Hash algorithm in PE/COFF Authenticode.
+ // According to PKCS#7 Definition:
+ // SignedData ::= SEQUENCE {
+ // version Version,
+ // digestAlgorithms DigestAlgorithmIdentifiers,
+ // contentInfo ContentInfo,
+ // .... }
+ // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing
+ // This field has the fixed offset (+32) in final Authenticode ASN.1 data.
+ // Fixed offset (+32) is calculated based on two bytes of length encoding.
+ //
+ if ((PkcsCertSize > 1) && ((*(PkcsCertData->CertData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)) {
//
- // Check the Hash algorithm in PE/COFF Authenticode.
- // According to PKCS#7 Definition:
- // SignedData ::= SEQUENCE {
- // version Version,
- // digestAlgorithms DigestAlgorithmIdentifiers,
- // contentInfo ContentInfo,
- // .... }
- // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing
- // This field has the fixed offset (+32) in final Authenticode ASN.1 data.
- // Fixed offset (+32) is calculated based on two bytes of length encoding.
+ // Only support two bytes of Long Form of Length Encoding.
//
- if ((*(PkcsCertData->CertData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE) {
- //
- // Only support two bytes of Long Form of Length Encoding.
- //
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ for (Index = 0; Index < HASHALG_MAX; Index++) {
+ if (PkcsCertSize < 32 + mHash[Index].OidLength) {
continue;
}
- //
if (CompareMem (PkcsCertData->CertData + 32, mHash[Index].OidValue, mHash[Index].OidLength) == 0) {
break;
}
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c index 54e0887..8ede590 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c @@ -1294,8 +1294,43 @@ SmbiosPrintStructure ( case 42:
DisplayMCHostInterfaceType (Struct->Type42->InterfaceType, Option);
if (AE_SMBIOS_VERSION (0x3, 0x2)) {
+ UINT32 DataValue = 0;
PRINT_STRUCT_VALUE_H (Struct, Type42, InterfaceTypeSpecificDataLength);
- PRINT_BIT_FIELD (Struct, Type42, InterfaceTypeSpecificData, Struct->Type42->InterfaceTypeSpecificDataLength);
+ if (Struct->Type42->InterfaceTypeSpecificDataLength < 4) {
+ ShellPrintEx (-1, -1, L"WARNING: InterfaceTypeSpecificDataLength should be >= 4.\n");
+ }
+
+ ShellPrintEx (-1, -1, L"InterfaceTypeSpecificData\n");
+ // Decode and interpret InterfaceTypeSpecificData based on the InterfaceType
+ switch (Struct->Type42->InterfaceType) {
+ case MCHostInterfaceTypeOemDefined:
+ // The first four bytes are the vendor ID (MSB first), as assigned by the Internet Assigned Numbers Authority (IANA) as "Enterprise Number".
+ // See https://www.iana.org/assignments/enterprise-numbers.txt
+ ShellPrintEx (-1, -1, L"Vendor ID (IANA Enterprise Number): %d", (UINT32)*(Struct->Type42->InterfaceTypeSpecificData));
+ break;
+
+ // As defined in MCTP Host Interface Specification, DSP0256
+ case MCHostInterfaceTypeMMBI:
+ // For MCTP interface type of MMBI; this defines the pointer to the MMBI capability descriptor, as defined in DSP0282, Section 7.1
+ DataValue = *(UINT32 *)Struct->Type42->InterfaceTypeSpecificData;
+ ShellPrintEx (-1, -1, L"Pointer to MMBI capability descriptor: 0x%x\n", DataValue);
+ break;
+
+ case MCHostInterfaceTypeI2C_SMBUS:
+ case MCHostInterfaceTypeI3C:
+ case MCHostInterfaceTypeKCS:
+ // switch case fall through
+ // For MCTP interface type of I2C, I3C, KCS; this value is reserved and must be 0
+ DataValue = *(UINT32 *)Struct->Type42->InterfaceTypeSpecificData;
+ ShellPrintEx (-1, -1, L"For Interface type I2C, I3C or KCS, InterfaceTypeSpecificData is reserved and must be 0.\n");
+ ShellPrintEx (-1, -1, L"Actual value is : 0x%x\n", DataValue);
+ break;
+
+ default:
+ // The decoding is not defined for these values in SMBIOS 3.8.0. The value is dumped
+ PRINT_BIT_FIELD (Struct, Type42, InterfaceTypeSpecificData, Struct->Type42->InterfaceTypeSpecificDataLength);
+ break;
+ }
}
break;
@@ -2577,6 +2612,10 @@ DisplayProcessorFamily2 ( Print (L"ARMv8\n");
break;
+ case 0x102:
+ Print (L"ARMv9\n");
+ break;
+
case 0x104:
Print (L"SH-3\n");
break;
diff --git a/StandaloneMmPkg/Core/Dispatcher.c b/StandaloneMmPkg/Core/Dispatcher.c index b686c31..821d9d6 100644 --- a/StandaloneMmPkg/Core/Dispatcher.c +++ b/StandaloneMmPkg/Core/Dispatcher.c @@ -49,6 +49,33 @@ typedef struct { EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
} KNOWN_FWVOL;
+typedef struct {
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} FV_FILEPATH_DEVICE_PATH;
+
+FV_FILEPATH_DEVICE_PATH gMmDriverFilePathTemplate = {
+ {
+ {
+ MEDIA_DEVICE_PATH,
+ MEDIA_PIWG_FW_FILE_DP,
+ {
+ (UINT8)(sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)),
+ (UINT8)(sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) >> 8)
+ }
+ },
+ { 0 }
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ 0
+ }
+ }
+};
+
//
// Function Prototypes
//
@@ -201,7 +228,13 @@ MmLoadImage ( DriverEntry->LoadedImage.ParentHandle = NULL;
DriverEntry->LoadedImage.SystemTable = NULL;
DriverEntry->LoadedImage.DeviceHandle = NULL;
- DriverEntry->LoadedImage.FilePath = NULL;
+ DriverEntry->LoadedImage.FilePath = AllocateCopyPool (sizeof (FV_FILEPATH_DEVICE_PATH), &gMmDriverFilePathTemplate);
+ if (DriverEntry->LoadedImage.FilePath != NULL) {
+ CopyGuid (
+ &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)DriverEntry->LoadedImage.FilePath)->FvFileName,
+ &DriverEntry->FileName
+ );
+ }
DriverEntry->LoadedImage.ImageBase = (VOID *)(UINTN)DriverEntry->ImageBuffer;
DriverEntry->LoadedImage.ImageSize = ImageContext->ImageSize;
@@ -432,7 +465,9 @@ MmDispatcher ( // skip the LoadImage
//
if (DriverEntry->ImageHandle == NULL) {
+ PERF_LOAD_IMAGE_BEGIN (NULL);
Status = MmLoadImage (DriverEntry, &ImageContext);
+ PERF_LOAD_IMAGE_END (DriverEntry->ImageHandle);
//
// Update the driver state to reflect that it's been loaded
@@ -466,7 +501,9 @@ MmDispatcher ( // For each MM driver, pass NULL as ImageHandle
//
DEBUG ((DEBUG_INFO, "StartImage - 0x%x (Standalone Mode)\n", DriverEntry->ImageEntryPoint));
+ PERF_START_IMAGE_BEGIN (DriverEntry->ImageHandle);
Status = ((MM_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, &gMmCoreMmst);
+ PERF_START_IMAGE_END (DriverEntry->ImageHandle);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "StartImage Status - %r\n", Status));
diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c index ba36c5c..154285f 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.c +++ b/StandaloneMmPkg/Core/StandaloneMmCore.c @@ -502,11 +502,15 @@ MmEntryPoint ( IN CONST EFI_MM_ENTRY_CONTEXT *MmEntryContext
)
{
- EFI_STATUS Status;
- EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
- MM_COMM_BUFFER_STATUS *CommunicationStatus;
- UINTN BufferSize;
- EFI_HANDLE MmHandle;
+ EFI_STATUS Status;
+ EFI_MM_COMMUNICATE_HEADER_V3 *CommunicateHeader;
+ EFI_MM_COMMUNICATE_HEADER *LegacyCommunicateHeader;
+ MM_COMM_BUFFER_STATUS *CommunicationStatus;
+ UINTN BufferSize;
+ EFI_HANDLE MmHandle;
+ EFI_GUID *CommGuid;
+ UINTN CommGuidOffset;
+ UINTN CommHeaderSize;
DEBUG ((DEBUG_INFO, "MmEntryPoint ...\n"));
@@ -543,8 +547,22 @@ MmEntryPoint ( //
// Synchronous MMI for MM Core or request from Communicate protocol
//
- CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mMmCommunicationBuffer->PhysicalStart;
- BufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength;
+ CommGuid = &((EFI_MM_COMMUNICATE_HEADER_V3 *)(UINTN)mMmCommunicationBuffer->PhysicalStart)->HeaderGuid;
+ //
+ // Check if the signature matches EFI_MM_COMMUNICATE_HEADER_V3 definition
+ //
+ if (CompareGuid (CommGuid, &gEfiMmCommunicateHeaderV3Guid)) {
+ CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER_V3 *)(UINTN)mMmCommunicationBuffer->PhysicalStart;
+ CommGuidOffset = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER_V3, MessageGuid);
+ CommHeaderSize = sizeof (EFI_MM_COMMUNICATE_HEADER_V3);
+ BufferSize = CommunicateHeader->BufferSize;
+ } else {
+ LegacyCommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mMmCommunicationBuffer->PhysicalStart;
+ CommGuidOffset = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, HeaderGuid);
+ CommHeaderSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
+ BufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + LegacyCommunicateHeader->MessageLength;
+ }
+
if (BufferSize <= EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)) {
//
// Shadow the data from MM Communication Buffer to internal buffer
@@ -559,16 +577,15 @@ MmEntryPoint ( 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 -= CommHeaderSize;
+ Status = MmiManage (
+ (EFI_GUID *)((UINT8 *)mInternalCommBufferCopy + CommGuidOffset),
+ NULL,
+ (UINT8 *)mInternalCommBufferCopy + CommHeaderSize,
+ &BufferSize
+ );
- BufferSize = BufferSize + OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
+ BufferSize = BufferSize + CommHeaderSize;
if (BufferSize <= EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)) {
//
// Copy the data back to MM Communication Buffer
diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.h b/StandaloneMmPkg/Core/StandaloneMmCore.h index 3884ed3..da123c5 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.h +++ b/StandaloneMmPkg/Core/StandaloneMmCore.h @@ -47,6 +47,7 @@ #include <Library/PeCoffGetEntryPointLib.h>
#include <Library/StandaloneMmMemLib.h>
#include <Library/HobLib.h>
+#include <Library/PerformanceLib.h>
#include "StandaloneMmCorePrivateData.h"
diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf index f3340d2..bda86dc 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.inf +++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf @@ -55,6 +55,7 @@ StandaloneMmCoreEntryPoint
HobPrintLib
ImagePropertiesRecordLib
+ PerformanceLib
[Protocols]
gEfiDxeMmReadyToLockProtocolGuid ## UNDEFINED # SmiHandlerRegister
@@ -84,6 +85,7 @@ gEfiSmmSmramMemoryGuid
gEdkiiPiSmmMemoryAttributesTableGuid
gEfiMmPeiMmramMemoryReserveGuid
+ gEfiMmCommunicateHeaderV3Guid ## CONSUMES ## GUID # Communicate header
[Pcd]
gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth ##CONSUMES
diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c index 7b1e063..ba0b2ec 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c @@ -10,6 +10,13 @@ #include "MmCommunicationDxe.h"
//
+// PI 1.9 MM Communication Protocol 3 instance
+//
+EFI_MM_COMMUNICATION3_PROTOCOL mMmCommunication3 = {
+ MmCommunicate3
+};
+
+//
// PI 1.7 MM Communication Protocol 2 instance
//
EFI_MM_COMMUNICATION2_PROTOCOL mMmCommunication2 = {
@@ -260,10 +267,11 @@ ProcessCommunicationBuffer ( IN OUT UINTN *CommSize OPTIONAL
)
{
- EFI_STATUS Status;
- EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
- MM_COMM_BUFFER_STATUS *CommonBufferStatus;
- UINTN BufferSize;
+ EFI_STATUS Status;
+ EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
+ EFI_MM_COMMUNICATE_HEADER_V3 *CommunicateHeaderV3;
+ MM_COMM_BUFFER_STATUS *CommonBufferStatus;
+ UINTN BufferSize;
//
// Check parameters
@@ -273,7 +281,16 @@ ProcessCommunicationBuffer ( }
CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)CommBuffer;
- BufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength;
+ if (CompareGuid (&CommunicateHeader->HeaderGuid, &gEfiMmCommunicateHeaderV3Guid)) {
+ CommunicateHeaderV3 = (EFI_MM_COMMUNICATE_HEADER_V3 *)CommBuffer;
+ if (CommunicateHeaderV3->BufferSize < sizeof (EFI_MM_COMMUNICATE_HEADER_V3) + CommunicateHeaderV3->MessageSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BufferSize = ((EFI_MM_COMMUNICATE_HEADER_V3 *)CommBuffer)->BufferSize;
+ } else {
+ BufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength;
+ }
if (CommSize != NULL) {
ASSERT (*CommSize == BufferSize);
@@ -323,6 +340,38 @@ ProcessCommunicationBuffer ( This function provides a service to send and receive messages from a registered UEFI service.
+ @param[in] This The EFI_MM_COMMUNICATION3_PROTOCOL instance.
+ @param[in, out] CommBufferPhysical Physical address of the MM communication buffer, of which content must
+ start with EFI_MM_COMMUNICATE_HEADER_V3.
+ @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer, of which content must
+ start with EFI_MM_COMMUNICATE_HEADER_V3.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER CommBufferPhysical was NULL or CommBufferVirtual was NULL.
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
+ If this error is returned, the MessageSize field
+ in the CommBuffer header, are updated to reflect
+ the maximum payload size the implementation can accommodate.
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter are in address range
+ that cannot be accessed by the MM environment.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCommunicate3 (
+ IN CONST EFI_MM_COMMUNICATION3_PROTOCOL *This,
+ IN OUT VOID *CommBufferPhysical,
+ IN OUT VOID *CommBufferVirtual
+ )
+{
+ return ProcessCommunicationBuffer (CommBufferVirtual, NULL);
+}
+
+/**
+ 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.
@@ -435,6 +484,14 @@ MmCommunicationEntryPoint ( Handle = NULL;
Status = gBS->InstallProtocolInterface (
&Handle,
+ &gEfiMmCommunication3ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mMmCommunication3
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
&gEfiMmCommunication2ProtocolGuid,
EFI_NATIVE_INTERFACE,
&mMmCommunication2
diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h index d84d821..3b399da 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h @@ -22,6 +22,7 @@ #include <Library/ReportStatusCodeLib.h>
#include <Protocol/SmmControl2.h>
+#include <Protocol/MmCommunication3.h>
#include <Protocol/MmCommunication2.h>
#include <Protocol/MmCommunication.h>
#include <Protocol/DxeMmReadyToLock.h>
@@ -54,6 +55,35 @@ typedef struct { This function provides a service to send and receive messages from a registered UEFI service.
+ @param[in] This The EFI_MM_COMMUNICATION3_PROTOCOL instance.
+ @param[in, out] CommBufferPhysical Physical address of the MM communication buffer, of which content must
+ start with EFI_MM_COMMUNICATE_HEADER_V3.
+ @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer, of which content must
+ start with EFI_MM_COMMUNICATE_HEADER_V3.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER CommBufferPhysical was NULL or CommBufferVirtual was NULL.
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
+ If this error is returned, the MessageSize field
+ in the CommBuffer header, are updated to reflect
+ the maximum payload size the implementation can accommodate.
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter are in address range
+ that cannot be accessed by the MM environment.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCommunicate3 (
+ IN CONST EFI_MM_COMMUNICATION3_PROTOCOL *This,
+ IN OUT VOID *CommBufferPhysical,
+ IN OUT VOID *CommBufferVirtual
+ );
+
+/**
+ 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.
diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf index 821df02..dd5a0b1 100644 --- a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf +++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf @@ -44,8 +44,10 @@ gEfiEventVirtualAddressChangeGuid
gEfiEndOfDxeEventGroupGuid
gEfiEventExitBootServicesGuid
+ gEfiMmCommunicateHeaderV3Guid
[Protocols]
+ gEfiMmCommunication3ProtocolGuid
gEfiMmCommunication2ProtocolGuid
gEfiSmmControl2ProtocolGuid
gEfiMmCommunicationProtocolGuid
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c index 4a71871..b496c7c 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c @@ -8,12 +8,20 @@ #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
+EFI_PEI_MM_COMMUNICATION_PPI mMmCommunicationPpi = { Communicate };
+EFI_PEI_MM_COMMUNICATION3_PPI mMmCommunication3Ppi = { Communicate3 };
+
+EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gEfiPeiMmCommunicationPpiGuid,
+ &mMmCommunicationPpi
+ },
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMmCommunication3PpiGuid,
+ &mMmCommunication3Ppi
+ }
};
EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
@@ -128,6 +136,120 @@ Communicate ( }
/**
+ 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_COMMUNICATE3 instance.
+ @param[in, out] CommBuffer A pointer to the buffer to convey into MMRAM.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
+**/
+EFI_STATUS
+EFIAPI
+Communicate3 (
+ IN CONST EFI_PEI_MM_COMMUNICATION3_PPI *This,
+ IN OUT VOID *CommBuffer
+ )
+{
+ 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;
+ EFI_MM_COMMUNICATE_HEADER_V3 *CommunicateHeader;
+
+ 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) {
+ return EFI_INVALID_PARAMETER;
+ } else {
+ CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER_V3 *)CommBuffer;
+ //
+ // Check if the HeaderGuid is valid
+ //
+ if (CompareGuid (&CommunicateHeader->HeaderGuid, &gEfiMmCommunicateHeaderV3Guid)) {
+ DEBUG ((DEBUG_ERROR, "HeaderGuid is not valid!\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TempCommSize = CommunicateHeader->BufferSize;
+ //
+ // CommSize must hold HeaderGuid and MessageLength
+ //
+ if (TempCommSize < sizeof (EFI_MM_COMMUNICATE_HEADER_V3)) {
+ DEBUG ((DEBUG_ERROR, "Communicate buffer size (%d) is less than minimum size (%d)!", TempCommSize, sizeof (EFI_MM_COMMUNICATE_HEADER_V3)));
+ 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
+ //
+ TempCommSize = (UINTN)MmCommBufferStatus->ReturnBufferSize;
+
+ //
+ // Copy the returned data to the non-mmram buffer (CommBuffer)
+ //
+ CopyMem (CommBuffer, (VOID *)(MmCommBuffer->PhysicalStart), TempCommSize);
+
+ CommunicateHeader->BufferSize = TempCommSize;
+
+ 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.
@param MmFvBase Base address of FV which included MM Core driver.
@@ -817,7 +939,7 @@ StandaloneMmIplPeiEntry ( //
// Install MmCommunicationPpi
//
- Status = PeiServicesInstallPpi (&mPpiList);
+ Status = PeiServicesInstallPpi (mPpiList);
ASSERT_EFI_ERROR (Status);
//
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h index c5d5987..01b947c 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h @@ -23,6 +23,7 @@ #include <Library/PeiServicesTablePointerLib.h>
#include <Ppi/MmControl.h>
#include <Ppi/MmCommunication.h>
+#include <Ppi/MmCommunication3.h>
#include <Ppi/MmCoreFvLocationPpi.h>
#include <Protocol/MmCommunication.h>
#include <Library/MmPlatformHobProducerLib.h>
@@ -50,6 +51,24 @@ Communicate ( );
/**
+ 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_COMMUNICATE3 instance.
+ @param[in, out] CommBuffer A pointer to the buffer to convey into MMRAM.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
+**/
+EFI_STATUS
+EFIAPI
+Communicate3 (
+ IN CONST EFI_PEI_MM_COMMUNICATION3_PPI *This,
+ IN OUT VOID *CommBuffer
+ );
+
+/**
This is the callback function on end of PEI.
This callback is used for call MmEndOfPeiHandler in standalone MM core.
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf index 0341a98..9f446e8 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf @@ -57,10 +57,12 @@ gMmProfileDataHobGuid
gMmUnblockRegionHobGuid
gMmStatusCodeUseSerialHobGuid
+ gEfiMmCommunicateHeaderV3Guid
[Ppis]
gEfiPeiMmControlPpiGuid
gEfiPeiMmCommunicationPpiGuid
+ gEfiPeiMmCommunication3PpiGuid
gEfiEndOfPeiSignalPpiGuid
gMmCoreFvLocationPpiGuid
diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc index 08b80c9..d36081e 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -78,18 +78,18 @@ ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
StandaloneMmCoreEntryPoint|ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.inf
StandaloneMmMmuLib|ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
- ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
- ArmSvcLib|ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf
+ ArmSmcLib|MdePkg/Library/ArmSmcLib/ArmSmcLib.inf
+ ArmSvcLib|MdePkg/Library/ArmSvcLib/ArmSvcLib.inf
CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
PeCoffExtraActionLib|StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf
ArmTransferListLib|ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf
[LibraryClasses.common.MM_CORE_STANDALONE]
HobLib|StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
- ArmFfaLib|ArmPkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf
+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
[LibraryClasses.AARCH64.MM_CORE_STANDALONE, LibraryClasses.ARM.MM_CORE_STANDALONE]
- ArmFfaLib|ArmPkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf
+ ArmFfaLib|MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf
[LibraryClasses.common.MM_STANDALONE]
MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
diff --git a/UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf b/UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf index 71d8e5e..519c79f 100644 --- a/UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf +++ b/UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf @@ -16,7 +16,7 @@ FILE_GUID = 37E8137B-9F74-4250-8951-7A970A3C39C0
MODULE_TYPE = DXE_SMM_DRIVER
VERSION_STRING = 1.0
- LIBRARY_CLASS = MmSaveStateLib|DXE_SMM_DRIVER MM_STANDALONE
+ LIBRARY_CLASS = MmSaveStateLib|DXE_SMM_DRIVER MM_STANDALONE MM_CORE_STANDALONE
[Sources]
MmSaveState.h
diff --git a/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf b/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf index 50eb746..098e656 100644 --- a/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf +++ b/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf @@ -18,7 +18,7 @@ FILE_GUID = D6494E1B-E06F-4ab5-B64D-48B25AA9EB33
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
- LIBRARY_CLASS = SmmCpuPlatformHookLib|DXE_SMM_DRIVER MM_STANDALONE
+ LIBRARY_CLASS = SmmCpuPlatformHookLib|DXE_SMM_DRIVER MM_STANDALONE MM_CORE_STANDALONE
#
# The following information is for reference only and not required by the build tools.
diff --git a/UefiPayloadPkg/Include/Coreboot.h b/UefiPayloadPkg/Include/Coreboot.h index 2d454f7..1b05f15 100644 --- a/UefiPayloadPkg/Include/Coreboot.h +++ b/UefiPayloadPkg/Include/Coreboot.h @@ -249,6 +249,20 @@ struct cb_cbmem_tab { UINT64 cbmem_tab;
};
+#define CB_TAG_SMMSTOREV2 0x0039
+struct cb_smmstorev2 {
+ UINT32 tag;
+ UINT32 size;
+ UINT32 num_blocks; /* Number of writeable blocks in the store */
+ UINT32 block_size; /* Size of a block in bytes (64 KiB by default) */
+ UINT32 mmap_addr; /* MMIO address of the store for read-only access */
+ UINT32 com_buffer; /* Physical address of the communication buffer */
+ UINT32 com_buffer_size; /* Size of the communication buffer in bytes */
+ UINT8 apm_cmd; /* The command byte to write to the APM I/O port to
+ communicate with the store */
+ UINT8 unused[3]; /* Set to zero */
+} __attribute__ ((packed));
+
/* Helpful macros */
#define MEM_RANGE_COUNT(_rec) \
diff --git a/UefiPayloadPkg/Include/Guid/SmmStoreInfoGuid.h b/UefiPayloadPkg/Include/Guid/SmmStoreInfoGuid.h new file mode 100644 index 0000000..19b4bdc --- /dev/null +++ b/UefiPayloadPkg/Include/Guid/SmmStoreInfoGuid.h @@ -0,0 +1,26 @@ +/** @file
+ This file defines the hob structure for coreboot's SmmStore.
+
+ Copyright (c) 2022, 9elements GmbH<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef SMMSTORE_GUID_H_
+#define SMMSTORE_GUID_H_
+
+///
+/// System Table Information GUID
+///
+extern EFI_GUID gEfiSmmStoreInfoHobGuid;
+
+typedef struct {
+ UINT64 ComBuffer;
+ UINT32 ComBufferSize;
+ UINT32 NumBlocks;
+ UINT32 BlockSize;
+ UINT64 MmioAddress;
+ UINT8 ApmCmd;
+} SMMSTORE_INFO;
+
+#endif // SMMSTORE_GUID_H_
diff --git a/UefiPayloadPkg/Include/Library/SmmStoreLib.h b/UefiPayloadPkg/Include/Library/SmmStoreLib.h new file mode 100644 index 0000000..bf0b8a0 --- /dev/null +++ b/UefiPayloadPkg/Include/Library/SmmStoreLib.h @@ -0,0 +1,146 @@ +/** @file SmmStoreLib.h
+
+ Copyright (c) 2022, 9elements GmbH<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef SMM_STORE_LIB_H_
+#define SMM_STORE_LIB_H_
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Guid/SmmStoreInfoGuid.h>
+
+#define SMMSTORE_COMBUF_SIZE 16
+
+/**
+ Get the SmmStore block size
+
+ @param BlockSize The pointer to store the block size in.
+
+**/
+EFI_STATUS
+SmmStoreLibGetBlockSize (
+ OUT UINTN *BlockSize
+ );
+
+/**
+ Get the SmmStore number of blocks
+
+ @param NumBlocks The pointer to store the number of blocks in.
+
+**/
+EFI_STATUS
+SmmStoreLibGetNumBlocks (
+ OUT UINTN *NumBlocks
+ );
+
+/**
+ Get the SmmStore MMIO address
+
+ @param MmioAddress The pointer to store the address in.
+
+**/
+EFI_STATUS
+SmmStoreLibGetMmioAddress (
+ OUT EFI_PHYSICAL_ADDRESS *MmioAddress
+ );
+
+/**
+ Read from SmmStore
+
+ @param[in] Lba The starting logical block index to read from.
+ @param[in] Offset Offset into the block at which to begin reading.
+ @param[in] NumBytes On input, indicates the requested read size. On
+ output, indicates the actual number of bytes read.
+ @param[in] Buffer Pointer to the buffer to read into.
+
+**/
+EFI_STATUS
+SmmStoreLibRead (
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN UINTN *NumBytes,
+ IN UINT8 *Buffer
+ );
+
+/**
+ Write to SmmStore
+
+ @param[in] Lba The starting logical block index to write to.
+ @param[in] Offset Offset into the block at which to begin writing.
+ @param[in] NumBytes On input, indicates the requested write size. On
+ output, indicates the actual number of bytes written.
+ @param[in] Buffer Pointer to the data to write.
+
+**/
+EFI_STATUS
+SmmStoreLibWrite (
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN UINTN *NumBytes,
+ IN UINT8 *Buffer
+ );
+
+/**
+ Erase a block using the SmmStore
+
+ @param Lba The logical block index to erase.
+
+**/
+EFI_STATUS
+SmmStoreLibEraseBlock (
+ IN EFI_LBA Lba
+ );
+
+/**
+ Function to update a pointer on virtual address change. Matches the signature
+ and operation of EfiConvertPointer.
+
+**/
+typedef EFI_STATUS EFIAPI (*CONVERT_POINTER_CALLBACK) (
+ IN UINTN DebugDisposition,
+ IN OUT VOID **Address
+ );
+
+/**
+ Initializes SmmStore support
+
+ @retval EFI_WRITE_PROTECTED The SmmStore is not present.
+ @retval EFI_UNSUPPORTED The SmmStoreInfo HOB wasn't found.
+ @retval EFI_SUCCESS The SmmStore is supported.
+
+**/
+EFI_STATUS
+SmmStoreLibInitialize (
+ VOID
+ );
+
+/**
+ Fixup internal data so that EFI can be called in virtual mode.
+ Converts any pointers in lib to virtual mode. This function is meant to
+ be invoked on gEfiEventVirtualAddressChangeGuid event when the library is
+ used at run-time.
+
+ @param[in] ConvertPointer Function to switch virtual address space.
+
+**/
+VOID
+EFIAPI
+SmmStoreLibVirtualAddressChange (
+ IN CONVERT_POINTER_CALLBACK ConvertPointer
+ );
+
+/**
+ Deinitializes SmmStore support
+
+**/
+VOID
+EFIAPI
+SmmStoreLibDeinitialize (
+ VOID
+ );
+
+#endif /* SMM_STORE_LIB_H_ */
diff --git a/UefiPayloadPkg/Include/Library/SmmStoreParseLib.h b/UefiPayloadPkg/Include/Library/SmmStoreParseLib.h new file mode 100644 index 0000000..ec84aef --- /dev/null +++ b/UefiPayloadPkg/Include/Library/SmmStoreParseLib.h @@ -0,0 +1,29 @@ +/** @file
+ This library parses the coreboot table in memory to extract required
+ information.
+
+ Copyright (c) 2021, Star Labs Systems. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef SMM_STORE_PARSE_LIB_H_
+#define SMM_STORE_PARSE_LIB_H_
+
+#include <Guid/SmmStoreInfoGuid.h>
+
+/**
+ Find the SmmStore HOB.
+
+ @param SmmStoreInfo Pointer to the SMMSTORE_INFO structure
+
+ @retval RETURN_SUCCESS Successfully found the Smm store buffer information.
+ @retval RETURN_NOT_FOUND Failed to find the Smm store buffer information.
+**/
+RETURN_STATUS
+EFIAPI
+ParseSmmStoreInfo (
+ OUT SMMSTORE_INFO *SmmStoreInfo
+ );
+
+#endif // SMM_STORE_PARSE_LIB_H_
diff --git a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c index 9e14953..d7282e0 100644 --- a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c +++ b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c @@ -14,6 +14,7 @@ #include <Library/PcdLib.h>
#include <Library/IoLib.h>
#include <Library/BlParseLib.h>
+#include <Library/SmmStoreParseLib.h>
#include <IndustryStandard/Acpi.h>
#include <Coreboot.h>
@@ -400,15 +401,6 @@ ParseMemoryInfo ( MemoryMap.Size = cb_unpack64 (Range->size);
MemoryMap.Type = (UINT8)Range->type;
MemoryMap.Flag = 0;
- DEBUG ((
- DEBUG_INFO,
- "%d. %016lx - %016lx [%02x]\n",
- Index,
- MemoryMap.Base,
- MemoryMap.Base + MemoryMap.Size - 1,
- MemoryMap.Type
- ));
-
MemInfoCallback (&MemoryMap, Params);
}
@@ -604,3 +596,45 @@ ParseMiscInfo ( {
return RETURN_SUCCESS;
}
+
+/**
+ Find the SmmStore HOB.
+
+ @param SmmStoreInfo Pointer to the SMMSTORE_INFO structure
+
+ @retval RETURN_SUCCESS Successfully found the Smm store buffer information.
+ @retval RETURN_NOT_FOUND Failed to find the Smm store buffer information.
+**/
+RETURN_STATUS
+EFIAPI
+ParseSmmStoreInfo (
+ OUT SMMSTORE_INFO *SmmStoreInfo
+ )
+{
+ struct cb_smmstorev2 *CbSSRec;
+
+ if (SmmStoreInfo == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ CbSSRec = FindCbTag (CB_TAG_SMMSTOREV2);
+ if (CbSSRec == NULL) {
+ return RETURN_NOT_FOUND;
+ }
+
+ DEBUG ((DEBUG_INFO, "Found Smm Store information\n"));
+ DEBUG ((DEBUG_INFO, "block size: 0x%x\n", CbSSRec->block_size));
+ DEBUG ((DEBUG_INFO, "number of blocks: 0x%x\n", CbSSRec->num_blocks));
+ DEBUG ((DEBUG_INFO, "communication buffer: 0x%x\n", CbSSRec->com_buffer));
+ DEBUG ((DEBUG_INFO, "communication buffer size: 0x%x\n", CbSSRec->com_buffer_size));
+ DEBUG ((DEBUG_INFO, "MMIO address of store: 0x%x\n", CbSSRec->mmap_addr));
+
+ SmmStoreInfo->ComBuffer = CbSSRec->com_buffer;
+ SmmStoreInfo->ComBufferSize = CbSSRec->com_buffer_size;
+ SmmStoreInfo->BlockSize = CbSSRec->block_size;
+ SmmStoreInfo->NumBlocks = CbSSRec->num_blocks;
+ SmmStoreInfo->MmioAddress = CbSSRec->mmap_addr;
+ SmmStoreInfo->ApmCmd = CbSSRec->apm_cmd;
+
+ return RETURN_SUCCESS;
+}
diff --git a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c index d88238b..de139a5 100644 --- a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c +++ b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c @@ -14,6 +14,7 @@ #include <Library/IoLib.h>
#include <Library/HobLib.h>
#include <Library/BlParseLib.h>
+#include <Library/SmmStoreParseLib.h>
#include <IndustryStandard/Acpi.h>
#include <UniversalPayload/PciRootBridges.h>
@@ -289,3 +290,20 @@ ParseMiscInfo ( return Status;
}
+
+/**
+ Find the SmmStore HOB.
+
+ @param SmmStoreInfo Pointer to the SMMSTORE_INFO structure
+
+ @retval RETURN_SUCCESS Successfully found the Smm store buffer information.
+ @retval RETURN_NOT_FOUND Failed to find the Smm store buffer information.
+**/
+RETURN_STATUS
+EFIAPI
+ParseSmmStoreInfo (
+ OUT SMMSTORE_INFO *SmmStoreInfo
+ )
+{
+ return RETURN_NOT_FOUND;
+}
diff --git a/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.c b/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.c new file mode 100644 index 0000000..690bae0 --- /dev/null +++ b/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.c @@ -0,0 +1,447 @@ +/** @file SmmStore.c
+
+ Copyright (c) 2022, 9elements GmbH<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <PiDxe.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/SmmStoreLib.h>
+#include "SmmStore.h"
+
+/*
+ * A memory buffer to place arguments in.
+ */
+STATIC SMM_STORE_COM_BUF *mArgComBuf;
+STATIC EFI_PHYSICAL_ADDRESS mArgComBufPhys;
+
+/*
+ * Metadata provided by the first stage bootloader.
+ */
+STATIC SMMSTORE_INFO *mSmmStoreInfo;
+
+/**
+ Calls into SMM to use the SMMSTOREv2 implementation for persistent storage.
+
+ @param Cmd The command to write into the APM port. This allows to enter the
+ Smi special command handler.
+ @param SubCmd The subcommand to execute in the Smi handler.
+ @param Arg Optional argument to pass to the Smi handler. Typically a pointer
+ in 'flat' memory mode, which points to read only memory.
+
+ @retval EFI_NO_RESPONSE The SmmStore is not present or didn't response.
+ @retval EFI_UNSUPPORTED The request isn't supported.
+ @retval EFI_DEVICE_ERROR An error occurred while executing the request.
+ @retval EFI_SUCCESS The operation was executed successfully.
+**/
+STATIC
+EFI_STATUS
+CallSmm (
+ UINT8 Cmd,
+ UINT8 SubCmd,
+ UINTN Arg
+ )
+{
+ CONST UINTN Rax = ((SubCmd << 8) | Cmd);
+ CONST UINTN Rbx = Arg;
+ UINTN Result;
+
+ Result = TriggerSmi (Rax, Rbx, 5);
+ if (Result == Rax) {
+ return EFI_NO_RESPONSE;
+ } else if (Result == SMMSTORE_RET_SUCCESS) {
+ return EFI_SUCCESS;
+ } else if (Result == SMMSTORE_RET_UNSUPPORTED) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+/**
+ Get the SmmStore block size
+
+ @param BlockSize The pointer to store the block size in.
+
+**/
+EFI_STATUS
+SmmStoreLibGetBlockSize (
+ OUT UINTN *BlockSize
+ )
+{
+ if (mSmmStoreInfo == NULL) {
+ return EFI_NO_MEDIA;
+ }
+
+ if (BlockSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *BlockSize = mSmmStoreInfo->BlockSize;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get the SmmStore number of blocks
+
+ @param NumBlocks The pointer to store the number of blocks in.
+
+**/
+EFI_STATUS
+SmmStoreLibGetNumBlocks (
+ OUT UINTN *NumBlocks
+ )
+{
+ if (mSmmStoreInfo == NULL) {
+ return EFI_NO_MEDIA;
+ }
+
+ if (NumBlocks == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *NumBlocks = mSmmStoreInfo->NumBlocks;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get the SmmStore MMIO address
+
+ @param MmioAddress The pointer to store the address in.
+
+**/
+EFI_STATUS
+SmmStoreLibGetMmioAddress (
+ OUT EFI_PHYSICAL_ADDRESS *MmioAddress
+ )
+{
+ if (mSmmStoreInfo == NULL) {
+ return EFI_NO_MEDIA;
+ }
+
+ if (MmioAddress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *MmioAddress = mSmmStoreInfo->MmioAddress;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Read from SmmStore
+
+ @param[in] Lba The starting logical block index to read from.
+ @param[in] Offset Offset into the block at which to begin reading.
+ @param[in] NumBytes On input, indicates the requested read size. On
+ output, indicates the actual number of bytes read.
+ @param[in] Buffer Pointer to the buffer to read into.
+
+**/
+EFI_STATUS
+SmmStoreLibRead (
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+
+ if (mSmmStoreInfo == NULL) {
+ return EFI_NO_MEDIA;
+ }
+
+ if (Lba >= mSmmStoreInfo->NumBlocks) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((*NumBytes + Offset) > mSmmStoreInfo->BlockSize) ||
+ ((*NumBytes + Offset) > mSmmStoreInfo->ComBufferSize))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ mArgComBuf->Read.BufSize = *NumBytes;
+ mArgComBuf->Read.BufOffset = Offset;
+ mArgComBuf->Read.BlockId = Lba;
+
+ Status = CallSmm (mSmmStoreInfo->ApmCmd, SMMSTORE_CMD_RAW_READ, mArgComBufPhys);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ CopyMem (Buffer, (VOID *)(UINTN)(mSmmStoreInfo->ComBuffer + Offset), *NumBytes);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Write to SmmStore
+
+ @param[in] Lba The starting logical block index to write to.
+ @param[in] Offset Offset into the block at which to begin writing.
+ @param[in] NumBytes On input, indicates the requested write size. On
+ output, indicates the actual number of bytes written.
+ @param[in] Buffer Pointer to the data to write.
+
+**/
+EFI_STATUS
+SmmStoreLibWrite (
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ if (mSmmStoreInfo == NULL) {
+ return EFI_NO_MEDIA;
+ }
+
+ if (Lba >= mSmmStoreInfo->NumBlocks) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((*NumBytes + Offset) > mSmmStoreInfo->BlockSize) ||
+ ((*NumBytes + Offset) > mSmmStoreInfo->ComBufferSize))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ mArgComBuf->Write.BufSize = *NumBytes;
+ mArgComBuf->Write.BufOffset = Offset;
+ mArgComBuf->Write.BlockId = Lba;
+
+ CopyMem ((VOID *)(UINTN)(mSmmStoreInfo->ComBuffer + Offset), Buffer, *NumBytes);
+
+ return CallSmm (mSmmStoreInfo->ApmCmd, SMMSTORE_CMD_RAW_WRITE, mArgComBufPhys);
+}
+
+/**
+ Erase a SmmStore block
+
+ @param Lba The logical block index to erase.
+
+**/
+EFI_STATUS
+SmmStoreLibEraseBlock (
+ IN EFI_LBA Lba
+ )
+{
+ if (mSmmStoreInfo == NULL) {
+ return EFI_NO_MEDIA;
+ }
+
+ if (Lba >= mSmmStoreInfo->NumBlocks) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ mArgComBuf->Clear.BlockId = Lba;
+
+ return CallSmm (mSmmStoreInfo->ApmCmd, SMMSTORE_CMD_RAW_CLEAR, mArgComBufPhys);
+}
+
+/**
+ Fixup internal data so that EFI can be called in virtual mode.
+ Converts any pointers in lib to virtual mode. This function is meant to
+ be invoked on gEfiEventVirtualAddressChangeGuid event when the library is
+ used at run-time.
+
+ @param[in] ConvertPointer Function to switch virtual address space.
+
+**/
+VOID
+EFIAPI
+SmmStoreLibVirtualAddressChange (
+ IN CONVERT_POINTER_CALLBACK ConvertPointer
+ )
+{
+ ConvertPointer (0x0, (VOID **)&mArgComBuf);
+ if (mSmmStoreInfo != NULL) {
+ ConvertPointer (0x0, (VOID **)&mSmmStoreInfo->ComBuffer);
+ ConvertPointer (0x0, (VOID **)&mSmmStoreInfo);
+ }
+
+ return;
+}
+
+/**
+ Initializes SmmStore support
+
+ @retval EFI_WRITE_PROTECTED The SmmStore is not present.
+ @retval EFI_OUT_OF_RESOURCES Run out of memory.
+ @retval EFI_SUCCESS The SmmStore is supported.
+
+**/
+EFI_STATUS
+SmmStoreLibInitialize (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ VOID *GuidHob;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
+
+ //
+ // Find the SmmStore information guid hob
+ //
+ GuidHob = GetFirstGuidHob (&gEfiSmmStoreInfoHobGuid);
+ if (GuidHob == NULL) {
+ DEBUG ((DEBUG_WARN, "SmmStore not supported! Skipping driver init.\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Place SmmStore information hob in a runtime buffer
+ //
+ mSmmStoreInfo = AllocateRuntimePool (GET_GUID_HOB_DATA_SIZE (GuidHob));
+ if (mSmmStoreInfo == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CopyMem (mSmmStoreInfo, GET_GUID_HOB_DATA (GuidHob), GET_GUID_HOB_DATA_SIZE (GuidHob));
+
+ //
+ // Validate input
+ //
+ if ((mSmmStoreInfo->MmioAddress == 0) ||
+ (mSmmStoreInfo->ComBuffer == 0) ||
+ (mSmmStoreInfo->BlockSize == 0) ||
+ (mSmmStoreInfo->NumBlocks == 0))
+ {
+ DEBUG ((DEBUG_ERROR, "%a: Invalid data in SmmStore Info hob\n", __func__));
+ FreePool (mSmmStoreInfo);
+ mSmmStoreInfo = NULL;
+ return EFI_WRITE_PROTECTED;
+ }
+
+ //
+ // Allocate Communication Buffer for arguments to pass to SMM.
+ // The argument com buffer is only read by SMM, but never written.
+ // The FVB data send/retrieved will be placed in a separate bootloader
+ // pre-allocated memory region, the ComBuffer.
+ //
+ if (mSmmStoreInfo->ComBuffer < BASE_4GB) {
+ //
+ // Assume that SMM handler is running in 32-bit mode when ComBuffer is
+ // is placed below BASE_4GB.
+ //
+ mArgComBufPhys = BASE_4GB - 1;
+ } else {
+ mArgComBufPhys = BASE_8EB - 1;
+ }
+
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiRuntimeServicesData,
+ EFI_SIZE_TO_PAGES (sizeof (SMM_STORE_COM_BUF)),
+ &mArgComBufPhys
+ );
+
+ if (EFI_ERROR (Status)) {
+ FreePool (mSmmStoreInfo);
+ mSmmStoreInfo = NULL;
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mArgComBuf = (VOID *)mArgComBufPhys;
+
+ //
+ // Finally mark the SMM communication buffer provided by CB or SBL as runtime memory
+ //
+ Status = gDS->GetMemorySpaceDescriptor (mSmmStoreInfo->ComBuffer, &GcdDescriptor);
+ if (EFI_ERROR (Status) || (GcdDescriptor.GcdMemoryType != EfiGcdMemoryTypeReserved)) {
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: No memory space descriptor for com buffer found\n",
+ __func__
+ ));
+
+ //
+ // Add a new entry if not covered by existing mapping
+ //
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeReserved,
+ mSmmStoreInfo->ComBuffer,
+ mSmmStoreInfo->ComBufferSize,
+ EFI_MEMORY_WB | EFI_MEMORY_RUNTIME
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Mark as runtime service
+ //
+ Status = gDS->SetMemorySpaceAttributes (
+ mSmmStoreInfo->ComBuffer,
+ mSmmStoreInfo->ComBufferSize,
+ EFI_MEMORY_RUNTIME
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Mark the memory mapped store as MMIO memory
+ //
+ Status = gDS->GetMemorySpaceDescriptor (mSmmStoreInfo->MmioAddress, &GcdDescriptor);
+ if (EFI_ERROR (Status) || (GcdDescriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo)) {
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: No memory space descriptor for com buffer found\n",
+ __func__
+ ));
+
+ //
+ // Add a new entry if not covered by existing mapping
+ //
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeMemoryMappedIo,
+ mSmmStoreInfo->MmioAddress,
+ mSmmStoreInfo->NumBlocks * mSmmStoreInfo->BlockSize,
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Mark as runtime service
+ //
+ Status = gDS->SetMemorySpaceAttributes (
+ mSmmStoreInfo->MmioAddress,
+ mSmmStoreInfo->NumBlocks * mSmmStoreInfo->BlockSize,
+ EFI_MEMORY_RUNTIME
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Deinitializes SmmStore support by freeing allocated memory.
+
+**/
+VOID
+EFIAPI
+SmmStoreLibDeinitialize (
+ VOID
+ )
+{
+ if (mArgComBuf != NULL) {
+ gBS->FreePages (mArgComBufPhys, EFI_SIZE_TO_PAGES (sizeof (SMM_STORE_COM_BUF)));
+ mArgComBuf = NULL;
+ }
+
+ if (mSmmStoreInfo != NULL) {
+ FreePool (mSmmStoreInfo);
+ mSmmStoreInfo = NULL;
+ }
+}
diff --git a/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.h b/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.h new file mode 100644 index 0000000..d91b8e1 --- /dev/null +++ b/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.h @@ -0,0 +1,82 @@ +/** @file SmmStore.h
+
+ Copyright (c) 2022, 9elements GmbH<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef COREBOOT_SMMSTORE_H_
+#define COREBOOT_SMMSTORE_H_
+
+#define SMMSTORE_RET_SUCCESS 0
+#define SMMSTORE_RET_FAILURE 1
+#define SMMSTORE_RET_UNSUPPORTED 2
+
+/* Version 2 only */
+#define SMMSTORE_CMD_INIT 4
+#define SMMSTORE_CMD_RAW_READ 5
+#define SMMSTORE_CMD_RAW_WRITE 6
+#define SMMSTORE_CMD_RAW_CLEAR 7
+
+/*
+ * This allows the payload to store raw data in the flash regions.
+ * This can be used by a FaultTolerantWrite implementation, that uses at least
+ * two regions in an A/B update scheme.
+ */
+
+#pragma pack(1)
+
+/*
+ * Reads a chunk of raw data with size BufSize from the block specified by
+ * block_id starting at BufOffset.
+ * The read data is placed in buf.
+ *
+ * block_id must be less than num_blocks
+ * BufOffset + BufSize must be less than block_size
+ */
+typedef struct {
+ UINT32 BufSize;
+ UINT32 BufOffset;
+ UINT32 BlockId;
+} SMM_STORE_PARAMS_WRITE;
+
+/*
+ * Writes a chunk of raw data with size BufSize to the block specified by
+ * block_id starting at BufOffset.
+ *
+ * block_id must be less than num_blocks
+ * BufOffset + BufSize must be less than block_size
+ */
+typedef struct {
+ UINT32 BufSize;
+ UINT32 BufOffset;
+ UINT32 BlockId;
+} SMM_STORE_PARAMS_READ;
+
+/*
+ * Erases the specified block.
+ *
+ * block_id must be less than num_blocks
+ */
+typedef struct {
+ UINT32 BlockId;
+} SMM_STORE_PARAMS_CLEAR;
+
+typedef union {
+ SMM_STORE_PARAMS_WRITE Write;
+ SMM_STORE_PARAMS_READ Read;
+ SMM_STORE_PARAMS_CLEAR Clear;
+} SMM_STORE_COM_BUF;
+
+#pragma pack(0)
+
+UINTN
+EFIAPI
+TriggerSmi (
+ IN UINTN Cmd,
+ IN UINTN Arg,
+ IN UINTN Retry
+ );
+
+#endif // COREBOOT_SMMSTORE_H_
diff --git a/UefiPayloadPkg/Library/SmmStoreLib/SmmStoreLib.inf b/UefiPayloadPkg/Library/SmmStoreLib/SmmStoreLib.inf new file mode 100644 index 0000000..8111100 --- /dev/null +++ b/UefiPayloadPkg/Library/SmmStoreLib/SmmStoreLib.inf @@ -0,0 +1,40 @@ +## @file
+# SmmStore library for coreboot
+#
+# Copyright (c) 2022 9elements GmbH.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmStoreLib
+ FILE_GUID = 40A2CBC6-CFB8-447b-A90E-298E88FD345E
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SmmStoreLib
+
+[Sources]
+ SmmStore.c
+ SmmStore.h
+
+[Sources.X64]
+ X64/SmmStore.nasm
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ DxeServicesTableLib
+ HobLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+
+[Guids]
+ gEfiSmmStoreInfoHobGuid ## CONSUMES
+ gEfiEventVirtualAddressChangeGuid ## CONSUMES
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiPayloadPkg/UefiPayloadPkg.dec
diff --git a/UefiPayloadPkg/Library/SmmStoreLib/X64/SmmStore.nasm b/UefiPayloadPkg/Library/SmmStoreLib/X64/SmmStore.nasm new file mode 100644 index 0000000..ee20c1f --- /dev/null +++ b/UefiPayloadPkg/Library/SmmStoreLib/X64/SmmStore.nasm @@ -0,0 +1,48 @@ +;------------------------------------------------------------------------------ ;
+; Copyright (c) 2022, 9elements GmbH. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;-------------------------------------------------------------------------------
+
+%include "Nasm.inc"
+
+DEFAULT REL
+SECTION .text
+
+;UINTN
+;EFIAPI
+;TriggerSmi (
+; UINTN Cmd,
+; UINTN Arg,
+; UINTN Retry
+; )
+
+global ASM_PFX(TriggerSmi)
+ASM_PFX(TriggerSmi):
+ push rbx
+ mov rax, rcx ; Smi handler expect Cmd in RAX
+ mov rbx, rdx ; Smi handler expect Argument in RBX
+@Trigger:
+ out 0b2h, al ; write to APM port to trigger SMI
+
+; There might be a delay between writing the Smi trigger register and
+; entering SMM, in which case the Smi handler will do nothing as only
+; synchronous Smis are handled. In addition when there's no Smi handler
+; or the SmmStore feature isn't compiled in, no register will be modified.
+
+; As there's no livesign from SMM, just wait a bit for the handler to fire,
+; and then try again.
+
+ cmp rax, rcx ; Check if rax was modified by SMM
+ jne @Return ; SMM modified rax, return now
+ push rcx ; save rcx to stack
+ mov rcx, 10000
+ rep pause ; add a small delay
+ pop rcx ; restore rcx
+ cmp r8, 0
+ je @Return
+ dec r8
+ jmp @Trigger
+@Return:
+ pop rbx
+ ret
diff --git a/UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntime.c b/UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntime.c new file mode 100644 index 0000000..d5406f0 --- /dev/null +++ b/UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntime.c @@ -0,0 +1,289 @@ +/** @file SmmStoreFvbRuntime.c
+
+ Copyright (c) 2022, 9elements GmbH<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/SmmStoreLib.h>
+
+#include "SmmStoreFvbRuntime.h"
+
+STATIC EFI_EVENT mSmmStoreVirtualAddrChangeEvent;
+
+//
+// Global variable declarations
+//
+SMMSTORE_INSTANCE *mSmmStoreInstance;
+
+SMMSTORE_INSTANCE mSmmStoreInstanceTemplate = {
+ SMMSTORE_SIGNATURE, // Signature
+ NULL, // Handle ... NEED TO BE FILLED
+ {
+ FvbGetAttributes, // GetAttributes
+ FvbSetAttributes, // SetAttributes
+ FvbGetPhysicalAddress, // GetPhysicalAddress
+ FvbGetBlockSize, // GetBlockSize
+ FvbRead, // Read
+ FvbWrite, // Write
+ FvbEraseBlocks, // EraseBlocks
+ NULL, // ParentHandle
+ }, // FvbProtoccol
+ 0, // BlockSize ... NEED TO BE FILLED
+ 0, // LastBlock ... NEED TO BE FILLED
+ 0, // MmioAddress ... NEED TO BE FILLED
+ {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_MEMMAP_DP,
+ {
+ (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
+ (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8)
+ }
+ },
+ EfiMemoryMappedIO,
+ (EFI_PHYSICAL_ADDRESS)0, // NEED TO BE FILLED
+ (EFI_PHYSICAL_ADDRESS)0, // NEED TO BE FILLED
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+ } // DevicePath
+};
+
+/**
+ Initialize the SmmStore instance.
+
+
+ @param[in] FvBase The physical MMIO base address of the FV containing
+ the variable store.
+
+ @param[in] NumberofBlocks Number of blocks within the FV.
+ @param[in] BlockSize The size in bytes of one block within the FV.
+ @param[in, out] Instance The SmmStore instance to initialize.
+
+**/
+STATIC
+EFI_STATUS
+SmmStoreInitInstance (
+ IN EFI_PHYSICAL_ADDRESS FvBase,
+ IN UINTN NumberofBlocks,
+ IN UINTN BlockSize,
+ IN OUT SMMSTORE_INSTANCE *Instance
+ )
+{
+ EFI_STATUS Status;
+ FV_MEMMAP_DEVICE_PATH *FvDevicePath;
+
+ ASSERT (Instance != NULL);
+
+ Instance->BlockSize = BlockSize;
+ Instance->LastBlock = NumberofBlocks - 1;
+ Instance->MmioAddress = FvBase;
+
+ FvDevicePath = &Instance->DevicePath;
+ FvDevicePath->MemMapDevPath.StartingAddress = FvBase;
+ FvDevicePath->MemMapDevPath.EndingAddress = FvBase + BlockSize * NumberofBlocks - 1;
+
+ Status = FvbInitialize (Instance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Instance->Handle,
+ &gEfiDevicePathProtocolGuid,
+ &Instance->DevicePath,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ &Instance->FvbProtocol,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((DEBUG_INFO, "%a: Created a new instance\n", __func__));
+
+ return Status;
+}
+
+/**
+ Fixup internal data so that EFI can be call in virtual mode.
+ Call the passed in Child Notify event and convert any pointers in
+ lib to virtual mode.
+
+ @param[in] Event The Event that is being processed
+ @param[in] Context Event Context
+**/
+STATIC
+VOID
+EFIAPI
+SmmStoreVirtualNotifyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ SmmStoreLibVirtualAddressChange (EfiConvertPointer);
+
+ // Convert Fvb
+ EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->FvbProtocol.EraseBlocks);
+ EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->FvbProtocol.GetAttributes);
+ EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->FvbProtocol.GetBlockSize);
+ EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->FvbProtocol.GetPhysicalAddress);
+ EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->FvbProtocol.Read);
+ EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->FvbProtocol.SetAttributes);
+ EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->FvbProtocol.Write);
+ EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->MmioAddress);
+ EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance);
+
+ return;
+}
+
+/**
+ The user Entry Point for module SmmStoreFvbRuntimeDxe. The user code starts with this function.
+
+ @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 entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+SmmStoreInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS MmioAddress;
+ UINTN BlockSize;
+ UINTN BlockCount;
+ UINT32 NvStorageBase;
+ UINT32 NvStorageSize;
+ UINT32 NvVariableSize;
+ UINT32 FtwWorkingSize;
+ UINT32 FtwSpareSize;
+
+ Status = SmmStoreLibInitialize ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to initialize SmmStoreLib\n", __func__));
+ return Status;
+ }
+
+ Status = SmmStoreLibGetMmioAddress (&MmioAddress);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to get SmmStore MMIO address\n", __func__));
+ SmmStoreLibDeinitialize ();
+ return Status;
+ }
+
+ Status = SmmStoreLibGetNumBlocks (&BlockCount);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to get SmmStore No. blocks\n", __func__));
+ SmmStoreLibDeinitialize ();
+ return Status;
+ }
+
+ Status = SmmStoreLibGetBlockSize (&BlockSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to get SmmStore block size\n", __func__));
+ SmmStoreLibDeinitialize ();
+ return Status;
+ }
+
+ //
+ // The layout (starts at MmioAddress):
+ //
+ // -------------------------- ------------- ------------------------------
+ // | | | |
+ // | Variable | Working | Spare Range |
+ // | Range | Range | (larger than variable range) |
+ // | | | |
+ // <- (BlockCount / 2) - 1 -> <- 1 block -> <----- (BlockCount / 2) ----->
+ // blocks blocks
+ //
+
+ NvStorageSize = BlockCount * BlockSize;
+ NvStorageBase = MmioAddress;
+
+ FtwSpareSize = (BlockCount / 2) * BlockSize;
+ FtwWorkingSize = 1 * BlockSize;
+ NvVariableSize = NvStorageSize - FtwSpareSize - FtwWorkingSize;
+ DEBUG ((DEBUG_INFO, "NvStorageBase:0x%x, NvStorageSize:0x%x\n", NvStorageBase, NvStorageSize));
+
+ Status = PcdSet32S (PcdFlashNvStorageVariableSize, NvVariableSize);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet32S (PcdFlashNvStorageVariableBase, NvStorageBase);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet64S (PcdFlashNvStorageVariableBase64, NvStorageBase);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PcdSet32S (PcdFlashNvStorageFtwWorkingSize, FtwWorkingSize);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet32S (PcdFlashNvStorageFtwWorkingBase, NvStorageBase + NvVariableSize);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet64S (PcdFlashNvStorageFtwWorkingBase64, NvStorageBase + NvVariableSize);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PcdSet32S (PcdFlashNvStorageFtwSpareSize, FtwSpareSize);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet32S (PcdFlashNvStorageFtwSpareBase, NvStorageBase + NvVariableSize + FtwWorkingSize);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet64S (PcdFlashNvStorageFtwSpareBase64, NvStorageBase + NvVariableSize + FtwWorkingSize);
+ ASSERT_EFI_ERROR (Status);
+
+ mSmmStoreInstance = AllocateRuntimeCopyPool (sizeof (SMMSTORE_INSTANCE), &mSmmStoreInstanceTemplate);
+ if (mSmmStoreInstance == NULL) {
+ SmmStoreLibDeinitialize ();
+ DEBUG ((DEBUG_ERROR, "%a: Out of resources\n", __func__));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = SmmStoreInitInstance (
+ MmioAddress,
+ BlockCount,
+ BlockSize,
+ mSmmStoreInstance
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Fail to create instance for SmmStore\n",
+ __func__
+ ));
+ FreePool (mSmmStoreInstance);
+ SmmStoreLibDeinitialize ();
+ return Status;
+ }
+
+ //
+ // Register for the virtual address change event
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ SmmStoreVirtualNotifyEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &mSmmStoreVirtualAddrChangeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntime.h b/UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntime.h new file mode 100644 index 0000000..8015d12 --- /dev/null +++ b/UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntime.h @@ -0,0 +1,111 @@ +/** @file SmmStoreFvbRuntime.h
+
+ Copyright (c) 2022, 9elements GmbH<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef SMM_STORE_DXE_H_
+#define SMM_STORE_DXE_H_
+
+#include <Base.h>
+#include <PiDxe.h>
+
+#include <Guid/EventGroup.h>
+
+#include <Protocol/FirmwareVolumeBlock.h>
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeLib.h>
+
+#define SMMSTORE_SIGNATURE SIGNATURE_32('S', 'M', 'M', 'S')
+#define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE)
+
+typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE;
+
+typedef struct {
+ MEMMAP_DEVICE_PATH MemMapDevPath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevPath;
+} FV_MEMMAP_DEVICE_PATH;
+
+struct _SMMSTORE_INSTANCE {
+ UINT32 Signature;
+ EFI_HANDLE Handle;
+ EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;
+ UINTN BlockSize;
+ UINTN LastBlock;
+ EFI_PHYSICAL_ADDRESS MmioAddress;
+ FV_MEMMAP_DEVICE_PATH DevicePath;
+};
+
+//
+// SmmStoreFvbRuntimeDxe.c
+//
+
+EFI_STATUS
+EFIAPI
+FvbInitialize (
+ IN SMMSTORE_INSTANCE *Instance
+ );
+
+EFI_STATUS
+EFIAPI
+FvbGetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+FvbSetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+FvbGetPhysicalAddress (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ );
+
+EFI_STATUS
+EFIAPI
+FvbGetBlockSize (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ OUT UINTN *BlockSize,
+ OUT UINTN *NumberOfBlocks
+ );
+
+EFI_STATUS
+EFIAPI
+FvbRead (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN OUT UINT8 *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+FvbWrite (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+FvbEraseBlocks (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ ...
+ );
+
+#endif // SMM_STORE_DXE_H_
diff --git a/UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntimeDxe.c b/UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntimeDxe.c new file mode 100644 index 0000000..63cb760 --- /dev/null +++ b/UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntimeDxe.c @@ -0,0 +1,844 @@ +/** @file SmmStoreFvbRuntimeDxe.c
+
+ Copyright (c) 2022, 9elements GmbH<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/PcdLib.h>
+#include <Library/BaseLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/SmmStoreLib.h>
+
+#include <Guid/VariableFormat.h>
+#include <Guid/SystemNvDataGuid.h>
+#include <Guid/NvVarStoreFormatted.h>
+
+#include "SmmStoreFvbRuntime.h"
+
+///
+/// The Firmware Volume Block Protocol is the low-level interface
+/// to a firmware volume. File-level access to a firmware volume
+/// should not be done using the Firmware Volume Block Protocol.
+/// Normal access to a firmware volume must use the Firmware
+/// Volume Protocol. Typically, only the file system driver that
+/// produces the Firmware Volume Protocol will bind to the
+/// Firmware Volume Block Protocol.
+///
+
+/**
+ Initialises the FV Header and Variable Store Header
+ to support variable operations.
+
+ @param[in] Instance - Pointer to SmmStore instance
+
+**/
+EFI_STATUS
+InitializeFvAndVariableStoreHeaders (
+ IN SMMSTORE_INSTANCE *Instance
+ )
+{
+ EFI_STATUS Status;
+ VOID *Headers;
+ UINTN HeadersLength;
+ EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader;
+ VARIABLE_STORE_HEADER *VariableStoreHeader;
+ UINT32 NvStorageFtwSpareSize;
+ UINT32 NvStorageFtwWorkingSize;
+ UINT32 NvStorageVariableSize;
+ UINT64 NvStorageFtwSpareBase;
+ UINT64 NvStorageFtwWorkingBase;
+ UINT64 NvStorageVariableBase;
+
+ HeadersLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY) + sizeof (VARIABLE_STORE_HEADER);
+ Headers = AllocateZeroPool (HeadersLength);
+
+ NvStorageFtwWorkingSize = PcdGet32 (PcdFlashNvStorageFtwWorkingSize);
+ NvStorageFtwSpareSize = PcdGet32 (PcdFlashNvStorageFtwSpareSize);
+ NvStorageVariableSize = PcdGet32 (PcdFlashNvStorageVariableSize);
+
+ NvStorageFtwSpareBase = (PcdGet64 (PcdFlashNvStorageFtwSpareBase64) != 0) ?
+ PcdGet64 (PcdFlashNvStorageFtwSpareBase64) : PcdGet32 (PcdFlashNvStorageFtwSpareBase);
+ NvStorageFtwWorkingBase = (PcdGet64 (PcdFlashNvStorageFtwWorkingBase64) != 0) ?
+ PcdGet64 (PcdFlashNvStorageFtwWorkingBase64) : PcdGet32 (PcdFlashNvStorageFtwWorkingBase);
+ NvStorageVariableBase = (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0) ?
+ PcdGet64 (PcdFlashNvStorageVariableBase64) : PcdGet32 (PcdFlashNvStorageVariableBase);
+
+ // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous.
+ if ((NvStorageVariableBase + NvStorageVariableSize) != NvStorageFtwWorkingBase) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: NvStorageFtwWorkingBase is not contiguous with NvStorageVariableBase region\n",
+ __func__
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((NvStorageFtwWorkingBase + NvStorageFtwWorkingSize) != NvStorageFtwSpareBase) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: NvStorageFtwSpareBase is not contiguous with NvStorageFtwWorkingBase region\n",
+ __func__
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check if the size of the area is at least one block size
+ if ((NvStorageVariableSize <= 0) || (NvStorageVariableSize / Instance->BlockSize <= 0)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: NvStorageVariableSize is 0x%x, should be at least one block in size\n",
+ __func__,
+ NvStorageVariableSize
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((NvStorageFtwWorkingSize <= 0) || (NvStorageFtwWorkingSize / Instance->BlockSize <= 0)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: NvStorageFtwWorkingSize is 0x%x, should be at least one block in size\n",
+ __func__,
+ NvStorageFtwWorkingSize
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((NvStorageFtwSpareSize <= 0) || (NvStorageFtwSpareSize / Instance->BlockSize <= 0)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: NvStorageFtwSpareSize is 0x%x, should be at least one block in size\n",
+ __func__,
+ NvStorageFtwSpareSize
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // EFI_FIRMWARE_VOLUME_HEADER
+ //
+ FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER *)Headers;
+ CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid);
+ FirmwareVolumeHeader->FvLength =
+ PcdGet32 (PcdFlashNvStorageVariableSize) +
+ PcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+ PcdGet32 (PcdFlashNvStorageFtwSpareSize);
+ FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE;
+ FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2)(
+ EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled
+ EFI_FVB2_READ_STATUS | // Reads are currently enabled
+ EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
+ EFI_FVB2_MEMORY_MAPPED | // It is memory mapped
+ EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1')
+ EFI_FVB2_WRITE_STATUS | // Writes are currently enabled
+ EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled
+ );
+ FirmwareVolumeHeader->HeaderLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY);
+ FirmwareVolumeHeader->Revision = EFI_FVH_REVISION;
+ FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->LastBlock + 1;
+ FirmwareVolumeHeader->BlockMap[0].Length = Instance->BlockSize;
+ FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0;
+ FirmwareVolumeHeader->BlockMap[1].Length = 0;
+ FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16 *)FirmwareVolumeHeader, FirmwareVolumeHeader->HeaderLength);
+
+ //
+ // VARIABLE_STORE_HEADER
+ //
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength);
+ //
+ // Should be gEfiVariableGuid as SMM doesn't authenticate, but userspace does
+ // Caveat: SecureBoot requires gEfiAuthenticatedVariableGuid type of storage
+ //
+ CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid);
+ VariableStoreHeader->Size = PcdGet32 (PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength;
+ VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED;
+ VariableStoreHeader->State = VARIABLE_STORE_HEALTHY;
+
+ // Install the combined super-header in the NorFlash
+ Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers);
+
+ FreePool (Headers);
+ return Status;
+}
+
+/**
+ Check the integrity of firmware volume header.
+
+ @retval EFI_SUCCESS - The firmware volume is consistent
+ @retval EFI_NOT_FOUND - The firmware volume has been corrupted.
+
+**/
+EFI_STATUS
+ValidateFvHeader (
+ VOID
+ )
+{
+ UINT16 Checksum;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ VARIABLE_STORE_HEADER *VariableStoreHeader;
+ UINTN VariableStoreLength;
+ UINTN FvLength;
+ EFI_STATUS TempStatus;
+ UINTN BufferSize;
+ UINTN BufferSizeRequested;
+
+ BufferSizeRequested = sizeof (EFI_FIRMWARE_VOLUME_HEADER);
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)AllocatePool (BufferSizeRequested);
+ if (!FwVolHeader) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ BufferSize = BufferSizeRequested;
+ TempStatus = SmmStoreLibRead (0, 0, &BufferSize, (UINT8 *)FwVolHeader);
+ if (EFI_ERROR (TempStatus) || (BufferSizeRequested != BufferSize)) {
+ FreePool (FwVolHeader);
+ return EFI_DEVICE_ERROR;
+ }
+
+ FvLength = PcdGet32 (PcdFlashNvStorageVariableSize) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+ PcdGet32 (PcdFlashNvStorageFtwSpareSize);
+
+ //
+ // Verify the header revision, header signature, length
+ // Length of FvBlock cannot be 2**64-1
+ // HeaderLength cannot be an odd number
+ //
+ if ( (FwVolHeader->Revision != EFI_FVH_REVISION)
+ || (FwVolHeader->Signature != EFI_FVH_SIGNATURE)
+ || (FwVolHeader->FvLength != FvLength)
+ )
+ {
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: No Firmware Volume header present\n",
+ __func__
+ ));
+ FreePool (FwVolHeader);
+ return EFI_NOT_FOUND;
+ }
+
+ // Check the Firmware Volume Guid
+ if ( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE ) {
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: Firmware Volume Guid non-compatible\n",
+ __func__
+ ));
+ FreePool (FwVolHeader);
+ return EFI_NOT_FOUND;
+ }
+
+ BufferSizeRequested = FwVolHeader->HeaderLength;
+ FreePool (FwVolHeader);
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)AllocatePool (BufferSizeRequested);
+ if (!FwVolHeader) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ BufferSize = BufferSizeRequested;
+ TempStatus = SmmStoreLibRead (0, 0, &BufferSize, (UINT8 *)FwVolHeader);
+ if (EFI_ERROR (TempStatus) || (BufferSizeRequested != BufferSize)) {
+ FreePool (FwVolHeader);
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Verify the header checksum
+ Checksum = CalculateSum16 ((UINT16 *)FwVolHeader, FwVolHeader->HeaderLength);
+ if (Checksum != 0) {
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: FV checksum is invalid (Checksum:0x%X)\n",
+ __func__,
+ Checksum
+ ));
+ FreePool (FwVolHeader);
+ return EFI_NOT_FOUND;
+ }
+
+ BufferSizeRequested = sizeof (VARIABLE_STORE_HEADER);
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *)AllocatePool (BufferSizeRequested);
+ if (!VariableStoreHeader) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ BufferSize = BufferSizeRequested;
+ TempStatus = SmmStoreLibRead (0, FwVolHeader->HeaderLength, &BufferSize, (UINT8 *)VariableStoreHeader);
+ if (EFI_ERROR (TempStatus) || (BufferSizeRequested != BufferSize)) {
+ FreePool (VariableStoreHeader);
+ FreePool (FwVolHeader);
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Check the Variable Store Guid
+ if (!CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) &&
+ !CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid))
+ {
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: Variable Store Guid non-compatible\n",
+ __func__
+ ));
+ FreePool (FwVolHeader);
+ FreePool (VariableStoreHeader);
+ return EFI_NOT_FOUND;
+ }
+
+ VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength;
+ if (VariableStoreHeader->Size != VariableStoreLength) {
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: Variable Store Length does not match\n",
+ __func__
+ ));
+ FreePool (FwVolHeader);
+ FreePool (VariableStoreHeader);
+ return EFI_NOT_FOUND;
+ }
+
+ FreePool (FwVolHeader);
+ FreePool (VariableStoreHeader);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The GetAttributes() function retrieves the attributes and
+ current settings of the block.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes and
+ current settings are returned.
+ Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER.
+
+ @retval EFI_SUCCESS The firmware volume attributes were returned.
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbGetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+{
+ EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes;
+
+ FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2)(
+ EFI_FVB2_READ_STATUS | // Reads are currently enabled
+ EFI_FVB2_WRITE_STATUS | // Writes are enabled
+ EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
+ EFI_FVB2_MEMORY_MAPPED | // It is memory mapped
+ EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1')
+ );
+
+ *Attributes = FlashFvbAttributes;
+
+ DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The SetAttributes() function sets configurable firmware volume attributes
+ and returns the new settings of the firmware volume.
+
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2
+ that contains the desired firmware volume settings.
+ On successful return, it contains the new settings of
+ the firmware volume.
+ Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER.
+
+ @retval EFI_SUCCESS The firmware volume attributes were returned.
+
+ @retval EFI_INVALID_PARAMETER The attributes requested are in conflict with the capabilities
+ as declared in the firmware volume header.
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbSetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+{
+ DEBUG ((DEBUG_ERROR, "FvbSetAttributes(0x%X) is not supported\n", *Attributes));
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ The GetPhysicalAddress() function retrieves the base address of
+ a memory-mapped firmware volume. This function should be called
+ only for memory-mapped firmware volumes.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Address Pointer to a caller-allocated
+ EFI_PHYSICAL_ADDRESS that, on successful
+ return from GetPhysicalAddress(), contains the
+ base address of the firmware volume.
+
+ @retval EFI_SUCCESS The firmware volume base address was returned.
+
+ @retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped.
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbGetPhysicalAddress (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ )
+{
+ SMMSTORE_INSTANCE *Instance;
+
+ Instance = INSTANCE_FROM_FVB_THIS (This);
+
+ ASSERT (Address != NULL);
+ *Address = Instance->MmioAddress;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The GetBlockSize() function retrieves the size of the requested
+ block. It also returns the number of additional blocks with
+ the identical size. The GetBlockSize() function is used to
+ retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER).
+
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Lba Indicates the block for which to return the size.
+
+ @param BlockSize Pointer to a caller-allocated UINTN in which
+ the size of the block is returned.
+
+ @param NumberOfBlocks Pointer to a caller-allocated UINTN in
+ which the number of consecutive blocks,
+ starting with Lba, is returned. All
+ blocks in this range have a size of
+ BlockSize.
+
+
+ @retval EFI_SUCCESS The firmware volume base address was returned.
+
+ @retval EFI_INVALID_PARAMETER The requested LBA is out of range.
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbGetBlockSize (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ OUT UINTN *BlockSize,
+ OUT UINTN *NumberOfBlocks
+ )
+{
+ EFI_STATUS Status;
+ SMMSTORE_INSTANCE *Instance;
+
+ Instance = INSTANCE_FROM_FVB_THIS (This);
+
+ DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize(Lba=%ld, BlockSize=0x%x, LastBlock=%ld)\n", Lba, Instance->BlockSize, Instance->LastBlock));
+
+ if (Lba > Instance->LastBlock) {
+ DEBUG ((DEBUG_ERROR, "FvbGetBlockSize: ERROR - Parameter LBA %ld is beyond the last Lba (%ld).\n", Lba, Instance->LastBlock));
+ Status = EFI_INVALID_PARAMETER;
+ } else {
+ *BlockSize = (UINTN)Instance->BlockSize;
+ *NumberOfBlocks = (UINTN)(Instance->LastBlock - Lba + 1);
+
+ DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize: *BlockSize=0x%x, *NumberOfBlocks=0x%x.\n", *BlockSize, *NumberOfBlocks));
+
+ Status = EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+/**
+ Reads the specified number of bytes into a buffer from the specified block.
+
+ The Read() function reads the requested number of bytes from the
+ requested block and stores them in the provided buffer.
+ Implementations should be mindful that the firmware volume
+ might be in the ReadDisabled state. If it is in this state,
+ the Read() function must return the status code
+ EFI_ACCESS_DENIED without modifying the contents of the
+ buffer. The Read() function must also prevent spanning block
+ boundaries. If a read is requested that would span a block
+ boundary, the read must read up to the boundary but not
+ beyond. The output parameter NumBytes must be set to correctly
+ indicate the number of bytes actually read. The caller must be
+ aware that a read may be partially completed.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Lba The starting logical block index from which to read.
+
+ @param Offset Offset into the block at which to begin reading.
+
+ @param NumBytes Pointer to a UINTN.
+ At entry, *NumBytes contains the total size of the buffer.
+ At exit, *NumBytes contains the total number of bytes read.
+
+ @param Buffer Pointer to a caller-allocated buffer that will be used
+ to hold the data that is read.
+
+ @retval EFI_SUCCESS The firmware volume was read successfully, and contents are
+ in Buffer.
+
+ @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary.
+ On output, NumBytes contains the total number of bytes
+ returned in Buffer.
+
+ @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state.
+
+ @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read.
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbRead (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN OUT UINT8 *Buffer
+ )
+{
+ UINTN BlockSize;
+ SMMSTORE_INSTANCE *Instance;
+
+ Instance = INSTANCE_FROM_FVB_THIS (This);
+
+ DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer));
+
+ // Cache the block size to avoid de-referencing pointers all the time
+ BlockSize = Instance->BlockSize;
+
+ // The read must not span block boundaries.
+ // We need to check each variable individually because adding two large values together overflows.
+ if ((Offset >= BlockSize) ||
+ (*NumBytes > BlockSize) ||
+ ((Offset + *NumBytes) > BlockSize))
+ {
+ DEBUG ((DEBUG_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize));
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ // We must have some bytes to read
+ if (*NumBytes == 0) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ return SmmStoreLibRead (Lba, Offset, NumBytes, Buffer);
+}
+
+/**
+ Writes the specified number of bytes from the input buffer to the block.
+
+ The Write() function writes the specified number of bytes from
+ the provided buffer to the specified block and offset. If the
+ firmware volume is sticky write, the caller must ensure that
+ all the bits of the specified range to write are in the
+ EFI_FVB_ERASE_POLARITY state before calling the Write()
+ function, or else the result will be unpredictable. This
+ unpredictability arises because, for a sticky-write firmware
+ volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY
+ state but cannot flip it back again. Before calling the
+ Write() function, it is recommended for the caller to first call
+ the EraseBlocks() function to erase the specified block to
+ write. A block erase cycle will transition bits from the
+ (NOT)EFI_FVB_ERASE_POLARITY state back to the
+ EFI_FVB_ERASE_POLARITY state. Implementations should be
+ mindful that the firmware volume might be in the WriteDisabled
+ state. If it is in this state, the Write() function must
+ return the status code EFI_ACCESS_DENIED without modifying the
+ contents of the firmware volume. The Write() function must
+ also prevent spanning block boundaries. If a write is
+ requested that spans a block boundary, the write must store up
+ to the boundary but not beyond. The output parameter NumBytes
+ must be set to correctly indicate the number of bytes actually
+ written. The caller must be aware that a write may be
+ partially completed. All writes, partial or otherwise, must be
+ fully flushed to the hardware before the Write() service
+ returns.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Lba The starting logical block index to write to.
+
+ @param Offset Offset into the block at which to begin writing.
+
+ @param NumBytes The pointer to a UINTN.
+ At entry, *NumBytes contains the total size of the buffer.
+ At exit, *NumBytes contains the total number of bytes actually written.
+
+ @param Buffer The pointer to a caller-allocated buffer that contains the source for the write.
+
+ @retval EFI_SUCCESS The firmware volume was written successfully.
+
+ @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary.
+ On output, NumBytes contains the total number of bytes
+ actually written.
+
+ @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state.
+
+ @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written.
+
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbWrite (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ UINTN BlockSize;
+ SMMSTORE_INSTANCE *Instance;
+
+ Instance = INSTANCE_FROM_FVB_THIS (This);
+
+ DEBUG ((DEBUG_BLKIO, "FvbWrite(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer));
+
+ // Cache the block size to avoid de-referencing pointers all the time
+ BlockSize = Instance->BlockSize;
+
+ // The read must not span block boundaries.
+ // We need to check each variable individually because adding two large values together overflows.
+ if ((Offset >= BlockSize) ||
+ (*NumBytes > BlockSize) ||
+ ((Offset + *NumBytes) > BlockSize))
+ {
+ DEBUG ((DEBUG_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize));
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ // We must have some bytes to read
+ if (*NumBytes == 0) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ return SmmStoreLibWrite (Lba, Offset, NumBytes, Buffer);
+}
+
+/**
+ Erases and initialises a firmware volume block.
+
+ The EraseBlocks() function erases one or more blocks as denoted
+ by the variable argument list. The entire parameter list of
+ blocks must be verified before erasing any blocks. If a block is
+ requested that does not exist within the associated firmware
+ volume (it has a larger index than the last block of the
+ firmware volume), the EraseBlocks() function must return the
+ status code EFI_INVALID_PARAMETER without modifying the contents
+ of the firmware volume. Implementations should be mindful that
+ the firmware volume might be in the WriteDisabled state. If it
+ is in this state, the EraseBlocks() function must return the
+ status code EFI_ACCESS_DENIED without modifying the contents of
+ the firmware volume. All calls to EraseBlocks() must be fully
+ flushed to the hardware before the EraseBlocks() service
+ returns.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
+ instance.
+
+ @param ... The variable argument list is a list of tuples.
+ Each tuple describes a range of LBAs to erase
+ and consists of the following:
+ - An EFI_LBA that indicates the starting LBA
+ - A UINTN that indicates the number of blocks to erase.
+
+ The list is terminated with an EFI_LBA_LIST_TERMINATOR.
+ For example, the following indicates that two ranges of blocks
+ (5-7 and 10-11) are to be erased:
+ EraseBlocks (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR);
+
+ @retval EFI_SUCCESS The erase request successfully completed.
+
+ @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state.
+
+ @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be written.
+ The firmware device may have been partially erased.
+
+ @retval EFI_INVALID_PARAMETER One or more of the LBAs listed in the variable argument list do
+ not exist in the firmware volume.
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbEraseBlocks (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ ...
+ )
+{
+ EFI_STATUS Status;
+ VA_LIST Args;
+ EFI_LBA StartingLba; // Lba from which we start erasing
+ UINTN NumOfLba; // Number of Lba blocks to erase
+ SMMSTORE_INSTANCE *Instance;
+
+ Instance = INSTANCE_FROM_FVB_THIS (This);
+
+ Status = EFI_SUCCESS;
+
+ // Before erasing, check the entire list of parameters to ensure all specified blocks are valid
+
+ VA_START (Args, This);
+ do {
+ // Get the Lba from which we start erasing
+ StartingLba = VA_ARG (Args, EFI_LBA);
+
+ // Have we reached the end of the list?
+ if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
+ // Exit the while loop
+ break;
+ }
+
+ // How many Lba blocks are we requested to erase?
+ NumOfLba = VA_ARG (Args, UINTN);
+
+ // All blocks must be within range
+ DEBUG ((
+ DEBUG_BLKIO,
+ "FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%Lu - 1 ) > LastBlock=%ld.\n",
+ StartingLba,
+ (UINT64)NumOfLba,
+ Instance->LastBlock
+ ));
+ if ((NumOfLba == 0) || ((StartingLba + NumOfLba - 1) > Instance->LastBlock)) {
+ VA_END (Args);
+ DEBUG ((DEBUG_ERROR, "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n"));
+ Status = EFI_INVALID_PARAMETER;
+ goto EXIT;
+ }
+ } while (TRUE);
+
+ VA_END (Args);
+
+ //
+ // To get here, all must be ok, so start erasing
+ //
+ VA_START (Args, This);
+ do {
+ // Get the Lba from which we start erasing
+ StartingLba = VA_ARG (Args, EFI_LBA);
+
+ // Have we reached the end of the list?
+ if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
+ // Exit the while loop
+ break;
+ }
+
+ // How many Lba blocks are we requested to erase?
+ NumOfLba = VA_ARG (Args, UINTN);
+
+ // Go through each one and erase it
+ while (NumOfLba > 0) {
+ // Erase it
+ DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Erasing Lba=%ld\n", StartingLba));
+ Status = SmmStoreLibEraseBlock (StartingLba);
+ if (EFI_ERROR (Status)) {
+ VA_END (Args);
+ Status = EFI_DEVICE_ERROR;
+ goto EXIT;
+ }
+
+ // Move to the next Lba
+ StartingLba++;
+ NumOfLba--;
+ }
+ } while (TRUE);
+
+ VA_END (Args);
+
+EXIT:
+ return Status;
+}
+
+/**
+ Initialized the Firmware Volume if necessary and installs the
+ gEdkiiNvVarStoreFormattedGuid protocol.
+
+ @param Instance Pointer to SmmStore instance
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbInitialize (
+ IN SMMSTORE_INSTANCE *Instance
+ )
+{
+ EFI_STATUS Status;
+ UINT32 FvbNumLba;
+ EFI_BOOT_MODE BootMode;
+
+ ASSERT ((Instance != NULL));
+
+ BootMode = GetBootModeHob ();
+ if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
+ Status = EFI_INVALID_PARAMETER;
+ } else {
+ // Determine if there is a valid header at the beginning of the NorFlash
+ Status = ValidateFvHeader ();
+ }
+
+ // Install the Default FVB header if required
+ if (EFI_ERROR (Status)) {
+ // There is no valid header, so time to install one.
+ DEBUG ((DEBUG_INFO, "%a: The FVB Header is not valid.\n", __func__));
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: Installing a correct one for this volume.\n",
+ __func__
+ ));
+
+ // Erase all the NorFlash that is reserved for variable storage
+ FvbNumLba = (PcdGet32 (PcdFlashNvStorageVariableSize) +
+ PcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+ PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / Instance->BlockSize;
+
+ Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Install all appropriate headers
+ Status = InitializeFvAndVariableStoreHeaders (Instance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ } else {
+ DEBUG ((DEBUG_INFO, "%a: FVB header is valid\n", __func__));
+ }
+
+ //
+ // The driver implementing the variable read service can now be dispatched;
+ // the varstore headers are in place.
+ //
+ Status = gBS->InstallProtocolInterface (
+ &gImageHandle,
+ &gEdkiiNvVarStoreFormattedGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntimeDxe.inf b/UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntimeDxe.inf new file mode 100644 index 0000000..003f829 --- /dev/null +++ b/UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntimeDxe.inf @@ -0,0 +1,63 @@ +## @file
+# This is the component description file for SmmStore module.
+#
+# Copyright (c) 2022, 9elements GmbH.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmStoreFvbRuntimeDxe
+ FILE_GUID = A0402FCA-6B25-4CEA-B7DD-C08F99714B29
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SmmStoreInitialize
+
+[Sources.common]
+ SmmStoreFvbRuntimeDxe.c
+ SmmStoreFvbRuntime.h
+ SmmStoreFvbRuntime.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ UefiPayloadPkg/UefiPayloadPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ HobLib
+ SmmStoreLib
+ UefiLib
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ UefiRuntimeLib
+ DxeServicesTableLib
+
+[Guids]
+ gEfiSystemNvDataFvGuid
+ gEfiVariableGuid ## PRODUCES ## PROTOCOL
+ gEfiAuthenticatedVariableGuid
+ gEfiEventVirtualAddressChangeGuid
+ gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL
+
+[Protocols]
+ gEfiDevicePathProtocolGuid ## BY_START
+ gEfiFirmwareVolumeBlockProtocolGuid ## BY_START
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
+
+[Depex]
+ TRUE
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c index 939873d..eb5f14e 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c @@ -168,6 +168,108 @@ FindToludCallback ( }
/**
+ Callback function to find free and usable DRAM for HOB
+ The memory region returned will have at least PcdSystemMemoryUefiRegionSize bytes
+ and will be aligned to 1 MiB.
+
+ The caller must initialize HobMemBase to zero.
+
+ @param MemoryMapEntry Memory map entry info got from bootloader.
+ @param Params Pointer to HobMemBase
+
+ @retval EFI_SUCCESS Continue walking the memory map
+ @retval EFI_ALREADY_STARTED HobMemBase is not zero
+
+**/
+EFI_STATUS
+FindFreeMemForHobCallback (
+ IN MEMORY_MAP_ENTRY *MemoryMapEntry,
+ IN VOID *Params
+ )
+{
+ EFI_STATUS Status;
+ MEMORY_MAP_ENTRY MemoryMapEntrySplit;
+ UINTN *HobMemBase = (UINTN *)Params;
+
+ //
+ // Found new base, nothing to do
+ //
+ if (*HobMemBase != 0) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ //
+ // Skip memory types not RAM
+ //
+ if (MemoryMapEntry->Type != E820_RAM) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Align on 1 MiB
+ //
+ if (ALIGN_VALUE (MemoryMapEntry->Base, SIZE_1MB) > MemoryMapEntry->Base) {
+ //
+ // Skip too small
+ //
+ if (ALIGN_VALUE (MemoryMapEntry->Base, SIZE_1MB) >= (MemoryMapEntry->Base + MemoryMapEntry->Size)) {
+ return EFI_SUCCESS;
+ }
+
+ MemoryMapEntry->Size -= ALIGN_VALUE (MemoryMapEntry->Base, SIZE_1MB) - MemoryMapEntry->Base;
+ MemoryMapEntry->Base = ALIGN_VALUE (MemoryMapEntry->Base, SIZE_1MB);
+ }
+
+ //
+ // Skip resources above 4GiB on x86_32
+ //
+ if ((sizeof (UINTN) == 4) && (MemoryMapEntry->Base >= 0x100000000ULL)) {
+ return EFI_SUCCESS;
+ }
+
+ if ((sizeof (UINTN) == 4) && ((MemoryMapEntry->Base + MemoryMapEntry->Size) > 0x100000000ULL)) {
+ MemoryMapEntry->Size = 0x100000000ULL - MemoryMapEntry->Base;
+ }
+
+ //
+ // Skip too small
+ //
+ if (MemoryMapEntry->Size < FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Overlaps UefiPayload, split into smaller chunks
+ //
+ if ((MemoryMapEntry->Base <= PcdGet32 (PcdPayloadFdMemBase)) &&
+ ((MemoryMapEntry->Base + MemoryMapEntry->Size) >= PcdGet32 (PcdPayloadFdMemBase)))
+ {
+ MemoryMapEntrySplit.Type = E820_RAM;
+ MemoryMapEntrySplit.Base = MemoryMapEntry->Base;
+ MemoryMapEntrySplit.Size = PcdGet32 (PcdPayloadFdMemBase) - MemoryMapEntrySplit.Base;
+ Status = FindFreeMemForHobCallback (&MemoryMapEntrySplit, Params);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if ((MemoryMapEntry->Base + MemoryMapEntry->Size) > (PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize))) {
+ MemoryMapEntrySplit.Base = PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize);
+ MemoryMapEntrySplit.Size = (MemoryMapEntry->Base + MemoryMapEntry->Size) - MemoryMapEntrySplit.Base;
+ Status = FindFreeMemForHobCallback (&MemoryMapEntrySplit, Params);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ *HobMemBase = MemoryMapEntry->Base;
+
+ return EFI_ALREADY_STARTED;
+}
+
+/**
Callback function to build resource descriptor HOB
This function build a HOB based on the memory map entry info.
@@ -236,6 +338,8 @@ BuildHobFromBl ( {
EFI_STATUS Status;
ACPI_BOARD_INFO *AcpiBoardInfo;
+ SMMSTORE_INFO SmmStoreInfo;
+ SMMSTORE_INFO *NewSmmStoreInfo;
EFI_PEI_GRAPHICS_INFO_HOB GfxInfo;
EFI_PEI_GRAPHICS_INFO_HOB *NewGfxInfo;
EFI_PEI_GRAPHICS_DEVICE_INFO_HOB GfxDeviceInfo;
@@ -283,6 +387,17 @@ BuildHobFromBl ( }
//
+ // Create guid hob for SmmStore
+ //
+ Status = ParseSmmStoreInfo (&SmmStoreInfo);
+ if (!EFI_ERROR (Status)) {
+ NewSmmStoreInfo = BuildGuidHob (&gEfiSmmStoreInfoHobGuid, sizeof (SmmStoreInfo));
+ ASSERT (NewSmmStoreInfo != NULL);
+ CopyMem (NewSmmStoreInfo, &SmmStoreInfo, sizeof (SmmStoreInfo));
+ DEBUG ((DEBUG_INFO, "Created SmmStore info hob\n"));
+ }
+
+ //
// Creat SmBios table Hob
//
SmBiosTableHob = BuildGuidHob (&gUniversalPayloadSmbiosTableGuid, sizeof (UNIVERSAL_PAYLOAD_SMBIOS_TABLE));
@@ -404,8 +519,19 @@ _ModuleEntryPoint ( // HOB region is used for HOB and memory allocation for this module
MemBase = PcdGet32 (PcdPayloadFdMemBase);
- HobMemBase = ALIGN_VALUE (MemBase + PcdGet32 (PcdPayloadFdMemSize), SIZE_1MB);
- HobMemTop = HobMemBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
+ HobMemBase = 0;
+
+ //
+ // Find a good place for HOB and memory allocation
+ //
+ ParseMemoryInfo (FindFreeMemForHobCallback, &HobMemBase);
+
+ ASSERT (HobMemBase != 0);
+ if (HobMemBase == 0) {
+ HobMemBase = ALIGN_VALUE (MemBase + PcdGet32 (PcdPayloadFdMemSize), SIZE_1MB);
+ }
+
+ HobMemTop = HobMemBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
HobConstructor ((VOID *)MemBase, (VOID *)HobMemTop, (VOID *)HobMemBase, (VOID *)HobMemTop);
@@ -435,6 +561,8 @@ _ModuleEntryPoint ( // The library constructors might depend on serial port, so call it after serial port hob
ProcessLibraryConstructorList ();
DEBUG ((DEBUG_INFO, "sizeof(UINTN) = 0x%x\n", sizeof (UINTN)));
+ DEBUG ((DEBUG_INFO, "MemBase = 0x%llx\n", (UINT64)MemBase));
+ DEBUG ((DEBUG_INFO, "HobMemBase = 0x%llx\n", (UINT64)HobMemBase));
// Build HOB based on information from Bootloader
Status = BuildHobFromBl ();
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h index 077e526..b6fe5ef 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h @@ -22,6 +22,7 @@ #include <Library/IoLib.h>
#include <Library/PeCoffLib.h>
#include <Library/BlParseLib.h>
+#include <Library/SmmStoreParseLib.h>
#include <Library/PlatformSupportLib.h>
#include <Library/CpuLib.h>
#include <IndustryStandard/Acpi.h>
@@ -37,6 +38,7 @@ #include <UniversalPayload/SerialPortInfo.h>
#include <UniversalPayload/DeviceTree.h>
#include <Guid/PcdDataBaseSignatureGuid.h>
+#include <Guid/SmmStoreInfoGuid.h>
#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
#define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf index 1ed319f..702be0d 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf @@ -71,6 +71,7 @@ gUniversalPayloadSmbiosTableGuid
gUniversalPayloadAcpiTableGuid
gUniversalPayloadSerialPortInfoGuid
+ gEfiSmmStoreInfoHobGuid
[FeaturePcd.IA32]
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayloadPkg.dec index a6ab2dd..491e542 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dec +++ b/UefiPayloadPkg/UefiPayloadPkg.dec @@ -45,6 +45,8 @@ gS3CommunicationGuid = { 0x88e31ba1, 0x1856, 0x4b8b, { 0xbb, 0xdf, 0xf8, 0x16, 0xdd, 0x94, 0xa, 0xef } }
gUplPciSegmentInfoHobGuid = {0x37e0e3a9, 0xb3fc, 0x4e85, { 0x97, 0x2b, 0x40, 0x82, 0xfc, 0x79, 0x40, 0x54 } }
+ gEfiSmmStoreInfoHobGuid = { 0xf585ca19, 0x881b, 0x44fb, { 0x3f, 0x3d, 0x81, 0x89, 0x7c, 0x57, 0xbb, 0x01 } }
+
[Ppis]
gEfiPayLoadHobBasePpiGuid = { 0xdbe23aa1, 0xa342, 0x4b97, {0x85, 0xb6, 0xb2, 0x26, 0xf1, 0x61, 0x73, 0x89} }
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 29edae6..11cf414 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -126,6 +126,7 @@ #
# EMU: UEFI payload with EMU variable
# SPI: UEFI payload with SPI NV variable support
+ # SMMSTORE: UEFI payload with coreboot SMM NV variable support
# NONE: UEFI payload with no variable modules
#
DEFINE VARIABLE_SUPPORT = EMU
@@ -343,6 +344,9 @@ !if $(VARIABLE_SUPPORT) == "EMU"
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+!elseif $(VARIABLE_SUPPORT) == "SMMSTORE"
+ SmmStoreLib|UefiPayloadPkg/Library/SmmStoreLib/SmmStoreLib.inf
+ TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
!elseif $(VARIABLE_SUPPORT) == "SPI"
PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
@@ -388,7 +392,7 @@ ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
- ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+ ArmSmcLib|MdePkg/Library/ArmSmcLib/ArmSmcLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
@@ -559,7 +563,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x10000
!if $(VARIABLE_SUPPORT) == "EMU"
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable |TRUE
-!else
+!elseif $(VARIABLE_SUPPORT) == "SPI" || $(VARIABLE_SUPPORT) == "SMMSTORE"
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable |FALSE
!endif
@@ -619,8 +623,6 @@ !endif
[PcdsFixedAtBuild.AARCH64]
- gArmTokenSpaceGuid.PcdVFPEnabled|1
-
# System Memory Base -- fixed at 0x4000_0000
gArmTokenSpaceGuid.PcdSystemMemoryBase|0x40000000
@@ -758,14 +760,18 @@ !endif
gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
-!if $(VARIABLE_SUPPORT) == "SPI"
+!if $(VARIABLE_SUPPORT) == "SPI" || $(VARIABLE_SUPPORT) == "SMMSTORE"
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize |0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize |0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase |0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|0
!endif
# Disable SMM S3 script
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable|FALSE
@@ -1086,6 +1092,14 @@ !if $(VARIABLE_SUPPORT) == "EMU"
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+!elseif $(VARIABLE_SUPPORT) == "SMMSTORE"
+ UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntimeDxe.inf
+ MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+ NULL|EmbeddedPkg/Library/NvVarStoreFormattedLib/NvVarStoreFormattedLib.inf
+ }
!elseif $(VARIABLE_SUPPORT) == "SPI"
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf {
<LibraryClasses>
@@ -1158,10 +1172,7 @@ OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
# SMBIOS Support
- MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf {
- <LibraryClasses>
- NULL|OvmfPkg/Library/SmbiosVersionLib/DetectSmbiosVersionLib.inf
- }
+ MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
# PCI support
UefiCpuPkg/CpuMmio2Dxe/CpuMmio2Dxe.inf {
diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 9549019..4264fa9 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -223,6 +223,10 @@ INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf !if $(VARIABLE_SUPPORT) == "EMU"
INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+!elseif $(VARIABLE_SUPPORT) == "SMMSTORE"
+ INF UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntimeDxe.inf
+ INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
!elseif $(VARIABLE_SUPPORT) == "SPI"
INF UefiPayloadPkg/FvbRuntimeDxe/FvbSmm.inf
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
|