public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Sami Mujawar" <sami.mujawar@arm.com>
To: <devel@edk2.groups.io>
Cc: Sami Mujawar <sami.mujawar@arm.com>, <ardb+tianocore@kernel.org>,
	<thomas.abraham@arm.com>, <leif@nuviainc.com>,
	<Matteo.Carlini@arm.com>, <Ben.Adderson@arm.com>, <nd@arm.com>
Subject: [PATCH edk2-platforms v1 06/12] Platform/ARM/VExpressPkg: ACPI support for FVP RevC model
Date: Fri, 12 Feb 2021 10:23:35 +0000	[thread overview]
Message-ID: <20210212102341.24056-7-sami.mujawar@arm.com> (raw)
In-Reply-To: <20210212102341.24056-1-sami.mujawar@arm.com>

Base Platform RevC is a configuration of the Base Platform that includes
a PCIe subsystem and a SMMUv3. It also has an AHCI-SATA disk controller
as a device on the PCIe bus.

To enable an OS to use these features add the following ACPI tables:
  - IORT
  - MCFG
  - SSDT PCIe

Also add checks such that these additional tables are only installed if
the FVP model is RevC. This allows a unified firmware for use with both
the FVP_Base_AEMv8A-AEMv8A model and the FVP_Base_RevC-2xAEMv8A model.

Note: The CPU affinities are shifted in the FVP_Base_RevC-2xAEMv8A model
and this is adjusted in InitializePlatformRepository().

Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
 Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtPci.asl       | 204 ++++++++++++
 Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.c      | 349 +++++++++++++++++++-
 Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h      |  30 +-
 Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf |  10 +-
 4 files changed, 588 insertions(+), 5 deletions(-)

