From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web11.9366.1651071602792509885 for ; Wed, 27 Apr 2022 08:00:03 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: arm.com, ip: 217.140.110.172, mailfrom: pierre.gondois@arm.com) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6715A1474; Wed, 27 Apr 2022 08:00:02 -0700 (PDT) Received: from pierre123.arm.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 4B8433F73B; Wed, 27 Apr 2022 08:00:01 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Sami Mujawar Subject: [PATCH edk2-platforms v1 3/3] Platform/ARM: Juno: Generate ASL description of a PCIe bus Date: Wed, 27 Apr 2022 16:59:43 +0200 Message-Id: <20220427145943.402487-4-Pierre.Gondois@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220427145943.402487-1-Pierre.Gondois@arm.com> References: <20220427145943.402487-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable From: Pierre Gondois The Dynamic Tables Framework has been updated to add support for generating an ASL description of PCIe busses. This patch: - Describes the PCI address-range mapping and PCI devices legacy interrupts in the Configuration Manager of the Juno - Add the generation of a new SSDT table describing the PCIe bus - Removes the existing (and hard-coded) SSDT table describing the PCIe bus Signed-off-by: Pierre Gondois --- .../AslTables/SsdtPci.asl | 195 --------------- .../ConfigurationManager.c | 227 +++++++++++++++++- .../ConfigurationManager.h | 27 +++ .../ConfigurationManagerDxe.inf | 1 - 4 files changed, 249 insertions(+), 201 deletions(-) delete mode 100644 Platform/ARM/JunoPkg/ConfigurationManager/Configurati= onManagerDxe/AslTables/SsdtPci.asl diff --git a/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManag= erDxe/AslTables/SsdtPci.asl b/Platform/ARM/JunoPkg/ConfigurationManager/C= onfigurationManagerDxe/AslTables/SsdtPci.asl deleted file mode 100644 index 2ed37ea83c6c..000000000000 --- a/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManagerDxe/A= slTables/SsdtPci.asl +++ /dev/null @@ -1,195 +0,0 @@ -/** @file - SSDT for Juno PCIe - - Copyright (c) 2014 - 2019, ARM Ltd. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "ArmPlatform.h" - -/* - See ACPI 6.1 Section 6.2.13 - - There are two ways that _PRT can be used. - - In the first model, a PCI Link device is used to provide additional - configuration information such as whether the interrupt is Level or - Edge triggered, it is active High or Low, Shared or Exclusive, etc. - - In the second model, the PCI interrupts are hardwired to specific - interrupt inputs on the interrupt controller and are not - configurable. In this case, the Source field in _PRT does not - reference a device, but instead contains the value zero, and the - Source Index field contains the global system interrupt to which the - PCI interrupt is hardwired. - - We use the first model with link indirection to set the correct - interrupt type as PCI defaults (Level Triggered, Active Low) are not - compatible with GICv2. -*/ -#define LNK_DEVICE(Unique_Id, Link_Name, irq) = \ - Device(Link_Name) { = \ - Name(_HID, EISAID("PNP0C0F")) = \ - Name(_UID, Unique_Id) = \ - Name(_PRS, ResourceTemplate() { = \ - Interrupt(ResourceProducer, Level, ActiveHigh, Exclusive) { irq } = \ - }) = \ - Method (_CRS, 0) { Return (_PRS) } = \ - Method (_SRS, 1) { } = \ - Method (_DIS) { } = \ -} - -#define PRT_ENTRY(Address, Pin, Link) = \ - Package (4) { = \ - Address, /* uses the same format as _ADR */ = \ - Pin, /* The PCI pin number of the device (0-INTA, 1-INTB, 2-INT= C, 3-INTD) */ \ - Link, /* Interrupt allocated via Link device */ = \ - Zero /* global system interrupt number (no used) */ = \ -} - -/* - See Reference [1] 6.1.1 - "High word=E2=80=93Device #, Low word=E2=80=93Function #. (for example= , device 3, - function 2 is 0x00030002). To refer to all the functions on a device #= , - use a function number of FFFF)." -*/ -#define ROOT_PRT_ENTRY(Pin, Link) PRT_ENTRY(0x0000FFFF, Pin, Link) - // Device 0 for Brid= ge. - -DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI= _ARM_OEM_REVISION) { - Scope(_SB) { - // - // PCI Root Complex - // - LNK_DEVICE(1, LNKA, 168) - LNK_DEVICE(2, LNKB, 169) - LNK_DEVICE(3, LNKC, 170) - LNK_DEVICE(4, LNKD, 171) - - Device(PCI0) - { - Name(_HID, EISAID("PNP0A08")) // PCI Express Root Bridge - Name(_CID, EISAID("PNP0A03")) // Compatible PCI Root Bridge - Name(_SEG, Zero) // PCI Segment Group number - Name(_BBN, Zero) // PCI Base Bus Number - Name(_CCA, 1) // Initially mark the PCI coherent (for JunoR1) - - // Root Complex 0 - Device (RP0) { - Name(_ADR, 0xF0000000) // Dev 0, Func 0 - } - - // PCI Routing Table - Name(_PRT, Package() { - ROOT_PRT_ENTRY(0, LNKA), // INTA - ROOT_PRT_ENTRY(1, LNKB), // INTB - ROOT_PRT_ENTRY(2, LNKC), // INTC - ROOT_PRT_ENTRY(3, LNKD), // INTD - }) - // Root complex resources - Method (_CRS, 0, Serialized) { - Name (RBUF, ResourceTemplate () { - WordBusNumber ( // Bus numbers assigned to this root - ResourceProducer, - MinFixed, MaxFixed, PosDecode, - 0, // AddressGranularity - 0, // AddressMinimum - Minimum Bus Number - 255, // AddressMaximum - Maximum Bus Number - 0, // AddressTranslation - Set to 0 - 256 // RangeLength - Number of Busses - ) - - DWordMemory ( // 32-bit BAR Windows - ResourceProducer, PosDecode, - MinFixed, MaxFixed, - Cacheable, ReadWrite, - 0x00000000, // Granularity - 0x50000000, // Min Base Address - 0x57FFFFFF, // Max Base Address - 0x00000000, // Translate - 0x08000000 // Length - ) - - QWordMemory ( // 64-bit BAR Windows - ResourceProducer, PosDecode, - MinFixed, MaxFixed, - Cacheable, ReadWrite, - 0x00000000, // Granularity - 0x4000000000, // Min Base Address - 0x40FFFFFFFF, // Max Base Address - 0x00000000, // Translate - 0x100000000 // Length - ) - - DWordIo ( // IO window - ResourceProducer, - MinFixed, - MaxFixed, - PosDecode, - EntireRange, - 0x00000000, // Granularity - 0x00000000, // Min Base Address - 0x007fffff, // Max Base Address - 0x5f800000, // Translate - 0x00800000, // Length - ,,,TypeTranslation - ) - }) // Name(RBUF) - - Return (RBUF) - } // Method(_CRS) - - // - // OS Control Handoff - // - Name(SUPP, Zero) // PCI _OSC Support Field value - Name(CTRL, Zero) // PCI _OSC Control Field value - - /* - See [1] 6.2.10, [2] 4.5 - */ - Method(_OSC,4) { - // Check for proper UUID - If(LEqual(Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) = { - // Create DWord-adressable fields from the Capabilities Buffer - CreateDWordField(Arg3,0,CDW1) - CreateDWordField(Arg3,4,CDW2) - CreateDWordField(Arg3,8,CDW3) - - // Save Capabilities DWord2 & 3 - Store(CDW2,SUPP) - Store(CDW3,CTRL) - - // Only allow native hot plug control if OS supports: - // * ASPM - // * Clock PM - // * MSI/MSI-X - If(LNotEqual(And(SUPP, 0x16), 0x16)) { - And(CTRL,0x1E,CTRL) // Mask bit 0 (and undefined bits) - } - - // Always allow native PME, AER (no dependencies) - - // Never allow SHPC (no SHPC controller in this system) - And(CTRL,0x1D,CTRL) - - If(LNotEqual(Arg1,One)) { // Unknown revision - Or(CDW1,0x08,CDW1) - } - - If(LNotEqual(CDW3,CTRL)) { // Capabilities bits were ma= sked - Or(CDW1,0x10,CDW1) - } - - // Update DWORD3 in the buffer - Store(CTRL,CDW3) - Return(Arg3) - } Else { - Or(CDW1,4,CDW1) // Unrecognized UUID - Return(Arg3) - } - } // End _OSC - } // PCI0 - } -} diff --git a/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManag= erDxe/ConfigurationManager.c b/Platform/ARM/JunoPkg/ConfigurationManager/= ConfigurationManagerDxe/ConfigurationManager.c index d147bbc317db..61c704411620 100644 --- a/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManagerDxe/C= onfigurationManager.c +++ b/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManagerDxe/C= onfigurationManager.c @@ -111,11 +111,12 @@ EDKII_PLATFORM_REPOSITORY_INFO ArmJunoPlatformRepos= itoryInfo =3D { }, // SSDT table describing the PCI root complex { - EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, 0, // Unused - CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdt), - (EFI_ACPI_DESCRIPTION_HEADER*)ssdtpci_aml_code - } + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtPciExpress), + NULL, + SIGNATURE_64 ('S','S','D','T','-','P','C','I') + }, }, =20 // Boot architecture information @@ -244,7 +245,86 @@ EDKII_PLATFORM_REPOSITORY_INFO ArmJunoPlatformReposi= toryInfo =3D { // The start bus number FixedPcdGet32 (PcdPciBusMin), // The end bus number - FixedPcdGet32 (PcdPciBusMax) + FixedPcdGet32 (PcdPciBusMax), + // AddressMapToken + REFERENCE_TOKEN (PciAddressMapRef), + // InterruptMapToken + REFERENCE_TOKEN (PciInterruptMapRef) + }, + + // PCI address-range mapping references + { + { REFERENCE_TOKEN (PciAddressMapInfo[0]) }, + { REFERENCE_TOKEN (PciAddressMapInfo[1]) }, + { REFERENCE_TOKEN (PciAddressMapInfo[2]) } + }, + // PCI address-range mapping information + { + { // PciAddressMapInfo[0] -> 32-bit BAR Window + PCI_SS_M32, // SpaceCode + 0x50000000, // PciAddress + 0x50000000, // CpuAddress + 0x08000000 // AddressSize + }, + { // PciAddressMapInfo[1] -> 64-bit BAR Window + PCI_SS_M64, // SpaceCode + 0x4000000000, // PciAddress + 0x4000000000, // CpuAddress + 0x0100000000 // AddressSize + }, + { // PciAddressMapInfo[2] -> IO BAR Window + PCI_SS_IO, // SpaceCode + 0x00000000, // PciAddress + 0x5f800000, // CpuAddress + 0x00800000 // AddressSize + }, + }, + + // PCI device legacy interrupts mapping information + { + { REFERENCE_TOKEN (PciInterruptMapInfo[0]) }, + { REFERENCE_TOKEN (PciInterruptMapInfo[1]) }, + { REFERENCE_TOKEN (PciInterruptMapInfo[2]) }, + { REFERENCE_TOKEN (PciInterruptMapInfo[3]) } + }, + // PCI device legacy interrupts mapping information + { + { // PciInterruptMapInfo[0] -> Device 0, INTA + 0, // PciBus + 0, // PciDevice + 0, // PciInterrupt + { + 168, // Interrupt + 0x0 // Flags + } + }, + { // PciInterruptMapInfo[1] -> Device 0, INTB + 0, // PciBus + 0, // PciDevice + 1, // PciInterrupt + { + 169, // Interrupt + 0x0 // Flags + } + }, + { // PciInterruptMapInfo[2] -> Device 0, INTC + 0, // PciBus + 0, // PciDevice + 2, // PciInterrupt + { + 170, // Interrupt + 0x0 // Flags + } + }, + { // PciInterruptMapInfo[3] -> Device 0, INTD + 0, // PciBus + 0, // PciDevice + 3, // PciInterrupt + { + 171, // Interrupt + 0x0 // Flags + } + }, }, =20 // GIC Msi Frame Info @@ -962,6 +1042,105 @@ GetLpiInfo ( return EFI_NOT_FOUND; } =20 + +/** Return PCI address-range mapping Info. + + @param [in] This Pointer to the Configuration Manager P= rotocol. + @param [in] CmObjectId The Object ID of the CM object request= ed + @param [in] SearchToken A unique token for identifying the req= uested + CM_ARM_PCI_ADDRESS_MAP_INFO object. + @param [in, out] CmObject Pointer to the Configuration Manager O= bject + descriptor describing the requested Ob= ject. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object information is not= found. +**/ +EFI_STATUS +EFIAPI +GetPciAddressMapInfo ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This, + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN SearchToken, + IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject + ) +{ + EDKII_PLATFORM_REPOSITORY_INFO * PlatformRepo; + UINT32 TotalObjCount; + UINT32 ObjIndex; + + if ((This =3D=3D NULL) || (CmObject =3D=3D NULL)) { + ASSERT (This !=3D NULL); + ASSERT (CmObject !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + PlatformRepo =3D This->PlatRepoInfo; + + TotalObjCount =3D ARRAY_SIZE (PlatformRepo->PciAddressMapInfo); + + for (ObjIndex =3D 0; ObjIndex < TotalObjCount; ObjIndex++) { + if (SearchToken =3D=3D (CM_OBJECT_TOKEN)&PlatformRepo->PciAddressMap= Info[ObjIndex]) { + CmObject->ObjectId =3D CmObjectId; + CmObject->Size =3D sizeof (PlatformRepo->PciAddressMapInfo[ObjInde= x]); + CmObject->Data =3D (VOID*)&PlatformRepo->PciAddressMapInfo[ObjInde= x]; + CmObject->Count =3D 1; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +/** Return PCI device legacy interrupt mapping Info. + + @param [in] This Pointer to the Configuration Manager P= rotocol. + @param [in] CmObjectId The Object ID of the CM object request= ed + @param [in] SearchToken A unique token for identifying the req= uested + CM_ARM_PCI_INTERRUPT_MAP_INFO object. + @param [in, out] CmObject Pointer to the Configuration Manager O= bject + descriptor describing the requested Ob= ject. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object information is not= found. +**/ +EFI_STATUS +EFIAPI +GetPciInterruptMapInfo ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This, + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN SearchToken, + IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject + ) +{ + EDKII_PLATFORM_REPOSITORY_INFO * PlatformRepo; + UINT32 TotalObjCount; + UINT32 ObjIndex; + + if ((This =3D=3D NULL) || (CmObject =3D=3D NULL)) { + ASSERT (This !=3D NULL); + ASSERT (CmObject !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + PlatformRepo =3D This->PlatRepoInfo; + + TotalObjCount =3D ARRAY_SIZE (PlatformRepo->PciInterruptMapInfo); + + for (ObjIndex =3D 0; ObjIndex < TotalObjCount; ObjIndex++) { + if (SearchToken =3D=3D (CM_OBJECT_TOKEN)&PlatformRepo->PciInterruptM= apInfo[ObjIndex]) { + CmObject->ObjectId =3D CmObjectId; + CmObject->Size =3D sizeof (PlatformRepo->PciInterruptMapInfo[ObjIn= dex]); + CmObject->Data =3D (VOID*)&PlatformRepo->PciInterruptMapInfo[ObjIn= dex]; + CmObject->Count =3D 1; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + /** Return a list of Configuration Manager object references pointed to = by the given input token. =20 @@ -1031,6 +1210,18 @@ GetCmObjRefs ( CmObject->Count =3D ARRAY_SIZE (PlatformRepo->CoresLpiRef); return EFI_SUCCESS; } + if (SearchToken =3D=3D (CM_OBJECT_TOKEN)&PlatformRepo->PciAddressMapRe= f) { + CmObject->Size =3D sizeof (PlatformRepo->PciAddressMapRef); + CmObject->Data =3D (VOID*)&PlatformRepo->PciAddressMapRef; + CmObject->Count =3D ARRAY_SIZE (PlatformRepo->PciAddressMapRef); + return EFI_SUCCESS; + } + if (SearchToken =3D=3D (CM_OBJECT_TOKEN)&PlatformRepo->PciInterruptMap= Ref) { + CmObject->Size =3D sizeof (PlatformRepo->PciInterruptMapRef); + CmObject->Data =3D (VOID*)&PlatformRepo->PciInterruptMapRef; + CmObject->Count =3D ARRAY_SIZE (PlatformRepo->PciInterruptMapRef); + return EFI_SUCCESS; + } =20 return EFI_NOT_FOUND; } @@ -1320,6 +1511,32 @@ GetArmNameSpaceObject ( ); break; =20 + case EArmObjPciAddressMapInfo: + Status =3D HandleCmObjectRefByToken ( + This, + CmObjectId, + PlatformRepo->PciAddressMapInfo, + sizeof (PlatformRepo->PciAddressMapInfo), + ARRAY_SIZE (PlatformRepo->PciAddressMapInfo), + Token, + GetPciAddressMapInfo, + CmObject + ); + break; + + case EArmObjPciInterruptMapInfo: + Status =3D HandleCmObjectRefByToken ( + This, + CmObjectId, + PlatformRepo->PciInterruptMapInfo, + sizeof (PlatformRepo->PciInterruptMapInfo), + ARRAY_SIZE (PlatformRepo->PciInterruptMapInfo), + Token, + GetPciInterruptMapInfo, + CmObject + ); + break; + default: { Status =3D EFI_NOT_FOUND; DEBUG (( diff --git a/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManag= erDxe/ConfigurationManager.h b/Platform/ARM/JunoPkg/ConfigurationManager/= ConfigurationManagerDxe/ConfigurationManager.h index 1bc242bc9d85..5b5e62427f2b 100644 --- a/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManagerDxe/C= onfigurationManager.h +++ b/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManagerDxe/C= onfigurationManager.h @@ -90,6 +90,21 @@ extern CHAR8 ssdtpci_aml_code[]; (WritePolicy << 4) = \ ) =20 +/** PCI space codes. +*/ +#define PCI_SS_CONFIG 0 +#define PCI_SS_IO 1 +#define PCI_SS_M32 2 +#define PCI_SS_M64 3 + +/** Count of PCI address-range mapping struct. +*/ +#define PCI_ADDRESS_MAP_COUNT 3 + +/** Count of PCI device legacy interrupt mapping struct. +*/ +#define PCI_INTERRUPT_MAP_COUNT 4 + /** A function that prepares Configuration Manager Objects for returning= . =20 @param [in] This Pointer to the Configuration Manager Protocol= . @@ -226,6 +241,18 @@ typedef struct PlatformRepositoryInfo { /// PCI configuration space information CM_ARM_PCI_CONFIG_SPACE_INFO PciConfigInfo; =20 + // PCI address-range mapping references + CM_ARM_OBJ_REF PciAddressMapRef[PCI_ADDRESS_MAP= _COUNT]; + + // PCI address-range mapping information + CM_ARM_PCI_ADDRESS_MAP_INFO PciAddressMapInfo[PCI_ADDRESS_MA= P_COUNT]; + + // PCI device legacy interrupts mapping references + CM_ARM_OBJ_REF PciInterruptMapRef[PCI_INTERRUPT= _MAP_COUNT]; + + // PCI device legacy interrupts mapping information + CM_ARM_PCI_INTERRUPT_MAP_INFO PciInterruptMapInfo[PCI_INTERRUP= T_MAP_COUNT]; + /// GIC MSI Frame information CM_ARM_GIC_MSI_FRAME_INFO GicMsiFrameInfo; =20 diff --git a/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManag= erDxe/ConfigurationManagerDxe.inf b/Platform/ARM/JunoPkg/ConfigurationMan= ager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf index 7ca134d6674b..91bffe8d5d82 100644 --- a/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManagerDxe/C= onfigurationManagerDxe.inf +++ b/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManagerDxe/C= onfigurationManagerDxe.inf @@ -24,7 +24,6 @@ [Sources] ConfigurationManager.c AslTables/Dsdt.asl AslTables/SsdtJunoUsb.asl - AslTables/SsdtPci.asl =20 [Packages] ArmPkg/ArmPkg.dec --=20 2.25.1