[edk2][PATCH v1 1/1] StandaloneMmPkg: add support to populate StMM boot data from device tree


Sayanta Pattanayak
 

Introduce support to populate StMM boot data via DTS parsing. The DTB is
passed as a boot argument by a binary of higer exception level.
Previously it was achieved by placing the boot data structure in a
shared buffer and the address of this shared buffer was passed by the
binary of higher exception level. Now either of the option can be used
for populating StMM boot info.

StMM boot information structure binding in device tree can be of followin=
g
prototype. Property values are not mentioned here.

bootarg {
compatible =3D "bootargs";
h_type =3D <..>;
h_version =3D <..>;
h_size =3D <..>;
h_attr =3D <..>;
sp_mem_base =3D <..>;
sp_mem_limit =3D <..>;
sp_image_base =3D <..>;
sp_stack_base =3D <..>;
sp_heap_base =3D <..>;
sp_ns_comm_buf_base =3D <..>;
sp_shared_buf_base =3D <..>;
sp_image_size =3D <..>;
sp_pcpu_stack_size =3D <..>;
sp_heap_size =3D <..>;
sp_ns_comm_buf_size =3D <..>;
sp_shared_buf_size =3D <..>;
num_sp_mem_regions =3D <..>;
num_cpus =3D <..>;
};

Addition of DTS supoort involves a dependency on FdtLib from EmbeddedPkg.

Signed-off-by: Sayanta Pattanayak <sayanta.pattanayak@arm.com>
---
Link to github branch with this patch -
https://github.com/SayantaP-arm/edk2/tree/stmm-dts

StandaloneMmPkg/StandaloneMmPkg.dsc =
| 1 +
StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntry=
Point.inf | 3 +
StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmC=
oreEntryPoint.c | 153 ++++++++++++++++++--
3 files changed, 143 insertions(+), 14 deletions(-)

diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/Standa=
loneMmPkg.dsc
index 0c45df95e2dd..e3a3a6ee3ba1 100644
--- a/StandaloneMmPkg/StandaloneMmPkg.dsc
+++ b/StandaloneMmPkg/StandaloneMmPkg.dsc
@@ -49,6 +49,7 @@
HobLib|StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.i=
nf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
MemLib|StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.i=
nf
+ FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllo=
cationLib/StandaloneMmCoreMemoryAllocationLib.inf
MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/Standal=
oneMmServicesTableLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/Standalon=
eMmCoreEntryPoint.inf b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoin=
t/StandaloneMmCoreEntryPoint.inf
index 4fa426f58ef4..0a2e519dd664 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCore=
EntryPoint.inf
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCore=
EntryPoint.inf
@@ -30,6 +30,7 @@
X64/StandaloneMmCoreEntryPoint.c
=20
[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
StandaloneMmPkg/StandaloneMmPkg.dec
@@ -40,10 +41,12 @@
[LibraryClasses]
BaseLib
DebugLib
+ FdtLib
=20
[LibraryClasses.AARCH64]
StandaloneMmMmuLib
ArmSvcLib
+ FdtLib
=20
[Guids]
gMpInformationHobGuid
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/S=
tandaloneMmCoreEntryPoint.c b/StandaloneMmPkg/Library/StandaloneMmCoreEnt=
ryPoint/AArch64/StandaloneMmCoreEntryPoint.c
index 6c50f470aa35..cc09d75dac36 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/Standalo=
neMmCoreEntryPoint.c
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/Standalo=
neMmCoreEntryPoint.c
@@ -16,6 +16,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Guid/MmramMemoryReserve.h>
#include <Guid/MpInformation.h>
=20
+#include <libfdt.h>
#include <Library/ArmMmuLib.h>
#include <Library/ArmSvcLib.h>
#include <Library/DebugLib.h>
@@ -45,33 +46,31 @@ STATIC CONST UINT32 mSpmMinorVerFfa =3D SPM_MINOR_VER=
SION_FFA;
PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint =3D NULL;
=20
/**
- Retrieve a pointer to and print the boot information passed by privile=
ged
- secure firmware.
+ Prints boot information.
=20
- @param [in] SharedBufAddress The pointer memory shared with privile=
ged
- firmware.
+ This function prints the boot information, which is passed by privileg=
ed
+ secure firmware through shared buffer or other mechanism.
=20
+ @param [in] PayloadBootInfo Pointer to StandaloneMM Boot Info struc=
ture.
**/
-EFI_SECURE_PARTITION_BOOT_INFO *
-GetAndPrintBootinformation (
- IN VOID *SharedBufAddress
+VOID
+PrintBootinformation (
+ IN EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo
)
{
- EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo;
EFI_SECURE_PARTITION_CPU_INFO *PayloadCpuInfo;
UINTN Index;
=20
- PayloadBootInfo =3D (EFI_SECURE_PARTITION_BOOT_INFO *) SharedBufAddres=
s;
=20
if (PayloadBootInfo =3D=3D NULL) {
DEBUG ((DEBUG_ERROR, "PayloadBootInfo NULL\n"));
- return NULL;
+ return;
}
=20
if (PayloadBootInfo->Header.Version !=3D BOOT_PAYLOAD_VERSION) {
DEBUG ((DEBUG_ERROR, "Boot Information Version Mismatch. Current=3D0=
x%x, Expected=3D0x%x.\n",
PayloadBootInfo->Header.Version, BOOT_PAYLOAD_VERSION));
- return NULL;
+ return;
}
=20
DEBUG ((DEBUG_INFO, "NumSpMemRegions - 0x%x\n", PayloadBootInfo->NumSp=
MemRegions));
@@ -96,7 +95,7 @@ GetAndPrintBootinformation (
=20
if (PayloadCpuInfo =3D=3D NULL) {
DEBUG ((DEBUG_ERROR, "PayloadCpuInfo NULL\n"));
- return NULL;
+ return;
}
=20
for (Index =3D 0; Index < PayloadBootInfo->NumCpus; Index++) {
@@ -105,7 +104,7 @@ GetAndPrintBootinformation (
DEBUG ((DEBUG_INFO, "Flags - 0x%x\n", PayloadCpuInfo[Index=
].Flags));
}
=20
- return PayloadBootInfo;
+ return;
}
=20
/**
@@ -194,6 +193,119 @@ DelegatedEventLoop (
}
}
=20
+/**
+ Populates StandAloneMM boot information structure.
+
+ This function receives dtb Address, where StMM Boot information specif=
ic
+ properties will be looked out to form the booting structure of type
+ EFI_SECURE_PARTITION_BOOT_INFO. At first, the properties for StandAlon=
eMM
+ ConfigSize and Memory limit will be checked out. Boot information wil=
l
+ be stored at address (Memory Limit - ConfigSize). Thereafter all boot
+ information specific properties will be parsed and corresponding value=
s
+ will be obtained.
+
+ @param [out] BootInfo Pointer, where Boot Info structure will be po=
pulated.
+ @param [in] DtbAddress Address of the Device tree from where Boot
+ information will be fetched.
+**/
+VOID
+PopulateBootinformation (
+ OUT EFI_SECURE_PARTITION_BOOT_INFO **BootInfo,
+ IN VOID *DtbAddress
+)
+{
+ INT32 Offset;
+ CONST UINT32 *Property;
+ CONST UINT64 *Property64;
+ UINT32 ConfigSize;
+ UINT64 SpMemLimit;
+ EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo;
+
+ Offset =3D fdt_node_offset_by_compatible (DtbAddress, -1, "config-size=
");
+ if (Offset < 0) {
+ DEBUG ((DEBUG_WARN, "Total Config Size is not defined\n"));
+ } else {
+ Property =3D fdt_getprop (DtbAddress, Offset, "size", NULL);
+ if (Property) {
+ ConfigSize =3D fdt32_to_cpu (*Property);
+ DEBUG ((DEBUG_INFO, "stmm dtb config-size =3D 0x%x \n", ConfigSiz=
e));
+ }
+ }
+
+ Offset =3D fdt_node_offset_by_compatible (DtbAddress, -1, "bootargs");
+ if (Offset >=3D 0) {
+ Property64 =3D fdt_getprop (DtbAddress, Offset, "sp_mem_limit", NUL=
L);
+ SpMemLimit =3D fdt64_to_cpu (*Property64);
+ }
+
+ if (SpMemLimit && ConfigSize)
+ PayloadBootInfo =3D
+ (EFI_SECURE_PARTITION_BOOT_INFO *)(SpMemLimit - ConfigSize);
+
+ if (PayloadBootInfo) {
+ PayloadBootInfo->SpMemLimit =3D SpMemLimit;
+
+ Property =3D fdt_getprop (DtbAddress, Offset, "h_type", NULL);
+ PayloadBootInfo->Header.Type =3D (UINT8) fdt32_to_cpu(*Property);
+
+ Property =3D fdt_getprop (DtbAddress, Offset, "h_version", NULL);
+ PayloadBootInfo->Header.Version =3D (UINT8) fdt32_to_cpu(*Property);
+
+ Property =3D fdt_getprop (DtbAddress, Offset, "h_size", NULL);
+ PayloadBootInfo->Header.Size =3D (UINT8) fdt32_to_cpu(*Property);
+
+ Property =3D fdt_getprop (DtbAddress, Offset, "h_attr", NULL);
+ PayloadBootInfo->Header.Attr =3D fdt32_to_cpu(*Property);
+
+ Property64 =3D fdt_getprop (DtbAddress, Offset, "sp_mem_base", NULL=
);
+ PayloadBootInfo->SpMemBase =3D fdt64_to_cpu(*Property64);
+
+ Property64 =3D fdt_getprop (DtbAddress, Offset, "sp_image_base", NU=
LL);
+ PayloadBootInfo->SpImageBase =3D fdt64_to_cpu(*Property64);
+
+ Property64 =3D fdt_getprop (DtbAddress, Offset, "sp_stack_base", NU=
LL);
+ PayloadBootInfo->SpStackBase =3D fdt64_to_cpu(*Property64);
+
+ Property64 =3D fdt_getprop (DtbAddress, Offset, "sp_heap_base", NUL=
L);
+ PayloadBootInfo->SpHeapBase =3D fdt64_to_cpu(*Property64);
+
+ Property64 =3D fdt_getprop (DtbAddress, Offset, "sp_ns_comm_buf_bas=
e", NULL);
+ PayloadBootInfo->SpNsCommBufBase =3D fdt64_to_cpu(*Property64);
+
+ Property64 =3D fdt_getprop (DtbAddress, Offset, "sp_shared_buf_base=
", NULL);
+ PayloadBootInfo->SpSharedBufBase =3D fdt64_to_cpu(*Property64);
+
+ Property64 =3D fdt_getprop (DtbAddress, Offset, "sp_image_size", NU=
LL);
+ PayloadBootInfo->SpImageSize =3D fdt64_to_cpu(*Property64);
+
+ Property64 =3D fdt_getprop (DtbAddress, Offset, "sp_pcpu_stack_size=
", NULL);
+ PayloadBootInfo->SpPcpuStackSize =3D fdt64_to_cpu(*Property64);
+
+ Property64 =3D fdt_getprop (DtbAddress, Offset, "sp_heap_size", NUL=
L);
+ PayloadBootInfo->SpHeapSize =3D fdt64_to_cpu(*Property64);
+
+ Property64 =3D fdt_getprop (DtbAddress, Offset, "sp_ns_comm_buf_siz=
e", NULL);
+ PayloadBootInfo->SpNsCommBufSize =3D fdt64_to_cpu(*Property64);
+
+ Property64 =3D fdt_getprop (DtbAddress, Offset, "sp_shared_buf_size=
", NULL);
+ PayloadBootInfo->SpPcpuSharedBufSize =3D fdt64_to_cpu(*Property64);
+
+ Property =3D fdt_getprop (DtbAddress, Offset, "num_sp_mem_regions",=
NULL);
+ PayloadBootInfo->NumSpMemRegions =3D fdt32_to_cpu(*Property);
+
+ Property =3D fdt_getprop (DtbAddress, Offset, "num_cpus", NULL);
+ PayloadBootInfo->NumCpus =3D fdt32_to_cpu(*Property);
+
+ PayloadBootInfo->CpuInfo =3D
+ (EFI_SECURE_PARTITION_CPU_INFO *)((UINT64)PayloadBootInfo +
+ sizeof(EFI_SECURE_PARTITION_BOOT=
_INFO));
+ }
+
+ *BootInfo =3D PayloadBootInfo;
+
+ return;
+}
+
/**
Query the SPM version, check compatibility and return success if compa=
tible.
=20
@@ -313,6 +425,7 @@ _ModuleEntryPoint (
VOID *TeData;
UINTN TeDataSize;
EFI_PHYSICAL_ADDRESS ImageBase;
+ VOID *DtbAddress;
=20
// Get Secure Partition Manager Version Information
Status =3D GetSpmVersion ();
@@ -320,12 +433,24 @@ _ModuleEntryPoint (
goto finish;
}
=20
- PayloadBootInfo =3D GetAndPrintBootinformation (SharedBufAddress);
+ // In cookie1 the DTB address is passed. With reference to DTB, Boot
+ // info structure can be populated.
+ // If cookie1 doesn't have any value, then Boot info is copied from
+ // Sharedbuffer.
+ if (cookie1) {
+ DtbAddress =3D (void *)cookie1;
+ PopulateBootinformation (&PayloadBootInfo, DtbAddress);
+ } else {
+ PayloadBootInfo =3D (EFI_SECURE_PARTITION_BOOT_INFO *)SharedBufAddre=
ss;
+ }
+
if (PayloadBootInfo =3D=3D NULL) {
Status =3D EFI_UNSUPPORTED;
goto finish;
}
=20
+ PrintBootinformation (PayloadBootInfo);
+
// Locate PE/COFF File information for the Standalone MM core module
Status =3D LocateStandaloneMmCorePeCoffData (
(EFI_FIRMWARE_VOLUME_HEADER *) PayloadBootInfo->SpImageBase=
,
--=20
2.17.1

Join devel@edk2.groups.io to automatically receive all group messages.