diff --git a/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtPci.asl b/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtPci.asl
new file mode 100644
index 0000000000000000000000000000000000000000..e4b5a02cc9571743c4a0300a0657f090ae996326
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtPci.asl
@@ -0,0 +1,204 @@
+/** @file
+  SSDT for FVP PCIe
+
+  Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>
+
+  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-INTC, 3-INTD)  */  \
+    Link,     /* Interrupt allocated via Link device  */                                \
+    Zero      /* global system interrupt number (no used) */                            \
+}
+
+/*
+  See Reference [1] 6.1.1
+  "High word�Device #, Low word�Function #. (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 Bridge.
+
+DefinitionBlock ("SsdtPci.aml", "SSDT", 2, "ARMLTD", "FVP-REVC", 1) {
+  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
+
+      // 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 masked
+            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/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.c b/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.c
index 49aa16184a2da587471239a7c90ed864f963896c..273ae35ffcdae2fbe1214676a10f6a3ca04e4242 100644
--- a/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.c
+++ b/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.c
@@ -12,6 +12,8 @@
 
 #include <IndustryStandard/DebugPort2Table.h>
 #include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
+#include <IndustryStandard/IoRemappingTable.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
 #include <Library/ArmLib.h>
 #include <Library/DebugLib.h>
 #include <Library/IoLib.h>
@@ -74,7 +76,30 @@ EDKII_PLATFORM_REPOSITORY_INFO VExpressPlatRepositoryInfo = {
       EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,
       CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDbg2),
       NULL
-    }
+    },
+
+    // Note: The last 3 tables in this list are for FVP RevC only.
+    // IORT Table - FVP RevC
+    {
+      EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE,
+      EFI_ACPI_IO_REMAPPING_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdIort),
+      NULL
+    },
+    // PCI MCFG Table - FVP RevC
+    {
+      EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
+      EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMcfg),
+      NULL
+    },
+    // SSDT table describing the PCI root complex - FVP RevC
+    {
+      EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+      0, // Unused
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdt),
+      (EFI_ACPI_DESCRIPTION_HEADER*)ssdtpci_aml_code
+    },
   },
 
   // Boot architecture information
@@ -90,6 +115,8 @@ EDKII_PLATFORM_REPOSITORY_INFO VExpressPlatRepositoryInfo = {
 
   /* GIC CPU Interface information
      GIC_ENTRY (CPUInterfaceNumber, Mpidr, PmuIrq, VGicIrq, EnergyEfficiency)
+     Note: The MPIDR is fixed up in InitializePlatformRepository() if the
+           platform is FVP RevC.
   */
   {
     GICC_ENTRY (0, GET_MPID (0, 0), 92, 25, 0),
@@ -215,7 +242,121 @@ EDKII_PLATFORM_REPOSITORY_INFO VExpressPlatRepositoryInfo = {
     0,
     // The physical address for the Interrupt Translation Service
     0x2f020000
-  }
+  },
+
+  // SMMUv3 Node
+  {
+    // Reference token for this Iort node
+    REFERENCE_TOKEN (SmmuV3Info),
+    // Number of ID mappings
+    1,
+    // Reference token for the ID mapping array
+    REFERENCE_TOKEN (DeviceIdMapping[0]),
+
+    // SMMU Base Address
+    FVP_REVC_SMMUV3_BASE,
+    // SMMU flags
+    EFI_ACPI_IORT_SMMUv3_FLAG_COHAC_OVERRIDE,
+    // VATOS address
+    0,
+    // Model
+    EFI_ACPI_IORT_SMMUv3_MODEL_GENERIC,
+    // GSIV of the Event interrupt if SPI based
+    0x6A,
+    // PRI Interrupt if SPI based
+    0x6B,
+    // GERR interrupt if GSIV based
+    0x6F,
+    // Sync interrupt if GSIV based
+    0x6D,
+
+    // Proximity domain flag, ignored in this case
+    0,
+    // Index into the array of ID mapping, ignored as SMMU
+    // control interrupts are GSIV based
+    0
+  },
+
+  // ITS group node
+  {
+    // Reference token for this Iort node
+    REFERENCE_TOKEN (ItsGroupInfo),
+    // The number of ITS identifiers in the ITS node.
+    1,
+    // Reference token for the ITS identifier array
+    REFERENCE_TOKEN (ItsIdentifierArray)
+  },
+  // ITS identifier array
+  {
+    {
+      // The ITS Identifier
+      0
+    }
+  },
+
+  // Root Complex node info
+  {
+    // Reference token for this Iort node
+    REFERENCE_TOKEN (RootComplexInfo),
+    // Number of ID mappings
+    1,
+    // Reference token for the ID mapping array
+    REFERENCE_TOKEN (DeviceIdMapping[1]),
+
+    // Memory access properties : Cache coherent attributes
+    EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA,
+    // Memory access properties : Allocation hints
+    0,
+    // Memory access properties : Memory access flags
+    0,
+    // ATS attributes
+    EFI_ACPI_IORT_ROOT_COMPLEX_ATS_UNSUPPORTED,
+    // PCI segment number
+    0
+  },
+
+  // Array of Device ID mappings
+  {
+    /* Mapping When SMMUv3 is defined
+       RootComplex -> SMMUv3 -> ITS Group
+    */
+
+    // SMMUv3 device ID mapping
+    {
+      // Input base
+      0x0,
+      // Number of input IDs
+      0x0000FFFF,
+      // Output Base
+      0x0,
+      // Output reference
+      REFERENCE_TOKEN (ItsGroupInfo),
+      // Flags
+      0
+    },
+    // Device ID mapping for Root complex node
+    {
+      // Input base
+      0x0,
+      // Number of input IDs
+      0x0000FFFF,
+      // Output Base
+      0x0,
+      // Output reference token for the IORT node
+      REFERENCE_TOKEN (SmmuV3Info),
+      // Flags
+      0
+    }
+  },
+
+  // PCI Configuration Space Info
+  {
+    FixedPcdGet64 (PcdPciExpressBaseAddress),
+    // PciSegmentGroupNumber
+    0,
+    FixedPcdGet32 (PcdPciBusMin),
+    FixedPcdGet32 (PcdPciBusMax)
+  },
 };
 
 /** A helper function for returning the Configuration Manager Objects.
@@ -324,6 +465,24 @@ InitializePlatformRepository (
   IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST This
   )
 {
+  EDKII_PLATFORM_REPOSITORY_INFO  * PlatformRepo;
+
+  PlatformRepo = This->PlatRepoInfo;
+
+  PlatformRepo->SysId = MmioRead32 (ARM_VE_SYS_ID_REG);
+  if ((PlatformRepo->SysId & ARM_FVP_SYS_ID_REV_MASK) ==
+       ARM_FVP_BASE_REVC_REV) {
+    // REVC affinity is shifted, update the MPIDR
+    PlatformRepo->GicCInfo[0].MPIDR = GET_MPID_MT (0, 0, 0);
+    PlatformRepo->GicCInfo[1].MPIDR = GET_MPID_MT (0, 1, 0);
+    PlatformRepo->GicCInfo[2].MPIDR = GET_MPID_MT (0, 2, 0);
+    PlatformRepo->GicCInfo[3].MPIDR = GET_MPID_MT (0, 3, 0);
+
+    PlatformRepo->GicCInfo[4].MPIDR = GET_MPID_MT (1, 0, 0);
+    PlatformRepo->GicCInfo[5].MPIDR = GET_MPID_MT (1, 1, 0);
+    PlatformRepo->GicCInfo[6].MPIDR = GET_MPID_MT (1, 2, 0);
+    PlatformRepo->GicCInfo[7].MPIDR = GET_MPID_MT (1, 3, 0);
+  }
   return EFI_SUCCESS;
 }
 
@@ -370,6 +529,91 @@ GetGTBlockTimerFrameInfo (
   return EFI_SUCCESS;
 }
 
+/** Return an ITS identifier array.
+
+  @param [in]  This        Pointer to the Configuration Manager Protocol.
+  @param [in]  CmObjectId  The Configuration Manager Object ID.
+  @param [in]  Token       A token for identifying the object
+  @param [out] CmObject    Pointer to the Configuration Manager Object
+                           descriptor describing the requested Object.
+
+  @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
+GetItsIdentifierArray (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST This,
+  IN  CONST CM_OBJECT_ID                                  CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                               Token,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     * CONST CmObject
+  )
+{
+  EDKII_PLATFORM_REPOSITORY_INFO  * PlatformRepo;
+
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformRepo = This->PlatRepoInfo;
+
+  if (Token != (CM_OBJECT_TOKEN)&PlatformRepo->ItsIdentifierArray) {
+    return EFI_NOT_FOUND;
+  }
+
+  CmObject->ObjectId = CmObjectId;
+  CmObject->Size = sizeof (PlatformRepo->ItsIdentifierArray);
+  CmObject->Data = (VOID*)&PlatformRepo->ItsIdentifierArray;
+  CmObject->Count = ARRAY_SIZE (PlatformRepo->ItsIdentifierArray);
+  return EFI_SUCCESS;
+}
+
+/** Return a device Id mapping array.
+
+  @param [in]  This        Pointer to the Configuration Manager Protocol.
+  @param [in]  CmObjectId  The Configuration Manager Object ID.
+  @param [in]  Token       A token for identifying the object
+  @param [out] CmObject    Pointer to the Configuration Manager Object
+                           descriptor describing the requested Object.
+
+  @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
+GetDeviceIdMappingArray (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST This,
+  IN  CONST CM_OBJECT_ID                                  CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                               Token,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     * CONST CmObject
+  )
+{
+  EDKII_PLATFORM_REPOSITORY_INFO  * PlatformRepo;
+
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformRepo = This->PlatRepoInfo;
+
+  if ((Token != (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[0]) &&
+      (Token != (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[1])) {
+    return EFI_NOT_FOUND;
+  }
+
+  CmObject->ObjectId = CmObjectId;
+  CmObject->Size = sizeof (CM_ARM_ID_MAPPING);
+  CmObject->Data = (VOID*)Token;
+  CmObject->Count = 1;
+  return EFI_SUCCESS;
+}
+
 /** Return a standard namespace object.
 
   @param [in]      This        Pointer to the Configuration Manager Protocol.
@@ -394,7 +638,9 @@ GetStandardNameSpaceObject (
 {
   EFI_STATUS                      Status;
   EDKII_PLATFORM_REPOSITORY_INFO  * PlatformRepo;
+  UINTN                           AcpiTableCount;
 
+  Status = EFI_SUCCESS;
   if ((This == NULL) || (CmObject == NULL)) {
     ASSERT (This != NULL);
     ASSERT (CmObject != NULL);
@@ -402,8 +648,16 @@ GetStandardNameSpaceObject (
   }
 
   Status = EFI_NOT_FOUND;
+  AcpiTableCount = ARRAY_SIZE (PlatformRepo->CmAcpiTableList);
   PlatformRepo = This->PlatRepoInfo;
 
+  if ((PlatformRepo->SysId & ARM_FVP_SYS_ID_REV_MASK) !=
+       ARM_FVP_BASE_REVC_REV) {
+    // The last 3 tables in the ACPI table list are for FVP RevC
+    // Reduce the count by 3 if the platform is not FVP RevC
+    AcpiTableCount -= 3;
+  }
+
   switch (GET_CM_OBJECT_ID (CmObjectId)) {
     case EStdObjCfgMgrInfo:
       Status = HandleCmObject (
@@ -420,7 +674,7 @@ GetStandardNameSpaceObject (
                  CmObjectId,
                  &PlatformRepo->CmAcpiTableList,
                  sizeof (PlatformRepo->CmAcpiTableList),
-                 ARRAY_SIZE (PlatformRepo->CmAcpiTableList),
+                 AcpiTableCount,
                  CmObject
                  );
       break;
@@ -464,6 +718,12 @@ GetArmNameSpaceObject (
 {
   EFI_STATUS                        Status;
   EDKII_PLATFORM_REPOSITORY_INFO  * PlatformRepo;
+  UINTN                             Smmuv3Count;
+  UINTN                             ItsGroupCount;
+  UINTN                             ItsIdentifierArrayCount;
+  UINTN                             RootComplexCount;
+  UINTN                             DeviceIdMappingArrayCount;
+  UINTN                             PciConfigSpaceCount;
 
   if ((This == NULL) || (CmObject == NULL)) {
     ASSERT (This != NULL);
@@ -474,6 +734,23 @@ GetArmNameSpaceObject (
   Status = EFI_NOT_FOUND;
   PlatformRepo = This->PlatRepoInfo;
 
+  if ((PlatformRepo->SysId & ARM_FVP_SYS_ID_REV_MASK) ==
+       ARM_FVP_BASE_REVC_REV) {
+    Smmuv3Count = 1;
+    ItsGroupCount = 1;
+    ItsIdentifierArrayCount = ARRAY_SIZE (PlatformRepo->ItsIdentifierArray);
+    RootComplexCount = 1;
+    DeviceIdMappingArrayCount = ARRAY_SIZE (PlatformRepo->DeviceIdMapping);
+    PciConfigSpaceCount = 1;
+  } else {
+    Smmuv3Count = 0;
+    ItsGroupCount = 0;
+    ItsIdentifierArrayCount = 0;
+    RootComplexCount = 0;
+    DeviceIdMappingArrayCount = 0;
+    PciConfigSpaceCount = 0;
+  }
+
   switch (GET_CM_OBJECT_ID (CmObjectId)) {
     case EArmObjBootArchInfo:
       Status = HandleCmObject (
@@ -609,6 +886,72 @@ GetArmNameSpaceObject (
                  );
       break;
 
+    case EArmObjSmmuV3:
+      Status = HandleCmObject (
+                 CmObjectId,
+                 &PlatformRepo->SmmuV3Info,
+                 sizeof (PlatformRepo->SmmuV3Info),
+                 Smmuv3Count,
+                 CmObject
+                 );
+      break;
+
+    case EArmObjItsGroup:
+      Status = HandleCmObject (
+                 CmObjectId,
+                 &PlatformRepo->ItsGroupInfo,
+                 sizeof (PlatformRepo->ItsGroupInfo),
+                 ItsGroupCount,
+                 CmObject
+                 );
+      break;
+
+    case EArmObjGicItsIdentifierArray:
+      Status = HandleCmObjectRefByToken (
+                 This,
+                 CmObjectId,
+                 PlatformRepo->ItsIdentifierArray,
+                 sizeof (PlatformRepo->ItsIdentifierArray),
+                 ItsIdentifierArrayCount,
+                 Token,
+                 GetItsIdentifierArray,
+                 CmObject
+                 );
+      break;
+
+    case EArmObjRootComplex:
+      Status = HandleCmObject (
+                 CmObjectId,
+                 &PlatformRepo->RootComplexInfo,
+                 sizeof (PlatformRepo->RootComplexInfo),
+                 1,
+                 CmObject
+                 );
+      break;
+
+    case EArmObjIdMappingArray:
+      Status = HandleCmObjectRefByToken (
+                 This,
+                 CmObjectId,
+                 PlatformRepo->DeviceIdMapping,
+                 sizeof (PlatformRepo->DeviceIdMapping),
+                 ARRAY_SIZE (PlatformRepo->DeviceIdMapping),
+                 Token,
+                 GetDeviceIdMappingArray,
+                 CmObject
+                 );
+      break;
+
+    case EArmObjPciConfigSpaceInfo:
+      Status = HandleCmObject (
+                 CmObjectId,
+                 &PlatformRepo->PciConfigInfo,
+                 sizeof (PlatformRepo->PciConfigInfo),
+                 PciConfigSpaceCount,
+                 CmObject
+                 );
+      break;
+
     default: {
       Status = EFI_NOT_FOUND;
       DEBUG ((
diff --git a/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h b/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h
index c21f160dd082bddb9e8e1ab666143887d67869cd..aebf0a355291df5df5f588e8b7076e21eda9a152 100644
--- a/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h
+++ b/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h
@@ -17,6 +17,7 @@
     containing the AML bytecode array.
 */
 extern CHAR8  dsdt_aml_code[];
