From 87a8a9148cd5acbeb31c6668f55d6c31865a524a Mon Sep 17 00:00:00 2001 From: eeshanl <eeshanlondhe@microsoft.com> Date: Wed, 11 Dec 2024 00:32:59 +0000 Subject: [PATCH] Add SMMU Sbsa support - Configure SMMU config HOB in SbsaPlatformPeiLib - Update SbsaQemuAcpiDxe to use ArmMonitor calls to work with updated qemu version 9.1.50 - Relies on cherry-pick 42925c15bee09162c6dfc8c2204843ffac6201c1 in Silicon/Arm/TFA --- .../SbsaPlatformPeiLib/PlatformPeiLib.c | 140 ++++++++++++++++++ .../SbsaPlatformPeiLib/PlatformPeiLib.inf | 52 +++++++ Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc | 5 +- Platforms/QemuSbsaPkg/QemuSbsaPkg.fdf | 1 + .../SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c | 63 +++++++- .../SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf | 2 + 6 files changed, 259 insertions(+), 4 deletions(-) create mode 100644 Platforms/QemuSbsaPkg/Library/SbsaPlatformPeiLib/PlatformPeiLib.c create mode 100644 Platforms/QemuSbsaPkg/Library/SbsaPlatformPeiLib/PlatformPeiLib.inf diff --git a/Platforms/QemuSbsaPkg/Library/SbsaPlatformPeiLib/PlatformPeiLib.c b/Platforms/QemuSbsaPkg/Library/SbsaPlatformPeiLib/PlatformPeiLib.c new file mode 100644 index 0000000000..057805b8c9 --- /dev/null +++ b/Platforms/QemuSbsaPkg/Library/SbsaPlatformPeiLib/PlatformPeiLib.c @@ -0,0 +1,140 @@ +/** @file + + Copyright (c) 2011-2014, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Guid/SmmuConfig.h> +#include <Library/ArmPlatformLib.h> +#include <Library/DebugLib.h> +#include <Library/HobLib.h> +#include <Library/PcdLib.h> +#include <PiPei.h> + +#define SBSAQEMU_ACPI_HEADER(Signature, Type, Revision) \ + { \ + Signature, /* UINT32 Signature */ \ + sizeof (Type), /* UINT32 Length */ \ + Revision, /* UINT8 Revision */ \ + 0, /* UINT8 Checksum */ \ + { 'L', 'I', 'N', 'A', 'R', 'O' }, /* UINT8 OemId[6] */ \ + FixedPcdGet64 (PcdAcpiDefaultOemTableId), /* UINT64 OemTableId */ \ + FixedPcdGet32 (PcdAcpiDefaultOemRevision), /* UINT32 OemRevision */ \ + FixedPcdGet32 (PcdAcpiDefaultCreatorId), /* UINT32 CreatorId */ \ + FixedPcdGet32 (PcdAcpiDefaultCreatorRevision) /* UINT32 CreatorRevision */ \ + } + +EFI_STATUS +EFIAPI +PlatformPeim ( + VOID + ) +{ + + BuildFvHob(PcdGet64(PcdFvBaseAddress), PcdGet32(PcdFvSize)); + + // Create SMMU Config Hob struct. Same as IORT we want to publish as it is platform dependent. + SMMU_CONFIG SmmuConfig = { + .VersionMajor = CURRENT_SMMU_CONFIG_VERSION_MAJOR, + .VersionMinor = CURRENT_SMMU_CONFIG_VERSION_MINOR, + + // Initialize IORT Table Header + .Config.Iort = { + SBSAQEMU_ACPI_HEADER(EFI_ACPI_6_0_IO_REMAPPING_TABLE_SIGNATURE, + PLATFORM_IO_REMAPPING_STRUCTURE, + EFI_ACPI_IO_REMAPPING_TABLE_REVISION_00), + 3, + sizeof(EFI_ACPI_6_0_IO_REMAPPING_TABLE), // NodeOffset + 0 + }, + + // Initialize SMMU3 Structure + .Config.SmmuNode = { + { + { + EFI_ACPI_IORT_TYPE_SMMUv3, + sizeof(PLATFORM_ACPI_6_0_IO_REMAPPING_SMMU3_NODE), + 2, // Revision + 0, // Reserved + 1, // NumIdMapping + OFFSET_OF(PLATFORM_ACPI_6_0_IO_REMAPPING_SMMU3_NODE, + SmmuIdMap) // IdReference + }, + 0x60050000, // Base address + EFI_ACPI_IORT_SMMUv3_FLAG_COHAC_OVERRIDE, // Flags + 0, // Reserved + 0, // VATOS address + EFI_ACPI_IORT_SMMUv3_MODEL_GENERIC, // SMMUv3 Model + 74, // Event + 75, // Pri + 77, // Gerror + 76, // Sync + 0, // Proximity domain + 1 // DevIDMappingIndex + }, + { + 0x0000, // InputBase + 0xffff, // NumIds + 0x0000, // OutputBase + OFFSET_OF(PLATFORM_IO_REMAPPING_STRUCTURE, ItsNode), // OutputReference + 0 // Flags + } + }, + + // Initialize RC Node + .Config.RcNode = { + { + { + EFI_ACPI_IORT_TYPE_ROOT_COMPLEX, // Type + sizeof(PLATFORM_ACPI_6_0_IO_REMAPPING_RC_NODE), // Length + 0, // Revision + 0, // Reserved + 1, // NumIdMappings + OFFSET_OF(PLATFORM_ACPI_6_0_IO_REMAPPING_RC_NODE, + RcIdMap) // IdReference + }, + 1, // CacheCoherent + 0, // AllocationHints + 0, // Reserved + 1, // MemoryAccessFlags + EFI_ACPI_IORT_ROOT_COMPLEX_ATS_UNSUPPORTED, // AtsAttribute + 0x0, // PciSegmentNumber + // 0, //MemoryAddressSizeLimit + }, + { + 0x0000, // InputBase + 0xffff, // NumIds + 0x0000, // OutputBase + OFFSET_OF(PLATFORM_IO_REMAPPING_STRUCTURE, + SmmuNode), // OutputReference + 0, // Flags + } + }, + + // Initialize ITS Node + .Config.ItsNode = { + // EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE + { + // EFI_ACPI_6_0_IO_REMAPPING_NODE + { + EFI_ACPI_IORT_TYPE_ITS_GROUP, // Type + sizeof(PLATFORM_ACPI_6_0_IO_REMAPPING_ITS_NODE), // Length + 0, // Revision + 0, // Identifier + 0, // NumIdMappings + 0, // IdReference + }, + 1, // ITS count + }, + 0 // GIC ITS Identifiers + } + }; + + BuildGuidDataHob( & gSmmuConfigHobGuid, & SmmuConfig, sizeof(SMMU_CONFIG)); + + DEBUG((DEBUG_INFO, "Configured SmmuConfig Hob.\n")); + + return EFI_SUCCESS; +} diff --git a/Platforms/QemuSbsaPkg/Library/SbsaPlatformPeiLib/PlatformPeiLib.inf b/Platforms/QemuSbsaPkg/Library/SbsaPlatformPeiLib/PlatformPeiLib.inf new file mode 100644 index 0000000000..43a626198a --- /dev/null +++ b/Platforms/QemuSbsaPkg/Library/SbsaPlatformPeiLib/PlatformPeiLib.inf @@ -0,0 +1,52 @@ +#/** @file +# +# Copyright (c) 2011-2012, ARM Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmPlatformPeiLib + FILE_GUID = aa2c31d7-9029-4071-8a6b-9ca3f55c9bb0 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = PlatformPeiLib + +[Sources] + PlatformPeiLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + +[LibraryClasses] + DebugLib + HobLib + ArmPlatformLib + +[Guids] + gSmmuConfigHobGuid + +[Ppis] + gEfiPeiMasterBootModePpiGuid # PPI ALWAYS_PRODUCED + gEfiPeiBootInRecoveryModePpiGuid # PPI SOMETIMES_PRODUCED + +[FixedPcd] + gArmTokenSpaceGuid.PcdFdBaseAddress + gArmTokenSpaceGuid.PcdFdSize + + gArmTokenSpaceGuid.PcdFvBaseAddress + gArmTokenSpaceGuid.PcdFvSize + + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision + +[depex] + TRUE diff --git a/Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc b/Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc index d6272c190c..50f3b559fe 100644 --- a/Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc +++ b/Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc @@ -163,7 +163,7 @@ ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf - PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf + PlatformPeiLib|QemuSbsaPkg/Library/SbsaPlatformPeiLib/PlatformPeiLib.inf MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf # ARM PL031 RTC Driver @@ -571,7 +571,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE - gEfiMdeModulePkgTokenSpaceGuid.PcdRequireIommu|FALSE # don't require IOMMU + gEfiMdeModulePkgTokenSpaceGuid.PcdRequireIommu|TRUE # require IOMMU gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport|FALSE gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache|FALSE @@ -1363,6 +1363,7 @@ MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf QemuSbsaPkg/AcpiTables/AcpiTables.inf QemuSbsaPkg/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf + ArmPkg/Drivers/SmmuDxe/SmmuDxe.inf # # Standalone MM drivers in non-secure world diff --git a/Platforms/QemuSbsaPkg/QemuSbsaPkg.fdf b/Platforms/QemuSbsaPkg/QemuSbsaPkg.fdf index 5af2edc4e8..7a42b3f11a 100644 --- a/Platforms/QemuSbsaPkg/QemuSbsaPkg.fdf +++ b/Platforms/QemuSbsaPkg/QemuSbsaPkg.fdf @@ -343,6 +343,7 @@ READ_LOCK_STATUS = TRUE INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf INF QemuSbsaPkg/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf INF RuleOverride = ACPITABLE QemuSbsaPkg/AcpiTables/AcpiTables.inf + INF ArmPkg/Drivers/SmmuDxe/SmmuDxe.inf # # EBC support diff --git a/Platforms/QemuSbsaPkg/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c b/Platforms/QemuSbsaPkg/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c index fcbac5d491..52c1005a7e 100644 --- a/Platforms/QemuSbsaPkg/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c +++ b/Platforms/QemuSbsaPkg/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c @@ -9,6 +9,8 @@ #include <IndustryStandard/Acpi.h> #include <IndustryStandard/AcpiAml.h> #include <IndustryStandard/SbsaQemuAcpi.h> +#include <IndustryStandard/ArmStdSmc.h> +#include <Library/ArmMonitorLib.h> #include <Library/AcpiLib.h> #include <Library/BaseMemoryLib.h> #include <Library/DebugLib.h> @@ -16,11 +18,68 @@ #include <Library/MemoryAllocationLib.h> #include <Library/PcdLib.h> #include <Library/PrintLib.h> +#include <Library/ResetSystemLib.h> #include <Library/UefiBootServicesTableLib.h> #include <Library/UefiDriverEntryPoint.h> #include <Library/UefiLib.h> #include <Protocol/AcpiTable.h> +#define SIP_SVC_GET_CPU_COUNT SMC_SIP_FUNCTION_ID(200) +#define SIP_SVC_GET_CPU_NODE SMC_SIP_FUNCTION_ID(201) +#define SMC_SIP_CALL_SUCCESS SMC_ARCH_CALL_SUCCESS + +/** + Get CPU count from information passed by TF-A. + +**/ +UINT32 +GetCpuCount ( + VOID + ) +{ + ARM_MONITOR_ARGS SmcArgs; + + SmcArgs.Arg0 = SIP_SVC_GET_CPU_COUNT; + ArmMonitorCall (&SmcArgs); + + if (SmcArgs.Arg0 != SMC_SIP_CALL_SUCCESS) { + DEBUG ((DEBUG_ERROR, "%a: SIP_SVC_GET_CPU_COUNT call failed. We have no cpu information.\n", __func__)); + ResetShutdown (); + } + + DEBUG ((DEBUG_INFO, "%a: We have %d cpus.\n", __func__, SmcArgs.Arg1)); + + return SmcArgs.Arg1; +} + +/** + Get MPIDR for a given cpu from TF-A. + + @param [in] CpuId Index of cpu to retrieve MPIDR value for. + + @retval MPIDR value of CPU at index <CpuId> +**/ +UINT64 +GetMpidr ( + IN UINTN CpuId + ) +{ + ARM_MONITOR_ARGS SmcArgs; + + SmcArgs.Arg0 = SIP_SVC_GET_CPU_NODE; + SmcArgs.Arg1 = CpuId; + ArmMonitorCall (&SmcArgs); + + if (SmcArgs.Arg0 != SMC_SIP_CALL_SUCCESS) { + DEBUG ((DEBUG_ERROR, "%a: SIP_SVC_GET_CPU_NODE call failed. We have no MPIDR for CPU%d.\n", __func__, CpuId)); + ResetShutdown (); + } + + DEBUG ((DEBUG_INFO, "%a: MPIDR for CPU%d: = %d\n", __func__, CpuId, SmcArgs.Arg2)); + + return SmcArgs.Arg2; +} + /* * A Function to Compute the ACPI Table Checksum */ @@ -129,7 +188,7 @@ AddMadtTable ( CopyMem (New, &Gicc, sizeof (EFI_ACPI_6_0_GIC_STRUCTURE)); GiccPtr = (EFI_ACPI_6_0_GIC_STRUCTURE *)New; GiccPtr->AcpiProcessorUid = CoreIndex; - GiccPtr->MPIDR = FdtHelperGetMpidr (CoreIndex); + GiccPtr->MPIDR = GetMpidr (CoreIndex); New += sizeof (EFI_ACPI_6_0_GIC_STRUCTURE); } @@ -431,7 +490,7 @@ InitializeSbsaQemuAcpiDxe ( UINT32 NumCores; // Parse the device tree and get the number of CPUs - NumCores = FdtHelperCountCpus (); + NumCores = GetCpuCount (); ASSERT (PcdGet32 (PcdCoreCount) == NumCores); // Check if ACPI Table Protocol has been installed diff --git a/Platforms/QemuSbsaPkg/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf b/Platforms/QemuSbsaPkg/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf index 4b49551100..eadf8a53a9 100644 --- a/Platforms/QemuSbsaPkg/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf +++ b/Platforms/QemuSbsaPkg/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf @@ -29,6 +29,7 @@ [LibraryClasses] ArmLib + ArmMonitorLib BaseMemoryLib BaseLib DebugLib @@ -36,6 +37,7 @@ FdtHelperLib PcdLib PrintLib + ResetSystemLib UefiDriverEntryPoint UefiLib UefiRuntimeServicesTableLib