From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f45.google.com (mail-pj1-f45.google.com [209.85.216.45]) by mx.groups.io with SMTP id smtpd.web09.3560.1614753901408527419 for ; Tue, 02 Mar 2021 22:45:01 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@linaro.org header.s=google header.b=Q7ygLi4G; spf=pass (domain: linaro.org, ip: 209.85.216.45, mailfrom: masahisa.kojima@linaro.org) Received: by mail-pj1-f45.google.com with SMTP id i14so3535754pjz.4 for ; Tue, 02 Mar 2021 22:45:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6rHkmChqf2DJi7CIorT0zhcfCFoZzLh+vfs/yWhasR8=; b=Q7ygLi4GkSRNrzDpaGBBF136IWf1fK9EThPn6gAdx+2n47d6KZvKvx/C+aQLOsvvMS /GeLdeMRz/gbe+EE3k0fD6SUgbJv+er0pyJFR4FuJLBebZCsWQ4GDgRqdgqYPCGtddbl 1zytFS0MQrzUxrd4UA+xINlLC5LvuUlAJ4zG8fhtel4vFZBmoAuvVjDTWRQVtJ6iukTw 61Cgb7XaKElSW07W45nRoQD0jXiFNkqmj1zR3+r+oFxlMyeLkyaogLs8sjwgk2QyI+4j TyeIXpD92b3T7RYsvsHzpUkn2t6A8KlTMjFSC3jUwSkrDEUSPxoe3JOmylyUopyNNbc2 l2Tw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6rHkmChqf2DJi7CIorT0zhcfCFoZzLh+vfs/yWhasR8=; b=t7H/LoPHF7R2iwiDXSlJbDAIc2o4Cu0wmfrZ/nJIEzh91Nwt8Y5sohB6L5JRIwDIAK 8RcU2Q7qQkqZ2DD5nUoLZvkrsY++hCfJV5nWlG4TJnULurslXKYTU7v0xtKRDfMBV7Pf LfVGSzxOpdbkwSetdij6xCy71B4sulaAV/QsVcczRYStnZtsIJ7z6IRGLEda/SSyA7EN fr5dN/g8gogFiCYqx8hH8eNmhWrE4CtHdl4GTs2T0OFMurpd1/5RkPUL2KWJKxRqamzJ VBwFw9h7oBOsRq05Tik4voggoSqKKgFCt0cMkeUNRuYRmVTbjqjM0KZf+TF1DqVqreFs b8Tw== X-Gm-Message-State: AOAM533jH8Hi9ktfq6geBejS0OiFWpD1Wb3KtTQSuqHgDQRukzi15EZI sBqPjQSpTsr+v46XRI82sr8/rwGoOG5Xtw== X-Google-Smtp-Source: ABdhPJxxolm2CFhAmlJwXkSEVsOYDY4TUPesrGgKZK59hSySUnx6WtYv+9bLuhPvGkH3Rkvzw7wf0g== X-Received: by 2002:a17:90b:1213:: with SMTP id gl19mr8181497pjb.55.1614753900723; Tue, 02 Mar 2021 22:45:00 -0800 (PST) Return-Path: Received: from localhost.localdomain ([2400:2411:502:a100:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id ms21sm5809240pjb.5.2021.03.02.22.44.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Mar 2021 22:44:59 -0800 (PST) From: "Masahisa Kojima" To: devel@edk2.groups.io Cc: Masahisa Kojima , Ard Biesheuvel , Leif Lindholm , Graeme Gregory , Radoslaw Biernacki , Shashi Mallela Subject: [PATCH edk2-platforms v3 2/4] SbsaQemu: add MM based UEFI secure boot support Date: Wed, 3 Mar 2021 15:47:45 +0900 Message-Id: <20210303064747.27312-3-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210303064747.27312-1-masahisa.kojima@linaro.org> References: <20210303064747.27312-1-masahisa.kojima@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit This implements support for UEFI secure boot on SbsaQemu using the standalone MM framework. This moves all of the software handling of the UEFI authenticated variable store into the standalone MM context residing in a secure partition. Secure variable storage is located at 0x01000000 in secure NOR Flash. Non-secure shared memory between UEFI and standalone MM is allocated at the top of DRAM. DRAM size of SbsaQemu varies depends on the QEMU parameter, the non-secure shared memory base address is passed from trusted-firmware through the device tree "/reserved-memory" node. Together with "/reserved-memory" parsing implementation newly added in this commit, pre-existing "/memory" node parsing is moved to a helper function in FdtHelperLib. Signed-off-by: Masahisa Kojima --- Platform/Qemu/SbsaQemu/SbsaQemu.dsc | 25 ++++- Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc | 39 +++++++ Platform/Qemu/SbsaQemu/SbsaQemu.fdf | 81 ++++++++++++-- Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf | 7 +- Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf | 3 + Silicon/Qemu/SbsaQemu/Include/Library/FdtHelperLib.h | 27 +++++ Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.c | 111 ++++++++++++++++++++ Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c | 55 +++------- 8 files changed, 294 insertions(+), 54 deletions(-) diff --git a/Platform/Qemu/SbsaQemu/SbsaQemu.dsc b/Platform/Qemu/SbsaQemu/SbsaQemu.dsc index c1f8a4696560..8a239bd17138 100644 --- a/Platform/Qemu/SbsaQemu/SbsaQemu.dsc +++ b/Platform/Qemu/SbsaQemu/SbsaQemu.dsc @@ -28,6 +28,8 @@ [Defines] DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x8000004F + DEFINE SECURE_BOOT_ENABLE = FALSE + # # Network definition # @@ -152,12 +154,10 @@ [LibraryClasses.common] # Secure Boot dependencies # TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf - AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf # re-use the UserPhysicalPresent() dummy implementation from the ovmf tree PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf - VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf @@ -300,6 +300,8 @@ [PcdsFeatureFlag.common] gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache|FALSE + [PcdsFixedAtBuild.common] gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000 gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000 @@ -551,6 +553,9 @@ [PcdsDynamicDefault.common] gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdChassisAssetTag|L"AT0000" gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdChassisSKU|L"SK0000" + gArmTokenSpaceGuid.PcdMmBufferBase|0x10000000000 + gArmTokenSpaceGuid.PcdMmBufferSize|0x00200000 + ################################################################################ # # Components Section - list of all EDK II Modules needed by this Platform @@ -628,19 +633,31 @@ [Components.common] # ArmPkg/Drivers/CpuDxe/CpuDxe.inf MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf +!if $(SECURE_BOOT_ENABLE) == FALSE + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf + VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf # don't use unaligned CopyMem () on the UEFI varstore NOR flash region BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf } +!else + ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf { + + NULL|StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf + } + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf + SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf +!endif MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf { +!if $(SECURE_BOOT_ENABLE) == TRUE NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf +!endif } - SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf - MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf diff --git a/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc index 87f5ee351eaa..b80379acd1ad 100644 --- a/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc +++ b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc @@ -77,6 +77,18 @@ [LibraryClasses.common.MM_STANDALONE] HobLib|StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf + AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + NorFlashPlatformLib|Silicon/Qemu/SbsaQemu/Library/SbsaQemuNorFlashLib/SbsaQemuNorFlashLib.inf + OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf + RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf + PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf + TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf + VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf + ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf ################################################################################ # @@ -94,6 +106,20 @@ [PcdsFixedAtBuild] gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x2 + gArmTokenSpaceGuid.PcdFdBaseAddress|0x01000000 + gArmTokenSpaceGuid.PcdFdSize|0x000C0000 + + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000 + gEfiSecurityPkgTokenSpaceGuid.PcdUserPhysicalPresence|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800 + + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x01000000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x00040000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0x01040000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x00040000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0x01080000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x00040000 + ################################################################################################### # # Components Section - list of the modules and components that will be processed by compilation @@ -118,6 +144,19 @@ [Components.common] # StandaloneMmPkg/Core/StandaloneMmCore.inf StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf + ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf + + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf { + + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + NULL|MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.inf + # don't use unaligned CopyMem () on the UEFI varstore NOR flash region + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf + } ################################################################################################### # diff --git a/Platform/Qemu/SbsaQemu/SbsaQemu.fdf b/Platform/Qemu/SbsaQemu/SbsaQemu.fdf index b61ae1891233..36d09d34a374 100644 --- a/Platform/Qemu/SbsaQemu/SbsaQemu.fdf +++ b/Platform/Qemu/SbsaQemu/SbsaQemu.fdf @@ -21,10 +21,10 @@ [FD.SBSA_FLASH0] BaseAddress = 0x00000000 -Size = 0x00400000 +Size = 0x01100000 ErasePolarity = 1 BlockSize = 0x00001000 -NumBlocks = 0x400 +NumBlocks = 0x1100 ################################################################################ # @@ -50,6 +50,66 @@ [FD.SBSA_FLASH0] 0x00008000|0x00300000 FILE = Platform/Qemu/Sbsa/fip.bin +!if $(SECURE_BOOT_ENABLE) +## Place for Secure Variables. +# Must be aligned to Flash Block size 0x40000 +0x01000000|0x00040000 +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize +#NV_VARIABLE_STORE +DATA = { + ## This is the EFI_FIRMWARE_VOLUME_HEADER + # ZeroVector [] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + # FileSystemGuid: gEfiSystemNvDataFvGuid = + # { 0xFFF12B8D, 0x7696, 0x4C8B, + # { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }} + 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C, + 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50, + # FvLength: 0xC0000 + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, + # Signature "_FVH" # Attributes + 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00, + # HeaderLength # CheckSum # ExtHeaderOffset #Reserved #Revision + 0x48, 0x00, 0x28, 0x09, 0x00, 0x00, 0x00, 0x02, + # Blockmap[0]: 0x3 Blocks * 0x40000 Bytes / Block + 0x3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + # Blockmap[1]: End + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ## This is the VARIABLE_STORE_HEADER + # It is compatible with SECURE_BOOT_ENABLE == FALSE as well. + # Signature: gEfiAuthenticatedVariableGuid = + # { 0xaaf32c78, 0x947b, 0x439a, + # { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }} + 0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43, + 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92, + # Size: 0x40000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - + # 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x3ffb8 + # This can speed up the Variable Dispatch a bit. + 0xB8, 0xFF, 0x03, 0x00, + # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32 + 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +} + +0x01040000|0x00040000 +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize +#NV_FTW_WORKING +DATA = { + # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid = + # { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95 }} + 0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49, + 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95, + # Crc:UINT32 #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved + 0x5b, 0xe7, 0xc6, 0x86, 0xFE, 0xFF, 0xFF, 0xFF, + # WriteQueueSize: UINT64 + 0xE0, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 +} + +0x01080000|0x00040000 +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize +#NV_FTW_SPARE +!endif + ################################################################################ # # FD Section for FLASH1 @@ -169,15 +229,25 @@ [FV.FvMain] INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf - INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf - INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf - INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + # + # Variable services + # +!if $(SECURE_BOOT_ENABLE) == FALSE + INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf + INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf + INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +!else + INF ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf + INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf + INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf +!endif + # # Multiple Console IO support # @@ -189,7 +259,6 @@ [FV.FvMain] INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf - INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf # diff --git a/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf index a1acefcfb0a7..dbe1555c68f2 100644 --- a/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf +++ b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf @@ -19,8 +19,8 @@ ################################################################################ [FD.STANDALONE_MM] -BaseAddress = 0x20001000|gArmTokenSpaceGuid.PcdFdBaseAddress -Size = 0x00e00000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the device (14MiB). +BaseAddress = 0x20002000 +Size = 0x00e00000 ErasePolarity = 1 BlockSize = 0x00001000 @@ -49,6 +49,9 @@ [FV.FVMAIN_COMPACT] READ_LOCK_STATUS = TRUE INF StandaloneMmPkg/Core/StandaloneMmCore.inf + INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf + INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf + INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf INF StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf ################################################################################ diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf index c067a80cc715..3cd398bcb7e7 100644 --- a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf +++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf @@ -35,11 +35,14 @@ [LibraryClasses] FdtLib MemoryAllocationLib PcdLib + FdtHelperLib [Pcd] gArmTokenSpaceGuid.PcdSystemMemoryBase gArmTokenSpaceGuid.PcdSystemMemorySize gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdDeviceTreeBaseAddress + gArmTokenSpaceGuid.PcdMmBufferBase + gArmTokenSpaceGuid.PcdMmBufferSize [FixedPcd] gArmTokenSpaceGuid.PcdFdBaseAddress diff --git a/Silicon/Qemu/SbsaQemu/Include/Library/FdtHelperLib.h b/Silicon/Qemu/SbsaQemu/Include/Library/FdtHelperLib.h index ea9159857215..6b618847a0a6 100644 --- a/Silicon/Qemu/SbsaQemu/Include/Library/FdtHelperLib.h +++ b/Silicon/Qemu/SbsaQemu/Include/Library/FdtHelperLib.h @@ -33,4 +33,31 @@ FdtHelperCountCpus ( VOID ); +/** + Get memory information from device tree passed by Qemu. + + @param [out] NewBase A pointer to store the memory phisical address. + @param [out] NewSize A pointer to store the memory size. + +**/ +VOID +FdtHelperGetMemInfo ( + OUT UINT64 *NewBase, + OUT UINT64 *NewSize + ); + +/** + Get reserved memory information from device tree passed by Qemu. + + @param [out] NsBufBase A pointer to store the reserved memory + phisical address. + @param [out] NsBufSize A pointer to store the reserved memory size. + +**/ +VOID +FdtHelperGetReservedMemInfo ( + OUT UINT64 *NsBufBase, + OUT UINT32 *NsBufSize + ); + #endif /* FDT_HELPER_LIB_ */ diff --git a/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.c b/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.c index 7fdfb055db76..8308f71bdd34 100644 --- a/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.c +++ b/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.c @@ -96,3 +96,114 @@ FdtHelperCountCpus ( return CpuCount; } + +/** + Get memory information from device tree passed by Qemu. + + @param [out] NewBase A pointer to store the memory phisical address. + @param [out] NewSize A pointer to store the memory size. + +**/ +VOID +FdtHelperGetMemInfo ( + OUT UINT64 *NewBase, + OUT UINT64 *NewSize + ) +{ + VOID *DeviceTreeBase; + INT32 Node, Prev; + CONST CHAR8 *Type; + CONST UINT64 *RegProp; + INT32 Len; + UINT64 CurBase; + UINT64 CurSize; + + DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress); + ASSERT (DeviceTreeBase != NULL); + + // Make sure we have a valid device tree blob + ASSERT (fdt_check_header (DeviceTreeBase) == 0); + + // Look for the lowest memory node + for (Prev = 0;; Prev = Node) { + Node = fdt_next_node (DeviceTreeBase, Prev, NULL); + if (Node < 0) { + break; + } + + // Check for memory node + Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len); + if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) { + // Get the 'reg' property of this node. For now, we will assume + // two 8 byte quantities for base and size, respectively. + RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len); + if (RegProp != 0 && Len == (2 * sizeof (UINT64))) { + + CurBase = fdt64_to_cpu (ReadUnaligned64 (RegProp)); + CurSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1)); + + DEBUG ((DEBUG_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n", + __FUNCTION__, CurBase, CurBase + CurSize - 1)); + + if (*NewBase > CurBase || *NewBase == 0) { + *NewBase = CurBase; + *NewSize = CurSize; + } + } else { + DEBUG ((DEBUG_ERROR, "%a: Failed to parse FDT memory node\n", + __FUNCTION__)); + } + } + } +} + +/** + Get reserved memory information from device tree passed by Qemu. + + @param [out] NsBufBase A pointer to store the reserved memory + phisical address. + @param [out] NsBufSize A pointer to store the reserved memory size. + +**/ +VOID +FdtHelperGetReservedMemInfo ( + OUT UINT64 *NsBufBase, + OUT UINT32 *NsBufSize + ) +{ + VOID *DeviceTreeBase; + CONST UINT64 *RegProp; + INT32 ParentOffset; + INT32 Offset; + INT32 Len; + + DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress); + ASSERT (DeviceTreeBase != NULL); + + // Make sure we have a valid device tree blob + ASSERT (fdt_check_header (DeviceTreeBase) == 0); + + ParentOffset = fdt_path_offset(DeviceTreeBase, "/reserved-memory"); + if (ParentOffset < 0) { + DEBUG ((DEBUG_ERROR, "%a: reserved-memory node not found\n", + __FUNCTION__)); + } + Offset = fdt_subnode_offset(DeviceTreeBase, ParentOffset, "ns-buf-spm-mm"); + if (Offset < 0) { + DEBUG ((DEBUG_ERROR, "%a: ns-buf-spm-mm node not found\n", + __FUNCTION__)); + } + // Get the 'reg' property of this node. 8 byte quantities for base address + // and 4 byte quantities for size. + RegProp = fdt_getprop (DeviceTreeBase, Offset, "reg", &Len); + if (RegProp != 0 && Len == (sizeof (UINT64) + sizeof(UINT32))) { + *NsBufBase = fdt64_to_cpu (ReadUnaligned64 (RegProp)); + *NsBufSize = fdt32_to_cpu (ReadUnaligned32 ((UINT32 *)(RegProp + 1))); + + DEBUG ((DEBUG_INFO, "%a: ns buf @ 0x%lx - 0x%lx\n", + __FUNCTION__, *NsBufBase, *NsBufBase + *NsBufSize - 1)); + } else { + DEBUG ((DEBUG_ERROR, "%a: Failed to parse FDT reserved-memory node Len %d\n", + __FUNCTION__, Len)); + } +} diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c index 8c2eb0b6a028..d4c47c7fd4d6 100644 --- a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c +++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c @@ -13,6 +13,7 @@ #include #include #include +#include // Number of Virtual Memory Map Descriptors #define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 4 @@ -23,59 +24,29 @@ SbsaQemuLibConstructor ( VOID ) { - VOID *DeviceTreeBase; - INT32 Node, Prev; - UINT64 NewBase, CurBase; - UINT64 NewSize, CurSize; - CONST CHAR8 *Type; - INT32 Len; - CONST UINT64 *RegProp; + UINT64 NewBase, NsBufBase; + UINT64 NewSize; + UINT32 NsBufSize; RETURN_STATUS PcdStatus; NewBase = 0; NewSize = 0; + NsBufBase = 0; + NsBufSize = 0; - DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress); - ASSERT (DeviceTreeBase != NULL); + FdtHelperGetMemInfo (&NewBase, &NewSize); - // Make sure we have a valid device tree blob - ASSERT (fdt_check_header (DeviceTreeBase) == 0); + // StandaloneMM non-secure shared buffer is allocated at the top of + // the system memory by trusted-firmware using "/reserved-memory" node. + FdtHelperGetReservedMemInfo(&NsBufBase, &NsBufSize); - // Look for the lowest memory node - for (Prev = 0;; Prev = Node) { - Node = fdt_next_node (DeviceTreeBase, Prev, NULL); - if (Node < 0) { - break; - } - - // Check for memory node - Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len); - if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) { - // Get the 'reg' property of this node. For now, we will assume - // two 8 byte quantities for base and size, respectively. - RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len); - if (RegProp != 0 && Len == (2 * sizeof (UINT64))) { - - CurBase = fdt64_to_cpu (ReadUnaligned64 (RegProp)); - CurSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1)); - - DEBUG ((DEBUG_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n", - __FUNCTION__, CurBase, CurBase + CurSize - 1)); - - if (NewBase > CurBase || NewBase == 0) { - NewBase = CurBase; - NewSize = CurSize; - } - } else { - DEBUG ((DEBUG_ERROR, "%a: Failed to parse FDT memory node\n", - __FUNCTION__)); - } - } - } + NewSize -= NsBufSize; // Make sure the start of DRAM matches our expectation ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase); PcdStatus = PcdSet64S (PcdSystemMemorySize, NewSize); + PcdStatus = PcdSet64S (PcdMmBufferBase, NsBufBase); + PcdStatus = PcdSet64S (PcdMmBufferSize, (UINT64)NsBufSize); ASSERT_RETURN_ERROR (PcdStatus); return RETURN_SUCCESS; -- 2.17.1