On Tue, Aug 22, 2023 at 18:53:43 +0200, Marcin Juszkiewicz wrote: > From: Shashi Mallela <shashi.mall...@linaro.org> > > SBSA Reference Platform has GIC ITS support. Let make use of it to have > complex PCI Express setups. > > Base address is read from TF-A via SMC call. > > If firmware is used with QEMU 8.0 or older then there will be no GIC ITS > support. In such case we would not add information about it into MCFG > and there will be no IORT table. > > Co-authored-by: Marcin Juszkiewicz <marcin.juszkiew...@linaro.org> > Signed-off-by: Shashi Mallela <shashi.mall...@linaro.org> > Signed-off-by: Marcin Juszkiewicz <marcin.juszkiew...@linaro.org>
Reviewed-by: Leif Lindholm <quic_llind...@quicinc.com> Pushed as e509ac5a729e. Thanks! > --- > Silicon/Qemu/SbsaQemu/SbsaQemu.dec | 4 + > Platform/Qemu/SbsaQemu/SbsaQemu.dsc | 4 + > .../Qemu/SbsaQemu/AcpiTables/AcpiTables.inf | 1 + > .../SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf | 2 + > .../SbsaQemuPlatformDxe.inf | 1 + > .../Include/IndustryStandard/SbsaQemuAcpi.h | 11 + > .../Include/IndustryStandard/SbsaQemuSmc.h | 1 + > .../Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c | 206 ++++++++++++++++++ > .../SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c | 10 + > 9 files changed, 240 insertions(+) > > diff --git a/Silicon/Qemu/SbsaQemu/SbsaQemu.dec > b/Silicon/Qemu/SbsaQemu/SbsaQemu.dec > index 5182978cf56d..aab2894e6455 100644 > --- a/Silicon/Qemu/SbsaQemu/SbsaQemu.dec > +++ b/Silicon/Qemu/SbsaQemu/SbsaQemu.dec > @@ -70,3 +70,7 @@ [PcdsDynamic.common] > > > gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdPlatformVersionMajor|0x0|UINT32|0x0000011E > > gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdPlatformVersionMinor|0x0|UINT32|0x0000011F > + > + # ARM Generic Interrupt Controller ITS > + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdGicItsBase|0|UINT64|0x00000120 > + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdSmmuBase|0|UINT64|0x00000121 > diff --git a/Platform/Qemu/SbsaQemu/SbsaQemu.dsc > b/Platform/Qemu/SbsaQemu/SbsaQemu.dsc > index b88729ad8ad6..be406144c242 100644 > --- a/Platform/Qemu/SbsaQemu/SbsaQemu.dsc > +++ b/Platform/Qemu/SbsaQemu/SbsaQemu.dsc > @@ -523,6 +523,10 @@ [PcdsDynamicDefault.common] > gArmTokenSpaceGuid.PcdGicDistributorBase|0x40060000 > gArmTokenSpaceGuid.PcdGicRedistributorsBase|0x40080000 > > + # GIC ITS > + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdGicItsBase|0 > + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdSmmuBase|0x60050000 > + > # > # Set video resolution for boot options > # PlatformDxe can set the former at runtime. > diff --git a/Silicon/Qemu/SbsaQemu/AcpiTables/AcpiTables.inf > b/Silicon/Qemu/SbsaQemu/AcpiTables/AcpiTables.inf > index 0501c670d565..97021f7971c7 100644 > --- a/Silicon/Qemu/SbsaQemu/AcpiTables/AcpiTables.inf > +++ b/Silicon/Qemu/SbsaQemu/AcpiTables/AcpiTables.inf > @@ -75,3 +75,4 @@ [FixedPcd] > [Pcd] > gArmTokenSpaceGuid.PcdGicDistributorBase > gArmTokenSpaceGuid.PcdGicRedistributorsBase > + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdGicItsBase > diff --git > a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf > b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf > index c1c33788567d..14d760b36400 100644 > --- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf > +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf > @@ -48,6 +48,8 @@ [Pcd] > > gArmTokenSpaceGuid.PcdGicDistributorBase > gArmTokenSpaceGuid.PcdGicRedistributorsBase > + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdGicItsBase > + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdSmmuBase > > [Depex] > gEfiAcpiTableProtocolGuid ## CONSUMES > diff --git > a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.inf > b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.inf > index 545794a8c7ff..0e3b11d60426 100644 > --- > a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.inf > +++ > b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.inf > @@ -43,6 +43,7 @@ [Pcd] > > gArmTokenSpaceGuid.PcdGicDistributorBase > gArmTokenSpaceGuid.PcdGicRedistributorsBase > + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdGicItsBase > > > [Depex] > diff --git a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuAcpi.h > b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuAcpi.h > index 853b81b34df5..983d17f6fa50 100644 > --- a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuAcpi.h > +++ b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuAcpi.h > @@ -27,6 +27,7 @@ > #define SBSAQEMU_MADT_GIC_HBASE 0x2c010000 > #define SBSAQEMU_MADT_GIC_PMU_IRQ 23 > #define SBSAQEMU_MADT_GICR_SIZE 0x4000000 > +#define SBSAQEMU_MADT_GITS_SIZE 0x20000 > > // Macro for MADT GIC Redistributor Structure > #define SBSAQEMU_MADT_GICR_INIT() { > \ > @@ -37,6 +38,16 @@ > SBSAQEMU_MADT_GICR_SIZE /* DiscoveryRangeLength */ > \ > } > > +// Macro for MADT GIC ITS Structure > +#define SBSAQEMU_MADT_GIC_ITS_INIT(GicItsId) { > \ > + EFI_ACPI_6_5_GIC_ITS, /* Type */ > \ > + sizeof (EFI_ACPI_6_5_GIC_ITS_STRUCTURE), /* Length */ > \ > + EFI_ACPI_RESERVED_WORD, /* Reserved */ > \ > + GicItsId, /* GicItsId */ > \ > + PcdGet64 (PcdGicItsBase), /* PhysicalBaseAddress */ > \ > + EFI_ACPI_RESERVED_DWORD /* Reserved2 */ > \ > + } > + > #define SBSAQEMU_ACPI_SCOPE_OP_MAX_LENGTH 5 > > #define SBSAQEMU_ACPI_SCOPE_NAME { '_', 'S', 'B', '_' } > diff --git a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h > b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h > index 7fbd3bd887d0..7934875e4aba 100644 > --- a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h > +++ b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h > @@ -13,5 +13,6 @@ > > #define SIP_SVC_VERSION SMC_SIP_FUNCTION_ID(1) > #define SIP_SVC_GET_GIC SMC_SIP_FUNCTION_ID(100) > +#define SIP_SVC_GET_GIC_ITS SMC_SIP_FUNCTION_ID(101) > > #endif /* SBSA_QEMU_SMC_H_ */ > diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c > b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c > index ae5397bab768..3bc25a6e3540 100644 > --- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c > +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c > @@ -8,6 +8,7 @@ > **/ > #include <IndustryStandard/Acpi.h> > #include <IndustryStandard/AcpiAml.h> > +#include <IndustryStandard/IoRemappingTable.h> > #include <IndustryStandard/SbsaQemuAcpi.h> > #include <Library/AcpiLib.h> > #include <Library/BaseMemoryLib.h> > @@ -21,6 +22,36 @@ > #include <Library/UefiLib.h> > #include <Protocol/AcpiTable.h> > > +#pragma pack(1) > + > +typedef struct { > + EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE Node; > + UINT32 Identifiers; > +} SBSA_EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE; > + > +typedef struct > +{ > + EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE SmmuNode; > + EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE SmmuIdMap; > +} SBSA_EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE; > + > +typedef struct > +{ > + EFI_ACPI_6_0_IO_REMAPPING_RC_NODE RcNode; > + EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE RcIdMap; > +} SBSA_EFI_ACPI_6_0_IO_REMAPPING_RC_NODE; > + > +typedef struct { > + EFI_ACPI_6_0_IO_REMAPPING_TABLE Iort; > + SBSA_EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE ItsNode; > + SBSA_EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE SmmuNode; > + SBSA_EFI_ACPI_6_0_IO_REMAPPING_RC_NODE RcNode; > +} SBSA_IO_REMAPPING_STRUCTURE; > + > +static UINTN GicItsBase; > + > +#pragma pack () > + > /* > * A Function to Compute the ACPI Table Checksum > */ > @@ -40,6 +71,159 @@ AcpiPlatformChecksum ( > Buffer[ChecksumOffset] = CalculateCheckSum8(Buffer, Size); > } > > +/* > + * A function that add the IORT ACPI table. > + IN EFI_ACPI_COMMON_HEADER *CurrentTable > + */ > +EFI_STATUS > +AddIortTable ( > + IN EFI_ACPI_TABLE_PROTOCOL *AcpiTable > + ) > +{ > + EFI_STATUS Status; > + UINTN TableHandle; > + UINT32 TableSize; > + EFI_PHYSICAL_ADDRESS PageAddress; > + UINT8 *New; > + > + // Initialize IORT ACPI Header > + EFI_ACPI_6_0_IO_REMAPPING_TABLE Header = { > + SBSAQEMU_ACPI_HEADER(EFI_ACPI_6_0_IO_REMAPPING_TABLE_SIGNATURE, > + SBSA_IO_REMAPPING_STRUCTURE, > + EFI_ACPI_IO_REMAPPING_TABLE_REVISION_00), > + 3, > + sizeof(EFI_ACPI_6_0_IO_REMAPPING_TABLE), // NodeOffset > + 0 }; > + > + // Initialize SMMU3 Structure > + SBSA_EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE Smmu3 = { > + { > + { > + EFI_ACPI_IORT_TYPE_SMMUv3, > + sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE), > + 2, // Revision > + 0, // Reserved > + 1, // NumIdMapping > + OFFSET_OF (SBSA_EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE, SmmuIdMap) // > IdReference > + }, > + PcdGet64 (PcdSmmuBase), // 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 (SBSA_IO_REMAPPING_STRUCTURE, ItsNode), // OutputReference > + 0 // Flags > + } > + }; > + > +//NOTE(hrw): update to IORT E.e? > + SBSA_EFI_ACPI_6_0_IO_REMAPPING_RC_NODE Rc = { > + { > + { > + EFI_ACPI_IORT_TYPE_ROOT_COMPLEX, // Type > + sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_RC_NODE), // Length > + 0, // Revision > + 0, // Reserved > + 1, // NumIdMappings > + OFFSET_OF (SBSA_EFI_ACPI_6_0_IO_REMAPPING_RC_NODE, RcIdMap) // > IdReference > + }, > + 1, // CacheCoherent > + 0, // AllocationHints > + 0, // Reserved > + 0, // MemoryAccessFlags > + EFI_ACPI_IORT_ROOT_COMPLEX_ATS_UNSUPPORTED, // AtsAttribute > + 0x0, // PciSegmentNumber > + //0, //MemoryAddressSizeLimit > + }, > + { > + 0x0000, // InputBase > + 0xffff, // NumIds > + 0x0000, // OutputBase > + OFFSET_OF (SBSA_IO_REMAPPING_STRUCTURE, SmmuNode), // OutputReference > + 0, // Flags > + } > + }; > + > + SBSA_EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE Its = { > + // EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE > + { > + // EFI_ACPI_6_0_IO_REMAPPING_NODE > + { > + EFI_ACPI_IORT_TYPE_ITS_GROUP, // Type > + sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE), // Length > + 0, // Revision > + 0, // Identifier > + 0, // NumIdMappings > + 0, // IdReference > + }, > + 1, // ITS count > + }, > + 0, // GIC ITS Identifiers > + }; > + > + // Calculate the new table size based on the number of cores > + TableSize = sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE) + > + sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE) + > + sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE) + > + sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_RC_NODE); > + > + Status = gBS->AllocatePages ( > + AllocateAnyPages, > + EfiACPIReclaimMemory, > + EFI_SIZE_TO_PAGES (TableSize), > + &PageAddress > + ); > + if (EFI_ERROR(Status)) { > + DEBUG ((DEBUG_ERROR, "Failed to allocate pages for IORT table\n")); > + return EFI_OUT_OF_RESOURCES; > + } > + > + New = (UINT8 *)(UINTN) PageAddress; > + ZeroMem (New, TableSize); > + > + // Add the ACPI Description table header > + CopyMem (New, &Header, sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE)); > + ((EFI_ACPI_DESCRIPTION_HEADER*) New)->Length = TableSize; > + New += sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE); > + > + // ITS Node > + CopyMem (New, &Its, sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE)); > + New += sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE); > + > + // SMMUv3 Node > + CopyMem (New, &Smmu3, sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE)); > + New += sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE); > + > + // RC Node > + CopyMem (New, &Rc, sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_RC_NODE)); > + New += sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_RC_NODE); > + > + AcpiPlatformChecksum ((UINT8*) PageAddress, TableSize); > + > + Status = AcpiTable->InstallAcpiTable ( > + AcpiTable, > + (EFI_ACPI_COMMON_HEADER *)PageAddress, > + TableSize, > + &TableHandle > + ); > + if (EFI_ERROR(Status)) { > + DEBUG ((DEBUG_ERROR, "Failed to install IORT table\n")); > + } > + > + return Status; > +} > + > /* > * A function that add the MADT ACPI table. > IN EFI_ACPI_COMMON_HEADER *CurrentTable > @@ -100,6 +284,13 @@ AddMadtTable ( > sizeof (EFI_ACPI_6_0_GIC_DISTRIBUTOR_STRUCTURE) + > sizeof (EFI_ACPI_6_0_GICR_STRUCTURE); > > + // Initialize GIC ITS Structure > + EFI_ACPI_6_5_GIC_ITS_STRUCTURE Gic_Its = SBSAQEMU_MADT_GIC_ITS_INIT(0); > + > + if (GicItsBase > 0) { > + TableSize += sizeof (EFI_ACPI_6_5_GIC_ITS_STRUCTURE); > + } > + > Status = gBS->AllocatePages ( > AllocateAnyPages, > EfiACPIReclaimMemory, > @@ -138,6 +329,12 @@ AddMadtTable ( > CopyMem (New, &Gicr, sizeof (EFI_ACPI_6_0_GICR_STRUCTURE)); > New += sizeof (EFI_ACPI_6_0_GICR_STRUCTURE); > > + if (GicItsBase > 0) { > + // GIC ITS Structure > + CopyMem (New, &Gic_Its, sizeof (EFI_ACPI_6_5_GIC_ITS_STRUCTURE)); > + New += sizeof (EFI_ACPI_6_5_GIC_ITS_STRUCTURE); > + } > + > AcpiPlatformChecksum ((UINT8*) PageAddress, TableSize); > > Status = AcpiTable->InstallAcpiTable ( > @@ -438,6 +635,15 @@ InitializeSbsaQemuAcpiDxe ( > return Status; > } > > + GicItsBase = PcdGet64 (PcdGicItsBase); > + > + if (GicItsBase > 0) { > + Status = AddIortTable (AcpiTable); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "Failed to add IORT table\n")); > + } > + } > + > Status = AddMadtTable (AcpiTable); > if (EFI_ERROR(Status)) { > DEBUG ((DEBUG_ERROR, "Failed to add MADT table\n")); > diff --git > a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c > b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c > index f6a3e84483fe..ddcca2b7243c 100644 > --- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c > +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c > @@ -86,5 +86,15 @@ InitializeSbsaQemuPlatformDxe ( > > DEBUG ((DEBUG_INFO, "GICR base: 0x%x\n", Arg0)); > > + SmcResult = ArmCallSmc0 (SIP_SVC_GET_GIC_ITS, &Arg0, NULL, NULL); > + if (SmcResult == SMC_ARCH_CALL_SUCCESS) { > + Result = PcdSet64S (PcdGicItsBase, Arg0); > + ASSERT_RETURN_ERROR (Result); > + } > + > + Arg0 = PcdGet64 (PcdGicItsBase); > + > + DEBUG ((DEBUG_INFO, "GICI base: 0x%x\n", Arg0)); > + > return EFI_SUCCESS; > } > -- > 2.41.0 > > > > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#107960): https://edk2.groups.io/g/devel/message/107960 Mute This Topic: https://groups.io/mt/100898112/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/9847357/21656/1706620634/xyzzy [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-