+extern CHAR8  ssdtpci_aml_code[];
 
 /** The configuration manager version.
 */
@@ -77,13 +78,18 @@ typedef EFI_STATUS (*CM_OBJECT_HANDLER_PROC) (
           (CM_OBJECT_TOKEN)((UINT8*)&VExpressPlatRepositoryInfo + \
            OFFSET_OF (EDKII_PLATFORM_REPOSITORY_INFO, Field))
 
+/** Macro to return MPIDR for Multi Threaded Cores
+*/
+#define GET_MPID_MT(Cluster, Core, Thread)                        \
+          (((Cluster) << 16) | ((Core) << 8) | (Thread))
+
 /** The number of CPUs
 */
 #define PLAT_CPU_COUNT              8
 
 /** The number of ACPI tables to install
 */
-#define PLAT_ACPI_TABLE_COUNT       6
+#define PLAT_ACPI_TABLE_COUNT       9
 
 /** The number of platform generic timer blocks
 */
@@ -145,6 +151,28 @@ typedef struct PlatformRepositoryInfo {
 
   /// GIC ITS information
   CM_ARM_GIC_ITS_INFO                   GicItsInfo;
+
+  // FVP RevC components
+  /// SMMUv3 node
+  CM_ARM_SMMUV3_NODE                    SmmuV3Info;
+
+  /// ITS Group node
+  CM_ARM_ITS_GROUP_NODE                 ItsGroupInfo;
+
+  /// ITS Identifier array
+  CM_ARM_ITS_IDENTIFIER                 ItsIdentifierArray[1];
+
+  /// PCI Root complex node
+  CM_ARM_ROOT_COMPLEX_NODE              RootComplexInfo;
+
+  /// Array of DeviceID mapping
+  CM_ARM_ID_MAPPING                     DeviceIdMapping[2];
+
+  /// PCI configuration space information
+  CM_ARM_PCI_CONFIG_SPACE_INFO          PciConfigInfo;
+
+  /// System ID
+  UINT32                                SysId;
 } EDKII_PLATFORM_REPOSITORY_INFO;
 
 #endif // CONFIGURATION_MANAGER_H__
diff --git a/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf b/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf
index c17595b7ec37cdd1c99b258cd32d1bde6c76a5ed..b53daf51d4b1afd45e41d0debb0b9f084f135f6a 100644
--- a/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf
+++ b/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf
@@ -1,7 +1,7 @@
 ## @file
 #  Configuration Manager Dxe
 #
-#  Copyright (c) 2017 - 2020, Arm Limited. All rights reserved.<BR>
+#  Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 ##
@@ -23,6 +23,7 @@ [Defines]
 [Sources]
   ConfigurationManager.c
   AslTables/Dsdt.asl
+  AslTables/SsdtPci.asl
 
 [Packages]
   ArmPkg/ArmPkg.dec
@@ -68,6 +69,13 @@ [FixedPcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
   gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
 
+  # PCI Root complex specific PCDs
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseSize
+
+  gArmTokenSpaceGuid.PcdPciBusMin
+  gArmTokenSpaceGuid.PcdPciBusMax
+
 [Pcd]
 
 [Depex]
-- 
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'


  parent reply	other threads:[~2021-02-12 10:26 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-12 10:23 [PATCH edk2-platforms v1 00/12] Platform/ARM: Add support for FVP RevC Model Sami Mujawar
2021-02-12 10:23 ` [PATCH edk2-platforms v1 01/12] Platform/ARM/VExpressPkg: FVP RevC SysID.Rev defintion Sami Mujawar
2021-02-12 10:23 ` [PATCH edk2-platforms v1 02/12] Platform/ARM/VExpressPkg: Add PCIe Host Bridge lib for FVP Sami Mujawar
2021-02-12 10:23 ` [PATCH edk2-platforms v1 03/12] Platform/ARM/VExpressPkg: Memory map for FVP RevC model Sami Mujawar
2021-02-12 10:23 ` [PATCH edk2-platforms v1 04/12] Platform/ARM/VExpressPkg: Configure SMMUv3 for FVP RevC Sami Mujawar
2021-02-12 10:23 ` [PATCH edk2-platforms v1 05/12] Platform/ARM/VExpressPkg: Helper macro to map reference token Sami Mujawar
2021-02-12 10:23 ` Sami Mujawar [this message]
2021-02-12 10:23 ` [PATCH edk2-platforms v1 07/12] Platform/ARM/VExpressPkg: Add support for FVP RevC model Sami Mujawar
2021-02-12 10:23 ` [PATCH edk2-platforms v1 08/12] Platform/ARM/VExpressPkg: Update ACPI Revision to 6.3 Sami Mujawar
2021-02-12 10:23 ` [PATCH edk2-platforms v1 09/12] Platform/ARM/VExpressPkg: Add SMC91x device description Sami Mujawar
2021-02-12 10:23 ` [PATCH edk2-platforms v1 10/12] Platform/ARM/VExpressPkg: Add Virtio Block Device description Sami Mujawar
2021-02-12 10:23 ` [PATCH edk2-platforms v1 11/12] Platform/ARM/VExpressPkg: Make Dynamic Tables Framework default Sami Mujawar
2021-02-12 10:23 ` [PATCH edk2-platforms v1 12/12] Platform/ARM/VExpressPkg: Remove redundant traditional ACPI support Sami Mujawar
2021-02-13 10:26 ` [PATCH edk2-platforms v1 00/12] Platform/ARM: Add support for FVP RevC Model Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210212102341.24056-7-sami.mujawar@arm.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox