public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-platforms][PATCH V1 00/11] Add Support for Morello SoC
@ 2021-12-04 12:30 chandni cherukuri
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 01/11] Platform/ARM/Morello: Rename PlatformLib.inf file chandni cherukuri
                   ` (10 more replies)
  0 siblings, 11 replies; 31+ messages in thread
From: chandni cherukuri @ 2021-12-04 12:30 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Chandni Cherukuri

This patch series add support for Morello SoC platform. The folder
Platform/ARM/Morello is going to contain both Morello FVP and Morello
SoC platforms.

This patch series also contain the patches which are necessary for
the modified boot flow of the platforms.

The changes can be seen at:
https://github.com/chandnich/edk2-platforms/tree/morello_soc_v1

Anurag Koul (4):
  Platform/ARM/Morello: Port PCI Segment Library
  Platform/ARM/Morello: Port PCI Express library
  Platform/ARM/Morello: Enable PCIe and CCIX Root Ports
  Platform/ARM/Morello: Add ACPI bindings for PCIe & CCIX

Chandni Cherukuri (6):
  Platform/ARM/Morello: Rename PlatformLib.inf file
  Platform/ARM/Morello: Add Platform Library support for Morello SoC
  Platform/ARM/Morello: Add PlatformDxe for Morello SoC
  Platform/ARM/Morello: Add ConfigurationManager for Morello SoC
  Platform/ARM/Morello: Add initial support for Morello SoC
  Platform/ARM/Morello: Update Readme.md

sah01 (1):
  Platform/ARM/Morello: Add support to parse NT_FW_CONFIG

 Platform/ARM/Morello/MorelloPlatform.dec      |   51 +-
 .../ConfigurationManagerSoc.dsc.inc           |   16 +
 Platform/ARM/Morello/MorelloPlatform.dsc.inc  |   14 +-
 Platform/ARM/Morello/MorelloPlatformFvp.dsc   |   23 +-
 ...PlatformFvp.dsc => MorelloPlatformSoc.dsc} |   59 +-
 Platform/ARM/Morello/MorelloPlatformSoc.fdf   |  312 ++++
 .../ConfigurationManagerDxeSoc.inf            |  107 ++
 .../Drivers/PlatformDxe/PlatformDxeSoc.inf    |   43 +
 .../Library/PciExpressLib/PciExpressLib.inf   |   49 +
 .../PciHostBridgeLib/PciHostBridgeLibSoc.inf  |   57 +
 .../Library/PciSegmentLib/PciSegmentLib.inf   |   30 +
 .../{PlatformLib.inf => PlatformLibFvp.inf}   |   10 +-
 .../{PlatformLib.inf => PlatformLibSoc.inf}   |   22 +-
 .../ConfigurationManagerSoc.h                 |  119 ++
 .../ARM/Morello/Include/MorelloPlatform.h     |   18 +-
 .../ConfigurationManagerSoc.c                 |  755 +++++++++
 .../Drivers/PlatformDxe/PlatformDxeSoc.c      |   67 +
 .../Library/PciExpressLib/PciExpressLib.c     | 1431 +++++++++++++++++
 .../PciHostBridgeLib/PciHostBridgeLibSoc.c    |  247 +++
 .../Library/PciSegmentLib/PciSegmentLib.c     | 1405 ++++++++++++++++
 .../Morello/Library/PlatformLib/PlatformLib.c |    9 +
 .../{PlatformLibMem.c => PlatformLibMemFvp.c} |   74 +-
 .../Library/PlatformLib/PlatformLibMemSoc.c   |  333 ++++
 .../AslTables/DsdtSoc.asl                     |   41 +
 .../AslTables/SsdtPciSoc.asl                  |  223 +++
 .../Library/PciExpressLib/PciExpressLib.uni   |   18 +
 .../Library/PlatformLib/AArch64/Helper.S      |    2 +
 Platform/ARM/Morello/Readme.md                |   12 +-
 28 files changed, 5478 insertions(+), 69 deletions(-)
 create mode 100644 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
 copy Platform/ARM/Morello/{MorelloPlatformFvp.dsc => MorelloPlatformSoc.dsc} (50%)
 create mode 100644 Platform/ARM/Morello/MorelloPlatformSoc.fdf
 create mode 100644 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
 create mode 100644 Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf
 create mode 100644 Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf
 create mode 100644 Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.inf
 create mode 100644 Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.inf
 copy Platform/ARM/Morello/Library/PlatformLib/{PlatformLib.inf => PlatformLibFvp.inf} (84%)
 rename Platform/ARM/Morello/Library/PlatformLib/{PlatformLib.inf => PlatformLibSoc.inf} (64%)
 create mode 100644 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
 create mode 100644 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
 create mode 100644 Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.c
 create mode 100644 Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.c
 create mode 100644 Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.c
 create mode 100644 Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.c
 rename Platform/ARM/Morello/Library/PlatformLib/{PlatformLibMem.c => PlatformLibMemFvp.c} (77%)
 create mode 100644 Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
 create mode 100644 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl
 create mode 100644 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtPciSoc.asl
 create mode 100644 Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.uni

-- 
2.17.1


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [edk2-platforms][PATCH V1 01/11] Platform/ARM/Morello: Rename PlatformLib.inf file
  2021-12-04 12:30 [edk2-platforms][PATCH V1 00/11] Add Support for Morello SoC chandni cherukuri
@ 2021-12-04 12:30 ` chandni cherukuri
  2021-12-07 20:44   ` Sami Mujawar
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 02/11] Platform/ARM/Morello: Add Platform Library support for Morello SoC chandni cherukuri
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: chandni cherukuri @ 2021-12-04 12:30 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Chandni Cherukuri

PlatformLibMem.c file is going to be different for Morello
FVP and Morello SoC platforms since the virtual memory mapping
is different so the file PlatformLibMem.c is renamed as
PlatformLibMemFvp.c and PlatformLib.inf is renamed as
PlatformLibFvp.inf.

Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
---
 Platform/ARM/Morello/Library/PlatformLib/{PlatformLib.inf => PlatformLibFvp.inf}   | 4 ++--
 Platform/ARM/Morello/Library/PlatformLib/{PlatformLibMem.c => PlatformLibMemFvp.c} | 0
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLib.inf b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf
similarity index 91%
rename from Platform/ARM/Morello/Library/PlatformLib/PlatformLib.inf
rename to Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf
index c2d7da3701d2..d4c8744c0954 100644
--- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLib.inf
+++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf
@@ -1,5 +1,5 @@
 ## @file
-#  Platform Library for Morello platform.
+#  Platform Library for Morello FVP platform.
 #
 #  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
 #
@@ -24,7 +24,7 @@
 
 [Sources.common]
   PlatformLib.c
-  PlatformLibMem.c
+  PlatformLibMemFvp.c
 
 [Sources.AARCH64]
   AArch64/Helper.S | GCC
diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMem.c b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemFvp.c
similarity index 100%
rename from Platform/ARM/Morello/Library/PlatformLib/PlatformLibMem.c
rename to Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemFvp.c
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [edk2-platforms][PATCH V1 02/11] Platform/ARM/Morello: Add Platform Library support for Morello SoC
  2021-12-04 12:30 [edk2-platforms][PATCH V1 00/11] Add Support for Morello SoC chandni cherukuri
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 01/11] Platform/ARM/Morello: Rename PlatformLib.inf file chandni cherukuri
@ 2021-12-04 12:30 ` chandni cherukuri
  2021-12-07 20:44   ` Sami Mujawar
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 03/11] Platform/ARM/Morello: Add PlatformDxe " chandni cherukuri
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: chandni cherukuri @ 2021-12-04 12:30 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Chandni Cherukuri

It includes virutal memory map for Morello SoC platform.

Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
---
 Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf  |  44 +++++
 Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c | 176 ++++++++++++++++++++
 2 files changed, 220 insertions(+)

diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
new file mode 100644
index 000000000000..bc31b8709152
--- /dev/null
+++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
@@ -0,0 +1,44 @@
+## @file
+#  Platform Library for Morello SoC platform.
+#
+#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = ArmMorelloLib
+  FILE_GUID                      = 7858ED56-9716-454F-90D7-D117B05063EA
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmPlatformLib
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Platform/ARM/Morello/MorelloPlatform.dec
+
+[Sources.common]
+  PlatformLib.c
+  PlatformLibMemSoc.c
+
+[Sources.AARCH64]
+  AArch64/Helper.S | GCC
+
+[FixedPcd]
+  gArmMorelloTokenSpaceGuid.PcdDramBlock2Base
+
+  gArmTokenSpaceGuid.PcdArmPrimaryCore
+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+
+[Guids]
+  gEfiHobListGuid          ## CONSUMES  ## SystemTable
+
+[Ppis]
+  gArmMpCoreInfoPpiGuid
diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
new file mode 100644
index 000000000000..67dd8469feb8
--- /dev/null
+++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
@@ -0,0 +1,176 @@
+/** @file
+
+  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <MorelloPlatform.h>
+
+// The total number of descriptors, including the final "end-of-table" descriptor.
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS  9
+
+#if !defined (MDEPKG_NDEBUG)
+  STATIC CONST CHAR8  *gTblAttrDesc[] = {
+    "UNCACHED_UNBUFFERED          ",
+    "NONSECURE_UNCACHED_UNBUFFERED",
+    "WRITE_BACK                   ",
+    "NONSECURE_WRITE_BACK         ",
+    "WB_NONSHAREABLE              ",
+    "NONSECURE_WB_NONSHAREABLE    ",
+    "WRITE_THROUGH                ",
+    "NONSECURE_WRITE_THROUGH      ",
+    "DEVICE                       ",
+    "NONSECURE_DEVICE             "
+  };
+#endif
+
+#define LOG_MEM(desc)  DEBUG ((                                             \
+                        DEBUG_ERROR,                                        \
+                        desc,                                               \
+                        VirtualMemoryTable[Index].PhysicalBase,             \
+                        (VirtualMemoryTable[Index].PhysicalBase +           \
+                         VirtualMemoryTable[Index].Length - 1),             \
+                        VirtualMemoryTable[Index].Length,                   \
+                        gTblAttrDesc[VirtualMemoryTable[Index].Attributes]  \
+                        ));
+
+/**
+  Returns the Virtual Memory Map of the platform.
+
+  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU
+  on your platform.
+
+  @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing
+                               a Physical-to-Virtual Memory mapping. This array
+                               must be ended by a zero-filled entry.
+**/
+VOID
+ArmPlatformGetVirtualMemoryMap (
+  OUT ARM_MEMORY_REGION_DESCRIPTOR **VirtualMemoryMap
+  )
+{
+  UINTN                         Index;
+  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
+  EFI_RESOURCE_ATTRIBUTE_TYPE   ResourceAttributes;
+  MORELLO_PLAT_INFO             *PlatInfo;
+  UINT64                        DramBlock2Size;
+
+  Index = 0;
+  DramBlock2Size = 0;
+
+  PlatInfo = (MORELLO_PLAT_INFO *)MORELLO_PLAT_INFO_STRUCT_BASE;
+  if (PlatInfo->LocalDdrSize > MORELLO_DRAM_BLOCK1_SIZE) {
+    DramBlock2Size = PlatInfo->LocalDdrSize - MORELLO_DRAM_BLOCK1_SIZE;
+  }
+
+  if (DramBlock2Size != 0) {
+    ResourceAttributes =
+      EFI_RESOURCE_ATTRIBUTE_PRESENT |
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_TESTED;
+
+    BuildResourceDescriptorHob (
+      EFI_RESOURCE_SYSTEM_MEMORY,
+      ResourceAttributes,
+      FixedPcdGet64 (PcdDramBlock2Base),
+      DramBlock2Size
+      );
+  }
+
+  ASSERT (VirtualMemoryMap != NULL);
+
+  VirtualMemoryTable = AllocatePool (
+                         sizeof (ARM_MEMORY_REGION_DESCRIPTOR) *
+                         MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS
+                         );
+  if (VirtualMemoryTable == NULL) {
+    return;
+  }
+
+  DEBUG ((
+    DEBUG_ERROR,
+    " Memory Map\n----------------------------------------------------------\n"
+    ));
+  DEBUG ((
+    DEBUG_ERROR,
+    "Description                     :        START       -        END         " \
+    "[        SIZE        ] {              ATTR             }\n"
+    ));
+
+  // SubSystem Peripherals - Generic Watchdog
+  VirtualMemoryTable[Index].PhysicalBase = MORELLO_GENERIC_WDOG_BASE;
+  VirtualMemoryTable[Index].VirtualBase  = MORELLO_GENERIC_WDOG_BASE;
+  VirtualMemoryTable[Index].Length     = MORELLO_GENERIC_WDOG_SZ;
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  LOG_MEM ("Generic Watchdog                : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+  // SubSystem Peripherals - GIC-600
+  VirtualMemoryTable[++Index].PhysicalBase = MORELLO_GIC_BASE;
+  VirtualMemoryTable[Index].VirtualBase    = MORELLO_GIC_BASE;
+  VirtualMemoryTable[Index].Length     = MORELLO_GIC_SZ;
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  LOG_MEM ("GIC-600                         : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+  // SubSystem Peripherals - GICR-600
+  VirtualMemoryTable[++Index].PhysicalBase = MORELLO_GICR_BASE;
+  VirtualMemoryTable[Index].VirtualBase    = MORELLO_GICR_BASE;
+  VirtualMemoryTable[Index].Length     = MORELLO_GICR_SZ;
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  LOG_MEM ("GICR-600                        : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+  // SubSystem non-secure SRAM
+  VirtualMemoryTable[++Index].PhysicalBase = MORELLO_NON_SECURE_SRAM_BASE;
+  VirtualMemoryTable[Index].VirtualBase    = MORELLO_NON_SECURE_SRAM_BASE;
+  VirtualMemoryTable[Index].Length     = MORELLO_NON_SECURE_SRAM_SZ;
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;
+  LOG_MEM ("non-secure SRAM                 : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+  // SubSystem Pheripherals - UART0
+  VirtualMemoryTable[++Index].PhysicalBase = MORELLO_UART0_BASE;
+  VirtualMemoryTable[Index].VirtualBase    = MORELLO_UART0_BASE;
+  VirtualMemoryTable[Index].Length     = MORELLO_UART0_SZ;
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  LOG_MEM ("UART0                           : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+  // DDR Primary
+  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[Index].VirtualBase    = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[Index].Length     = PcdGet64 (PcdSystemMemorySize);
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;
+  LOG_MEM ("DDR Primary                     : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+  // DDR Secondary
+  if (DramBlock2Size != 0) {
+    VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdDramBlock2Base);
+    VirtualMemoryTable[Index].VirtualBase    = PcdGet64 (PcdDramBlock2Base);
+    VirtualMemoryTable[Index].Length     = DramBlock2Size;
+    VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;
+    LOG_MEM ("DDR Secondary                   : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+  }
+
+  // Expansion Peripherals
+  VirtualMemoryTable[++Index].PhysicalBase = MORELLO_EXP_PERIPH_BASE;
+  VirtualMemoryTable[Index].VirtualBase    = MORELLO_EXP_PERIPH_BASE;
+  VirtualMemoryTable[Index].Length     = MORELLO_EXP_PERIPH_BASE_SZ;
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  LOG_MEM ("Expansion Peripherals           : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+  // End of Table
+  VirtualMemoryTable[++Index].PhysicalBase = 0;
+  VirtualMemoryTable[Index].VirtualBase    = 0;
+  VirtualMemoryTable[Index].Length     = 0;
+  VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0;
+
+  ASSERT ((Index) < MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
+  DEBUG ((DEBUG_INIT, "Virtual Memory Table setup complete.\n"));
+
+  *VirtualMemoryMap = VirtualMemoryTable;
+}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [edk2-platforms][PATCH V1 03/11] Platform/ARM/Morello: Add PlatformDxe for Morello SoC
  2021-12-04 12:30 [edk2-platforms][PATCH V1 00/11] Add Support for Morello SoC chandni cherukuri
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 01/11] Platform/ARM/Morello: Rename PlatformLib.inf file chandni cherukuri
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 02/11] Platform/ARM/Morello: Add Platform Library support for Morello SoC chandni cherukuri
@ 2021-12-04 12:30 ` chandni cherukuri
  2021-12-07 20:44   ` Sami Mujawar
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 04/11] Platform/ARM/Morello: Add ConfigurationManager " chandni cherukuri
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: chandni cherukuri @ 2021-12-04 12:30 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Chandni Cherukuri

This patch adds PlatformDxe support for Morello SoC platform.
It includes the registration of ramdisk device.

Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
---
 Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf | 43 +++++++++++++
 Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.c   | 67 ++++++++++++++++++++
 2 files changed, 110 insertions(+)

diff --git a/Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf b/Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf
new file mode 100644
index 000000000000..a5d8ac36a3f2
--- /dev/null
+++ b/Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf
@@ -0,0 +1,43 @@
+## @file
+#  Platform DXE driver for Morello SoC Platform
+#
+#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = PlatformDxe
+  FILE_GUID                      = D75DB98F-5750-47C8-A46F-3140965537FC
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = ArmMorelloEntryPoint
+
+[Sources.common]
+  PlatformDxeSoc.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  Platform/ARM/Morello/MorelloPlatform.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEfiRamDiskProtocolGuid
+
+[FeaturePcd]
+  gArmMorelloTokenSpaceGuid.PcdRamDiskSupported
+
+[FixedPcd]
+  gArmMorelloTokenSpaceGuid.PcdRamDiskBase
+  gArmMorelloTokenSpaceGuid.PcdRamDiskSize
+
+[Depex]
+  gEfiRamDiskProtocolGuid
+
+[Guids]
+  gEfiVirtualCdGuid      ## SOMETIMES_CONSUMES   ## GUID
diff --git a/Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.c b/Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.c
new file mode 100644
index 000000000000..358c80acc7ee
--- /dev/null
+++ b/Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.c
@@ -0,0 +1,67 @@
+/** @file
+
+  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/RamDisk.h>
+
+/**
+  Entrypoint of Platform Dxe Driver
+
+  @param  ImageHandle[in]       The firmware allocated handle for the EFI image.
+  @param  SystemTable[in]       A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS           The entry point is executed successfully.
+**/
+EFI_STATUS
+EFIAPI
+ArmMorelloEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS                Status;
+  EFI_RAM_DISK_PROTOCOL     *RamDisk;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+
+  Status = EFI_SUCCESS;
+
+  if (FeaturePcdGet (PcdRamDiskSupported)) {
+    Status = gBS->LocateProtocol (
+                    &gEfiRamDiskProtocolGuid,
+                    NULL,
+                    (VOID **)&RamDisk
+                    );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "Couldn't find the RAM Disk protocol %r\n",
+        __FUNCTION__,
+        Status
+        ));
+      return Status;
+    }
+
+    Status = RamDisk->Register (
+                        (UINTN)PcdGet32 (PcdRamDiskBase),
+                        (UINTN)PcdGet32 (PcdRamDiskSize),
+                        &gEfiVirtualCdGuid,
+                        NULL,
+                        &DevicePath
+                        );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "%a: Failed to register RAM Disk - %r\n",
+        __FUNCTION__,
+        Status
+        ));
+    }
+  }
+
+  return Status;
+}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [edk2-platforms][PATCH V1 04/11] Platform/ARM/Morello: Add ConfigurationManager for Morello SoC
  2021-12-04 12:30 [edk2-platforms][PATCH V1 00/11] Add Support for Morello SoC chandni cherukuri
                   ` (2 preceding siblings ...)
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 03/11] Platform/ARM/Morello: Add PlatformDxe " chandni cherukuri
@ 2021-12-04 12:30 ` chandni cherukuri
  2021-12-07 20:51   ` Sami Mujawar
  2021-12-08  3:02   ` Khasim Mohammed
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 05/11] Platform/ARM/Morello: Add initial support " chandni cherukuri
                   ` (6 subsequent siblings)
  10 siblings, 2 replies; 31+ messages in thread
From: chandni cherukuri @ 2021-12-04 12:30 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Chandni Cherukuri

This patch implements the configuration manager for Morello
SoC platform. It enables support for generating the following
ACPI tables for Morello SoC Platform:
               1. FADT
               2. DSDT
               3. GTDT
               4. MADT
               5. SPCR
               6. DBG2
               7. PPTT

Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
---
 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc                        |  16 ++
 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf |  72 +++++++++
 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h      |  97 ++++++++++++
 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c      | 161 ++++++++++++++++++++
 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl          |  41 +++++
 5 files changed, 387 insertions(+)

diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
new file mode 100644
index 000000000000..f7e58185696e
--- /dev/null
+++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
@@ -0,0 +1,16 @@
+## @file
+#  dsc include file for Configuration Manager
+#
+#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+
+[BuildOptions]
+
+[Components.common]
+  # Configuration Manager
+  Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
new file mode 100644
index 000000000000..6f9199a6fda2
--- /dev/null
+++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
@@ -0,0 +1,72 @@
+## @file
+#  Configuration Manager Dxe
+#
+#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = ConfigurationManagerDxe
+  FILE_GUID                      = BF8FBCEE-AD95-466B-9185-50A1BB651DDA
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = ConfigurationManagerDxeInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = AARCH64
+#
+
+[Sources]
+  AslTables/DsdtSoc.asl
+  ConfigurationManager.c
+  ConfigurationManager.h
+  ConfigurationManagerSoc.c
+  ConfigurationManagerSoc.h
+  Platform.h
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  DynamicTablesPkg/DynamicTablesPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Platform/ARM/Morello/MorelloPlatform.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEdkiiConfigurationManagerProtocolGuid
+
+[FixedPcd]
+  ## PL011 Serial Debug UART
+  gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
+  gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate
+  gArmPlatformTokenSpaceGuid.PcdSerialDbgUartClkInHz
+
+  gArmPlatformTokenSpaceGuid.PL011UartClkInHz
+  gArmPlatformTokenSpaceGuid.PL011UartInterrupt
+
+  gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum
+  gArmTokenSpaceGuid.PcdArmArchTimerIntrNum
+  gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum
+  gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum
+
+  # SBSA Generic Watchdog
+  gArmTokenSpaceGuid.PcdGenericWatchdogControlBase
+  gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum
+  gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase
+
+  gArmTokenSpaceGuid.PcdGicDistributorBase
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
+  gArmTokenSpaceGuid.PcdGicRedistributorsBase
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+
+[Depex]
+  TRUE
diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
new file mode 100644
index 000000000000..8a521b83c8dc
--- /dev/null
+++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
@@ -0,0 +1,97 @@
+/** @file
+
+  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Glossary:
+    - Cm or CM   - Configuration Manager
+    - Obj or OBJ - Object
+**/
+
+#ifndef SOC_CONFIGURATION_MANAGER_H_
+#define SOC_CONFIGURATION_MANAGER_H_
+
+#include "ConfigurationManager.h"
+
+/** The number of ACPI tables to install
+*/
+#define PLAT_ACPI_TABLE_COUNT  7
+
+/** A helper macro for mapping a reference token
+*/
+#define REFERENCE_TOKEN_SOC(Field)                                \
+  (CM_OBJECT_TOKEN)((UINT8*)&MorelloSocRepositoryInfo +           \
+    OFFSET_OF (EDKII_SOC_PLATFORM_REPOSITORY_INFO, Field))
+
+/** C array containing the compiled AML template.
+    These symbols are defined in the auto generated C file
+    containing the AML bytecode array.
+*/
+extern CHAR8  dsdtsoc_aml_code[];
+
+/** A structure describing the SoC Platform specific information
+*/
+typedef struct SocPlatformRepositoryInfo {
+  /// List of ACPI tables
+  CM_STD_OBJ_ACPI_TABLE_INFO    CmAcpiTableList[PLAT_ACPI_TABLE_COUNT];
+} EDKII_SOC_PLATFORM_REPOSITORY_INFO;
+
+/** A structure describing the platform configuration
+    manager repository information
+*/
+typedef struct PlatformRepositoryInfo {
+  /// Common information
+  EDKII_COMMON_PLATFORM_REPOSITORY_INFO    *CommonPlatRepoInfo;
+
+  /// SoC Platform specific information
+  EDKII_SOC_PLATFORM_REPOSITORY_INFO       *SocPlatRepoInfo;
+} EDKII_PLATFORM_REPOSITORY_INFO;
+
+extern EDKII_COMMON_PLATFORM_REPOSITORY_INFO  CommonPlatformInfo;
+
+/** Return platform specific ARM namespace object.
+
+  @param [in]      This        Pointer to the Configuration Manager Protocol.
+  @param [in]      CmObjectId  The Configuration Manager Object ID.
+  @param [in]      Token       An optional token identifying the object. If
+                               unused this must be CM_NULL_TOKEN.
+  @param [in, 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
+GetArmNameSpaceObjectPlat (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST This,
+  IN  CONST CM_OBJECT_ID                                 CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                              Token OPTIONAL,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST CmObject
+  );
+
+/** Return platform specific standard namespace object.
+
+  @param [in]      This        Pointer to the Configuration Manager Protocol.
+  @param [in]      CmObjectId  The Configuration Manager Object ID.
+  @param [in]      Token       An optional token identifying the object. If
+                               unused this must be CM_NULL_TOKEN.
+  @param [in, 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
+GetStandardNameSpaceObjectPlat (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST This,
+  IN  CONST CM_OBJECT_ID                                 CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                              Token OPTIONAL,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST CmObject
+  );
+
+#endif // SOC_CONFIGURATION_MANAGER_H_
diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
new file mode 100644
index 000000000000..7ca8ae212a61
--- /dev/null
+++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
@@ -0,0 +1,161 @@
+/** @file
+  Configuration Manager Dxe
+
+  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Glossary:
+    - Cm or CM   - Configuration Manager
+    - Obj or OBJ - Object
+**/
+
+#include <IndustryStandard/DebugPort2Table.h>
+#include <IndustryStandard/IoRemappingTable.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+#include "ConfigurationManagerSoc.h"
+#include "Platform.h"
+
+EDKII_SOC_PLATFORM_REPOSITORY_INFO  MorelloSocRepositoryInfo = {
+  // ACPI Table List
+  {
+    // FADT Table
+    {
+      EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+      EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt),
+      NULL
+    },
+    // GTDT Table
+    {
+      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
+      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdGtdt),
+      NULL
+    },
+    // MADT Table
+    {
+      EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
+      EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMadt),
+      NULL
+    },
+    // SPCR Table
+    {
+      EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
+      EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSpcr),
+      NULL
+    },
+    // DSDT Table
+    {
+      EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+      0, // Unused
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDsdt),
+      (EFI_ACPI_DESCRIPTION_HEADER *)dsdtsoc_aml_code
+    },
+    // DBG2 Table
+    {
+      EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE,
+      EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDbg2),
+      NULL
+    },
+    // PPTT Table
+    {
+      EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
+      EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdPptt),
+      NULL
+    },
+  },
+};
+
+EDKII_PLATFORM_REPOSITORY_INFO  MorelloRepositoryInfo = {
+  &CommonPlatformInfo,
+  &MorelloSocRepositoryInfo
+};
+
+/** Return platform specific ARM namespace object.
+
+  @param [in]      This        Pointer to the Configuration Manager Protocol.
+  @param [in]      CmObjectId  The Configuration Manager Object ID.
+  @param [in]      Token       An optional token identifying the object. If
+                               unused this must be CM_NULL_TOKEN.
+  @param [in, 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
+GetArmNameSpaceObjectPlat (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST This,
+  IN  CONST CM_OBJECT_ID                                 CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                              Token OPTIONAL,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST CmObject
+  )
+{
+  return EFI_NOT_FOUND;
+}
+
+/** Return platform specific standard namespace object.
+
+  @param [in]      This        Pointer to the Configuration Manager Protocol.
+  @param [in]      CmObjectId  The Configuration Manager Object ID.
+  @param [in]      Token       An optional token identifying the object. If
+                               unused this must be CM_NULL_TOKEN.
+  @param [in, 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
+GetStandardNameSpaceObjectPlat (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST This,
+  IN  CONST CM_OBJECT_ID                                 CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                              Token OPTIONAL,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST CmObject
+  )
+{
+  EFI_STATUS                          Status;
+  EDKII_SOC_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
+
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = EFI_NOT_FOUND;
+  PlatformRepo = This->PlatRepoInfo->SocPlatRepoInfo;
+
+  switch (GET_CM_OBJECT_ID (CmObjectId)) {
+    case EStdObjAcpiTableList:
+      Status = HandleCmObject (
+                 CmObjectId,
+                 PlatformRepo->CmAcpiTableList,
+                 sizeof (PlatformRepo->CmAcpiTableList),
+                 ARRAY_SIZE (PlatformRepo->CmAcpiTableList),
+                 CmObject
+                 );
+      break;
+
+    default:
+    {
+      break;
+    }
+  }
+
+  return Status;
+}
diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl
new file mode 100644
index 000000000000..806e170515b7
--- /dev/null
+++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl
@@ -0,0 +1,41 @@
+/** @file
+  Differentiated System Description Table Fields (DSDT)
+
+  Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Reference(s):
+  - ACPI for Arm Components  1.0, Platform Design Document
+
+**/
+
+#include "ConfigurationManager.h"
+
+DefinitionBlock("Dsdt.aml", "DSDT", 1, "ARMLTD", "MORELLO", CFG_MGR_OEM_REVISION) {
+  Scope(_SB) {
+    Device(CP00) { // Cluster 0, Cpu 0
+      Name(_HID, "ACPI0007")
+      Name(_UID, 0)
+      Name(_STA, 0xF)
+    }
+
+    Device(CP01) { // Cluster 0, Cpu 1
+      Name(_HID, "ACPI0007")
+      Name(_UID, 1)
+      Name(_STA, 0xF)
+    }
+
+    Device(CP02) { // Cluster 1, Cpu 0
+      Name(_HID, "ACPI0007")
+      Name(_UID, 2)
+      Name(_STA, 0xF)
+    }
+
+    Device(CP03) { // Cluster 1, Cpu 1
+      Name(_HID, "ACPI0007")
+      Name(_UID, 3)
+      Name(_STA, 0xF)
+    }
+  } // Scope(_SB)
+}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [edk2-platforms][PATCH V1 05/11] Platform/ARM/Morello: Add initial support for Morello SoC
  2021-12-04 12:30 [edk2-platforms][PATCH V1 00/11] Add Support for Morello SoC chandni cherukuri
                   ` (3 preceding siblings ...)
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 04/11] Platform/ARM/Morello: Add ConfigurationManager " chandni cherukuri
@ 2021-12-04 12:30 ` chandni cherukuri
  2021-12-07 20:54   ` Sami Mujawar
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 06/11] Platform/ARM/Morello: Port PCI Segment Library chandni cherukuri
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: chandni cherukuri @ 2021-12-04 12:30 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Chandni Cherukuri

This patch adds initial support for Morello SoC platform.

Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
---
 Platform/ARM/Morello/MorelloPlatform.dsc.inc |  27 +-
 Platform/ARM/Morello/MorelloPlatformFvp.dsc  |  30 +-
 Platform/ARM/Morello/MorelloPlatformSoc.dsc  |  47 ++++
 Platform/ARM/Morello/MorelloPlatformSoc.fdf  | 287 ++++++++++++++++++++
 4 files changed, 363 insertions(+), 28 deletions(-)

diff --git a/Platform/ARM/Morello/MorelloPlatform.dsc.inc b/Platform/ARM/Morello/MorelloPlatform.dsc.inc
index dccd22248318..862d5f2da1b0 100644
--- a/Platform/ARM/Morello/MorelloPlatform.dsc.inc
+++ b/Platform/ARM/Morello/MorelloPlatform.dsc.inc
@@ -9,13 +9,13 @@
 [LibraryClasses.common]
   ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
   ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
-  ArmPlatformLib|Platform/ARM/Morello/Library/PlatformLib/PlatformLib.inf
   BasePathLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
   TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
 
   # Ramdisk Support
   FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
 
 [LibraryClasses.common.SEC]
   HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
@@ -47,9 +47,6 @@
 
 [LibraryClasses.common.DXE_DRIVER]
   FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
-  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
-  PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
-  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
 
 [LibraryClasses.common.DXE_RUNTIME_DRIVER]
   BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
@@ -131,11 +128,6 @@
   gArmMorelloTokenSpaceGuid.PcdRamDiskBase|0x88000000
   gArmMorelloTokenSpaceGuid.PcdRamDiskSize|0x18000000
 
-  # PCIe
-  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|24
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
-  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x20000000
-
 [PcdsDynamicHii.common.DEFAULT]
   gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|0
 
@@ -217,20 +209,3 @@
 
   # RAM Disk
   MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
-
-  # Required by PCI
-  ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
-
-  # PCI Support
-  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
-  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
-    <PcdsFixedAtBuild>
-      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8010004F
-  }
-
-  # AHCI Support
-  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
-  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
-
-  # SATA Controller
-  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
diff --git a/Platform/ARM/Morello/MorelloPlatformFvp.dsc b/Platform/ARM/Morello/MorelloPlatformFvp.dsc
index ee612296a80e..1f9199fba2dc 100644
--- a/Platform/ARM/Morello/MorelloPlatformFvp.dsc
+++ b/Platform/ARM/Morello/MorelloPlatformFvp.dsc
@@ -39,14 +39,18 @@
 !include MdePkg/MdeLibs.dsc.inc
 
 [LibraryClasses.common]
+  # Platform Library
+  ArmPlatformLib|Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf
+
   # Virtio Support
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
   VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
-  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
-  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
 
 [LibraryClasses.common.DXE_DRIVER]
   PciHostBridgeLib|Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibFvp.inf
+  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
+  PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
 
 [PcdsFeatureFlag.common]
   gArmMorelloTokenSpaceGuid.PcdVirtioBlkSupported|TRUE
@@ -63,9 +67,31 @@
   gArmMorelloTokenSpaceGuid.PcdVirtioNetSize|0x200
   gArmMorelloTokenSpaceGuid.PcdVirtioNetInterrupt|134
 
+  # PCIe
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|24
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x20000000
+
 [Components.common]
   OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
   OvmfPkg/VirtioNetDxe/VirtioNet.inf
 
   # Platform driver
   Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeFvp.inf
+
+  # Required by PCI
+  ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
+
+  # PCI Support
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8010004F
+  }
+
+  # AHCI Support
+  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+
+  # SATA Controller
+  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
diff --git a/Platform/ARM/Morello/MorelloPlatformSoc.dsc b/Platform/ARM/Morello/MorelloPlatformSoc.dsc
new file mode 100644
index 000000000000..8335c50803b3
--- /dev/null
+++ b/Platform/ARM/Morello/MorelloPlatformSoc.dsc
@@ -0,0 +1,47 @@
+## @file
+#  Compoenent description file specific for Morello SoC Platform
+#
+#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = morellosoc
+  PLATFORM_GUID                  = 8AC37B62-713D-449D-876D-06AD1B8E67E5
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x0001001B
+!ifdef $(EDK2_OUT_DIR)
+  OUTPUT_DIRECTORY               = $(EDK2_OUT_DIR)
+!else
+  OUTPUT_DIRECTORY               = Build/$(PLATFORM_NAME)
+!endif
+  SUPPORTED_ARCHITECTURES        = AARCH64
+  BUILD_TARGETS                  = NOOPT|DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = Platform/ARM/Morello/MorelloPlatformSoc.fdf
+  BUILD_NUMBER                   = 1
+
+  # Network definition
+  DEFINE NETWORK_ISCSI_ENABLE    = FALSE
+
+!include Platform/ARM/Morello/MorelloPlatform.dsc.inc
+!include Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
+!include DynamicTablesPkg/DynamicTables.dsc.inc
+!include Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
+
+# include common/basic libraries from MdePkg.
+!include MdePkg/MdeLibs.dsc.inc
+
+[LibraryClasses.common]
+  # Platform Library
+  ArmPlatformLib|Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
+
+[Components.common]
+  # Platform driver
+  Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf
diff --git a/Platform/ARM/Morello/MorelloPlatformSoc.fdf b/Platform/ARM/Morello/MorelloPlatformSoc.fdf
new file mode 100644
index 000000000000..e7d4a6a9828d
--- /dev/null
+++ b/Platform/ARM/Morello/MorelloPlatformSoc.fdf
@@ -0,0 +1,287 @@
+## @file
+#  FDF file of Morello SoC platform
+#
+#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+[FD.BL33_AP_UEFI]
+BaseAddress   = 0xE0000000|gArmTokenSpaceGuid.PcdFdBaseAddress  # The base address of the Firmware in NOR Flash.
+Size          = 0x00200000|gArmTokenSpaceGuid.PcdFdSize         # The size in bytes of the FLASH Device
+ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
+BlockSize     = 0x00001000
+NumBlocks     = 0x200
+
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of
+# different images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required)
+# followed by the pipe "|" character, followed by the size of the region, also
+# in hex with the leading "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+#
+################################################################################
+
+0x00000000|0x00200000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a
+# flash device file. This section also defines order the components and modules
+# are positioned within the image. The [FV] section consists of define
+# statements, set statements and module statements.
+#
+################################################################################
+
+[FV.FvMain]
+BlockSize          = 0x40
+NumBlocks          = 0         # This FV gets compressed so make it just big enough
+FvAlignment        = 8         # FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+  INF MdeModulePkg/Core/Dxe/DxeMain.inf
+
+  # PI DXE Drivers producing Architectural Protocols (EFI Services)
+  INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  INF MdeModulePkg/Universal/Metronome/Metronome.inf
+  INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+
+  # ACPI Support
+  INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  # Configuration Manager
+  INF Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
+
+  # Dynamic Table fdf
+  !include DynamicTablesPkg/DynamicTables.fdf.inc
+
+  # Multiple Console IO support
+  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+  INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+  INF ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
+  INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+  INF Platform/ARM/Drivers/BootMonFs/BootMonFs.inf
+  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+  # FAT filesystem + GPT/MBR partitioning
+  INF FatPkg/EnhancedFatDxe/Fat.inf
+  INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+  # FV FileSystem
+  INF MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
+  INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
+
+  # UEFI applications
+  INF ShellPkg/Application/Shell/Shell.inf
+
+  # Platform driver
+  INF Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf
+
+  # Bds
+  INF MdeModulePkg/Application/UiApp/UiApp.inf
+  INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+
+[FV.FVMAIN_COMPACT]
+FvAlignment        = 8
+BlockSize          = 0x1000
+NumBlocks          = 0x200
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+  INF ArmPkg/Drivers/CpuPei/CpuPei.inf
+  INF ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
+  INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+  INF ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
+  INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+  INF MdeModulePkg/Core/Pei/PeiMain.inf
+  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+
+  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+      SECTION FV_IMAGE = FVMAIN
+    }
+  }
+
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+
+############################################################################
+# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section   #
+############################################################################
+#
+#[Rule.Common.DXE_DRIVER]
+#  FILE DRIVER = $(NAMED_GUID) {
+#    DXE_DEPEX    DXE_DEPEX               Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+#    COMPRESS PI_STD {
+#      GUIDED {
+#        PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+#        UI       STRING="$(MODULE_NAME)" Optional
+#        VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+#      }
+#    }
+#  }
+#
+############################################################################
+
+#
+# These SEC rules are used for ArmPlatformPkg/PrePeiCore module.
+# ArmPlatformPkg/PrePeiCore is declared as a SEC module to make GenFv patch
+# the UEFI Firmware to jump to ArmPlatformPkg/PrePeiCore entrypoint
+#
+
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED FIXED {
+    TE  TE Align = Auto                 $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID) FIXED {
+    TE  TE Align = Auto                 $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI  STRING ="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) FIXED {
+     PEI_DEPEX PEI_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+     TE  TE Align = Auto                $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI  STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM.TIANOCOMPRESSED]
+  FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
+    PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+    GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
+      PE32      PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+      UI        STRING="$(MODULE_NAME)" Optional
+    }
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32     PE32                       $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    UI     STRING ="$(MODULE_NAME)" Optional
+    PE32   PE32                         $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      |.depex
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [edk2-platforms][PATCH V1 06/11] Platform/ARM/Morello: Port PCI Segment Library
  2021-12-04 12:30 [edk2-platforms][PATCH V1 00/11] Add Support for Morello SoC chandni cherukuri
                   ` (4 preceding siblings ...)
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 05/11] Platform/ARM/Morello: Add initial support " chandni cherukuri
@ 2021-12-04 12:30 ` chandni cherukuri
  2021-12-07 20:54   ` Sami Mujawar
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 07/11] Platform/ARM/Morello: Port PCI Express library chandni cherukuri
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: chandni cherukuri @ 2021-12-04 12:30 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Chandni Cherukuri

From: Anurag Koul <anurag.koul@arm.com>

A custom PCI Segment library is required to handle multiple PCIe
segments in Morello, as the base PCI Segment library doesn't allow
supporting more than a single PCIe segment.

This custom platform-specific PCI Segment Library has been adapted
from MdePkg/BasePciSegmentLib.

Signed-off-by: Anurag Koul <anurag.koul@arm.com>
Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
---
 Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.inf |   30 +
 Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.c   | 1405 ++++++++++++++++++++
 2 files changed, 1435 insertions(+)

diff --git a/Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.inf b/Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.inf
new file mode 100644
index 000000000000..c37458cba826
--- /dev/null
+++ b/Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.inf
@@ -0,0 +1,30 @@
+## @file
+# PCI Segment Library for Morello SoC with multiple RCs
+#
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = PciSegmentLib
+  FILE_GUID                      = 5811c256-4d1f-11ec-81d3-0242ac130003
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PciSegmentLib
+
+[Sources]
+  PciSegmentLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Platform/ARM/Morello/MorelloPlatform.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
+  PciLib
diff --git a/Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.c b/Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.c
new file mode 100644
index 000000000000..41a998830710
--- /dev/null
+++ b/Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.c
@@ -0,0 +1,1405 @@
+/** @file
+  PCI Segment Library for Morello SoC with multiple RCs
+
+  Having two distinct root complexes is not supported by the standard
+  set of PciLib/PciExpressLib/PciSegmentLib, this PciSegmentLib
+  reimplements the functionality to support multiple root ports under
+  different PCIe segments.
+
+  Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/PciSegmentLib.h>
+#include <MorelloPlatform.h>
+
+typedef enum {
+  PciCfgWidthUint8 = 0,
+  PciCfgWidthUint16,
+  PciCfgWidthUint32,
+  PciCfgWidthMax
+} PCI_CFG_WIDTH;
+
+/**
+ Assert the validity of a PCI Segment address.
+ A valid PCI Segment address should not contain 1's in bits 28..31 and 48..63
+
+  @param A The address to validate.
+  @param M Additional bits to assert to be zero.
+**/
+#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A, M) \
+  ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
+
+/**
+  Internal worker function to read a PCI configuration register.
+
+  @param [in]  Address    The address that encodes the PCI Bus, Device, Function
+                          and Register.
+  @param [in]  Width      The width of data to read
+
+  @return The value read from the PCI configuration register.
+**/
+STATIC
+UINT32
+PciSegmentLibReadWorker (
+  IN  UINT64        Address,
+  IN  PCI_CFG_WIDTH Width
+  )
+{
+  switch (Width) {
+    case PciCfgWidthUint8:
+      return PciRead8 (Address);
+    case PciCfgWidthUint16:
+      return PciRead16 (Address);
+    case PciCfgWidthUint32:
+      return PciRead32 (Address);
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+/**
+  Internal worker function to write to a PCI configuration register.
+
+  @param [in]  Address   The address that encodes the PCI Bus, Device, Function
+                         and Register.
+  @param [in]  Width     The width of data to write
+  @param [in]  Data      The value to write.
+
+  @return  The value written to the PCI configuration register.
+**/
+STATIC
+UINT32
+PciSegmentLibWriteWorker (
+  IN  UINT64        Address,
+  IN  PCI_CFG_WIDTH Width,
+  IN  UINT32        Data
+  )
+{
+  switch (Width) {
+    case PciCfgWidthUint8:
+      PciWrite8 (Address, Data);
+      break;
+    case PciCfgWidthUint16:
+      PciWrite16 (Address, Data);
+      break;
+    case PciCfgWidthUint32:
+      PciWrite32 (Address, Data);
+      break;
+    default:
+      ASSERT (FALSE);
+  }
+
+  return Data;
+}
+
+/**
+  Reads an 8-bit PCI configuration register.
+
+  Reads and returns the 8-bit PCI configuration register specified by Address.
+  This function must guarantee that all PCI read and write operations are
+  serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param [in]  Address     The address that encodes the PCI Segment, Bus,
+                           Device, Function and Register.
+
+  @return The 8-bit PCI configuration register specified by the Address.
+**/
+UINT8
+EFIAPI
+PciSegmentRead8 (
+  IN UINT64 Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+
+  return (UINT8)PciSegmentLibReadWorker (Address, PciCfgWidthUint8);
+}
+
+/**
+  Writes an 8-bit PCI configuration register.
+
+  Writes the 8-bit Value in the PCI configuration register specified by the
+  Address. This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param [in]  Address     The address that encodes the PCI Segment, Bus,
+                           Device, Function, and Register.
+  @param [in]  Value       The value to write.
+
+  @return The value written to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciSegmentWrite8 (
+  IN UINT64 Address,
+  IN UINT8  Value
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+
+  return (UINT8)PciSegmentLibWriteWorker (Address, PciCfgWidthUint8, Value);
+}
+
+/**
+  Performs a bitwise OR of an 8-bit PCI configuration register with
+  an 8-bit value.
+
+  Reads the 8-bit PCI configuration register specified by Address,
+  performs a bitwise OR between the read result and the value specified by
+  OrData, and writes the result to the 8-bit PCI configuration register
+  specified by Address.
+
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
+                         Function, and Register.
+  @param [in]  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciSegmentOr8 (
+  IN UINT64 Address,
+  IN UINT8  OrData
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           (UINT8)(PciSegmentRead8 (Address) | OrData)
+           );
+}
+
+/**
+  Performs a bitwise AND of an 8-bit PCI configuration register with
+  an 8-bit value.
+
+  Reads the 8-bit PCI configuration register specified by Address,
+  performs a bitwise AND between the read result and the value specified by
+  AndData, and writes the result to the 8-bit PCI configuration register
+  specified by Address.
+
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations
+  are serialized. If any reserved bits in Address are set, then ASSERT().
+
+  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
+                         Function, and Register.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciSegmentAnd8 (
+  IN UINT64 Address,
+  IN UINT8  AndData
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           (UINT8)(PciSegmentRead8 (Address) & AndData)
+           );
+}
+
+/**
+  Performs a bitwise AND of an 8-bit PCI configuration register with
+  an 8-bit value, followed by a bitwise OR with another 8-bit value.
+
+  Reads the 8-bit PCI configuration register specified by Address,
+  performs a bitwise AND between the read result and the value specified
+  by AndData, performs a bitwise OR between the result of the AND operation
+  and the value specified by OrData, and writes the result to the 8-bit
+  PCI configuration register specified by Address.
+
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
+                         Function, and Register.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+  @param [in]  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentAndThenOr8 (
+  IN UINT64 Address,
+  IN UINT8  AndData,
+  IN UINT8  OrData
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           (UINT8)((PciSegmentRead8 (Address) & AndData) | OrData)
+           );
+}
+
+/**
+  Reads a bit field of a PCI configuration register.
+
+  Reads the bit field in an 8-bit PCI configuration register. The bit field is
+  specified by the StartBit and the EndBit. The value of the bit field is
+  returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to read.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..7.
+
+  @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldRead8 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit
+  )
+{
+  return BitFieldRead8 (PciSegmentRead8 (Address), StartBit, EndBit);
+}
+
+/**
+  Writes a bit field to a PCI configuration register.
+
+  Writes Value to the bit field of the PCI configuration register. The bit
+  field is specified by the StartBit and the EndBit. All other bits in the
+  destination PCI configuration register are preserved. The new value of the
+  8-bit register is returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit
+  and EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  Value     The new value of the bit field.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldWrite8 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit,
+  IN UINT8  Value
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           BitFieldWrite8 (PciSegmentRead8 (Address), StartBit, EndBit, Value)
+           );
+}
+
+/**
+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
+  writes the result back to the bit field in the 8-bit port.
+
+  Reads the 8-bit PCI configuration register specified by Address, performs a
+  bitwise OR between the read result and the value specified by
+  OrData, and writes the result to the 8-bit PCI configuration register
+  specified by Address. The value written to the PCI configuration register is
+  returned. This function must guarantee that all PCI read and write operations
+  are serialized. Extra left bits in OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldOr8 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit,
+  IN UINT8  OrData
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           BitFieldOr8 (PciSegmentRead8 (Address), StartBit, EndBit, OrData)
+           );
+}
+
+/**
+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
+  AND, and writes the result back to the bit field in the 8-bit register.
+
+  Reads the 8-bit PCI configuration register specified by Address, performs a
+  bitwise AND between the read result and the value specified by AndData, and
+  writes the result to the 8-bit PCI configuration register specified by
+  Address. The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are
+  serialized. Extra left bits in AndData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldAnd8 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit,
+  IN UINT8  AndData
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           BitFieldAnd8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData)
+           );
+}
+
+/**
+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
+  bitwise OR, and writes the result back to the bit field in the
+  8-bit port.
+
+  Reads the 8-bit PCI configuration register specified by Address, performs a
+  bitwise AND followed by a bitwise OR between the read result and
+  the value specified by AndData, and writes the result to the 8-bit PCI
+  configuration register specified by Address. The value written to the PCI
+  configuration register is returned. This function must guarantee that all PCI
+  read and write operations are serialized. Extra left bits in both AndData and
+  OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit
+  and EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit
+  and EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+  @param [in]  OrData    The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldAndThenOr8 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit,
+  IN UINT8  AndData,
+  IN UINT8  OrData
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           BitFieldAndThenOr8 (
+             PciSegmentRead8 (Address),
+             StartBit,
+             EndBit,
+             AndData,
+             OrData
+             )
+           );
+}
+
+/**
+  Reads a 16-bit PCI configuration register.
+
+  Reads and returns the 16-bit PCI configuration register specified by Address.
+  This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
+                         Function, and Register.
+
+  @return The 16-bit PCI configuration register specified by Address.
+
+**/
+UINT16
+EFIAPI
+PciSegmentRead16 (
+  IN UINT64 Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
+
+  return (UINT16)PciSegmentLibReadWorker (Address, PciCfgWidthUint16);
+}
+
+/**
+  Writes a 16-bit PCI configuration register.
+
+  Writes the 16-bit PCI configuration register specified by Address with the
+  value specified by Value. Value is returned.
+  This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param [in]  Address     The address that encodes the PCI Segment, Bus, Device,
+                           Function, and Register.
+  @param [in]  Value       The value to write.
+
+  @return The Value written is returned.
+
+**/
+UINT16
+EFIAPI
+PciSegmentWrite16 (
+  IN UINT64 Address,
+  IN UINT16 Value
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
+
+  return (UINT16)PciSegmentLibWriteWorker (Address, PciCfgWidthUint16, Value);
+}
+
+/**
+  Performs a bitwise OR of a 16-bit PCI configuration register with
+  a 16-bit value.
+
+  Reads the 16-bit PCI configuration register specified by Address, performs a
+  bitwise OR between the read result and the value specified by
+  OrData, and writes the result to the 16-bit PCI configuration register
+  specified by Address. The value written to the PCI configuration register is
+  returned. This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Segment, Bus, Device,
+                       Function and Register.
+  @param [in]  OrData  The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentOr16 (
+  IN UINT64 Address,
+  IN UINT16 OrData
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           (UINT16)(PciSegmentRead16 (Address) | OrData)
+           );
+}
+
+/**
+  Performs a bitwise AND of a 16-bit PCI configuration register with
+  a 16-bit value.
+
+  Reads the 16-bit PCI configuration register specified by Address,
+  performs a bitwise AND between the read result and the value specified
+  by AndData, and writes the result to the 16-bit PCI configuration register
+  specified by the Address.
+
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
+                         Function, and Register.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentAnd16 (
+  IN UINT64 Address,
+  IN UINT16 AndData
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           (UINT16)(PciSegmentRead16 (Address) & AndData)
+           );
+}
+
+/**
+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
+  value, followed a  bitwise OR with another 16-bit value.
+
+  Reads the 16-bit PCI configuration register specified by Address,
+  performs a bitwise AND between the read result and the value specified by
+  AndData, performs a bitwise OR between the result of the AND operation and
+  the value specified by OrData, and writes the result to the 16-bit PCI
+  configuration register specified by the Address.
+
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
+                         Function, and Register.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+  @param [in]  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentAndThenOr16 (
+  IN UINT64 Address,
+  IN UINT16 AndData,
+  IN UINT16 OrData
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           (UINT16)((PciSegmentRead16 (Address) & AndData) | OrData)
+           );
+}
+
+/**
+  Reads a bit field of a PCI configuration register.
+
+  Reads the bit field in a 16-bit PCI configuration register. The bit field is
+  specified by the StartBit and the EndBit. The value of the bit field is
+  returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to read.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..15.
+
+  @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldRead16 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit
+  )
+{
+  return BitFieldRead16 (PciSegmentRead16 (Address), StartBit, EndBit);
+}
+
+/**
+  Writes a bit field to a PCI configuration register.
+
+  Writes Value to the bit field of the PCI configuration register. The bit
+  field is specified by the StartBit and the EndBit. All other bits in the
+  destination PCI configuration register are preserved. The new value of the
+  16-bit register is returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  Value     The new value of the bit field.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldWrite16 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit,
+  IN UINT16 Value
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           BitFieldWrite16 (PciSegmentRead16 (Address), StartBit, EndBit, Value)
+           );
+}
+
+/**
+  Reads the 16-bit PCI configuration register specified by Address,
+  performs a bitwise OR between the read result and the value specified
+  by OrData, and writes the result to the 16-bit PCI configuration register
+  specified by the Address.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldOr16 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit,
+  IN UINT16 OrData
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           BitFieldOr16 (PciSegmentRead16 (Address), StartBit, EndBit, OrData)
+           );
+}
+
+/**
+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,
+  and writes the result back to the bit field in the 16-bit port.
+
+  Reads the 16-bit PCI configuration register specified by Address,
+  performs a bitwise OR between the read result and the value specified by
+  OrData, and writes the result to the 16-bit PCI configuration register
+  specified by the Address.
+
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are
+  serialized. Extra left bits in OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
+                         Function, and Register.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. The ordinal of the least significant bit in a
+                         byte is bit 0.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. The ordinal of the most significant bit in a
+                         byte is bit 7.
+  @param [in]  AndData   The value to AND with the read value from the PCI
+                         configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldAnd16 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit,
+  IN UINT16 AndData
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           BitFieldAnd16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData)
+           );
+}
+
+/**
+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
+  bitwise OR, and writes the result back to the bit field in the
+  16-bit port.
+
+  Reads the 16-bit PCI configuration register specified by Address, performs a
+  bitwise AND followed by a bitwise OR between the read result and
+  the value specified by AndData, and writes the result to the 16-bit PCI
+  configuration register specified by Address. The value written to the PCI
+  configuration register is returned. This function must guarantee that all PCI
+  read and write operations are serialized. Extra left bits in both AndData and
+  OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+  @param [in]  OrData    The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldAndThenOr16 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit,
+  IN UINT16 AndData,
+  IN UINT16 OrData
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           BitFieldAndThenOr16 (
+             PciSegmentRead16 (Address),
+             StartBit,
+             EndBit,
+             AndData,
+             OrData
+             )
+           );
+}
+
+/**
+  Reads a 32-bit PCI configuration register.
+
+  Reads and returns the 32-bit PCI configuration register specified by Address.
+  This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
+                         Function and Register.
+
+  @return The 32-bit PCI configuration register specified by Address.
+
+**/
+UINT32
+EFIAPI
+PciSegmentRead32 (
+  IN UINT64 Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
+
+  return PciSegmentLibReadWorker (Address, PciCfgWidthUint32);
+}
+
+/**
+  Writes a 32-bit PCI configuration register.
+
+  Writes the 32-bit PCI configuration register specified by Address with the
+  value specified by Value.  Value is returned. This function must guarantee
+  that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param [in]  Address     The address that encodes the PCI Segment, Bus, Device,
+                           Function, and Register.
+  @param [in]  Value       The value to write.
+
+  @return The parameter of Value.
+
+**/
+UINT32
+EFIAPI
+PciSegmentWrite32 (
+  IN UINT64 Address,
+  IN UINT32 Value
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
+
+  return PciSegmentLibWriteWorker (Address, PciCfgWidthUint32, Value);
+}
+
+/**
+  Performs a bitwise OR of a 32-bit PCI configuration register with a
+  32-bit value.
+
+  Reads the 32-bit PCI configuration register specified by Address,
+  performs a bitwise OR between the read result and the value specified
+  by OrData, and writes the result to the 32-bit PCI configuration register
+  specified by Address.
+
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
+                         Function, and Register.
+  @param [in]  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentOr32 (
+  IN UINT64 Address,
+  IN UINT32 OrData
+  )
+{
+  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) | OrData);
+}
+
+/**
+  Performs a bitwise AND of a 32-bit PCI configuration register with
+  a 32-bit value.
+
+  Reads the 32-bit PCI configuration register specified by Address,
+  performs a bitwise AND between the read result and the value specified
+  by AndData, and writes the result to the 32-bit PCI configuration register
+  specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
+                         Function and Register.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentAnd32 (
+  IN UINT64 Address,
+  IN UINT32 AndData
+  )
+{
+  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) & AndData);
+}
+
+/**
+  Performs a bitwise AND of a 32-bit PCI configuration register with
+  a 32-bit value, followed by a bitwise OR with another 32-bit value.
+
+  Reads the 32-bit PCI configuration register specified by Address,
+  performs a bitwise AND between the read result and the value specified
+  by AndData, performs a bitwise OR between the result of the AND operation
+  and the value specified by OrData, and writes the result to the 32-bit
+  PCI configuration register specified by Address.
+
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
+                         Function and Register.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+  @param [in]  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentAndThenOr32 (
+  IN UINT64 Address,
+  IN UINT32 AndData,
+  IN UINT32 OrData
+  )
+{
+  return PciSegmentWrite32 (
+           Address,
+           (PciSegmentRead32 (Address) & AndData) | OrData
+           );
+}
+
+/**
+  Reads a bit field of a PCI configuration register.
+
+  Reads the bit field in a 32-bit PCI configuration register. The bit field is
+  specified by the StartBit and the EndBit. The value of the bit field is
+  returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to read.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..31.
+
+  @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldRead32 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit
+  )
+{
+  return BitFieldRead32 (PciSegmentRead32 (Address), StartBit, EndBit);
+}
+
+/**
+  Writes a bit field to a PCI configuration register.
+
+  Writes Value to the bit field of the PCI configuration register. The bit
+  field is specified by the StartBit and the EndBit. All other bits in the
+  destination PCI configuration register are preserved. The new value of the
+  32-bit register is returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit
+  and EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  Value     The new value of the bit field.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldWrite32 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit,
+  IN UINT32 Value
+  )
+{
+  return PciSegmentWrite32 (
+           Address,
+           BitFieldWrite32 (PciSegmentRead32 (Address), StartBit, EndBit, Value)
+           );
+}
+
+/**
+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
+  writes the result back to the bit field in the 32-bit port.
+
+  Reads the 32-bit PCI configuration register specified by Address, performs a
+  bitwise OR between the read result and the value specified by
+  OrData, and writes the result to the 32-bit PCI configuration register
+  specified by Address. The value written to the PCI configuration register is
+  returned. This function must guarantee that all PCI read and write operations
+  are serialized. Extra left bits in OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldOr32 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit,
+  IN UINT32 OrData
+  )
+{
+  return PciSegmentWrite32 (
+           Address,
+           BitFieldOr32 (PciSegmentRead32 (Address), StartBit, EndBit, OrData)
+           );
+}
+
+/**
+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
+  AND, and writes the result back to the bit field in the 32-bit register.
+
+  Reads the 32-bit PCI configuration register specified by Address,
+  performs a bitwise AND between the read result and the value specified
+  by AndData, and writes the result to the 32-bit PCI configuration register
+  specified by Address. The value written to the PCI configuration register
+  is returned.  This function must guarantee that all PCI read and write
+  operations are serialized.  Extra left bits in AndData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldAnd32 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit,
+  IN UINT32 AndData
+  )
+{
+  return PciSegmentWrite32 (
+           Address,
+           BitFieldAnd32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData)
+           );
+}
+
+/**
+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
+  bitwise OR, and writes the result back to the bit field in the
+  32-bit port.
+
+  Reads the 32-bit PCI configuration register specified by Address, performs a
+  bitwise AND followed by a bitwise OR between the read result and
+  the value specified by AndData, and writes the result to the 32-bit PCI
+  configuration register specified by Address. The value written to the PCI
+  configuration register is returned. This function must guarantee that all PCI
+  read and write operations are serialized. Extra left bits in both AndData and
+  OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit
+  and EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit
+  and EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+  @param [in]  OrData    The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldAndThenOr32 (
+  IN UINT64 Address,
+  IN UINTN  StartBit,
+  IN UINTN  EndBit,
+  IN UINT32 AndData,
+  IN UINT32 OrData
+  )
+{
+  return PciSegmentWrite32 (
+           Address,
+           BitFieldAndThenOr32 (
+             PciSegmentRead32 (Address),
+             StartBit,
+             EndBit,
+             AndData,
+             OrData
+             )
+           );
+}
+
+/**
+  Reads a range of PCI configuration registers into a caller supplied buffer.
+
+  Reads the range of PCI configuration registers specified by StartAddress and
+  Size into the buffer specified by Buffer. This function only allows the PCI
+  configuration registers from a single PCI function to be read. Size is
+  returned. When possible 32-bit PCI configuration read cycles are used to read
+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
+  and 16-bit PCI configuration read cycles may be used at the beginning and the
+  end of the range.
+
+  If any reserved bits in StartAddress are set, then ASSERT().
+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+  If Size > 0 and Buffer is NULL, then ASSERT().
+
+  @param [in]   StartAddress  The starting address that encodes the PCI Segment,
+                              Bus, Device, Function and Register.
+  @param [in]   Size          The size in bytes of the transfer.
+  @param [out]  Buffer        The pointer to a buffer receiving the data read.
+
+  @return Size
+
+**/
+UINTN
+EFIAPI
+PciSegmentReadBuffer (
+  IN  UINT64 StartAddress,
+  IN  UINTN  Size,
+  OUT VOID   *Buffer
+  )
+{
+  UINTN  ReturnValue;
+
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
+
+  if (Size == 0) {
+    return Size;
+  }
+
+  ASSERT (Buffer != NULL);
+
+  // Save Size for return
+  ReturnValue = Size;
+
+  if ((StartAddress & BIT0) != 0) {
+    // Read a byte if StartAddress is byte aligned
+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
+    StartAddress += sizeof (UINT8);
+    Size  -= sizeof (UINT8);
+    Buffer = (UINT8 *)Buffer + 1;
+  }
+
+  if ((Size >= sizeof (UINT16)) && ((StartAddress & BIT1) != 0)) {
+    // Read a word if StartAddress is word aligned
+    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
+    StartAddress += sizeof (UINT16);
+    Size  -= sizeof (UINT16);
+    Buffer = (UINT16 *)Buffer + 1;
+  }
+
+  while (Size >= sizeof (UINT32)) {
+    // Read as many double words as possible
+    WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));
+    StartAddress += sizeof (UINT32);
+    Size  -= sizeof (UINT32);
+    Buffer = (UINT32 *)Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT16)) {
+    // Read the last remaining word if exist
+    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
+    StartAddress += sizeof (UINT16);
+    Size  -= sizeof (UINT16);
+    Buffer = (UINT16 *)Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT8)) {
+    // Read the last remaining byte if exist
+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
+  }
+
+  return ReturnValue;
+}
+
+/**
+  Copies the data in a caller supplied buffer to a specified range of PCI
+  configuration space.
+
+  Writes the range of PCI configuration registers specified by StartAddress and
+  Size from the buffer specified by Buffer. This function only allows the PCI
+  configuration registers from a single PCI function to be written. Size is
+  returned. When possible 32-bit PCI configuration write cycles are used to
+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,
+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning
+  and the end of the range.
+
+  If any reserved bits in StartAddress are set, then ASSERT().
+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+  If Size > 0 and Buffer is NULL, then ASSERT().
+
+  @param [in]  StartAddress  The starting address that encodes the PCI Segment,
+                             Bus, Device, Function and Register.
+  @param [in]  Size          The size in bytes of the transfer.
+  @param [in]  Buffer        The pointer to a buffer containing the data to write.
+
+  @return The parameter of Size.
+
+**/
+UINTN
+EFIAPI
+PciSegmentWriteBuffer (
+  IN UINT64 StartAddress,
+  IN UINTN  Size,
+  IN VOID   *Buffer
+  )
+{
+  UINTN  ReturnValue;
+
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
+
+  if (Size == 0) {
+    return 0;
+  }
+
+  ASSERT (Buffer != NULL);
+
+  // Save Size for return
+  ReturnValue = Size;
+
+  if ((StartAddress & BIT0) != 0) {
+    // Write a byte if StartAddress is byte aligned
+    PciSegmentWrite8 (StartAddress, *(UINT8 *)Buffer);
+    StartAddress += sizeof (UINT8);
+    Size  -= sizeof (UINT8);
+    Buffer = (UINT8 *)Buffer + 1;
+  }
+
+  if ((Size >= sizeof (UINT16)) && ((StartAddress & BIT1) != 0)) {
+    // Write a word if StartAddress is word aligned
+    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
+    StartAddress += sizeof (UINT16);
+    Size  -= sizeof (UINT16);
+    Buffer = (UINT16 *)Buffer + 1;
+  }
+
+  while (Size >= sizeof (UINT32)) {
+    // Write as many double words as possible
+    PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));
+    StartAddress += sizeof (UINT32);
+    Size  -= sizeof (UINT32);
+    Buffer = (UINT32 *)Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT16)) {
+    // Write the last remaining word if exist
+    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
+    StartAddress += sizeof (UINT16);
+    Size  -= sizeof (UINT16);
+    Buffer = (UINT16 *)Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT8)) {
+    // Write the last remaining byte if exist
+    PciSegmentWrite8 (StartAddress, *(UINT8 *)Buffer);
+  }
+
+  return ReturnValue;
+}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [edk2-platforms][PATCH V1 07/11] Platform/ARM/Morello: Port PCI Express library
  2021-12-04 12:30 [edk2-platforms][PATCH V1 00/11] Add Support for Morello SoC chandni cherukuri
                   ` (5 preceding siblings ...)
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 06/11] Platform/ARM/Morello: Port PCI Segment Library chandni cherukuri
@ 2021-12-04 12:30 ` chandni cherukuri
  2021-12-07 20:58   ` Sami Mujawar
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 08/11] Platform/ARM/Morello: Enable PCIe and CCIX Root Ports chandni cherukuri
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: chandni cherukuri @ 2021-12-04 12:30 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Chandni Cherukuri

From: Anurag Koul <anurag.koul@arm.com>

Morello platform requires a custom platform-specific PCI Express
library because the native PCI Express Library only allows for a
single ECAM config address to be supplied to it. If there is more
than one PCIe root port, it expects the ECAM regions for all the
root ports to be contiguous. This is not the case with Morello where
the two RPs have their ECAM regions mapped to non-contiguous address
ranges and reside in separate PCIe segments.

This custom plaform-specific PCI Express library, inherited from
MdePkg/BasePciExpressLib, routes the ECAM accesses to the appropriate
ECAM region based on the PCIe segment number in the incoming PCIe
address.

Signed-off-by: Anurag Koul <anurag.koul@arm.com>
Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
---
 Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf |   49 +
 Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.c   | 1431 ++++++++++++++++++++
 Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.uni |   18 +
 3 files changed, 1498 insertions(+)

diff --git a/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf
new file mode 100644
index 000000000000..71a2cf3a6276
--- /dev/null
+++ b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf
@@ -0,0 +1,49 @@
+## @file
+#  Instance of PCI Express Library using the 256 MB PCI Express MMIO window.
+#
+#  PCI Express Library that uses the 256 MB PCI Express MMIO window to perform
+#  PCI Configuration cycles. Layers on top of an I/O Library instance.
+#
+#  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  This library is inherited from MdePkg/Library/BasePciExpressLib to work with
+#  non-contiguous ECAM regions for the two supported PCIe root ports. The
+#  base PCI Express library expects the ECAM space for all the available root
+#  ports to be contiguous and hence exposes only a single hook(variable) to
+#  hold the ECAM base address informaion in.
+
+#  This library reinterprets the ECAM accesses and routes them to the
+#  appropriate Root Port Config based on the PCIe segment number in the
+#  incoming PCIe address.
+#
+#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = PciExpressLib
+  MODULE_UNI_FILE                = PciExpressLib.uni
+  FILE_GUID                      = 795fad20-e353-45f8-b77f-c59eb7907370
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PciExpressLib
+
+[Sources]
+  PciExpressLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Platform/ARM/Morello/MorelloPlatform.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
+  PcdLib
+
+[Pcd]
+  gArmMorelloTokenSpaceGuid.PcdCcixExpressBaseAddress  ## CONSUMES
+  gArmMorelloTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
diff --git a/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.c b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.c
new file mode 100644
index 000000000000..8f0652dc6678
--- /dev/null
+++ b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.c
@@ -0,0 +1,1431 @@
+/** @file
+  Functions in this library instance make use of MMIO functions in IoLib to
+  access memory mapped PCI configuration space.
+
+  All assertions for I/O operations are handled in MMIO functions in the IoLib
+  Library.
+
+  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+
+  On Morello platform, the PCIe ECAM regions for the two supported Root Ports,
+  which lie in separate PCIe segments, are not contiguous. As such, any ECAM
+  access from the PCI Express library should ideally be routed based on the
+  segment number within the incoming address, which is configured in the
+  platform PCI Host Bridge library.
+
+  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciExpressLib.h>
+#include <Library/PcdLib.h>
+#include <MorelloPlatform.h>
+
+/**
+  Assert the validity of a PCI address. A valid PCI address may contain 1's
+  only in the low 33 bits. Bit 32 carries the segment number which could be
+  either 0 or 1.
+
+  @param  A The address to validate.
+
+**/
+#define ASSERT_INVALID_PCI_ADDRESS(A) \
+        ASSERT (((A) & ~0x1ffffffffULL) == 0)
+
+#define GET_SEG_NUM(Address)  ((Address >> 32ULL) & 0x1)
+
+/**
+  Registers a PCI device so PCI configuration registers may be accessed after
+  SetVirtualAddressMap().
+
+  Registers the PCI device specified by Address so all the PCI configuration
+  registers associated with that PCI device may be accessed after
+  SetVirtualAddressMap() is called.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+
+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function
+                                   after ExitBootServices().
+                                   The resources required to access the PCI
+                                   device at runtime could not be mapped.
+
+**/
+RETURN_STATUS
+EFIAPI
+PciExpressRegisterForRuntimeAccess (
+  IN UINTN Address
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return RETURN_UNSUPPORTED;
+}
+
+/**
+  Gets the base address of PCI Express.
+
+  This internal functions retrieves PCI Express Base Address via a PCD entry.
+
+  @param [in]  Address The address that encodes the PCI Segment, Bus, Device,
+                       Function and Register.
+
+  @return The converted address relative to PCI Root's ECAM base address.
+
+**/
+STATIC
+VOID *
+GetPciExpressAddress (
+  IN      UINTN Address
+  )
+{
+  UINTN  ConvAddress;
+
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+
+  if (GET_SEG_NUM (Address) == 0) {
+    ConvAddress = PcdGet64 (PcdPciExpressBaseAddress) + (UINT32)Address;
+  } else if (GET_SEG_NUM (Address) == 1) {
+    ConvAddress = PcdGet64 (PcdCcixExpressBaseAddress) + (UINT32)Address;
+  } else {
+    DEBUG ((DEBUG_ERROR, "PciExpressLib: Invalid PCIe Address.\n"));
+    ASSERT (FALSE);
+    return NULL;
+  }
+
+  return (VOID *)ConvAddress;
+}
+
+/**
+  Reads an 8-bit PCI configuration register.
+
+  Reads and returns the 8-bit PCI configuration register specified by Address.
+  This function must guarantee that all PCI read and write operations are
+  serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+
+  @return The read value from the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciExpressRead8 (
+  IN      UINTN Address
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioRead8 ((UINTN)GetPciExpressAddress (Address));
+}
+
+/**
+  Writes an 8-bit PCI configuration register.
+
+  Writes the 8-bit PCI configuration register specified by Address with the
+  value specified by Value. Value is returned. This function must guarantee
+  that all PCI read and write operations are serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+  @param [in]  Value   The value to write.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciExpressWrite8 (
+  IN      UINTN Address,
+  IN      UINT8 Value
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+
+  return MmioWrite8 ((UINTN)GetPciExpressAddress (Address), Value);
+}
+
+/**
+  Performs a bitwise OR of an 8-bit PCI configuration register with
+  an 8-bit value.
+
+  Reads the 8-bit PCI configuration register specified by Address, performs a
+  bitwise OR between the read result and the value specified by
+  OrData, and writes the result to the 8-bit PCI configuration register
+  specified by Address. The value written to the PCI configuration register is
+  returned. This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+  @param [in]  OrData  The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciExpressOr8 (
+  IN      UINTN Address,
+  IN      UINT8 OrData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioOr8 ((UINTN)GetPciExpressAddress (Address), OrData);
+}
+
+/**
+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
+  value.
+
+  Reads the 8-bit PCI configuration register specified by Address, performs a
+  bitwise AND between the read result and the value specified by AndData, and
+  writes the result to the 8-bit PCI configuration register specified by
+  Address. The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are
+  serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+  @param [in]  AndData The value to AND with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciExpressAnd8 (
+  IN      UINTN Address,
+  IN      UINT8 AndData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioAnd8 ((UINTN)GetPciExpressAddress (Address), AndData);
+}
+
+/**
+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
+  value, followed a  bitwise OR with another 8-bit value.
+
+  Reads the 8-bit PCI configuration register specified by Address, performs a
+  bitwise AND between the read result and the value specified by AndData,
+  performs a bitwise OR between the result of the AND operation and
+  the value specified by OrData, and writes the result to the 8-bit PCI
+  configuration register specified by Address. The value written to the PCI
+  configuration register is returned. This function must guarantee that all PCI
+  read and write operations are serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+  @param [in]  AndData The value to AND with the PCI configuration register.
+  @param [in]  OrData  The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciExpressAndThenOr8 (
+  IN      UINTN Address,
+  IN      UINT8 AndData,
+  IN      UINT8 OrData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioAndThenOr8 (
+           (UINTN)GetPciExpressAddress (Address),
+           AndData,
+           OrData
+           );
+}
+
+/**
+  Reads a bit field of a PCI configuration register.
+
+  Reads the bit field in an 8-bit PCI configuration register. The bit field is
+  specified by the StartBit and the EndBit. The value of the bit field is
+  returned.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to read.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..7.
+
+  @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldRead8 (
+  IN      UINTN Address,
+  IN      UINTN StartBit,
+  IN      UINTN EndBit
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldRead8 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit
+           );
+}
+
+/**
+  Writes a bit field to a PCI configuration register.
+
+  Writes Value to the bit field of the PCI configuration register. The bit
+  field is specified by the StartBit and the EndBit. All other bits in the
+  destination PCI configuration register are preserved. The new value of the
+  8-bit register is returned.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  Value     The new value of the bit field.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldWrite8 (
+  IN      UINTN Address,
+  IN      UINTN StartBit,
+  IN      UINTN EndBit,
+  IN      UINT8 Value
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldWrite8 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit,
+           Value
+           );
+}
+
+/**
+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
+  writes the result back to the bit field in the 8-bit port.
+
+  Reads the 8-bit PCI configuration register specified by Address, performs a
+  bitwise OR between the read result and the value specified by
+  OrData, and writes the result to the 8-bit PCI configuration register
+  specified by Address. The value written to the PCI configuration register is
+  returned. This function must guarantee that all PCI read and write operations
+  are serialized. Extra left bits in OrData are stripped.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldOr8 (
+  IN      UINTN Address,
+  IN      UINTN StartBit,
+  IN      UINTN EndBit,
+  IN      UINT8 OrData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldOr8 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit,
+           OrData
+           );
+}
+
+/**
+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
+  AND, and writes the result back to the bit field in the 8-bit register.
+
+  Reads the 8-bit PCI configuration register specified by Address, performs a
+  bitwise AND between the read result and the value specified by AndData, and
+  writes the result to the 8-bit PCI configuration register specified by
+  Address. The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are
+  serialized. Extra left bits in AndData are stripped.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldAnd8 (
+  IN      UINTN Address,
+  IN      UINTN StartBit,
+  IN      UINTN EndBit,
+  IN      UINT8 AndData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldAnd8 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit,
+           AndData
+           );
+}
+
+/**
+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
+  bitwise OR, and writes the result back to the bit field in the
+  8-bit port.
+
+  Reads the 8-bit PCI configuration register specified by Address, performs a
+  bitwise AND followed by a bitwise OR between the read result and
+  the value specified by AndData, and writes the result to the 8-bit PCI
+  configuration register specified by Address. The value written to the PCI
+  configuration register is returned. This function must guarantee that all PCI
+  read and write operations are serialized. Extra left bits in both AndData and
+  OrData are stripped.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..7.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+  @param [in]  OrData    The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldAndThenOr8 (
+  IN      UINTN Address,
+  IN      UINTN StartBit,
+  IN      UINTN EndBit,
+  IN      UINT8 AndData,
+  IN      UINT8 OrData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldAndThenOr8 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit,
+           AndData,
+           OrData
+           );
+}
+
+/**
+  Reads a 16-bit PCI configuration register.
+
+  Reads and returns the 16-bit PCI configuration register specified by Address.
+  This function must guarantee that all PCI read and write operations are
+  serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+
+  @return The read value from the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciExpressRead16 (
+  IN      UINTN Address
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioRead16 ((UINTN)GetPciExpressAddress (Address));
+}
+
+/**
+  Writes a 16-bit PCI configuration register.
+
+  Writes the 16-bit PCI configuration register specified by Address with the
+  value specified by Value. Value is returned. This function must guarantee
+  that all PCI read and write operations are serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+  @param [in]  Value   The value to write.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciExpressWrite16 (
+  IN      UINTN  Address,
+  IN      UINT16 Value
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+
+  return MmioWrite16 ((UINTN)GetPciExpressAddress (Address), Value);
+}
+
+/**
+  Performs a bitwise OR of a 16-bit PCI configuration register with
+  a 16-bit value.
+
+  Reads the 16-bit PCI configuration register specified by Address, performs a
+  bitwise OR between the read result and the value specified by
+  OrData, and writes the result to the 16-bit PCI configuration register
+  specified by Address. The value written to the PCI configuration register is
+  returned. This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+  @param [in]  OrData  The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciExpressOr16 (
+  IN      UINTN  Address,
+  IN      UINT16 OrData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioOr16 ((UINTN)GetPciExpressAddress (Address), OrData);
+}
+
+/**
+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
+  value.
+
+  Reads the 16-bit PCI configuration register specified by Address, performs a
+  bitwise AND between the read result and the value specified by AndData, and
+  writes the result to the 16-bit PCI configuration register specified by
+  Address. The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are
+  serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+  @param [in]  AndData The value to AND with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciExpressAnd16 (
+  IN      UINTN  Address,
+  IN      UINT16 AndData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioAnd16 ((UINTN)GetPciExpressAddress (Address), AndData);
+}
+
+/**
+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
+  value, followed a  bitwise OR with another 16-bit value.
+
+  Reads the 16-bit PCI configuration register specified by Address, performs a
+  bitwise AND between the read result and the value specified by AndData,
+  performs a bitwise OR between the result of the AND operation and
+  the value specified by OrData, and writes the result to the 16-bit PCI
+  configuration register specified by Address. The value written to the PCI
+  configuration register is returned. This function must guarantee that all PCI
+  read and write operations are serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+  @param [in]  AndData The value to AND with the PCI configuration register.
+  @param [in]  OrData  The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciExpressAndThenOr16 (
+  IN      UINTN  Address,
+  IN      UINT16 AndData,
+  IN      UINT16 OrData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioAndThenOr16 (
+           (UINTN)GetPciExpressAddress (Address),
+           AndData,
+           OrData
+           );
+}
+
+/**
+  Reads a bit field of a PCI configuration register.
+
+  Reads the bit field in a 16-bit PCI configuration register. The bit field is
+  specified by the StartBit and the EndBit. The value of the bit field is
+  returned.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to read.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..15.
+
+  @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldRead16 (
+  IN      UINTN Address,
+  IN      UINTN StartBit,
+  IN      UINTN EndBit
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldRead16 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit
+           );
+}
+
+/**
+  Writes a bit field to a PCI configuration register.
+
+  Writes Value to the bit field of the PCI configuration register. The bit
+  field is specified by the StartBit and the EndBit. All other bits in the
+  destination PCI configuration register are preserved. The new value of the
+  16-bit register is returned.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  Value     The new value of the bit field.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldWrite16 (
+  IN      UINTN  Address,
+  IN      UINTN  StartBit,
+  IN      UINTN  EndBit,
+  IN      UINT16 Value
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldWrite16 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit,
+           Value
+           );
+}
+
+/**
+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
+  writes the result back to the bit field in the 16-bit port.
+
+  Reads the 16-bit PCI configuration register specified by Address, performs a
+  bitwise OR between the read result and the value specified by
+  OrData, and writes the result to the 16-bit PCI configuration register
+  specified by Address. The value written to the PCI configuration register is
+  returned. This function must guarantee that all PCI read and write operations
+  are serialized. Extra left bits in OrData are stripped.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldOr16 (
+  IN      UINTN  Address,
+  IN      UINTN  StartBit,
+  IN      UINTN  EndBit,
+  IN      UINT16 OrData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldOr16 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit,
+           OrData
+           );
+}
+
+/**
+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
+  AND, and writes the result back to the bit field in the 16-bit register.
+
+  Reads the 16-bit PCI configuration register specified by Address, performs a
+  bitwise AND between the read result and the value specified by AndData, and
+  writes the result to the 16-bit PCI configuration register specified by
+  Address. The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are
+  serialized. Extra left bits in AndData are stripped.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldAnd16 (
+  IN      UINTN  Address,
+  IN      UINTN  StartBit,
+  IN      UINTN  EndBit,
+  IN      UINT16 AndData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldAnd16 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit,
+           AndData
+           );
+}
+
+/**
+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
+  bitwise OR, and writes the result back to the bit field in the
+  16-bit port.
+
+  Reads the 16-bit PCI configuration register specified by Address, performs a
+  bitwise AND followed by a bitwise OR between the read result and
+  the value specified by AndData, and writes the result to the 16-bit PCI
+  configuration register specified by Address. The value written to the PCI
+  configuration register is returned. This function must guarantee that all PCI
+  read and write operations are serialized. Extra left bits in both AndData and
+  OrData are stripped.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..15.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+  @param [in]  OrData    The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldAndThenOr16 (
+  IN      UINTN  Address,
+  IN      UINTN  StartBit,
+  IN      UINTN  EndBit,
+  IN      UINT16 AndData,
+  IN      UINT16 OrData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldAndThenOr16 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit,
+           AndData,
+           OrData
+           );
+}
+
+/**
+  Reads a 32-bit PCI configuration register.
+
+  Reads and returns the 32-bit PCI configuration register specified by Address.
+  This function must guarantee that all PCI read and write operations are
+  serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+
+  @return The read value from the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciExpressRead32 (
+  IN      UINTN Address
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioRead32 ((UINTN)GetPciExpressAddress (Address));
+}
+
+/**
+  Writes a 32-bit PCI configuration register.
+
+  Writes the 32-bit PCI configuration register specified by Address with the
+  value specified by Value. Value is returned. This function must guarantee
+  that all PCI read and write operations are serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+  @param [in]  Value   The value to write.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciExpressWrite32 (
+  IN      UINTN  Address,
+  IN      UINT32 Value
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioWrite32 ((UINTN)GetPciExpressAddress (Address), Value);
+}
+
+/**
+  Performs a bitwise OR of a 32-bit PCI configuration register with
+  a 32-bit value.
+
+  Reads the 32-bit PCI configuration register specified by Address, performs a
+  bitwise OR between the read result and the value specified by
+  OrData, and writes the result to the 32-bit PCI configuration register
+  specified by Address. The value written to the PCI configuration register is
+  returned. This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+  @param [in]  OrData  The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciExpressOr32 (
+  IN      UINTN  Address,
+  IN      UINT32 OrData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioOr32 ((UINTN)GetPciExpressAddress (Address), OrData);
+}
+
+/**
+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
+  value.
+
+  Reads the 32-bit PCI configuration register specified by Address, performs a
+  bitwise AND between the read result and the value specified by AndData, and
+  writes the result to the 32-bit PCI configuration register specified by
+  Address. The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are
+  serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+  @param [in]  AndData The value to AND with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciExpressAnd32 (
+  IN      UINTN  Address,
+  IN      UINT32 AndData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioAnd32 ((UINTN)GetPciExpressAddress (Address), AndData);
+}
+
+/**
+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
+  value, followed a  bitwise OR with another 32-bit value.
+
+  Reads the 32-bit PCI configuration register specified by Address, performs a
+  bitwise AND between the read result and the value specified by AndData,
+  performs a bitwise OR between the result of the AND operation and
+  the value specified by OrData, and writes the result to the 32-bit PCI
+  configuration register specified by Address. The value written to the PCI
+  configuration register is returned. This function must guarantee that all PCI
+  read and write operations are serialized.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
+                       Register.
+  @param [in]  AndData The value to AND with the PCI configuration register.
+  @param [in]  OrData  The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciExpressAndThenOr32 (
+  IN      UINTN  Address,
+  IN      UINT32 AndData,
+  IN      UINT32 OrData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioAndThenOr32 (
+           (UINTN)GetPciExpressAddress (Address),
+           AndData,
+           OrData
+           );
+}
+
+/**
+  Reads a bit field of a PCI configuration register.
+
+  Reads the bit field in a 32-bit PCI configuration register. The bit field is
+  specified by the StartBit and the EndBit. The value of the bit field is
+  returned.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to read.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..31.
+
+  @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldRead32 (
+  IN      UINTN Address,
+  IN      UINTN StartBit,
+  IN      UINTN EndBit
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldRead32 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit
+           );
+}
+
+/**
+  Writes a bit field to a PCI configuration register.
+
+  Writes Value to the bit field of the PCI configuration register. The bit
+  field is specified by the StartBit and the EndBit. All other bits in the
+  destination PCI configuration register are preserved. The new value of the
+  32-bit register is returned.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  Value     The new value of the bit field.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldWrite32 (
+  IN      UINTN  Address,
+  IN      UINTN  StartBit,
+  IN      UINTN  EndBit,
+  IN      UINT32 Value
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldWrite32 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit,
+           Value
+           );
+}
+
+/**
+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
+  writes the result back to the bit field in the 32-bit port.
+
+  Reads the 32-bit PCI configuration register specified by Address, performs a
+  bitwise OR between the read result and the value specified by
+  OrData, and writes the result to the 32-bit PCI configuration register
+  specified by Address. The value written to the PCI configuration register is
+  returned. This function must guarantee that all PCI read and write operations
+  are serialized. Extra left bits in OrData are stripped.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldOr32 (
+  IN      UINTN  Address,
+  IN      UINTN  StartBit,
+  IN      UINTN  EndBit,
+  IN      UINT32 OrData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldOr32 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit,
+           OrData
+           );
+}
+
+/**
+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
+  AND, and writes the result back to the bit field in the 32-bit register.
+
+  Reads the 32-bit PCI configuration register specified by Address, performs a
+  bitwise AND between the read result and the value specified by AndData, and
+  writes the result to the 32-bit PCI configuration register specified by
+  Address. The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are
+  serialized. Extra left bits in AndData are stripped.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldAnd32 (
+  IN      UINTN  Address,
+  IN      UINTN  StartBit,
+  IN      UINTN  EndBit,
+  IN      UINT32 AndData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldAnd32 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit,
+           AndData
+           );
+}
+
+/**
+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
+  bitwise OR, and writes the result back to the bit field in the
+  32-bit port.
+
+  Reads the 32-bit PCI configuration register specified by Address, performs a
+  bitwise AND followed by a bitwise OR between the read result and
+  the value specified by AndData, and writes the result to the 32-bit PCI
+  configuration register specified by Address. The value written to the PCI
+  configuration register is returned. This function must guarantee that all PCI
+  read and write operations are serialized. Extra left bits in both AndData and
+  OrData are stripped.
+
+  If Address > 0x1FFFFFFFF, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and
+  EndBit, then ASSERT().
+
+  @param [in]  Address   The PCI configuration register to write.
+  @param [in]  StartBit  The ordinal of the least significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  EndBit    The ordinal of the most significant bit in the bit
+                         field. Range 0..31.
+  @param [in]  AndData   The value to AND with the PCI configuration register.
+  @param [in]  OrData    The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldAndThenOr32 (
+  IN      UINTN  Address,
+  IN      UINTN  StartBit,
+  IN      UINTN  EndBit,
+  IN      UINT32 AndData,
+  IN      UINT32 OrData
+  )
+{
+  ASSERT_INVALID_PCI_ADDRESS (Address);
+  return MmioBitFieldAndThenOr32 (
+           (UINTN)GetPciExpressAddress (Address),
+           StartBit,
+           EndBit,
+           AndData,
+           OrData
+           );
+}
+
+/**
+  Reads a range of PCI configuration registers into a caller supplied buffer.
+
+  Reads the range of PCI configuration registers specified by StartAddress and
+  Size into the buffer specified by Buffer. This function only allows the PCI
+  configuration registers from a single PCI function to be read. Size is
+  returned. When possible 32-bit PCI configuration read cycles are used to read
+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
+  and 16-bit PCI configuration read cycles may be used at the beginning and the
+  end of the range.
+
+  If StartAddress > 0x1FFFFFFFF, then ASSERT().
+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+  If Size > 0 and Buffer is NULL, then ASSERT().
+
+  @param [in]   StartAddress  The starting address that encodes the PCI Bus,
+                              Device, Function and Register.
+  @param [in]   Size          The size in bytes of the transfer.
+  @param [out]  Buffer        The pointer to a buffer receiving the data read.
+
+  @return Size read data from StartAddress.
+
+**/
+UINTN
+EFIAPI
+PciExpressReadBuffer (
+  IN      UINTN StartAddress,
+  IN      UINTN Size,
+  OUT     VOID  *Buffer
+  )
+{
+  UINTN  ReturnValue;
+
+  ASSERT_INVALID_PCI_ADDRESS (StartAddress);
+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
+
+  if (Size == 0) {
+    return Size;
+  }
+
+  ASSERT (Buffer != NULL);
+
+  // Save Size for return
+  ReturnValue = Size;
+
+  if ((StartAddress & 1) != 0) {
+    // Read a byte if StartAddress is byte aligned
+    *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);
+    StartAddress += sizeof (UINT8);
+    Size  -= sizeof (UINT8);
+    Buffer = (UINT8 *)Buffer + 1;
+  }
+
+  if ((Size >= sizeof (UINT16)) && ((StartAddress & 2) != 0)) {
+    // Read a word if StartAddress is word aligned
+    WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)PciExpressRead16 (StartAddress));
+
+    StartAddress += sizeof (UINT16);
+    Size  -= sizeof (UINT16);
+    Buffer = (UINT16 *)Buffer + 1;
+  }
+
+  while (Size >= sizeof (UINT32)) {
+    // Read as many double words as possible
+    WriteUnaligned32 ((UINT32 *)Buffer, (UINT32)PciExpressRead32 (StartAddress));
+
+    StartAddress += sizeof (UINT32);
+    Size  -= sizeof (UINT32);
+    Buffer = (UINT32 *)Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT16)) {
+    // Read the last remaining word if exist
+    WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)PciExpressRead16 (StartAddress));
+    StartAddress += sizeof (UINT16);
+    Size  -= sizeof (UINT16);
+    Buffer = (UINT16 *)Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT8)) {
+    // Read the last remaining byte if exist
+    *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);
+  }
+
+  return ReturnValue;
+}
+
+/**
+  Copies the data in a caller supplied buffer to a specified range of PCI
+  configuration space.
+
+  Writes the range of PCI configuration registers specified by StartAddress and
+  Size from the buffer specified by Buffer. This function only allows the PCI
+  configuration registers from a single PCI function to be written. Size is
+  returned. When possible 32-bit PCI configuration write cycles are used to
+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,
+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning
+  and the end of the range.
+
+  If StartAddress > 0x1FFFFFFFF, then ASSERT().
+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+  If Size > 0 and Buffer is NULL, then ASSERT().
+
+  @param [in]  StartAddress  The starting address that encodes the PCI Bus,
+                             Device, Function and Register.
+  @param [in]  Size          The size in bytes of the transfer.
+  @param [in]  Buffer        The pointer to a buffer containing the data to write.
+
+  @return Size written to StartAddress.
+
+**/
+UINTN
+EFIAPI
+PciExpressWriteBuffer (
+  IN      UINTN StartAddress,
+  IN      UINTN Size,
+  IN      VOID  *Buffer
+  )
+{
+  UINTN  ReturnValue;
+
+  ASSERT_INVALID_PCI_ADDRESS (StartAddress);
+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
+
+  if (Size == 0) {
+    return 0;
+  }
+
+  ASSERT (Buffer != NULL);
+
+  // Save Size for return
+  ReturnValue = Size;
+
+  if ((StartAddress & 1) != 0) {
+    // Write a byte if StartAddress is byte aligned
+    PciExpressWrite8 (StartAddress, *(UINT8 *)Buffer);
+    StartAddress += sizeof (UINT8);
+    Size  -= sizeof (UINT8);
+    Buffer = (UINT8 *)Buffer + 1;
+  }
+
+  if ((Size >= sizeof (UINT16)) && ((StartAddress & 2) != 0)) {
+    // Write a word if StartAddress is word aligned
+    PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16 *)Buffer));
+    StartAddress += sizeof (UINT16);
+    Size  -= sizeof (UINT16);
+    Buffer = (UINT16 *)Buffer + 1;
+  }
+
+  while (Size >= sizeof (UINT32)) {
+    // Write as many double words as possible
+    PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32 *)Buffer));
+    StartAddress += sizeof (UINT32);
+    Size  -= sizeof (UINT32);
+    Buffer = (UINT32 *)Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT16)) {
+    // Write the last remaining word if exist
+    PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16 *)Buffer));
+    StartAddress += sizeof (UINT16);
+    Size  -= sizeof (UINT16);
+    Buffer = (UINT16 *)Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT8)) {
+    // Write the last remaining byte if exist
+    PciExpressWrite8 (StartAddress, *(UINT8 *)Buffer);
+  }
+
+  return ReturnValue;
+}
diff --git a/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.uni b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.uni
new file mode 100644
index 000000000000..540453d4a189
--- /dev/null
+++ b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.uni
@@ -0,0 +1,18 @@
+// /** @file
+// Instance of PCI Express Library using the 256 MB PCI Express MMIO window.
+//
+// PCI Express Library that uses the 256 MB PCI Express MMIO window to perform
+// PCI Configuration cycles. Layers on top of an I/O Library instance.
+//
+// Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
+//
+// Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Instance of PCI Express Library using the 256 MB PCI Express MMIO window"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "PCI Express Library that uses the 256 MB PCI Express MMIO window to perform PCI Configuration cycles. Layers on top of an I/O Library instance."
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [edk2-platforms][PATCH V1 08/11] Platform/ARM/Morello: Enable PCIe and CCIX Root Ports
  2021-12-04 12:30 [edk2-platforms][PATCH V1 00/11] Add Support for Morello SoC chandni cherukuri
                   ` (6 preceding siblings ...)
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 07/11] Platform/ARM/Morello: Port PCI Express library chandni cherukuri
@ 2021-12-04 12:30 ` chandni cherukuri
  2021-12-07 20:59   ` Sami Mujawar
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 09/11] Platform/ARM/Morello: Add ACPI bindings for PCIe & CCIX chandni cherukuri
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: chandni cherukuri @ 2021-12-04 12:30 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Chandni Cherukuri

From: Anurag Koul <anurag.koul@arm.com>

Add definitions for both PCIe and CCIX Root Complex in PciHostBridge
Library. Also, use platform-specific PCI Segment Library and PCI
Express Library to enable PCIe support for Morello SoC.

With PCIe support added, various other modules dependent on PCIe
for instance, USB, AHCI, SATA, NVMe, etc., have also been enabled in
the platform definition files.

Signed-off-by: Anurag Koul <anurag.koul@arm.com>
Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
---
 Platform/ARM/Morello/MorelloPlatform.dec                              |  46 ++--
 Platform/ARM/Morello/MorelloPlatform.dsc.inc                          |  17 ++
 Platform/ARM/Morello/MorelloPlatformFvp.dsc                           |  21 +-
 Platform/ARM/Morello/MorelloPlatformSoc.dsc                           |  27 +++
 Platform/ARM/Morello/MorelloPlatformSoc.fdf                           |  25 ++
 Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.inf |  57 +++++
 Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf           |  18 ++
 Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.c   | 247 ++++++++++++++++++++
 Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c          |  50 +++-
 9 files changed, 479 insertions(+), 29 deletions(-)

diff --git a/Platform/ARM/Morello/MorelloPlatform.dec b/Platform/ARM/Morello/MorelloPlatform.dec
index 6f5c1c1b59fc..07701e7611b8 100644
--- a/Platform/ARM/Morello/MorelloPlatform.dec
+++ b/Platform/ARM/Morello/MorelloPlatform.dec
@@ -39,28 +39,46 @@
 
   # PCIe
   gArmMorelloTokenSpaceGuid.PcdPciBusMin|0|UINT32|0x00000009
-  gArmMorelloTokenSpaceGuid.PcdPciBusMax|15|UINT32|0x0000000A
-  gArmMorelloTokenSpaceGuid.PcdPciBusCount|16|UINT32|0x0000000B
+  gArmMorelloTokenSpaceGuid.PcdPciBusMax|255|UINT32|0x0000000A
+  gArmMorelloTokenSpaceGuid.PcdPciBusCount|256|UINT32|0x0000000B
   gArmMorelloTokenSpaceGuid.PcdPciIoBase|0x0|UINT32|0x0000000C
-  gArmMorelloTokenSpaceGuid.PcdPciIoSize|0x00800000|UINT32|0x0000000D
-  gArmMorelloTokenSpaceGuid.PcdPciIoMaxBase|0x007FFFFF|UINT32|0x0000000E
-  gArmMorelloTokenSpaceGuid.PcdPciIoTranslation|0x67800000|UINT32|0x0000000F
+  gArmMorelloTokenSpaceGuid.PcdPciIoSize|0x00400000|UINT32|0x0000000D
+  gArmMorelloTokenSpaceGuid.PcdPciIoMaxBase|0x003FFFFF|UINT32|0x0000000E
+  gArmMorelloTokenSpaceGuid.PcdPciIoTranslation|0x6F000000|UINT32|0x0000000F
   gArmMorelloTokenSpaceGuid.PcdPciMmio32Base|0x60000000|UINT32|0x00000010
-  gArmMorelloTokenSpaceGuid.PcdPciMmio32Size|0x07800000|UINT32|0x00000011
-  gArmMorelloTokenSpaceGuid.PcdPciMmio32MaxBase|0x677FFFFF|UINT32|0x00000012
+  gArmMorelloTokenSpaceGuid.PcdPciMmio32Size|0x0F000000|UINT32|0x00000011
+  gArmMorelloTokenSpaceGuid.PcdPciMmio32MaxBase|0x6EFFFFFF|UINT32|0x00000012
   gArmMorelloTokenSpaceGuid.PcdPciMmio32Translation|0x0|UINT32|0x00000013
   gArmMorelloTokenSpaceGuid.PcdPciMmio64Base|0x900000000|UINT64|0x00000014
-  gArmMorelloTokenSpaceGuid.PcdPciMmio64Size|0x2000000000|UINT64|0x00000015
-  gArmMorelloTokenSpaceGuid.PcdPciMmio64MaxBase|0x28FFFFFFFF|UINT64|0x00000016
+  gArmMorelloTokenSpaceGuid.PcdPciMmio64Size|0x1FC0000000|UINT64|0x00000015
+  gArmMorelloTokenSpaceGuid.PcdPciMmio64MaxBase|0x28BFFFFFFF|UINT64|0x00000016
   gArmMorelloTokenSpaceGuid.PcdPciMmio64Translation|0x0|UINT64|0x00000017
-  gArmMorelloTokenSpaceGuid.PcdPciExpressBaseAddress|0x20000000|UINT64|0x00000018
+  gArmMorelloTokenSpaceGuid.PcdPciExpressBaseAddress|0x28C0000000|UINT64|0x00000018
+
+  # CCIX
+  gArmMorelloTokenSpaceGuid.PcdCcixBusMin|0|UINT32|0x0000019
+  gArmMorelloTokenSpaceGuid.PcdCcixBusMax|255|UINT32|0x000001A
+  gArmMorelloTokenSpaceGuid.PcdCcixBusCount|256|UINT32|0x000001B
+  gArmMorelloTokenSpaceGuid.PcdCcixIoBase|0x0|UINT32|0x000001C
+  gArmMorelloTokenSpaceGuid.PcdCcixIoSize|0x0400000|UINT32|0x000001D
+  gArmMorelloTokenSpaceGuid.PcdCcixIoMaxBase|0x003FFFFF|UINT32|0x000001E
+  gArmMorelloTokenSpaceGuid.PcdCcixIoTranslation|0x7F000000|UINT32|0x00000001F
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Base|0x70000000|UINT32|0x00000020
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Size|0x0F000000|UINT32|0x00000021
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio32MaxBase|0x7EFFFFFF|UINT32|0x000000022
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Translation|0x0|UINT32|0x00000023
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Base|0x3000000000|UINT64|0x00000024
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Size|0x1FC0000000|UINT64|0x00000025
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio64MaxBase|0x4FBFFFFFFF|UINT64|0x00000026
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Translation|0x0|UINT64|0x00000027
+  gArmMorelloTokenSpaceGuid.PcdCcixExpressBaseAddress|0x4FC0000000|UINT64|0x0000028
 
   # Virtio Net device
-  gArmMorelloTokenSpaceGuid.PcdVirtioNetBaseAddress|0x00000000|UINT32|0x00000019
-  gArmMorelloTokenSpaceGuid.PcdVirtioNetSize|0x00000000|UINT32|0x0000001A
-  gArmMorelloTokenSpaceGuid.PcdVirtioNetInterrupt|0x00000000|UINT32|0x0000001B
+  gArmMorelloTokenSpaceGuid.PcdVirtioNetBaseAddress|0x00000000|UINT32|0x00000029
+  gArmMorelloTokenSpaceGuid.PcdVirtioNetSize|0x00000000|UINT32|0x0000002A
+  gArmMorelloTokenSpaceGuid.PcdVirtioNetInterrupt|0x00000000|UINT32|0x0000002B
 
 [PcdsFeatureFlag.common]
   gArmMorelloTokenSpaceGuid.PcdRamDiskSupported|FALSE|BOOLEAN|0x00000007
   gArmMorelloTokenSpaceGuid.PcdVirtioBlkSupported|FALSE|BOOLEAN|0x00000008
-  gArmMorelloTokenSpaceGuid.PcdVirtioNetSupported|FALSE|BOOLEAN|0x0000001C
+  gArmMorelloTokenSpaceGuid.PcdVirtioNetSupported|FALSE|BOOLEAN|0x0000002C
diff --git a/Platform/ARM/Morello/MorelloPlatform.dsc.inc b/Platform/ARM/Morello/MorelloPlatform.dsc.inc
index 862d5f2da1b0..e855c1ba0350 100644
--- a/Platform/ARM/Morello/MorelloPlatform.dsc.inc
+++ b/Platform/ARM/Morello/MorelloPlatform.dsc.inc
@@ -209,3 +209,20 @@
 
   # RAM Disk
   MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
+
+  # Required by PCI
+  ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
+
+  # PCI Support
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
+   <PcdsFixedAtBuild>
+     gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8010004F
+  }
+
+  # AHCI Support
+  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+
+  # SATA Controller
+  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
diff --git a/Platform/ARM/Morello/MorelloPlatformFvp.dsc b/Platform/ARM/Morello/MorelloPlatformFvp.dsc
index 1f9199fba2dc..61f54b891059 100644
--- a/Platform/ARM/Morello/MorelloPlatformFvp.dsc
+++ b/Platform/ARM/Morello/MorelloPlatformFvp.dsc
@@ -72,6 +72,13 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
   gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x20000000
 
+  #FVP Specific PCD values for PCIe
+  gArmMorelloTokenSpaceGuid.PcdPciBusMax|15
+  gArmMorelloTokenSpaceGuid.PcdPciBusCount|16
+  gArmMorelloTokenSpaceGuid.PcdPciMmio64Size|0x2000000000
+  gArmMorelloTokenSpaceGuid.PcdPciMmio64MaxBase|0x28FFFFFFFF
+  gArmMorelloTokenSpaceGuid.PcdPciExpressBaseAddress|0x20000000
+
 [Components.common]
   OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
   OvmfPkg/VirtioNetDxe/VirtioNet.inf
@@ -81,17 +88,3 @@
 
   # Required by PCI
   ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
-
-  # PCI Support
-  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
-  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
-    <PcdsFixedAtBuild>
-      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8010004F
-  }
-
-  # AHCI Support
-  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
-  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
-
-  # SATA Controller
-  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
diff --git a/Platform/ARM/Morello/MorelloPlatformSoc.dsc b/Platform/ARM/Morello/MorelloPlatformSoc.dsc
index 8335c50803b3..b6fe74ec6fdd 100644
--- a/Platform/ARM/Morello/MorelloPlatformSoc.dsc
+++ b/Platform/ARM/Morello/MorelloPlatformSoc.dsc
@@ -42,6 +42,33 @@
   # Platform Library
   ArmPlatformLib|Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
 
+  #USB Requirement
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+
+  [LibraryClasses.common.DXE_DRIVER]
+  PciHostBridgeLib|Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.inf
+  FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+  PciSegmentLib|Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.inf
+  PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
+  PciExpressLib|Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf
+
+[PcdsFixedAtBuild.common]
+  # PCIe
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|24
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
+
 [Components.common]
   # Platform driver
   Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf
+
+  # Usb Support
+  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+  # NVMe boot devices
+  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
diff --git a/Platform/ARM/Morello/MorelloPlatformSoc.fdf b/Platform/ARM/Morello/MorelloPlatformSoc.fdf
index e7d4a6a9828d..ec0297fdbca6 100644
--- a/Platform/ARM/Morello/MorelloPlatformSoc.fdf
+++ b/Platform/ARM/Morello/MorelloPlatformSoc.fdf
@@ -141,6 +141,31 @@ READ_LOCK_STATUS   = TRUE
   INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
   INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
 
+  # Required by PCI
+  INF ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
+
+  # PCI Support
+  INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+  INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+
+  # AHCI Support
+  INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+
+  # SATA Controller
+  INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+
+  # Usb Support
+  INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+  INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+  # NVMe boot devices
+  INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
 [FV.FVMAIN_COMPACT]
 FvAlignment        = 8
 BlockSize          = 0x1000
diff --git a/Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.inf b/Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.inf
new file mode 100644
index 000000000000..3187e4b34087
--- /dev/null
+++ b/Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.inf
@@ -0,0 +1,57 @@
+## @file
+#  PCI Host Bridge Library instance for ARM Morello SoC platform.
+#
+#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = PciHostBridgeLib
+  FILE_GUID                      = 82f5bd18-4e07-11ec-81d3-0242ac130003
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PciHostBridgeLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+#  VALID_ARCHITECTURES           = AARCH64
+#
+
+[Sources]
+  PciHostBridgeLibSoc.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Platform/ARM/Morello/MorelloPlatform.dec
+
+[FixedPcd]
+  gArmMorelloTokenSpaceGuid.PcdPciBusMax
+  gArmMorelloTokenSpaceGuid.PcdPciBusMin
+  gArmMorelloTokenSpaceGuid.PcdPciIoBase
+  gArmMorelloTokenSpaceGuid.PcdPciIoSize
+  gArmMorelloTokenSpaceGuid.PcdPciMmio32Base
+  gArmMorelloTokenSpaceGuid.PcdPciMmio32Size
+  gArmMorelloTokenSpaceGuid.PcdPciMmio64Base
+  gArmMorelloTokenSpaceGuid.PcdPciMmio64Size
+
+  gArmMorelloTokenSpaceGuid.PcdCcixBusMin
+  gArmMorelloTokenSpaceGuid.PcdCcixBusMax
+  gArmMorelloTokenSpaceGuid.PcdCcixIoBase
+  gArmMorelloTokenSpaceGuid.PcdCcixIoSize
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Base
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Size
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Base
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Size
+
+[Protocols]
+  gEfiCpuIo2ProtocolGuid          ## CONSUMES
+
+[Depex]
+  gEfiCpuIo2ProtocolGuid
diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
index bc31b8709152..0a36a5fe50a5 100644
--- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
+++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
@@ -32,6 +32,24 @@
 [FixedPcd]
   gArmMorelloTokenSpaceGuid.PcdDramBlock2Base
 
+  gArmMorelloTokenSpaceGuid.PcdPciBusMax
+  gArmMorelloTokenSpaceGuid.PcdPciBusMin
+  gArmMorelloTokenSpaceGuid.PcdPciExpressBaseAddress
+  gArmMorelloTokenSpaceGuid.PcdPciIoSize
+  gArmMorelloTokenSpaceGuid.PcdPciMmio32Base
+  gArmMorelloTokenSpaceGuid.PcdPciMmio32Size
+  gArmMorelloTokenSpaceGuid.PcdPciMmio64Base
+  gArmMorelloTokenSpaceGuid.PcdPciMmio64Size
+
+  gArmMorelloTokenSpaceGuid.PcdCcixBusMax
+  gArmMorelloTokenSpaceGuid.PcdCcixBusMin
+  gArmMorelloTokenSpaceGuid.PcdCcixExpressBaseAddress
+  gArmMorelloTokenSpaceGuid.PcdCcixIoSize
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Base
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Size
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Base
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Size
+
   gArmTokenSpaceGuid.PcdArmPrimaryCore
   gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
   gArmTokenSpaceGuid.PcdSystemMemoryBase
diff --git a/Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.c b/Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.c
new file mode 100644
index 000000000000..4d97474821df
--- /dev/null
+++ b/Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.c
@@ -0,0 +1,247 @@
+/** @file
+  PCI Host Bridge Library instance for ARM Morello SoC platform.
+
+  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+
+#define ROOT_COMPLEX_NUM  2
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+STATIC CHAR16 CONST *CONST  mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
+  L"Mem", L"I/O", L"Bus"
+};
+
+#pragma pack(1)
+typedef struct {
+  ACPI_HID_DEVICE_PATH        AcpiDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL    EndDevicePath;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+#pragma pack ()
+
+STATIC EFI_PCI_ROOT_BRIDGE_DEVICE_PATH  mEfiPciRootBridgeDevicePath[ROOT_COMPLEX_NUM] = {
+  {
+    {
+      {
+        ACPI_DEVICE_PATH,
+        ACPI_DP,
+        {
+          (UINT8)sizeof (ACPI_HID_DEVICE_PATH),
+          (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
+        }
+      },
+      EISA_PNP_ID (0x0A08),
+      0
+    },
+    {
+      END_DEVICE_PATH_TYPE,
+      END_ENTIRE_DEVICE_PATH_SUBTYPE,
+      {
+        END_DEVICE_PATH_LENGTH,
+        0
+      }
+    }
+  },
+  {
+    {
+      {
+        ACPI_DEVICE_PATH,
+        ACPI_DP,
+        {
+          (UINT8)sizeof (ACPI_HID_DEVICE_PATH),
+          (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
+        }
+      },
+      EISA_PNP_ID (0x0A09),
+      0
+    },
+    {
+      END_DEVICE_PATH_TYPE,
+      END_ENTIRE_DEVICE_PATH_SUBTYPE,
+      {
+        END_DEVICE_PATH_LENGTH,
+        0
+      }
+    }
+  },
+};
+
+STATIC PCI_ROOT_BRIDGE  mPciRootBridge[ROOT_COMPLEX_NUM] = {
+  {
+    0,                                              // Segment
+    0,                                              // Supports
+    0,                                              // Attributes
+    TRUE,                                           // DmaAbove4G
+    FALSE,                                          // NoExtendedConfigSpace
+    FALSE,                                          // ResourceAssigned
+    EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM |          // AllocationAttributes
+    EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+    {
+      // Bus
+      FixedPcdGet32 (PcdPciBusMin),
+      FixedPcdGet32 (PcdPciBusMax)
+    },{
+      // Io
+      FixedPcdGet64 (PcdPciIoBase),
+      FixedPcdGet64 (PcdPciIoBase) + FixedPcdGet64 (PcdPciIoSize) - 1
+    },{
+      // Mem
+      FixedPcdGet32 (PcdPciMmio32Base),
+      FixedPcdGet32 (PcdPciMmio32Base) + FixedPcdGet32 (PcdPciMmio32Size) - 1
+    },{
+      // MemAbove4G
+      FixedPcdGet64 (PcdPciMmio64Base),
+      FixedPcdGet64 (PcdPciMmio64Base) + FixedPcdGet64 (PcdPciMmio64Size) - 1
+    },{
+      // PMem
+      MAX_UINT64,
+      0
+    },{
+      // PMemAbove4G
+      MAX_UINT64,
+      0
+    },
+    (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[0]
+  },
+  {
+    1,                                              // Segment
+    0,                                              // Supports
+    0,                                              // Attributes
+    TRUE,                                           // DmaAbove4G
+    FALSE,                                          // NoExtendedConfigSpace
+    FALSE,                                          // ResourceAssigned
+    EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM |          // AllocationAttributes
+    EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+    {
+      // Bus
+      FixedPcdGet32 (PcdCcixBusMin),
+      FixedPcdGet32 (PcdCcixBusMax)
+    },{
+      // Io
+      FixedPcdGet64 (PcdCcixIoBase),
+      FixedPcdGet64 (PcdCcixIoBase) + FixedPcdGet64 (PcdCcixIoSize) - 1
+    },{
+      // Mem
+      FixedPcdGet32 (PcdCcixMmio32Base),
+      FixedPcdGet32 (PcdCcixMmio32Base) + FixedPcdGet32 (PcdCcixMmio32Size) - 1
+    },{
+      // MemAbove4G
+      FixedPcdGet64 (PcdCcixMmio64Base),
+      FixedPcdGet64 (PcdCcixMmio64Base) + FixedPcdGet64 (PcdCcixMmio64Size) - 1
+    },{
+      // PMem
+      MAX_UINT64,
+      0
+    },{
+      // PMemAbove4G
+      MAX_UINT64,
+      0
+    },
+    (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[1]
+  },
+};
+
+/**
+  Return all the root bridge instances in an array.
+
+  @param Count  Return the count of root bridge instances.
+
+  @return All the root bridge instances in an array.
+          The array should be passed into PciHostBridgeFreeRootBridges()
+          when it's not used.
+**/
+PCI_ROOT_BRIDGE *
+EFIAPI
+PciHostBridgeGetRootBridges (
+  UINTN *Count
+  )
+{
+  *Count = ARRAY_SIZE (mPciRootBridge);
+  return mPciRootBridge;
+}
+
+/**
+  Free the root bridge instances array returned from PciHostBridgeGetRootBridges().
+
+  @param Bridges The root bridge instances array.
+  @param Count   The count of the array.
+**/
+VOID
+EFIAPI
+PciHostBridgeFreeRootBridges (
+  PCI_ROOT_BRIDGE *Bridges,
+  UINTN           Count
+  )
+{
+}
+
+/**
+  Inform the platform that the resource conflict happens.
+
+  @param HostBridgeHandle Handle of the Host Bridge.
+  @param Configuration    Pointer to PCI I/O and PCI memory resource
+                          descriptors. The Configuration contains the resources
+                          for all the root bridges. The resource for each root
+                          bridge is terminated with END descriptor and an
+                          additional END is appended indicating the end of the
+                          entire resources. The resource descriptor field
+                          values follow the description in
+                          EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+                          .SubmitResources().
+**/
+VOID
+EFIAPI
+PciHostBridgeResourceConflict (
+  EFI_HANDLE HostBridgeHandle,
+  VOID       *Configuration
+  )
+{
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Descriptor;
+  UINTN                              RootBridgeIndex;
+
+  DEBUG ((DEBUG_ERROR, "PciHostBridge: Resource conflict happens!\n"));
+
+  RootBridgeIndex = 0;
+  Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Configuration;
+  while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+    DEBUG ((DEBUG_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
+    for ( ; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
+      ASSERT (
+        Descriptor->ResType <
+        (ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr))
+        );
+      DEBUG ((
+        DEBUG_ERROR,
+        "%s: Length/Alignment = 0x%lx / 0x%lx\n",
+        mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
+        Descriptor->AddrLen,
+        Descriptor->AddrRangeMax
+        ));
+      if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
+        DEBUG ((
+          DEBUG_ERROR,
+          "Granularity/SpecificFlag = %ld / %02x%s\n",
+          Descriptor->AddrSpaceGranularity,
+          Descriptor->SpecificFlag,
+          ((Descriptor->SpecificFlag &
+            EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
+            ) != 0) ? L" (Prefetchable)" : L""
+          ));
+      }
+    }
+
+    //
+    // Skip the END descriptor for root bridge
+    //
+    ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
+    Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
+                   (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
+                   );
+  }
+}
diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
index 67dd8469feb8..5140764c54bc 100644
--- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
+++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
@@ -12,7 +12,7 @@
 #include <MorelloPlatform.h>
 
 // The total number of descriptors, including the final "end-of-table" descriptor.
-#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS  9
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS  15
 
 #if !defined (MDEPKG_NDEBUG)
   STATIC CONST CHAR8  *gTblAttrDesc[] = {
@@ -163,6 +163,54 @@ ArmPlatformGetVirtualMemoryMap (
   VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
   LOG_MEM ("Expansion Peripherals           : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
 
+  // PCIe ECAM Configuration Space
+  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdPciExpressBaseAddress);
+  VirtualMemoryTable[Index].VirtualBase    = PcdGet64 (PcdPciExpressBaseAddress);
+  VirtualMemoryTable[Index].Length = (FixedPcdGet32 (PcdPciBusMax) -
+                                      FixedPcdGet32 (PcdPciBusMin) + 1) *
+                                     SIZE_1MB;
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  LOG_MEM ("PCIe ECAM Region                : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+  // PCIe MMIO32 Memory Space
+  VirtualMemoryTable[++Index].PhysicalBase = PcdGet32 (PcdPciMmio32Base);
+  VirtualMemoryTable[Index].VirtualBase    = PcdGet32 (PcdPciMmio32Base);
+  VirtualMemoryTable[Index].Length = (PcdGet32 (PcdPciMmio32Size) +
+                                      PcdGet32 (PcdPciIoSize));
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  LOG_MEM ("PCIe MMIO32 & IO Region         : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+  // PCIe MMIO64 Memory Space
+  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdPciMmio64Base);
+  VirtualMemoryTable[Index].VirtualBase    = PcdGet64 (PcdPciMmio64Base);
+  VirtualMemoryTable[Index].Length     = PcdGet64 (PcdPciMmio64Size);
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  LOG_MEM ("PCIe MMIO64 Region              : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+  // CCIX ECAM Configuration Space
+  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdCcixExpressBaseAddress);
+  VirtualMemoryTable[Index].VirtualBase    = PcdGet64 (PcdCcixExpressBaseAddress);
+  VirtualMemoryTable[Index].Length = (FixedPcdGet32 (PcdCcixBusMax) -
+                                      FixedPcdGet32 (PcdCcixBusMin) + 1) *
+                                     SIZE_1MB;
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  LOG_MEM ("CCIX ECAM Region                : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+  // CCIX MMIO32 Memory Space
+  VirtualMemoryTable[++Index].PhysicalBase = PcdGet32 (PcdCcixMmio32Base);
+  VirtualMemoryTable[Index].VirtualBase    = PcdGet32 (PcdCcixMmio32Base);
+  VirtualMemoryTable[Index].Length = (PcdGet32 (PcdCcixMmio32Size) +
+                                      PcdGet32 (PcdCcixIoSize));
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  LOG_MEM ("CCIX MMIO32 & IO Region         : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+  // CCIX MMIO64 Memory Space
+  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdCcixMmio64Base);
+  VirtualMemoryTable[Index].VirtualBase    = PcdGet64 (PcdCcixMmio64Base);
+  VirtualMemoryTable[Index].Length     = PcdGet64 (PcdCcixMmio64Size);
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  LOG_MEM ("CCIX MMIO64 Region              : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
   // End of Table
   VirtualMemoryTable[++Index].PhysicalBase = 0;
   VirtualMemoryTable[Index].VirtualBase    = 0;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [edk2-platforms][PATCH V1 09/11] Platform/ARM/Morello: Add ACPI bindings for PCIe & CCIX
  2021-12-04 12:30 [edk2-platforms][PATCH V1 00/11] Add Support for Morello SoC chandni cherukuri
                   ` (7 preceding siblings ...)
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 08/11] Platform/ARM/Morello: Enable PCIe and CCIX Root Ports chandni cherukuri
@ 2021-12-04 12:30 ` chandni cherukuri
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 10/11] Platform/ARM/Morello: Add support to parse NT_FW_CONFIG chandni cherukuri
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 11/11] Platform/ARM/Morello: Update Readme.md chandni cherukuri
  10 siblings, 0 replies; 31+ messages in thread
From: chandni cherukuri @ 2021-12-04 12:30 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Chandni Cherukuri

From: Anurag Koul <anurag.koul@arm.com>

This commit adds:

- SSDT, MCFG table for PCIe and CCIX RC nodes
- IORT nodes bindings for PCIe/CCIX and the associated ITSs and SMMUs
  in the Configuration Manager.

Signed-off-by: Anurag Koul <anurag.koul@arm.com>
Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
---
 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf |  35 ++
 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h      |  26 +-
 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c      | 596 +++++++++++++++++++-
 Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtPciSoc.asl       | 223 ++++++++
 4 files changed, 877 insertions(+), 3 deletions(-)

diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
index 6f9199a6fda2..fb6f72684148 100644
--- a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
+++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
@@ -22,6 +22,7 @@
 
 [Sources]
   AslTables/DsdtSoc.asl
+  AslTables/SsdtPciSoc.asl
   ConfigurationManager.c
   ConfigurationManager.h
   ConfigurationManagerSoc.c
@@ -43,6 +44,40 @@
   gEdkiiConfigurationManagerProtocolGuid
 
 [FixedPcd]
+  gArmMorelloTokenSpaceGuid.PcdPciBusCount
+  gArmMorelloTokenSpaceGuid.PcdPciBusMax
+  gArmMorelloTokenSpaceGuid.PcdPciBusMin
+  gArmMorelloTokenSpaceGuid.PcdPciExpressBaseAddress
+  gArmMorelloTokenSpaceGuid.PcdPciIoBase
+  gArmMorelloTokenSpaceGuid.PcdPciIoMaxBase
+  gArmMorelloTokenSpaceGuid.PcdPciIoSize
+  gArmMorelloTokenSpaceGuid.PcdPciIoTranslation
+  gArmMorelloTokenSpaceGuid.PcdPciMmio32Base
+  gArmMorelloTokenSpaceGuid.PcdPciMmio32MaxBase
+  gArmMorelloTokenSpaceGuid.PcdPciMmio32Size
+  gArmMorelloTokenSpaceGuid.PcdPciMmio32Translation
+  gArmMorelloTokenSpaceGuid.PcdPciMmio64Base
+  gArmMorelloTokenSpaceGuid.PcdPciMmio64MaxBase
+  gArmMorelloTokenSpaceGuid.PcdPciMmio64Size
+  gArmMorelloTokenSpaceGuid.PcdPciMmio64Translation
+
+  gArmMorelloTokenSpaceGuid.PcdCcixBusCount
+  gArmMorelloTokenSpaceGuid.PcdCcixBusMax
+  gArmMorelloTokenSpaceGuid.PcdCcixBusMin
+  gArmMorelloTokenSpaceGuid.PcdCcixExpressBaseAddress
+  gArmMorelloTokenSpaceGuid.PcdCcixIoBase
+  gArmMorelloTokenSpaceGuid.PcdCcixIoMaxBase
+  gArmMorelloTokenSpaceGuid.PcdCcixIoSize
+  gArmMorelloTokenSpaceGuid.PcdCcixIoTranslation
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Base
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio32MaxBase
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Size
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Translation
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Base
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio64MaxBase
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Size
+  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Translation
+
   ## PL011 Serial Debug UART
   gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
   gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate
diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
index 8a521b83c8dc..fc0bbabdd1aa 100644
--- a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
+++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
@@ -16,7 +16,7 @@
 
 /** The number of ACPI tables to install
 */
-#define PLAT_ACPI_TABLE_COUNT  7
+#define PLAT_ACPI_TABLE_COUNT  10
 
 /** A helper macro for mapping a reference token
 */
@@ -29,12 +29,34 @@
     containing the AML bytecode array.
 */
 extern CHAR8  dsdtsoc_aml_code[];
+extern CHAR8  ssdtpcisoc_aml_code[];
 
 /** A structure describing the SoC Platform specific information
 */
 typedef struct SocPlatformRepositoryInfo {
   /// List of ACPI tables
-  CM_STD_OBJ_ACPI_TABLE_INFO    CmAcpiTableList[PLAT_ACPI_TABLE_COUNT];
+  CM_STD_OBJ_ACPI_TABLE_INFO      CmAcpiTableList[PLAT_ACPI_TABLE_COUNT];
+
+  /// GIC ITS information
+  CM_ARM_GIC_ITS_INFO             GicItsInfo[4];
+
+  /// ITS Group node
+  CM_ARM_ITS_GROUP_NODE           ItsGroupInfo[4];
+
+  /// ITS Identifier array
+  CM_ARM_ITS_IDENTIFIER           ItsIdentifierArray[4];
+
+  /// SMMUv3 node
+  CM_ARM_SMMUV3_NODE              SmmuV3Info[2];
+
+  /// PCI Root complex node
+  CM_ARM_ROOT_COMPLEX_NODE        RootComplexInfo[2];
+
+  /// Array of DeviceID mapping
+  CM_ARM_ID_MAPPING               DeviceIdMapping[3][2];
+
+  /// PCI configuration space information
+  CM_ARM_PCI_CONFIG_SPACE_INFO    PciConfigInfo[2];
 } EDKII_SOC_PLATFORM_REPOSITORY_INFO;
 
 /** A structure describing the platform configuration
diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
index 7ca8ae212a61..f4ad6d934f0c 100644
--- a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
+++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
@@ -73,6 +73,341 @@ EDKII_SOC_PLATFORM_REPOSITORY_INFO  MorelloSocRepositoryInfo = {
       CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdPptt),
       NULL
     },
+    // IORT Table
+    {
+      EFI_ACPI_6_3_IO_REMAPPING_TABLE_SIGNATURE,
+      EFI_ACPI_IO_REMAPPING_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdIort),
+      NULL
+    },
+    // PCI MCFG Table
+    {
+      EFI_ACPI_6_3_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
+    {
+      EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+      0, // Unused
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdt),
+      (EFI_ACPI_DESCRIPTION_HEADER *)ssdtpcisoc_aml_code
+    },
+  },
+
+  // GIC ITS
+  {
+    // GIC ITS - PCIe TCU
+    {
+      // The GIC ITS ID.
+      0,
+      // The physical address for the Interrupt Translation Service
+      0x30060000,
+      // Proximity Domain
+      0
+    },
+    // GIC ITS - PCIe RC
+    {
+      // The GIC ITS ID.
+      1,
+      // The physical address for the Interrupt Translation Service
+      0x300A0000,
+      // Proximity Domain
+      0
+    },
+    // GIC ITS - CCIX TCU
+    {
+      // The GIC ITS ID.
+      2,
+      // The physical address for the Interrupt Translation Service
+      0x30040000,
+      // Proximity Domain
+      0
+    },
+    // GIC ITS - CCIX RC
+    {
+      // The GIC ITS ID.
+      3,
+      // The physical address for the Interrupt Translation Service
+      0x30080000,
+      // Proximity Domain
+      0
+    },
+  },
+
+  // ITS group node
+  {
+    {
+      // Reference token for this Iort node
+      REFERENCE_TOKEN_SOC (ItsGroupInfo[0]),
+      // The number of ITS identifiers in the ITS node.
+      1,
+      // Reference token for the ITS identifier array
+      REFERENCE_TOKEN_SOC (ItsIdentifierArray[0])
+    },
+    {
+      // Reference token for this Iort node
+      REFERENCE_TOKEN_SOC (ItsGroupInfo[1]),
+      // The number of ITS identifiers in the ITS node.
+      1,
+      // Reference token for the ITS identifier array
+      REFERENCE_TOKEN_SOC (ItsIdentifierArray[1])
+    },
+    {
+      // Reference token for this Iort node
+      REFERENCE_TOKEN_SOC (ItsGroupInfo[2]),
+      // The number of ITS identifiers in the ITS node.
+      1,
+      // Reference token for the ITS identifier array
+      REFERENCE_TOKEN_SOC (ItsIdentifierArray[2])
+    },
+    {
+      // Reference token for this Iort node
+      REFERENCE_TOKEN_SOC (ItsGroupInfo[3]),
+      // The number of ITS identifiers in the ITS node.
+      1,
+      // Reference token for the ITS identifier array
+      REFERENCE_TOKEN_SOC (ItsIdentifierArray[3])
+    },
+  },
+
+  // ITS identifier array
+  {
+    {
+      // The ITS Identifier
+      0
+    },
+    {
+      // The ITS Identifier
+      1
+    },
+    {
+      // The ITS Identifier
+      2
+    },
+    {
+      // The ITS Identifier
+      3
+    },
+  },
+
+  // SMMUv3 Node
+  {
+    {
+      // Reference token for this Iort node
+      REFERENCE_TOKEN_SOC (SmmuV3Info[0]),
+      // Number of ID mappings
+      2,
+      // Reference token for the ID mapping array
+      REFERENCE_TOKEN_SOC (DeviceIdMapping[0][0]),
+      // SMMU Base Address
+      0x4F400000,
+      // 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
+      267,
+      // PRI Interrupt if SPI based
+      72,
+      // GERR interrupt if GSIV based
+      269,
+      // Sync interrupt if GSIV based
+      268,
+      // Proximity domain flag, ignored in this case
+      0,
+      // Index into the array of ID mapping
+      1
+    },
+    {
+      // Reference token for this Iort node
+      REFERENCE_TOKEN_SOC (SmmuV3Info[1]),
+      // Number of ID mappings
+      2,
+      // Reference token for the ID mapping array
+      REFERENCE_TOKEN_SOC (DeviceIdMapping[2][0]),
+      // SMMU Base Address
+      0x4F000000,
+      // 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
+      260,
+      // PRI Interrupt if SPI based
+      73,
+      // GERR interrupt if GSIV based
+      262,
+      // Sync interrupt if GSIV based
+      261,
+      // Proximity domain flag, ignored in this case
+      0,
+      // Index into the array of ID mapping
+      1
+    },
+  },
+
+  // Root Complex node info
+  {
+    {
+      // Reference token for this Iort node
+      REFERENCE_TOKEN_SOC (RootComplexInfo[0]),
+      // Number of ID mappings
+      1,
+      // Reference token for the ID mapping array
+      REFERENCE_TOKEN_SOC (DeviceIdMapping[1][0]),
+
+      // 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
+      3,
+      // PCI segment number
+      0,
+      // Memory address size limit
+      42
+    },
+    {
+      // Reference token for this Iort node
+      REFERENCE_TOKEN_SOC (RootComplexInfo[1]),
+      // Number of ID mappings
+      1,
+      // Reference token for the ID mapping array
+      REFERENCE_TOKEN_SOC (DeviceIdMapping[1][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
+      3,
+      // PCI segment number
+      1,
+      // Memory address size limit
+      42
+    },
+  },
+
+  // Array of Device ID mappings
+  {
+    // DeviceIdMapping[0][0] - [0][1]
+    {
+      /* Mapping SMMUv3 -> ITS Group
+      */
+
+      // SMMUv3 device ID mapping
+      {
+        // Input base
+        0x0,
+        // Number of input IDs
+        0x0000FFFF,
+        // Output Base
+        0x0,
+        // Output reference
+        REFERENCE_TOKEN_SOC (ItsGroupInfo[1]),
+        // Flags
+        0
+      },
+      // SMMUv3 device ID mapping
+      {
+        // Input base
+        0x0,
+        // Number of input IDs
+        0x00000001,
+        // Output Base
+        0x0,
+        // Output reference token for the IORT node
+        REFERENCE_TOKEN_SOC (ItsGroupInfo[0]),
+        // Flags
+        EFI_ACPI_IORT_ID_MAPPING_FLAGS_SINGLE
+      }
+    },
+    // Device ID mapping [1][0] - [1][1]
+    {
+      // Mapping for  RootComplex -> SMMUv3
+      {
+        // Input base
+        0x0,
+        // Number of input IDs
+        0x0000FFFF,
+        // Output Base
+        0x0,
+        // Output reference
+        REFERENCE_TOKEN_SOC (SmmuV3Info[0]),
+        // Flags
+        0
+      },
+      {
+        // Input base
+        0x0,
+        // Number of input IDs
+        0x0000FFFF,
+        // Output Base
+        0x0,
+        // Output reference
+        REFERENCE_TOKEN_SOC (SmmuV3Info[1]),
+        // Flags
+        0
+      },
+    },
+    // DeviceIdMapping[2][0] - [2][1]
+    {
+      /* Mapping SMMUv3 -> ITS Group
+      */
+      // SMMUv3 device ID mapping
+      {
+        // Input base
+        0x0,
+        // Number of input IDs
+        0x0000FFFF,
+        // Output Base
+        0x0,
+        // Output reference
+        REFERENCE_TOKEN_SOC (ItsGroupInfo[3]),
+        // Flags
+        0
+      },
+      // SMMUv3 device ID mapping
+      {
+        // Input base
+        0x0,
+        // Number of input IDs
+        0x00000001,
+        // Output Base
+        0x0,
+        // Output reference token for the IORT node
+        REFERENCE_TOKEN_SOC (ItsGroupInfo[2]),
+        // Flags
+        EFI_ACPI_IORT_ID_MAPPING_FLAGS_SINGLE
+      }
+    },
+  },
+  // PCI Configuration Space Info
+  {
+    // PCIe ECAM
+    {
+      FixedPcdGet64 (PcdPciExpressBaseAddress),  // Base Address
+      0x0,                                       // Segment Group Number
+      FixedPcdGet32 (PcdPciBusMin),              // Start Bus Number
+      FixedPcdGet32 (PcdPciBusMax)               // End Bus Number
+    },
+    // CCIX ECAM
+    {
+      FixedPcdGet64 (PcdCcixExpressBaseAddress),  // Base Address
+      0x1,                                        // Segment Group Number
+      FixedPcdGet32 (PcdCcixBusMin),              // Start Bus Number
+      FixedPcdGet32 (PcdCcixBusMax)               // End Bus Number
+    }
   },
 };
 
@@ -81,6 +416,167 @@ EDKII_PLATFORM_REPOSITORY_INFO  MorelloRepositoryInfo = {
   &MorelloSocRepositoryInfo
 };
 
+/** 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 [in, 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_SOC_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
+  UINTN                               Count;
+
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformRepo = This->PlatRepoInfo->SocPlatRepoInfo;
+
+  DEBUG ((DEBUG_INFO, "DeviceIdMapping - Token = %p\n"));
+
+  if (Token == (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[0][0]) {
+    Count = 2;
+    DEBUG ((DEBUG_INFO, "DeviceIdMapping - Found DeviceIdMapping[0][0]\n"));
+  } else if (Token ==
+             (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[1][0])
+  {
+    Count = 1;
+    DEBUG ((DEBUG_INFO, "DeviceIdMapping - Found DeviceIdMapping[1][0]\n"));
+  } else if (Token ==
+             (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[1][1])
+  {
+    Count = 1;
+    DEBUG ((DEBUG_INFO, "DeviceIdMapping - Found DeviceIdMapping[1][1]\n"));
+  } else if (Token ==
+             (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[2][0])
+  {
+    Count = 2;
+    DEBUG ((DEBUG_INFO, "DeviceIdMapping - Found DeviceIdMapping[2][0]\n"));
+  } else {
+    DEBUG ((DEBUG_INFO, "DeviceIdMapping - Not Found\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  CmObject->Data     = (VOID *)Token;
+  CmObject->ObjectId = CmObjectId;
+  CmObject->Count    = Count;
+  CmObject->Size     = Count * sizeof (CM_ARM_ID_MAPPING);
+
+  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 [in, 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_SOC_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
+  UINTN                               Count;
+  UINTN                               Index;
+
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformRepo = This->PlatRepoInfo->SocPlatRepoInfo;
+
+  Count = ARRAY_SIZE (PlatformRepo->ItsIdentifierArray);
+
+  for (Index = 0; Index < Count; Index++) {
+    if (Token == (CM_OBJECT_TOKEN)&PlatformRepo->ItsIdentifierArray[Index]) {
+      CmObject->ObjectId = CmObjectId;
+      CmObject->Size     = sizeof (PlatformRepo->ItsIdentifierArray[0]);
+      CmObject->Data     = (VOID *)&PlatformRepo->ItsIdentifierArray[Index];
+      CmObject->Count    = 1;
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/** Return an ITS group info.
+
+  @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 [in, 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
+GetItsGroupInfo (
+  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_SOC_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
+  UINTN                               Count;
+  UINTN                               Index;
+
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformRepo = This->PlatRepoInfo->SocPlatRepoInfo;
+
+  Count = ARRAY_SIZE (PlatformRepo->ItsGroupInfo);
+
+  for (Index = 0; Index < Count; Index++) {
+    if (Token == (CM_OBJECT_TOKEN)&PlatformRepo->ItsGroupInfo[Index]) {
+      CmObject->ObjectId = CmObjectId;
+      CmObject->Size     = sizeof (PlatformRepo->ItsGroupInfo[0]);
+      CmObject->Data     = (VOID *)&PlatformRepo->ItsGroupInfo[Index];
+      CmObject->Count    = 1;
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
 /** Return platform specific ARM namespace object.
 
   @param [in]      This        Pointer to the Configuration Manager Protocol.
@@ -103,7 +599,105 @@ GetArmNameSpaceObjectPlat (
   IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST CmObject
   )
 {
-  return EFI_NOT_FOUND;
+  EFI_STATUS                          Status;
+  EDKII_SOC_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
+
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformRepo = This->PlatRepoInfo->SocPlatRepoInfo;
+  Status = EFI_NOT_FOUND;
+
+  switch (GET_CM_OBJECT_ID (CmObjectId)) {
+    case EArmObjGicItsInfo:
+      Status = HandleCmObject (
+                 CmObjectId,
+                 &PlatformRepo->GicItsInfo,
+                 sizeof (PlatformRepo->GicItsInfo),
+                 ARRAY_SIZE (PlatformRepo->GicItsInfo),
+                 CmObject
+                 );
+      break;
+
+    case EArmObjSmmuV3:
+      Status = HandleCmObject (
+                 CmObjectId,
+                 PlatformRepo->SmmuV3Info,
+                 sizeof (PlatformRepo->SmmuV3Info),
+                 ARRAY_SIZE (PlatformRepo->SmmuV3Info),
+                 CmObject
+                 );
+      break;
+
+    case EArmObjItsGroup:
+      Status = HandleCmObjectRefByToken (
+                 This,
+                 CmObjectId,
+                 PlatformRepo->ItsGroupInfo,
+                 sizeof (PlatformRepo->ItsGroupInfo),
+                 ARRAY_SIZE (PlatformRepo->ItsGroupInfo),
+                 Token,
+                 GetItsGroupInfo,
+                 CmObject
+                 );
+      break;
+
+    case EArmObjGicItsIdentifierArray:
+      Status = HandleCmObjectRefByToken (
+                 This,
+                 CmObjectId,
+                 PlatformRepo->ItsIdentifierArray,
+                 sizeof (PlatformRepo->ItsIdentifierArray),
+                 ARRAY_SIZE (PlatformRepo->ItsIdentifierArray),
+                 Token,
+                 GetItsIdentifierArray,
+                 CmObject
+                 );
+      break;
+
+    case EArmObjRootComplex:
+      Status = HandleCmObject (
+                 CmObjectId,
+                 PlatformRepo->RootComplexInfo,
+                 sizeof (PlatformRepo->RootComplexInfo),
+                 ARRAY_SIZE (PlatformRepo->RootComplexInfo),
+                 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),
+                 ARRAY_SIZE (PlatformRepo->PciConfigInfo),
+                 CmObject
+                 );
+      break;
+
+    default:
+    {
+      break;
+    }
+  }// switch
+
+  return Status;
 }
 
 /** Return platform specific standard namespace object.
diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtPciSoc.asl b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtPciSoc.asl
new file mode 100644
index 000000000000..32b78aa53aff
--- /dev/null
+++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtPciSoc.asl
@@ -0,0 +1,223 @@
+/** @file
+  Secondary System Description Table (SSDT)
+
+  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Reference(s):
+  - ACPI for Arm Components  1.0, Platform Design Document
+
+**/
+
+#include "ConfigurationManager.h"
+
+#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) */                            \
+}
+
+#define ROOT_PRT_ENTRY(Pin, Link)   PRT_ENTRY(0x0000FFFF, Pin, Link)  // Device 0 for Bridge.
+
+DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "MORELLO",
+                CFG_MGR_OEM_REVISION)
+{
+  Scope (_SB) {
+    // PCI Root Complex
+    LNK_DEVICE(1, LNKA, 201)
+    LNK_DEVICE(2, LNKB, 202)
+    LNK_DEVICE(3, LNKC, 203)
+    LNK_DEVICE(4, LNKD, 204)
+
+    // CCIX Root Complex
+    LNK_DEVICE(1, LNKE, 233)
+    LNK_DEVICE(2, LNKF, 234)
+    LNK_DEVICE(3, LNKG, 235)
+    LNK_DEVICE(4, LNKH, 236)
+
+    // PCI Root Complex
+    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)                 // Cache Coherency Attribute
+
+      // 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
+            FixedPcdGet32 (PcdPciBusMin),             // AddressMinimum - Minimum Bus Number
+            FixedPcdGet32 (PcdPciBusMax),             // AddressMaximum - Maximum Bus Number
+            0,                                        // AddressTranslation - Set to 0
+            FixedPcdGet32 (PcdPciBusCount)            // RangeLength - Number of Busses
+          )
+
+          DWordMemory (                               // 32-bit BAR Windows
+            ResourceProducer,
+            PosDecode,
+            MinFixed,
+            MaxFixed,
+            Cacheable,
+            ReadWrite,
+            0x00000000,                              // Granularity
+            FixedPcdGet32 (PcdPciMmio32Base),        // Min Base Address
+            FixedPcdGet32 (PcdPciMmio32MaxBase),     // Max Base Address
+            FixedPcdGet32 (PcdPciMmio32Translation), // Translate
+            FixedPcdGet32 (PcdPciMmio32Size)         // Length
+          )
+
+          QWordMemory (                               // 64-bit BAR Windows
+            ResourceProducer,
+            PosDecode,
+            MinFixed,
+            MaxFixed,
+            Cacheable,
+            ReadWrite,
+            0x00000000,                              // Granularity
+            FixedPcdGet64 (PcdPciMmio64Base),        // Min Base Address
+            FixedPcdGet64 (PcdPciMmio64MaxBase),     // Max Base Address
+            FixedPcdGet64 (PcdPciMmio64Translation), // Translate
+            FixedPcdGet64 (PcdPciMmio64Size)         // Length
+          )
+
+          DWordIo (                                   // IO window
+            ResourceProducer,
+            MinFixed,
+            MaxFixed,
+            PosDecode,
+            EntireRange,
+            0x00000000,                              // Granularity
+            FixedPcdGet32 (PcdPciIoBase),            // Min Base Address
+            FixedPcdGet32 (PcdPciIoMaxBase),         // Max Base Address
+            FixedPcdGet32 (PcdPciIoTranslation),     // Translate
+            FixedPcdGet32 (PcdPciIoSize),            // Length
+            ,
+            ,
+            ,
+            TypeTranslation
+          )
+        }) // Name(RBUF)
+        Return (RBUF)
+      } // Method (_CRS)
+    } // Device (PCI0)
+
+    // CCIX Root Complex
+    Device(PCI1) {
+      Name (_HID, EISAID("PNP0A08")) // PCI Express Root Bridge
+      Name (_CID, EISAID("PNP0A03")) // Compatible PCI Root Bridge
+      Name (_SEG, 1)                 // PCI Segment Group number
+      Name (_BBN, 0)                 // PCI Base Bus Number
+      Name (_CCA, 1)                 // Cache Coherency Attribute
+
+      // Root Complex 1
+      Device (RP1) {
+        Name(_ADR, 0xF0000000)    // Dev 0, Func 0
+      }
+
+      // PCI Routing Table
+      Name(_PRT, Package() {
+        ROOT_PRT_ENTRY(0, LNKE),   // INTA
+        ROOT_PRT_ENTRY(1, LNKF),   // INTB
+        ROOT_PRT_ENTRY(2, LNKG),   // INTC
+        ROOT_PRT_ENTRY(3, LNKH),   // INTD
+      })
+
+      // Root complex resources
+      Method (_CRS, 0, Serialized) {
+        Name (RBUF, ResourceTemplate () {
+          WordBusNumber (                             // Bus numbers assigned to this root
+            ResourceProducer,
+            MinFixed,
+            MaxFixed,
+            PosDecode,
+            0,                                        // AddressGranularity
+            FixedPcdGet32 (PcdCcixBusMin),            // AddressMinimum - Minimum Bus Number
+            FixedPcdGet32 (PcdCcixBusMax),            // AddressMaximum - Maximum Bus Number
+            0,                                        // AddressTranslation - Set to 0
+            FixedPcdGet32 (PcdCcixBusCount)           // RangeLength - Number of Busses
+          )
+
+          DWordMemory (                               // 32-bit BAR Windows
+            ResourceProducer,
+            PosDecode,
+            MinFixed,
+            MaxFixed,
+            Cacheable,
+            ReadWrite,
+            0x00000000,                               // Granularity
+            FixedPcdGet32 (PcdCcixMmio32Base),        // Min Base Address
+            FixedPcdGet32 (PcdCcixMmio32MaxBase),     // Max Base Address
+            FixedPcdGet32 (PcdCcixMmio32Translation), // Translate
+            FixedPcdGet32 (PcdCcixMmio32Size)         // Length
+          )
+
+          QWordMemory (                               // 64-bit BAR Windows
+            ResourceProducer,
+            PosDecode,
+            MinFixed,
+            MaxFixed,
+            Cacheable,
+            ReadWrite,
+            0x00000000,                               // Granularity
+            FixedPcdGet64 (PcdCcixMmio64Base),        // Min Base Address
+            FixedPcdGet64 (PcdCcixMmio64MaxBase),     // Max Base Address
+            FixedPcdGet64 (PcdCcixMmio64Translation), // Translate
+            FixedPcdGet64 (PcdCcixMmio64Size)         // Length
+          )
+
+          DWordIo (                                   // IO window
+            ResourceProducer,
+            MinFixed,
+            MaxFixed,
+            PosDecode,
+            EntireRange,
+            0x00000000,                               // Granularity
+            FixedPcdGet32 (PcdCcixIoBase),            // Min Base Address
+            FixedPcdGet32 (PcdCcixIoMaxBase),         // Max Base Address
+            FixedPcdGet32 (PcdCcixIoTranslation),     // Translate
+            FixedPcdGet32 (PcdCcixIoSize),            // Length
+            ,
+            ,
+            ,
+            TypeTranslation
+          )
+        }) // Name(RBUF)
+        Return (RBUF)
+      } // Method (_CRS)
+    } // Device (PCI1)
+  } // _SB
+} // DB
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [edk2-platforms][PATCH V1 10/11] Platform/ARM/Morello: Add support to parse NT_FW_CONFIG
  2021-12-04 12:30 [edk2-platforms][PATCH V1 00/11] Add Support for Morello SoC chandni cherukuri
                   ` (8 preceding siblings ...)
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 09/11] Platform/ARM/Morello: Add ACPI bindings for PCIe & CCIX chandni cherukuri
@ 2021-12-04 12:30 ` chandni cherukuri
  2021-12-07 20:59   ` Sami Mujawar
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 11/11] Platform/ARM/Morello: Update Readme.md chandni cherukuri
  10 siblings, 1 reply; 31+ messages in thread
From: chandni cherukuri @ 2021-12-04 12:30 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Chandni Cherukuri

From: sah01 <sahil@arm.com>

Support has been added to parse NT_FW_CONFIG DTB to get the
platform information.

Signed-off-by: sahil <sahil@arm.com>
Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
---
 Platform/ARM/Morello/MorelloPlatform.dec                     |   5 +
 Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf  |   6 ++
 Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf  |   6 ++
 Platform/ARM/Morello/Include/MorelloPlatform.h               |  18 +++-
 Platform/ARM/Morello/Library/PlatformLib/PlatformLib.c       |   9 ++
 Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemFvp.c |  74 ++++++++++++-
 Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c | 113 +++++++++++++++++++-
 Platform/ARM/Morello/Library/PlatformLib/AArch64/Helper.S    |   2 +
 8 files changed, 225 insertions(+), 8 deletions(-)

diff --git a/Platform/ARM/Morello/MorelloPlatform.dec b/Platform/ARM/Morello/MorelloPlatform.dec
index 07701e7611b8..3aec23b03b00 100644
--- a/Platform/ARM/Morello/MorelloPlatform.dec
+++ b/Platform/ARM/Morello/MorelloPlatform.dec
@@ -22,6 +22,8 @@
   Include                        # Root include for the package
 
 [Guids.common]
+  # ARM Morello Platform Info descriptor
+  gArmMorelloPlatformInfoDescriptorGuid = { 0x891422EF, 0x5377, 0x459E, { 0xA5, 0x42, 0x7A, 0xA2, 0x1A, 0x55, 0x54, 0x7F } }
   gArmMorelloTokenSpaceGuid =  { 0x0A8C3A78, 0xA56F, 0x4788, { 0x83, 0xB4, 0xCD, 0x29, 0x62, 0x96, 0x77, 0x51 } }
 
 [PcdsFixedAtBuild]
@@ -82,3 +84,6 @@
   gArmMorelloTokenSpaceGuid.PcdRamDiskSupported|FALSE|BOOLEAN|0x00000007
   gArmMorelloTokenSpaceGuid.PcdVirtioBlkSupported|FALSE|BOOLEAN|0x00000008
   gArmMorelloTokenSpaceGuid.PcdVirtioNetSupported|FALSE|BOOLEAN|0x0000002C
+
+[Ppis]
+  gNtFwConfigDtInfoPpiGuid =  { 0x8E289A83, 0x44E1, 0x41CF, { 0xA7, 0x41, 0x83, 0x80, 0x89, 0x23, 0x43, 0xA3 } }
diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf
index d4c8744c0954..0f87a18da184 100644
--- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf
+++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf
@@ -18,10 +18,14 @@
 [Packages]
   ArmPkg/ArmPkg.dec
   ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
   Platform/ARM/Morello/MorelloPlatform.dec
 
+[LibraryClasses]
+  FdtLib
+
 [Sources.common]
   PlatformLib.c
   PlatformLibMemFvp.c
@@ -46,7 +50,9 @@
   gArmTokenSpaceGuid.PcdSystemMemorySize
 
 [Guids]
+  gArmMorelloPlatformInfoDescriptorGuid
   gEfiHobListGuid          ## CONSUMES  ## SystemTable
 
 [Ppis]
   gArmMpCoreInfoPpiGuid
+  gNtFwConfigDtInfoPpiGuid
diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
index 0a36a5fe50a5..cc0687ebcaaa 100644
--- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
+++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
@@ -18,10 +18,14 @@
 [Packages]
   ArmPkg/ArmPkg.dec
   ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
   Platform/ARM/Morello/MorelloPlatform.dec
 
+[LibraryClasses]
+  FdtLib
+
 [Sources.common]
   PlatformLib.c
   PlatformLibMemSoc.c
@@ -56,7 +60,9 @@
   gArmTokenSpaceGuid.PcdSystemMemorySize
 
 [Guids]
+  gArmMorelloPlatformInfoDescriptorGuid
   gEfiHobListGuid          ## CONSUMES  ## SystemTable
 
 [Ppis]
   gArmMpCoreInfoPpiGuid
+  gNtFwConfigDtInfoPpiGuid
diff --git a/Platform/ARM/Morello/Include/MorelloPlatform.h b/Platform/ARM/Morello/Include/MorelloPlatform.h
index 8b3233025958..c55bb04445cb 100644
--- a/Platform/ARM/Morello/Include/MorelloPlatform.h
+++ b/Platform/ARM/Morello/Include/MorelloPlatform.h
@@ -51,13 +51,23 @@
  */
 #pragma pack(1)
 
+typedef struct {
+  UINT64  LocalDdrSize;    ///< Local DDR memory size in Bytes
+  UINT64  RemoteDdrSize;   ///< Remote DDR memory size in Bytes
+  UINT8   RemoteChipCount; ///< Remote chip count in C2C mode
+  UINT8   Mode;            ///< 0 - Single Chip, 1 - Chip to Chip (C2C)
+  UINT32  SccConfig;       ///< Contains SCC configuration from BOOT_GPR1 register
+} MORELLO_PLAT_INFO_SOC;
+
 typedef struct {
   UINT64  LocalDdrSize;  ///< Local DDR memory size in Bytes
-  UINT64  RemoteDdrSize; ///< Remote DDR memory size in Bytes
-  UINT8   SlaveCount;    ///< Slave count in C2C mode
-  UINT8   Mode;          ///< 0 - Single Chip, 1 - Chip to Chip (C2C)
-} MORELLO_PLAT_INFO;
+} MORELLO_PLAT_INFO_FVP;
 
 #pragma pack()
 
+// NT_FW_CONFIG DT structure
+typedef struct {
+  UINT64                  NtFwConfigDtAddr;
+} MORELLO_NT_FW_CONFIG_INFO_PPI;
+
 #endif //MORELLO_PLATFORM_H_
diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLib.c b/Platform/ARM/Morello/Library/PlatformLib/PlatformLib.c
index 52318a62911a..b46b3fcc2a7b 100644
--- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLib.c
+++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLib.c
@@ -8,7 +8,10 @@
 #include <Library/ArmPlatformLib.h>
 #include <Library/BaseLib.h>
 #include <Ppi/ArmMpCoreInfo.h>
+#include <MorelloPlatform.h>
 
+UINT64 NtFwConfigDtBlob;
+STATIC MORELLO_NT_FW_CONFIG_INFO_PPI mNtFwConfigDtInfoPpi;
 STATIC ARM_CORE_INFO mCoreInfoTable[] = {
   { 0x0, 0x0 }, // Cluster 0, Core 0
   { 0x0, 0x1 }, // Cluster 0, Core 1
@@ -44,6 +47,7 @@ ArmPlatformInitialize (
   IN  UINTN                     MpId
   )
 {
+  mNtFwConfigDtInfoPpi.NtFwConfigDtAddr = NtFwConfigDtBlob;
   return RETURN_SUCCESS;
 }
 
@@ -76,6 +80,11 @@ STATIC EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = {
     EFI_PEI_PPI_DESCRIPTOR_PPI,
     &gArmMpCoreInfoPpiGuid,
     &mMpCoreInfoPpi
+  },
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI,
+    &gNtFwConfigDtInfoPpiGuid,
+    &mNtFwConfigDtInfoPpi
   }
 };
 
diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemFvp.c b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemFvp.c
index 54a870cfb3ba..9c1da9a25fcd 100644
--- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemFvp.c
+++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemFvp.c
@@ -9,6 +9,8 @@
 #include <Library/DebugLib.h>
 #include <Library/HobLib.h>
 #include <Library/MemoryAllocationLib.h>
+#include <Library/PeiServicesLib.h>
+#include <libfdt.h>
 #include <MorelloPlatform.h>
 
 // The total number of descriptors, including the final "end-of-table" descriptor.
@@ -39,6 +41,60 @@ STATIC CONST CHAR8 *gTblAttrDesc[] = {
                         gTblAttrDesc[VirtualMemoryTable[Index].Attributes]  \
                         ));
 
+/** A helper function to locate the NtFwConfig PPI and get the base address of
+  NT_FW_CONFIG DT from which values are obtained using FDT helper functions.
+
+  @param [out]  plat_info  Pointer to the MORELLO PLATFORM_INFO HOB
+
+  @retval EFI_SUCCESS            Success.
+  returns EFI_INVALID_PARAMETER  A parameter is invalid.
+**/
+EFI_STATUS
+GetMorelloPlatInfo (
+  OUT MORELLO_PLAT_INFO_FVP *plat_info
+)
+{
+  CONST UINT64                  *Property;
+  INT32                         Offset;
+  CONST VOID                    *NtFwCfgDtBlob;
+  MORELLO_NT_FW_CONFIG_INFO_PPI *NtFwConfigInfoPpi;
+  EFI_STATUS                    Status;
+
+  Status = PeiServicesLocatePpi (
+             &gNtFwConfigDtInfoPpiGuid,
+             0,
+             NULL,
+             (VOID**)&NtFwConfigInfoPpi
+             );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR,
+      "PeiServicesLocatePpi failed with error %r\n", Status));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  NtFwCfgDtBlob = (VOID *)(UINTN)NtFwConfigInfoPpi->NtFwConfigDtAddr;
+  if (fdt_check_header (NtFwCfgDtBlob) != 0) {
+    DEBUG ((DEBUG_ERROR, "Invalid DTB file %p passed\n", NtFwCfgDtBlob));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Offset = fdt_subnode_offset (NtFwCfgDtBlob, 0, "platform-info");
+  if (Offset == -FDT_ERR_NOTFOUND) {
+    DEBUG ((DEBUG_ERROR, "Invalid DTB : platform-info node not found\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Property = fdt_getprop (NtFwCfgDtBlob, Offset, "local-ddr-size", NULL);
+  if (Property == NULL) {
+    DEBUG ((DEBUG_ERROR, "local-ddr-size property not found\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  plat_info->LocalDdrSize = fdt64_to_cpu (ReadUnaligned64 (Property));
+  return EFI_SUCCESS;
+}
+
 /**
   Returns the Virtual Memory Map of the platform.
 
@@ -57,13 +113,27 @@ ArmPlatformGetVirtualMemoryMap (
   UINTN                           Index;
   ARM_MEMORY_REGION_DESCRIPTOR  * VirtualMemoryTable;
   EFI_RESOURCE_ATTRIBUTE_TYPE     ResourceAttributes;
-  MORELLO_PLAT_INFO             * PlatInfo;
+  MORELLO_PLAT_INFO_FVP         * PlatInfo;
   UINT64                          DramBlock2Size;
+  EFI_STATUS                      Status;
 
   Index = 0;
   DramBlock2Size = 0;
 
-  PlatInfo = (MORELLO_PLAT_INFO *)MORELLO_PLAT_INFO_STRUCT_BASE;
+  // Create platform info HOB
+  PlatInfo = (MORELLO_PLAT_INFO_FVP *)BuildGuidHob (
+                                        &gArmMorelloPlatformInfoDescriptorGuid,
+                                        sizeof (MORELLO_PLAT_INFO_FVP)
+                                        );
+  if (PlatInfo == NULL) {
+    DEBUG ((DEBUG_ERROR, "Platform HOB is NULL\n"));
+    ASSERT (FALSE);
+    return;
+  }
+
+  Status = GetMorelloPlatInfo (PlatInfo);
+  ASSERT (Status == 0);
+
   if (PlatInfo->LocalDdrSize > MORELLO_DRAM_BLOCK1_SIZE) {
     DramBlock2Size = PlatInfo->LocalDdrSize - MORELLO_DRAM_BLOCK1_SIZE;
   }
diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
index 5140764c54bc..49e4994176a9 100644
--- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
+++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
@@ -9,6 +9,8 @@
 #include <Library/DebugLib.h>
 #include <Library/HobLib.h>
 #include <Library/MemoryAllocationLib.h>
+#include <Library/PeiServicesLib.h>
+#include <libfdt.h>
 #include <MorelloPlatform.h>
 
 // The total number of descriptors, including the final "end-of-table" descriptor.
@@ -39,6 +41,97 @@
                         gTblAttrDesc[VirtualMemoryTable[Index].Attributes]  \
                         ));
 
+/** A helper function to locate the NtFwConfig PPI and get the base address of
+  NT_FW_CONFIG DT from which values are obtained using FDT helper functions.
+
+  @param [out]  plat_info  Pointer to the MORELLO PLATFORM_INFO HOB
+
+  @retval EFI_SUCCESS            Success.
+  returns EFI_INVALID_PARAMETER  A parameter is invalid.
+**/
+EFI_STATUS
+GetMorelloPlatInfo (
+  OUT MORELLO_PLAT_INFO_SOC *plat_info
+  )
+{
+  CONST UINT32                   *Property;
+  CONST UINT64                   *DdrProperty;
+  INT32                          Offset;
+  CONST VOID                     *NtFwCfgDtBlob;
+  MORELLO_NT_FW_CONFIG_INFO_PPI  *NtFwConfigInfoPpi;
+  EFI_STATUS                     Status;
+
+  Status = PeiServicesLocatePpi (
+             &gNtFwConfigDtInfoPpiGuid,
+             0,
+             NULL,
+             (VOID **)&NtFwConfigInfoPpi
+             );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "PeiServicesLocatePpi failed with error %r\n",
+      Status
+      ));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  NtFwCfgDtBlob = (VOID *)(UINTN)NtFwConfigInfoPpi->NtFwConfigDtAddr;
+  if (fdt_check_header (NtFwCfgDtBlob) != 0) {
+    DEBUG ((DEBUG_ERROR, "Invalid DTB file %p passed\n", NtFwCfgDtBlob));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Offset = fdt_subnode_offset (NtFwCfgDtBlob, 0, "platform-info");
+  if (Offset == -FDT_ERR_NOTFOUND) {
+    DEBUG ((DEBUG_ERROR, "Invalid DTB : platform-info node not found\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DdrProperty = fdt_getprop (NtFwCfgDtBlob, Offset, "local-ddr-size", NULL);
+  if (DdrProperty == NULL) {
+    DEBUG ((DEBUG_ERROR, "local-ddr-size property not found\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  plat_info->LocalDdrSize = fdt64_to_cpu (ReadUnaligned64 (DdrProperty));
+
+  DdrProperty = fdt_getprop (NtFwCfgDtBlob, Offset, "remote-ddr-size", NULL);
+  if (DdrProperty == NULL) {
+    DEBUG ((DEBUG_ERROR, "remote-ddr-size property not found\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  plat_info->RemoteDdrSize = fdt64_to_cpu (ReadUnaligned64 (DdrProperty));
+
+  Property = fdt_getprop (NtFwCfgDtBlob, Offset, "remote-chip-count", NULL);
+  if (Property == NULL) {
+    DEBUG ((DEBUG_ERROR, "remote-chip-count property not found\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  plat_info->RemoteChipCount = fdt32_to_cpu (*Property);
+
+  Property = fdt_getprop (NtFwCfgDtBlob, Offset, "multichip-mode", NULL);
+  if (Property == NULL) {
+    DEBUG ((DEBUG_ERROR, "multichip-mode property not found\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  plat_info->Mode = fdt32_to_cpu (*Property);
+
+  Property = fdt_getprop (NtFwCfgDtBlob, Offset, "scc-config", NULL);
+  if (Property == NULL) {
+    DEBUG ((DEBUG_ERROR, "scc-config property not found\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  plat_info->SccConfig = fdt32_to_cpu (*Property);
+
+  return EFI_SUCCESS;
+}
+
 /**
   Returns the Virtual Memory Map of the platform.
 
@@ -57,17 +150,33 @@ ArmPlatformGetVirtualMemoryMap (
   UINTN                         Index;
   ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
   EFI_RESOURCE_ATTRIBUTE_TYPE   ResourceAttributes;
-  MORELLO_PLAT_INFO             *PlatInfo;
+  MORELLO_PLAT_INFO_SOC         *PlatInfo;
   UINT64                        DramBlock2Size;
+  EFI_STATUS                    Status;
 
   Index = 0;
   DramBlock2Size = 0;
 
-  PlatInfo = (MORELLO_PLAT_INFO *)MORELLO_PLAT_INFO_STRUCT_BASE;
+  // Create platform info HOB
+  PlatInfo = (MORELLO_PLAT_INFO_SOC *)BuildGuidHob (
+                                        &gArmMorelloPlatformInfoDescriptorGuid,
+                                        sizeof (MORELLO_PLAT_INFO_SOC)
+                                        );
+
+  if (PlatInfo == NULL) {
+    DEBUG ((DEBUG_ERROR, "Platform HOB is NULL\n"));
+    ASSERT (FALSE);
+    return;
+  }
+
+  Status = GetMorelloPlatInfo (PlatInfo);
+  ASSERT (Status == 0);
+
   if (PlatInfo->LocalDdrSize > MORELLO_DRAM_BLOCK1_SIZE) {
     DramBlock2Size = PlatInfo->LocalDdrSize - MORELLO_DRAM_BLOCK1_SIZE;
   }
 
+  DEBUG ((DEBUG_ERROR, "DramBlock2Size is 0x%lx\n", DramBlock2Size));
   if (DramBlock2Size != 0) {
     ResourceAttributes =
       EFI_RESOURCE_ATTRIBUTE_PRESENT |
diff --git a/Platform/ARM/Morello/Library/PlatformLib/AArch64/Helper.S b/Platform/ARM/Morello/Library/PlatformLib/AArch64/Helper.S
index 0bc624dfd2b4..d71cab916c75 100644
--- a/Platform/ARM/Morello/Library/PlatformLib/AArch64/Helper.S
+++ b/Platform/ARM/Morello/Library/PlatformLib/AArch64/Helper.S
@@ -19,6 +19,8 @@
 // the UEFI firmware through the CPU registers.
 //
 ASM_FUNC(ArmPlatformPeiBootAction)
+  adr  x10, NtFwConfigDtBlob
+  str  x0, [x10]
   ret
 
 //
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [edk2-platforms][PATCH V1 11/11] Platform/ARM/Morello: Update Readme.md
  2021-12-04 12:30 [edk2-platforms][PATCH V1 00/11] Add Support for Morello SoC chandni cherukuri
                   ` (9 preceding siblings ...)
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 10/11] Platform/ARM/Morello: Add support to parse NT_FW_CONFIG chandni cherukuri
@ 2021-12-04 12:30 ` chandni cherukuri
  2021-12-07 21:01   ` Sami Mujawar
  10 siblings, 1 reply; 31+ messages in thread
From: chandni cherukuri @ 2021-12-04 12:30 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Chandni Cherukuri

Morello SoC platform support has added and also
boot flow modified to reflect the new boot flow
for both Morello FVP and Morello SoC platforms

Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
---
 Platform/ARM/Morello/Readme.md | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/Platform/ARM/Morello/Readme.md b/Platform/ARM/Morello/Readme.md
index 8d441234f3b8..a5ecab5cdb51 100644
--- a/Platform/ARM/Morello/Readme.md
+++ b/Platform/ARM/Morello/Readme.md
@@ -7,6 +7,11 @@ The platform port in UEFI firmware provides ARMv8-A architecture enablement.
 
 Platform code is located at Platform/ARM/Morello.
 
+The following platforms are supported
+
+- Morello FVP
+- Morello SoC
+
 # Documentation
 
 Further information on Morello Platform is available at this [page](https://developer.arm.com/architectures/cpu-architecture/a-profile/morello).
@@ -26,9 +31,10 @@ Please refer to the `edk2-platforms/Readme.md` for build instructions.
 
 # Dependencies
 
-Once the FVP is running, the SCP will be the first to boot and will bring the AP
-core out of reset. The AP core will start executing Trusted Firmware-A at BL31
-and once it completes the execution, it will start executing UEFI.
+The SCP will be the first to boot and will bring the AP core out of reset. The AP
+core will start executing Trusted Firmware-A at BL1. BL1 authenticates and then loads
+BL2 and starts executing it. BL2 authenticates and loads BL31. Once BL31 finishes
+execution BL2 authenticates and loads BL33 (UEFI) and passes control to it.
 
 The SCP and TF-A binaries are required to boot to the UEFI Shell.
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [edk2-platforms][PATCH V1 01/11] Platform/ARM/Morello: Rename PlatformLib.inf file
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 01/11] Platform/ARM/Morello: Rename PlatformLib.inf file chandni cherukuri
@ 2021-12-07 20:44   ` Sami Mujawar
  0 siblings, 0 replies; 31+ messages in thread
From: Sami Mujawar @ 2021-12-07 20:44 UTC (permalink / raw)
  To: Chandni Cherukuri, devel; +Cc: Ard Biesheuvel, Leif Lindholm, nd

Hi Chandni,

Thank you for this patch.

I think the following change from "[edk2-platforms][PATCH V1 05/11] 
Platform/ARM/Morello: Add initial support for Morello SoC" should be 
part of this patch.

                 diff --git a/Platform/ARM/Morello/MorelloPlatform.dsc.inc b/Platform/ARM/Morello/MorelloPlatform.dsc.inc
                 index dccd22248318..862d5f2da1b0 100644
                 --- a/Platform/ARM/Morello/MorelloPlatform.dsc.inc
                 +++ b/Platform/ARM/Morello/MorelloPlatform.dsc.inc
                 @@ -9,13 +9,13 @@
                [LibraryClasses.common]
                  ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
                  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
               -  ArmPlatformLib|Platform/ARM/Morello/Library/PlatformLib/PlatformLib.inf
                  BasePathLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
                  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
                  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf

                 ++ b/Platform/ARM/Morello/MorelloPlatformFvp.dsc
                 @@ -39,14 +39,18 @@
                 !include MdePkg/MdeLibs.dsc.inc
                  [LibraryClasses.common]
                  +  # Platform Library
                  +  ArmPlatformLib|Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf

Can you update this accordingly, please?

With that changed,

Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>

Regards,

Sami Mujawar
On 04/12/2021 12:30 PM, Chandni Cherukuri wrote:
> PlatformLibMem.c file is going to be different for Morello
> FVP and Morello SoC platforms since the virtual memory mapping
> is different so the file PlatformLibMem.c is renamed as
> PlatformLibMemFvp.c and PlatformLib.inf is renamed as
> PlatformLibFvp.inf.
>
> Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
> ---
>   Platform/ARM/Morello/Library/PlatformLib/{PlatformLib.inf => PlatformLibFvp.inf}   | 4 ++--
>   Platform/ARM/Morello/Library/PlatformLib/{PlatformLibMem.c => PlatformLibMemFvp.c} | 0
>   2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLib.inf b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf
> similarity index 91%
> rename from Platform/ARM/Morello/Library/PlatformLib/PlatformLib.inf
> rename to Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf
> index c2d7da3701d2..d4c8744c0954 100644
> --- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLib.inf
> +++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf
> @@ -1,5 +1,5 @@
>   ## @file
> -#  Platform Library for Morello platform.
> +#  Platform Library for Morello FVP platform.
>   #
>   #  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
>   #
> @@ -24,7 +24,7 @@
>   
>   [Sources.common]
>     PlatformLib.c
> -  PlatformLibMem.c
> +  PlatformLibMemFvp.c
>   
>   [Sources.AARCH64]
>     AArch64/Helper.S | GCC
> diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMem.c b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemFvp.c
> similarity index 100%
> rename from Platform/ARM/Morello/Library/PlatformLib/PlatformLibMem.c
> rename to Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemFvp.c


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-platforms][PATCH V1 02/11] Platform/ARM/Morello: Add Platform Library support for Morello SoC
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 02/11] Platform/ARM/Morello: Add Platform Library support for Morello SoC chandni cherukuri
@ 2021-12-07 20:44   ` Sami Mujawar
  0 siblings, 0 replies; 31+ messages in thread
From: Sami Mujawar @ 2021-12-07 20:44 UTC (permalink / raw)
  To: Chandni Cherukuri, devel; +Cc: Ard Biesheuvel, Leif Lindholm, nd

Hi Chandni,

Thank you for this patch.

Please find my feedback inline marked [SAMI].

With that updated,

Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>

Regards,

Sami Mujawar


On 04/12/2021 12:30 PM, Chandni Cherukuri wrote:
> It includes virutal memory map for Morello SoC platform.
>
> Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
> ---
>   Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf  |  44 +++++
>   Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c | 176 ++++++++++++++++++++
>   2 files changed, 220 insertions(+)
>
> diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
> new file mode 100644
> index 000000000000..bc31b8709152
> --- /dev/null
> +++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
> @@ -0,0 +1,44 @@
> +## @file
> +#  Platform Library for Morello SoC platform.
> +#
> +#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = ArmMorelloLib
> +  FILE_GUID                      = 7858ED56-9716-454F-90D7-D117B05063EA
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = ArmPlatformLib
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Platform/ARM/Morello/MorelloPlatform.dec
> +
> +[Sources.common]
> +  PlatformLib.c
> +  PlatformLibMemSoc.c
> +
> +[Sources.AARCH64]
> +  AArch64/Helper.S | GCC
> +
> +[FixedPcd]
> +  gArmMorelloTokenSpaceGuid.PcdDramBlock2Base
> +
> +  gArmTokenSpaceGuid.PcdArmPrimaryCore
> +  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
> +  gArmTokenSpaceGuid.PcdSystemMemoryBase
> +  gArmTokenSpaceGuid.PcdSystemMemorySize
> +
> +[Guids]
> +  gEfiHobListGuid          ## CONSUMES  ## SystemTable
> +
> +[Ppis]
> +  gArmMpCoreInfoPpiGuid
> diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
> new file mode 100644
> index 000000000000..67dd8469feb8
> --- /dev/null
> +++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
> @@ -0,0 +1,176 @@
> +/** @file
> +
> +  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/ArmPlatformLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <MorelloPlatform.h>
> +
> +// The total number of descriptors, including the final "end-of-table" descriptor.
> +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS  9
> +
> +#if !defined (MDEPKG_NDEBUG)
> +  STATIC CONST CHAR8  *gTblAttrDesc[] = {
> +    "UNCACHED_UNBUFFERED          ",
> +    "NONSECURE_UNCACHED_UNBUFFERED",
> +    "WRITE_BACK                   ",
> +    "NONSECURE_WRITE_BACK         ",
> +    "WB_NONSHAREABLE              ",
> +    "NONSECURE_WB_NONSHAREABLE    ",
> +    "WRITE_THROUGH                ",
> +    "NONSECURE_WRITE_THROUGH      ",
> +    "DEVICE                       ",
> +    "NONSECURE_DEVICE             "
> +  };
> +#endif
> +
> +#define LOG_MEM(desc)  DEBUG ((                                             \
> +                        DEBUG_ERROR,                                        \
> +                        desc,                                               \
> +                        VirtualMemoryTable[Index].PhysicalBase,             \
> +                        (VirtualMemoryTable[Index].PhysicalBase +           \
> +                         VirtualMemoryTable[Index].Length - 1),             \
> +                        VirtualMemoryTable[Index].Length,                   \
> +                        gTblAttrDesc[VirtualMemoryTable[Index].Attributes]  \
> +                        ));
> +
> +/**
> +  Returns the Virtual Memory Map of the platform.
> +
> +  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU
> +  on your platform.
> +
> +  @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing
> +                               a Physical-to-Virtual Memory mapping. This array
> +                               must be ended by a zero-filled entry.
> +**/
> +VOID
> +ArmPlatformGetVirtualMemoryMap (
> +  OUT ARM_MEMORY_REGION_DESCRIPTOR **VirtualMemoryMap
> +  )
> +{
> +  UINTN                         Index;
> +  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
> +  EFI_RESOURCE_ATTRIBUTE_TYPE   ResourceAttributes;
> +  MORELLO_PLAT_INFO             *PlatInfo;
> +  UINT64                        DramBlock2Size;
> +
> +  Index = 0;
> +  DramBlock2Size = 0;
> +
> +  PlatInfo = (MORELLO_PLAT_INFO *)MORELLO_PLAT_INFO_STRUCT_BASE;
> +  if (PlatInfo->LocalDdrSize > MORELLO_DRAM_BLOCK1_SIZE) {
> +    DramBlock2Size = PlatInfo->LocalDdrSize - MORELLO_DRAM_BLOCK1_SIZE;
> +  }
> +
> +  if (DramBlock2Size != 0) {
[SAMI] I think the above check that DramBlock2Size != 0 is not required 
the followng code block
      <START>
> +    ResourceAttributes =
> +      EFI_RESOURCE_ATTRIBUTE_PRESENT |
> +      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_TESTED;
> +
> +    BuildResourceDescriptorHob (
> +      EFI_RESOURCE_SYSTEM_MEMORY,
> +      ResourceAttributes,
> +      FixedPcdGet64 (PcdDramBlock2Base),
> +      DramBlock2Size
> +      );
      <END>
  can be moved in the previous if block after initialising DramBlock2Size.
[/SAMI]
> +  }
> +
> +  ASSERT (VirtualMemoryMap != NULL);
> +
> +  VirtualMemoryTable = AllocatePool (
> +                         sizeof (ARM_MEMORY_REGION_DESCRIPTOR) *
> +                         MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS
> +                         );
> +  if (VirtualMemoryTable == NULL) {
> +    return;
> +  }
> +
> +  DEBUG ((
> +    DEBUG_ERROR,
> +    " Memory Map\n----------------------------------------------------------\n"
> +    ));
> +  DEBUG ((
> +    DEBUG_ERROR,
> +    "Description                     :        START       -        END         " \
> +    "[        SIZE        ] {              ATTR             }\n"
> +    ));
> +
> +  // SubSystem Peripherals - Generic Watchdog
> +  VirtualMemoryTable[Index].PhysicalBase = MORELLO_GENERIC_WDOG_BASE;
> +  VirtualMemoryTable[Index].VirtualBase  = MORELLO_GENERIC_WDOG_BASE;
> +  VirtualMemoryTable[Index].Length     = MORELLO_GENERIC_WDOG_SZ;
> +  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +  LOG_MEM ("Generic Watchdog                : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
> +
> +  // SubSystem Peripherals - GIC-600
> +  VirtualMemoryTable[++Index].PhysicalBase = MORELLO_GIC_BASE;
> +  VirtualMemoryTable[Index].VirtualBase    = MORELLO_GIC_BASE;
> +  VirtualMemoryTable[Index].Length     = MORELLO_GIC_SZ;
> +  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +  LOG_MEM ("GIC-600                         : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
> +
> +  // SubSystem Peripherals - GICR-600
> +  VirtualMemoryTable[++Index].PhysicalBase = MORELLO_GICR_BASE;
> +  VirtualMemoryTable[Index].VirtualBase    = MORELLO_GICR_BASE;
> +  VirtualMemoryTable[Index].Length     = MORELLO_GICR_SZ;
> +  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +  LOG_MEM ("GICR-600                        : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
> +
> +  // SubSystem non-secure SRAM
> +  VirtualMemoryTable[++Index].PhysicalBase = MORELLO_NON_SECURE_SRAM_BASE;
> +  VirtualMemoryTable[Index].VirtualBase    = MORELLO_NON_SECURE_SRAM_BASE;
> +  VirtualMemoryTable[Index].Length     = MORELLO_NON_SECURE_SRAM_SZ;
> +  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;
> +  LOG_MEM ("non-secure SRAM                 : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
> +
> +  // SubSystem Pheripherals - UART0
> +  VirtualMemoryTable[++Index].PhysicalBase = MORELLO_UART0_BASE;
> +  VirtualMemoryTable[Index].VirtualBase    = MORELLO_UART0_BASE;
> +  VirtualMemoryTable[Index].Length     = MORELLO_UART0_SZ;
> +  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +  LOG_MEM ("UART0                           : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
> +
> +  // DDR Primary
> +  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase);
> +  VirtualMemoryTable[Index].VirtualBase    = PcdGet64 (PcdSystemMemoryBase);
> +  VirtualMemoryTable[Index].Length     = PcdGet64 (PcdSystemMemorySize);
> +  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;
> +  LOG_MEM ("DDR Primary                     : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
> +
> +  // DDR Secondary
> +  if (DramBlock2Size != 0) {
> +    VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdDramBlock2Base);
> +    VirtualMemoryTable[Index].VirtualBase    = PcdGet64 (PcdDramBlock2Base);
> +    VirtualMemoryTable[Index].Length     = DramBlock2Size;
> +    VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;
> +    LOG_MEM ("DDR Secondary                   : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
> +  }
> +
> +  // Expansion Peripherals
> +  VirtualMemoryTable[++Index].PhysicalBase = MORELLO_EXP_PERIPH_BASE;
> +  VirtualMemoryTable[Index].VirtualBase    = MORELLO_EXP_PERIPH_BASE;
> +  VirtualMemoryTable[Index].Length     = MORELLO_EXP_PERIPH_BASE_SZ;
> +  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +  LOG_MEM ("Expansion Peripherals           : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
> +
> +  // End of Table
> +  VirtualMemoryTable[++Index].PhysicalBase = 0;
> +  VirtualMemoryTable[Index].VirtualBase    = 0;
> +  VirtualMemoryTable[Index].Length     = 0;
> +  VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0;
> +
> +  ASSERT ((Index) < MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
> +  DEBUG ((DEBUG_INIT, "Virtual Memory Table setup complete.\n"));
> +
> +  *VirtualMemoryMap = VirtualMemoryTable;
> +}


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-platforms][PATCH V1 03/11] Platform/ARM/Morello: Add PlatformDxe for Morello SoC
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 03/11] Platform/ARM/Morello: Add PlatformDxe " chandni cherukuri
@ 2021-12-07 20:44   ` Sami Mujawar
  0 siblings, 0 replies; 31+ messages in thread
From: Sami Mujawar @ 2021-12-07 20:44 UTC (permalink / raw)
  To: Chandni Cherukuri, devel; +Cc: Ard Biesheuvel, Leif Lindholm, nd

Hi Chandni,

Please find my feedback inline marked [SAMI].

With that fixed,

Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>

Regards,

Sami Mujawar

On 04/12/2021 12:30 PM, Chandni Cherukuri wrote:
> This patch adds PlatformDxe support for Morello SoC platform.
> It includes the registration of ramdisk device.
>
> Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
> ---
>   Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf | 43 +++++++++++++
>   Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.c   | 67 ++++++++++++++++++++
>   2 files changed, 110 insertions(+)
>
> diff --git a/Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf b/Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf
> new file mode 100644
> index 000000000000..a5d8ac36a3f2
> --- /dev/null
> +++ b/Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf
> @@ -0,0 +1,43 @@
> +## @file
> +#  Platform DXE driver for Morello SoC Platform
> +#
> +#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = PlatformDxe
> +  FILE_GUID                      = D75DB98F-5750-47C8-A46F-3140965537FC
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = ArmMorelloEntryPoint
> +
> +[Sources.common]
> +  PlatformDxeSoc.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  OvmfPkg/OvmfPkg.dec
> +  Platform/ARM/Morello/MorelloPlatform.dec
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +
> +[Protocols]
> +  gEfiRamDiskProtocolGuid
> +
> +[FeaturePcd]
> +  gArmMorelloTokenSpaceGuid.PcdRamDiskSupported
> +
> +[FixedPcd]
> +  gArmMorelloTokenSpaceGuid.PcdRamDiskBase
> +  gArmMorelloTokenSpaceGuid.PcdRamDiskSize
> +
> +[Depex]
> +  gEfiRamDiskProtocolGuid
> +
> +[Guids]
> +  gEfiVirtualCdGuid      ## SOMETIMES_CONSUMES   ## GUID
> diff --git a/Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.c b/Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.c
> new file mode 100644
> index 000000000000..358c80acc7ee
> --- /dev/null
> +++ b/Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.c
> @@ -0,0 +1,67 @@
> +/** @file
> +
> +  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/RamDisk.h>
> +
> +/**
> +  Entrypoint of Platform Dxe Driver
> +
> +  @param  ImageHandle[in]       The firmware allocated handle for the EFI image.
> +  @param  SystemTable[in]       A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS           The entry point is executed successfully.
> +**/
> +EFI_STATUS
> +EFIAPI
> +ArmMorelloEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_RAM_DISK_PROTOCOL     *RamDisk;
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> +
> +  Status = EFI_SUCCESS;
> +
> +  if (FeaturePcdGet (PcdRamDiskSupported)) {
> +    Status = gBS->LocateProtocol (
> +                    &gEfiRamDiskProtocolGuid,
> +                    NULL,
> +                    (VOID **)&RamDisk
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((
> +        DEBUG_ERROR,
> +        "Couldn't find the RAM Disk protocol %r\n",
[SAMI] One print format specifier appears to be missing in the above 
line. [/SAMI]
> +        __FUNCTION__,
> +        Status
> +        ));
> +      return Status;
> +    }
> +
> +    Status = RamDisk->Register (
> +                        (UINTN)PcdGet32 (PcdRamDiskBase),
> +                        (UINTN)PcdGet32 (PcdRamDiskSize),
> +                        &gEfiVirtualCdGuid,
> +                        NULL,
> +                        &DevicePath
> +                        );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((
> +        DEBUG_ERROR,
> +        "%a: Failed to register RAM Disk - %r\n",
> +        __FUNCTION__,
> +        Status
> +        ));
> +    }
> +  }
> +
> +  return Status;
> +}


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-platforms][PATCH V1 04/11] Platform/ARM/Morello: Add ConfigurationManager for Morello SoC
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 04/11] Platform/ARM/Morello: Add ConfigurationManager " chandni cherukuri
@ 2021-12-07 20:51   ` Sami Mujawar
  2021-12-08 12:28     ` [edk2-devel] " chandni cherukuri
  2021-12-08  3:02   ` Khasim Mohammed
  1 sibling, 1 reply; 31+ messages in thread
From: Sami Mujawar @ 2021-12-07 20:51 UTC (permalink / raw)
  To: Chandni Cherukuri, devel; +Cc: Ard Biesheuvel, Leif Lindholm, nd

Hi Chandni,

Since you have the CPU information in MADT.GICC and the PPTT table, it 
should be possible to use the SSDT CPU generator to create the AML 
description for the CPUs. This patch series can go ahead. However, you 
may want to consider using the SSDT Cpu Generator in the furture.

Otherwise, these changes look good to me.

Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>

Regards,

Sami Mujawar



On 04/12/2021 12:30 PM, Chandni Cherukuri wrote:
> This patch implements the configuration manager for Morello
> SoC platform. It enables support for generating the following
> ACPI tables for Morello SoC Platform:
>                 1. FADT
>                 2. DSDT
>                 3. GTDT
>                 4. MADT
>                 5. SPCR
>                 6. DBG2
>                 7. PPTT
>
> Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
> ---
>   Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc                        |  16 ++
>   Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf |  72 +++++++++
>   Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h      |  97 ++++++++++++
>   Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c      | 161 ++++++++++++++++++++
>   Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl          |  41 +++++
>   5 files changed, 387 insertions(+)
>
> diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
> new file mode 100644
> index 000000000000..f7e58185696e
> --- /dev/null
> +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
> @@ -0,0 +1,16 @@
> +## @file
> +#  dsc include file for Configuration Manager
> +#
> +#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +
> +[BuildOptions]
> +
> +[Components.common]
> +  # Configuration Manager
> +  Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> new file mode 100644
> index 000000000000..6f9199a6fda2
> --- /dev/null
> +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> @@ -0,0 +1,72 @@
> +## @file
> +#  Configuration Manager Dxe
> +#
> +#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = ConfigurationManagerDxe
> +  FILE_GUID                      = BF8FBCEE-AD95-466B-9185-50A1BB651DDA
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = ConfigurationManagerDxeInitialize
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = AARCH64
> +#
> +
> +[Sources]
> +  AslTables/DsdtSoc.asl
> +  ConfigurationManager.c
> +  ConfigurationManager.h
> +  ConfigurationManagerSoc.c
> +  ConfigurationManagerSoc.h
> +  Platform.h
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  DynamicTablesPkg/DynamicTablesPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Platform/ARM/Morello/MorelloPlatform.dec
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +
> +[Protocols]
> +  gEdkiiConfigurationManagerProtocolGuid
> +
> +[FixedPcd]
> +  ## PL011 Serial Debug UART
> +  gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
> +  gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate
> +  gArmPlatformTokenSpaceGuid.PcdSerialDbgUartClkInHz
> +
> +  gArmPlatformTokenSpaceGuid.PL011UartClkInHz
> +  gArmPlatformTokenSpaceGuid.PL011UartInterrupt
> +
> +  gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum
> +  gArmTokenSpaceGuid.PcdArmArchTimerIntrNum
> +  gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum
> +  gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum
> +
> +  # SBSA Generic Watchdog
> +  gArmTokenSpaceGuid.PcdGenericWatchdogControlBase
> +  gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum
> +  gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase
> +
> +  gArmTokenSpaceGuid.PcdGicDistributorBase
> +  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
> +  gArmTokenSpaceGuid.PcdGicRedistributorsBase
> +
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
> +
> +[Depex]
> +  TRUE
> diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
> new file mode 100644
> index 000000000000..8a521b83c8dc
> --- /dev/null
> +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
> @@ -0,0 +1,97 @@
> +/** @file
> +
> +  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  @par Glossary:
> +    - Cm or CM   - Configuration Manager
> +    - Obj or OBJ - Object
> +**/
> +
> +#ifndef SOC_CONFIGURATION_MANAGER_H_
> +#define SOC_CONFIGURATION_MANAGER_H_
> +
> +#include "ConfigurationManager.h"
> +
> +/** The number of ACPI tables to install
> +*/
> +#define PLAT_ACPI_TABLE_COUNT  7
> +
> +/** A helper macro for mapping a reference token
> +*/
> +#define REFERENCE_TOKEN_SOC(Field)                                \
> +  (CM_OBJECT_TOKEN)((UINT8*)&MorelloSocRepositoryInfo +           \
> +    OFFSET_OF (EDKII_SOC_PLATFORM_REPOSITORY_INFO, Field))
> +
> +/** C array containing the compiled AML template.
> +    These symbols are defined in the auto generated C file
> +    containing the AML bytecode array.
> +*/
> +extern CHAR8  dsdtsoc_aml_code[];
> +
> +/** A structure describing the SoC Platform specific information
> +*/
> +typedef struct SocPlatformRepositoryInfo {
> +  /// List of ACPI tables
> +  CM_STD_OBJ_ACPI_TABLE_INFO    CmAcpiTableList[PLAT_ACPI_TABLE_COUNT];
> +} EDKII_SOC_PLATFORM_REPOSITORY_INFO;
> +
> +/** A structure describing the platform configuration
> +    manager repository information
> +*/
> +typedef struct PlatformRepositoryInfo {
> +  /// Common information
> +  EDKII_COMMON_PLATFORM_REPOSITORY_INFO    *CommonPlatRepoInfo;
> +
> +  /// SoC Platform specific information
> +  EDKII_SOC_PLATFORM_REPOSITORY_INFO       *SocPlatRepoInfo;
> +} EDKII_PLATFORM_REPOSITORY_INFO;
> +
> +extern EDKII_COMMON_PLATFORM_REPOSITORY_INFO  CommonPlatformInfo;
> +
> +/** Return platform specific ARM namespace object.
> +
> +  @param [in]      This        Pointer to the Configuration Manager Protocol.
> +  @param [in]      CmObjectId  The Configuration Manager Object ID.
> +  @param [in]      Token       An optional token identifying the object. If
> +                               unused this must be CM_NULL_TOKEN.
> +  @param [in, 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
> +GetArmNameSpaceObjectPlat (
> +  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST This,
> +  IN  CONST CM_OBJECT_ID                                 CmObjectId,
> +  IN  CONST CM_OBJECT_TOKEN                              Token OPTIONAL,
> +  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST CmObject
> +  );
> +
> +/** Return platform specific standard namespace object.
> +
> +  @param [in]      This        Pointer to the Configuration Manager Protocol.
> +  @param [in]      CmObjectId  The Configuration Manager Object ID.
> +  @param [in]      Token       An optional token identifying the object. If
> +                               unused this must be CM_NULL_TOKEN.
> +  @param [in, 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
> +GetStandardNameSpaceObjectPlat (
> +  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST This,
> +  IN  CONST CM_OBJECT_ID                                 CmObjectId,
> +  IN  CONST CM_OBJECT_TOKEN                              Token OPTIONAL,
> +  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST CmObject
> +  );
> +
> +#endif // SOC_CONFIGURATION_MANAGER_H_
> diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
> new file mode 100644
> index 000000000000..7ca8ae212a61
> --- /dev/null
> +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
> @@ -0,0 +1,161 @@
> +/** @file
> +  Configuration Manager Dxe
> +
> +  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  @par Glossary:
> +    - Cm or CM   - Configuration Manager
> +    - Obj or OBJ - Object
> +**/
> +
> +#include <IndustryStandard/DebugPort2Table.h>
> +#include <IndustryStandard/IoRemappingTable.h>
> +#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
> +#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +
> +#include "ConfigurationManagerSoc.h"
> +#include "Platform.h"
> +
> +EDKII_SOC_PLATFORM_REPOSITORY_INFO  MorelloSocRepositoryInfo = {
> +  // ACPI Table List
> +  {
> +    // FADT Table
> +    {
> +      EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
> +      EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
> +      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt),
> +      NULL
> +    },
> +    // GTDT Table
> +    {
> +      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
> +      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION,
> +      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdGtdt),
> +      NULL
> +    },
> +    // MADT Table
> +    {
> +      EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
> +      EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
> +      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMadt),
> +      NULL
> +    },
> +    // SPCR Table
> +    {
> +      EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
> +      EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION,
> +      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSpcr),
> +      NULL
> +    },
> +    // DSDT Table
> +    {
> +      EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
> +      0, // Unused
> +      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDsdt),
> +      (EFI_ACPI_DESCRIPTION_HEADER *)dsdtsoc_aml_code
> +    },
> +    // DBG2 Table
> +    {
> +      EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE,
> +      EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,
> +      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDbg2),
> +      NULL
> +    },
> +    // PPTT Table
> +    {
> +      EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
> +      EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION,
> +      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdPptt),
> +      NULL
> +    },
> +  },
> +};
> +
> +EDKII_PLATFORM_REPOSITORY_INFO  MorelloRepositoryInfo = {
> +  &CommonPlatformInfo,
> +  &MorelloSocRepositoryInfo
> +};
> +
> +/** Return platform specific ARM namespace object.
> +
> +  @param [in]      This        Pointer to the Configuration Manager Protocol.
> +  @param [in]      CmObjectId  The Configuration Manager Object ID.
> +  @param [in]      Token       An optional token identifying the object. If
> +                               unused this must be CM_NULL_TOKEN.
> +  @param [in, 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
> +GetArmNameSpaceObjectPlat (
> +  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST This,
> +  IN  CONST CM_OBJECT_ID                                 CmObjectId,
> +  IN  CONST CM_OBJECT_TOKEN                              Token OPTIONAL,
> +  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST CmObject
> +  )
> +{
> +  return EFI_NOT_FOUND;
> +}
> +
> +/** Return platform specific standard namespace object.
> +
> +  @param [in]      This        Pointer to the Configuration Manager Protocol.
> +  @param [in]      CmObjectId  The Configuration Manager Object ID.
> +  @param [in]      Token       An optional token identifying the object. If
> +                               unused this must be CM_NULL_TOKEN.
> +  @param [in, 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
> +GetStandardNameSpaceObjectPlat (
> +  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST This,
> +  IN  CONST CM_OBJECT_ID                                 CmObjectId,
> +  IN  CONST CM_OBJECT_TOKEN                              Token OPTIONAL,
> +  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST CmObject
> +  )
> +{
> +  EFI_STATUS                          Status;
> +  EDKII_SOC_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
> +
> +  if ((This == NULL) || (CmObject == NULL)) {
> +    ASSERT (This != NULL);
> +    ASSERT (CmObject != NULL);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status = EFI_NOT_FOUND;
> +  PlatformRepo = This->PlatRepoInfo->SocPlatRepoInfo;
> +
> +  switch (GET_CM_OBJECT_ID (CmObjectId)) {
> +    case EStdObjAcpiTableList:
> +      Status = HandleCmObject (
> +                 CmObjectId,
> +                 PlatformRepo->CmAcpiTableList,
> +                 sizeof (PlatformRepo->CmAcpiTableList),
> +                 ARRAY_SIZE (PlatformRepo->CmAcpiTableList),
> +                 CmObject
> +                 );
> +      break;
> +
> +    default:
> +    {
> +      break;
> +    }
> +  }
> +
> +  return Status;
> +}
> diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl
> new file mode 100644
> index 000000000000..806e170515b7
> --- /dev/null
> +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl
> @@ -0,0 +1,41 @@
> +/** @file
> +  Differentiated System Description Table Fields (DSDT)
> +
> +  Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  @par Reference(s):
> +  - ACPI for Arm Components  1.0, Platform Design Document
> +
> +**/
> +
> +#include "ConfigurationManager.h"
> +
> +DefinitionBlock("Dsdt.aml", "DSDT", 1, "ARMLTD", "MORELLO", CFG_MGR_OEM_REVISION) {
> +  Scope(_SB) {
> +    Device(CP00) { // Cluster 0, Cpu 0
> +      Name(_HID, "ACPI0007")
> +      Name(_UID, 0)
> +      Name(_STA, 0xF)
> +    }
> +
> +    Device(CP01) { // Cluster 0, Cpu 1
> +      Name(_HID, "ACPI0007")
> +      Name(_UID, 1)
> +      Name(_STA, 0xF)
> +    }
> +
> +    Device(CP02) { // Cluster 1, Cpu 0
> +      Name(_HID, "ACPI0007")
> +      Name(_UID, 2)
> +      Name(_STA, 0xF)
> +    }
> +
> +    Device(CP03) { // Cluster 1, Cpu 1
> +      Name(_HID, "ACPI0007")
> +      Name(_UID, 3)
> +      Name(_STA, 0xF)
> +    }
> +  } // Scope(_SB)
> +}


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-platforms][PATCH V1 05/11] Platform/ARM/Morello: Add initial support for Morello SoC
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 05/11] Platform/ARM/Morello: Add initial support " chandni cherukuri
@ 2021-12-07 20:54   ` Sami Mujawar
  0 siblings, 0 replies; 31+ messages in thread
From: Sami Mujawar @ 2021-12-07 20:54 UTC (permalink / raw)
  To: Chandni Cherukuri, devel; +Cc: Ard Biesheuvel, Leif Lindholm, nd

Hi Chandni,

I would suggest adding a brief introduction about the Morello SoC 
platform in the commit message.

Otherwise, this patch looks good to me.

With the commit message updated.

Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>

Regards,

Sami Mujawar


On 04/12/2021 12:30 PM, Chandni Cherukuri wrote:
> This patch adds initial support for Morello SoC platform.
>
> Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
> ---
>   Platform/ARM/Morello/MorelloPlatform.dsc.inc |  27 +-
>   Platform/ARM/Morello/MorelloPlatformFvp.dsc  |  30 +-
>   Platform/ARM/Morello/MorelloPlatformSoc.dsc  |  47 ++++
>   Platform/ARM/Morello/MorelloPlatformSoc.fdf  | 287 ++++++++++++++++++++
>   4 files changed, 363 insertions(+), 28 deletions(-)
>
> diff --git a/Platform/ARM/Morello/MorelloPlatform.dsc.inc b/Platform/ARM/Morello/MorelloPlatform.dsc.inc
> index dccd22248318..862d5f2da1b0 100644
> --- a/Platform/ARM/Morello/MorelloPlatform.dsc.inc
> +++ b/Platform/ARM/Morello/MorelloPlatform.dsc.inc
> @@ -9,13 +9,13 @@
>   [LibraryClasses.common]
>     ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
>     ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
> -  ArmPlatformLib|Platform/ARM/Morello/Library/PlatformLib/PlatformLib.inf
>     BasePathLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
>     HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
>     TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
>   
>     # Ramdisk Support
>     FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
> +  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
>   
>   [LibraryClasses.common.SEC]
>     HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> @@ -47,9 +47,6 @@
>   
>   [LibraryClasses.common.DXE_DRIVER]
>     FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
> -  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
> -  PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
> -  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
>   
>   [LibraryClasses.common.DXE_RUNTIME_DRIVER]
>     BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
> @@ -131,11 +128,6 @@
>     gArmMorelloTokenSpaceGuid.PcdRamDiskBase|0x88000000
>     gArmMorelloTokenSpaceGuid.PcdRamDiskSize|0x18000000
>   
> -  # PCIe
> -  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|24
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
> -  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x20000000
> -
>   [PcdsDynamicHii.common.DEFAULT]
>     gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|0
>   
> @@ -217,20 +209,3 @@
>   
>     # RAM Disk
>     MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
> -
> -  # Required by PCI
> -  ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
> -
> -  # PCI Support
> -  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> -  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
> -    <PcdsFixedAtBuild>
> -      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8010004F
> -  }
> -
> -  # AHCI Support
> -  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> -  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> -
> -  # SATA Controller
> -  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
> diff --git a/Platform/ARM/Morello/MorelloPlatformFvp.dsc b/Platform/ARM/Morello/MorelloPlatformFvp.dsc
> index ee612296a80e..1f9199fba2dc 100644
> --- a/Platform/ARM/Morello/MorelloPlatformFvp.dsc
> +++ b/Platform/ARM/Morello/MorelloPlatformFvp.dsc
> @@ -39,14 +39,18 @@
>   !include MdePkg/MdeLibs.dsc.inc
>   
>   [LibraryClasses.common]
> +  # Platform Library
> +  ArmPlatformLib|Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf
> +
>     # Virtio Support
>     VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
>     VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
> -  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
> -  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
>   
>   [LibraryClasses.common.DXE_DRIVER]
>     PciHostBridgeLib|Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibFvp.inf
> +  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
> +  PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
> +  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
>   
>   [PcdsFeatureFlag.common]
>     gArmMorelloTokenSpaceGuid.PcdVirtioBlkSupported|TRUE
> @@ -63,9 +67,31 @@
>     gArmMorelloTokenSpaceGuid.PcdVirtioNetSize|0x200
>     gArmMorelloTokenSpaceGuid.PcdVirtioNetInterrupt|134
>   
> +  # PCIe
> +  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|24
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x20000000
> +
>   [Components.common]
>     OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
>     OvmfPkg/VirtioNetDxe/VirtioNet.inf
>   
>     # Platform driver
>     Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeFvp.inf
> +
> +  # Required by PCI
> +  ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
> +
> +  # PCI Support
> +  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8010004F
> +  }
> +
> +  # AHCI Support
> +  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> +  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +
> +  # SATA Controller
> +  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
> diff --git a/Platform/ARM/Morello/MorelloPlatformSoc.dsc b/Platform/ARM/Morello/MorelloPlatformSoc.dsc
> new file mode 100644
> index 000000000000..8335c50803b3
> --- /dev/null
> +++ b/Platform/ARM/Morello/MorelloPlatformSoc.dsc
> @@ -0,0 +1,47 @@
> +## @file
> +#  Compoenent description file specific for Morello SoC Platform
> +#
> +#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +################################################################################
> +#
> +# Defines Section - statements that will be processed to create a Makefile.
> +#
> +################################################################################
> +[Defines]
> +  PLATFORM_NAME                  = morellosoc
> +  PLATFORM_GUID                  = 8AC37B62-713D-449D-876D-06AD1B8E67E5
> +  PLATFORM_VERSION               = 0.1
> +  DSC_SPECIFICATION              = 0x0001001B
> +!ifdef $(EDK2_OUT_DIR)
> +  OUTPUT_DIRECTORY               = $(EDK2_OUT_DIR)
> +!else
> +  OUTPUT_DIRECTORY               = Build/$(PLATFORM_NAME)
> +!endif
> +  SUPPORTED_ARCHITECTURES        = AARCH64
> +  BUILD_TARGETS                  = NOOPT|DEBUG|RELEASE
> +  SKUID_IDENTIFIER               = DEFAULT
> +  FLASH_DEFINITION               = Platform/ARM/Morello/MorelloPlatformSoc.fdf
> +  BUILD_NUMBER                   = 1
> +
> +  # Network definition
> +  DEFINE NETWORK_ISCSI_ENABLE    = FALSE
> +
> +!include Platform/ARM/Morello/MorelloPlatform.dsc.inc
> +!include Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
> +!include DynamicTablesPkg/DynamicTables.dsc.inc
> +!include Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
> +
> +# include common/basic libraries from MdePkg.
> +!include MdePkg/MdeLibs.dsc.inc
> +
> +[LibraryClasses.common]
> +  # Platform Library
> +  ArmPlatformLib|Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
> +
> +[Components.common]
> +  # Platform driver
> +  Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf
> diff --git a/Platform/ARM/Morello/MorelloPlatformSoc.fdf b/Platform/ARM/Morello/MorelloPlatformSoc.fdf
> new file mode 100644
> index 000000000000..e7d4a6a9828d
> --- /dev/null
> +++ b/Platform/ARM/Morello/MorelloPlatformSoc.fdf
> @@ -0,0 +1,287 @@
> +## @file
> +#  FDF file of Morello SoC platform
> +#
> +#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +################################################################################
> +#
> +# FD Section
> +# The [FD] Section is made up of the definition statements and a
> +# description of what goes into  the Flash Device Image.  Each FD section
> +# defines one flash "device" image.  A flash device image may be one of
> +# the following: Removable media bootable image (like a boot floppy
> +# image,) an Option ROM image (that would be "flashed" into an add-in
> +# card,) a System "Flash"  image (that would be burned into a system's
> +# flash) or an Update ("Capsule") image that will be used to update and
> +# existing system flash.
> +#
> +################################################################################
> +
> +[FD.BL33_AP_UEFI]
> +BaseAddress   = 0xE0000000|gArmTokenSpaceGuid.PcdFdBaseAddress  # The base address of the Firmware in NOR Flash.
> +Size          = 0x00200000|gArmTokenSpaceGuid.PcdFdSize         # The size in bytes of the FLASH Device
> +ErasePolarity = 1
> +
> +# This one is tricky, it must be: BlockSize * NumBlocks = Size
> +BlockSize     = 0x00001000
> +NumBlocks     = 0x200
> +
> +################################################################################
> +#
> +# Following are lists of FD Region layout which correspond to the locations of
> +# different images within the flash device.
> +#
> +# Regions must be defined in ascending order and may not overlap.
> +#
> +# A Layout Region start with a eight digit hex offset (leading "0x" required)
> +# followed by the pipe "|" character, followed by the size of the region, also
> +# in hex with the leading "0x" characters. Like:
> +# Offset|Size
> +# PcdOffsetCName|PcdSizeCName
> +# RegionType <FV, DATA, or FILE>
> +#
> +################################################################################
> +
> +0x00000000|0x00200000
> +gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
> +FV = FVMAIN_COMPACT
> +
> +
> +################################################################################
> +#
> +# FV Section
> +#
> +# [FV] section is used to define what components or modules are placed within a
> +# flash device file. This section also defines order the components and modules
> +# are positioned within the image. The [FV] section consists of define
> +# statements, set statements and module statements.
> +#
> +################################################################################
> +
> +[FV.FvMain]
> +BlockSize          = 0x40
> +NumBlocks          = 0         # This FV gets compressed so make it just big enough
> +FvAlignment        = 8         # FV alignment and FV attributes setting.
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +  INF MdeModulePkg/Core/Dxe/DxeMain.inf
> +
> +  # PI DXE Drivers producing Architectural Protocols (EFI Services)
> +  INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
> +  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
> +  INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
> +  INF MdeModulePkg/Universal/Metronome/Metronome.inf
> +  INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
> +  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> +  INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
> +  INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
> +  INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> +
> +  # ACPI Support
> +  INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
> +  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
> +
> +  # Configuration Manager
> +  INF Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> +
> +  # Dynamic Table fdf
> +  !include DynamicTablesPkg/DynamicTables.fdf.inc
> +
> +  # Multiple Console IO support
> +  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
> +  INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
> +  INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
> +  INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
> +  INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
> +
> +  INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
> +  INF ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
> +  INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
> +
> +  INF Platform/ARM/Drivers/BootMonFs/BootMonFs.inf
> +  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
> +
> +  # FAT filesystem + GPT/MBR partitioning
> +  INF FatPkg/EnhancedFatDxe/Fat.inf
> +  INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
> +  INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
> +  INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
> +
> +  # FV FileSystem
> +  INF MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
> +  INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
> +
> +  # UEFI applications
> +  INF ShellPkg/Application/Shell/Shell.inf
> +
> +  # Platform driver
> +  INF Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf
> +
> +  # Bds
> +  INF MdeModulePkg/Application/UiApp/UiApp.inf
> +  INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
> +  INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
> +  INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
> +  INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
> +
> +[FV.FVMAIN_COMPACT]
> +FvAlignment        = 8
> +BlockSize          = 0x1000
> +NumBlocks          = 0x200
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +  INF ArmPkg/Drivers/CpuPei/CpuPei.inf
> +  INF ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
> +  INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
> +  INF ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
> +  INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
> +  INF MdeModulePkg/Core/Pei/PeiMain.inf
> +  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
> +  INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
> +
> +  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
> +    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
> +      SECTION FV_IMAGE = FVMAIN
> +    }
> +  }
> +
> +
> +################################################################################
> +#
> +# Rules are use with the [FV] section's module INF type to define
> +# how an FFS file is created for a given INF file. The following Rule are the default
> +# rules for the different module type. User can add the customized rules to define the
> +# content of the FFS file.
> +#
> +################################################################################
> +
> +
> +############################################################################
> +# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section   #
> +############################################################################
> +#
> +#[Rule.Common.DXE_DRIVER]
> +#  FILE DRIVER = $(NAMED_GUID) {
> +#    DXE_DEPEX    DXE_DEPEX               Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
> +#    COMPRESS PI_STD {
> +#      GUIDED {
> +#        PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
> +#        UI       STRING="$(MODULE_NAME)" Optional
> +#        VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +#      }
> +#    }
> +#  }
> +#
> +############################################################################
> +
> +#
> +# These SEC rules are used for ArmPlatformPkg/PrePeiCore module.
> +# ArmPlatformPkg/PrePeiCore is declared as a SEC module to make GenFv patch
> +# the UEFI Firmware to jump to ArmPlatformPkg/PrePeiCore entrypoint
> +#
> +
> +[Rule.Common.SEC]
> +  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED FIXED {
> +    TE  TE Align = Auto                 $(INF_OUTPUT)/$(MODULE_NAME).efi
> +  }
> +
> +[Rule.Common.PEI_CORE]
> +  FILE PEI_CORE = $(NAMED_GUID) FIXED {
> +    TE  TE Align = Auto                 $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI  STRING ="$(MODULE_NAME)" Optional
> +  }
> +
> +[Rule.Common.PEIM]
> +  FILE PEIM = $(NAMED_GUID) FIXED {
> +     PEI_DEPEX PEI_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
> +     TE  TE Align = Auto                $(INF_OUTPUT)/$(MODULE_NAME).efi
> +     UI  STRING="$(MODULE_NAME)" Optional
> +  }
> +
> +[Rule.Common.PEIM.TIANOCOMPRESSED]
> +  FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
> +    PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
> +      PE32      PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
> +      UI        STRING="$(MODULE_NAME)" Optional
> +    }
> +  }
> +
> +[Rule.Common.DXE_CORE]
> +  FILE DXE_CORE = $(NAMED_GUID) {
> +    PE32     PE32                       $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING="$(MODULE_NAME)" Optional
> +  }
> +
> +[Rule.Common.UEFI_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI           STRING="$(MODULE_NAME)" Optional
> +  }
> +
> +[Rule.Common.DXE_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI           STRING="$(MODULE_NAME)" Optional
> +  }
> +
> +[Rule.Common.DXE_RUNTIME_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI           STRING="$(MODULE_NAME)" Optional
> +  }
> +
> +[Rule.Common.UEFI_APPLICATION]
> +  FILE APPLICATION = $(NAMED_GUID) {
> +    UI     STRING ="$(MODULE_NAME)" Optional
> +    PE32   PE32                         $(INF_OUTPUT)/$(MODULE_NAME).efi
> +  }
> +
> +[Rule.Common.UEFI_DRIVER.BINARY]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional      |.depex
> +    PE32      PE32                    |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_APPLICATION.BINARY]
> +  FILE APPLICATION = $(NAMED_GUID) {
> +    PE32      PE32                    |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-platforms][PATCH V1 06/11] Platform/ARM/Morello: Port PCI Segment Library
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 06/11] Platform/ARM/Morello: Port PCI Segment Library chandni cherukuri
@ 2021-12-07 20:54   ` Sami Mujawar
  0 siblings, 0 replies; 31+ messages in thread
From: Sami Mujawar @ 2021-12-07 20:54 UTC (permalink / raw)
  To: Chandni Cherukuri, devel; +Cc: Ard Biesheuvel, Leif Lindholm, nd

Hi Chandni,

Thank you for this patch.

I have a minor suggestion marked inline as [SAMI].

Otherwise this patch looks good to me.

Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>

Regards,

Sami Mujawar


On 04/12/2021 12:30 PM, Chandni Cherukuri wrote:
> From: Anurag Koul <anurag.koul@arm.com>
>
> A custom PCI Segment library is required to handle multiple PCIe
> segments in Morello, as the base PCI Segment library doesn't allow
> supporting more than a single PCIe segment.
>
> This custom platform-specific PCI Segment Library has been adapted
> from MdePkg/BasePciSegmentLib.
>
> Signed-off-by: Anurag Koul <anurag.koul@arm.com>
> Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
> ---
>   Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.inf |   30 +
>   Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.c   | 1405 ++++++++++++++++++++
>   2 files changed, 1435 insertions(+)
>
> diff --git a/Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.inf b/Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.inf
> new file mode 100644
> index 000000000000..c37458cba826
> --- /dev/null
> +++ b/Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.inf
> @@ -0,0 +1,30 @@
> +## @file
> +# PCI Segment Library for Morello SoC with multiple RCs
> +#
> +# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = PciSegmentLib
> +  FILE_GUID                      = 5811c256-4d1f-11ec-81d3-0242ac130003
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PciSegmentLib
> +
> +[Sources]
> +  PciSegmentLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  Platform/ARM/Morello/MorelloPlatform.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  IoLib
> +  PciLib
> diff --git a/Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.c b/Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.c
> new file mode 100644
> index 000000000000..41a998830710
> --- /dev/null
> +++ b/Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.c
> @@ -0,0 +1,1405 @@
> +/** @file
> +  PCI Segment Library for Morello SoC with multiple RCs
> +
> +  Having two distinct root complexes is not supported by the standard
> +  set of PciLib/PciExpressLib/PciSegmentLib, this PciSegmentLib
> +  reimplements the functionality to support multiple root ports under
> +  different PCIe segments.
> +
> +  Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Base.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <MorelloPlatform.h>
> +
> +typedef enum {
> +  PciCfgWidthUint8 = 0,
> +  PciCfgWidthUint16,
> +  PciCfgWidthUint32,
> +  PciCfgWidthMax
> +} PCI_CFG_WIDTH;
> +
> +/**
> + Assert the validity of a PCI Segment address.
> + A valid PCI Segment address should not contain 1's in bits 28..31 and 48..63
> +
> +  @param A The address to validate.
> +  @param M Additional bits to assert to be zero.
> +**/
> +#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A, M) \
> +  ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
> +
> +/**
> +  Internal worker function to read a PCI configuration register.
> +
> +  @param [in]  Address    The address that encodes the PCI Bus, Device, Function
> +                          and Register.
> +  @param [in]  Width      The width of data to read
> +
> +  @return The value read from the PCI configuration register.
> +**/
> +STATIC
> +UINT32
> +PciSegmentLibReadWorker (
> +  IN  UINT64        Address,
> +  IN  PCI_CFG_WIDTH Width
> +  )
> +{
> +  switch (Width) {
> +    case PciCfgWidthUint8:
> +      return PciRead8 (Address);
> +    case PciCfgWidthUint16:
> +      return PciRead16 (Address);
> +    case PciCfgWidthUint32:
> +      return PciRead32 (Address);
> +    default:
> +      ASSERT (FALSE);
> +  }
> +
> +  return 0;
> +}
> +
> +/**
> +  Internal worker function to write to a PCI configuration register.
> +
> +  @param [in]  Address   The address that encodes the PCI Bus, Device, Function
> +                         and Register.
> +  @param [in]  Width     The width of data to write
> +  @param [in]  Data      The value to write.
> +
> +  @return  The value written to the PCI configuration register.
> +**/
> +STATIC
> +UINT32
> +PciSegmentLibWriteWorker (
> +  IN  UINT64        Address,
> +  IN  PCI_CFG_WIDTH Width,
> +  IN  UINT32        Data
> +  )
> +{
> +  switch (Width) {
> +    case PciCfgWidthUint8:
> +      PciWrite8 (Address, Data);
> +      break;
> +    case PciCfgWidthUint16:
> +      PciWrite16 (Address, Data);
> +      break;
> +    case PciCfgWidthUint32:
> +      PciWrite32 (Address, Data);
> +      break;
> +    default:
> +      ASSERT (FALSE);
> +  }
> +
> +  return Data;
> +}
> +
> +/**
> +  Reads an 8-bit PCI configuration register.
> +
> +  Reads and returns the 8-bit PCI configuration register specified by Address.
> +  This function must guarantee that all PCI read and write operations are
> +  serialized.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +
> +  @param [in]  Address     The address that encodes the PCI Segment, Bus,
> +                           Device, Function and Register.
> +
> +  @return The 8-bit PCI configuration register specified by the Address.
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentRead8 (
> +  IN UINT64 Address
> +  )
> +{
> +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> +
> +  return (UINT8)PciSegmentLibReadWorker (Address, PciCfgWidthUint8);
> +}
> +
> +/**
> +  Writes an 8-bit PCI configuration register.
> +
> +  Writes the 8-bit Value in the PCI configuration register specified by the
> +  Address. This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +
> +  @param [in]  Address     The address that encodes the PCI Segment, Bus,
> +                           Device, Function, and Register.
> +  @param [in]  Value       The value to write.
> +
> +  @return The value written to the PCI configuration register.
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentWrite8 (
> +  IN UINT64 Address,
> +  IN UINT8  Value
> +  )
> +{
> +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> +
> +  return (UINT8)PciSegmentLibWriteWorker (Address, PciCfgWidthUint8, Value);
> +}
> +
> +/**
> +  Performs a bitwise OR of an 8-bit PCI configuration register with
> +  an 8-bit value.
> +
> +  Reads the 8-bit PCI configuration register specified by Address,
> +  performs a bitwise OR between the read result and the value specified by
> +  OrData, and writes the result to the 8-bit PCI configuration register
> +  specified by Address.
> +
> +  The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +
> +  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
> +                         Function, and Register.
> +  @param [in]  OrData    The value to OR with the PCI configuration register.
> +
> +  @return The value written to the PCI configuration register.
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentOr8 (
> +  IN UINT64 Address,
> +  IN UINT8  OrData
> +  )
> +{
> +  return PciSegmentWrite8 (
> +           Address,
> +           (UINT8)(PciSegmentRead8 (Address) | OrData)
> +           );
> +}
> +
> +/**
> +  Performs a bitwise AND of an 8-bit PCI configuration register with
> +  an 8-bit value.
> +
> +  Reads the 8-bit PCI configuration register specified by Address,
> +  performs a bitwise AND between the read result and the value specified by
> +  AndData, and writes the result to the 8-bit PCI configuration register
> +  specified by Address.
> +
> +  The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations
> +  are serialized. If any reserved bits in Address are set, then ASSERT().
> +
> +  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
> +                         Function, and Register.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +
> +  @return The value written to the PCI configuration register.
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentAnd8 (
> +  IN UINT64 Address,
> +  IN UINT8  AndData
> +  )
> +{
> +  return PciSegmentWrite8 (
> +           Address,
> +           (UINT8)(PciSegmentRead8 (Address) & AndData)
> +           );
> +}
> +
> +/**
> +  Performs a bitwise AND of an 8-bit PCI configuration register with
> +  an 8-bit value, followed by a bitwise OR with another 8-bit value.
> +
> +  Reads the 8-bit PCI configuration register specified by Address,
> +  performs a bitwise AND between the read result and the value specified
> +  by AndData, performs a bitwise OR between the result of the AND operation
> +  and the value specified by OrData, and writes the result to the 8-bit
> +  PCI configuration register specified by Address.
> +
> +  The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +
> +  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
> +                         Function, and Register.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +  @param [in]  OrData    The value to OR with the PCI configuration register.
> +
> +  @return The value written to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentAndThenOr8 (
> +  IN UINT64 Address,
> +  IN UINT8  AndData,
> +  IN UINT8  OrData
> +  )
> +{
> +  return PciSegmentWrite8 (
> +           Address,
> +           (UINT8)((PciSegmentRead8 (Address) & AndData) | OrData)
> +           );
> +}
> +
> +/**
> +  Reads a bit field of a PCI configuration register.
> +
> +  Reads the bit field in an 8-bit PCI configuration register. The bit field is
> +  specified by the StartBit and the EndBit. The value of the bit field is
> +  returned.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to read.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..7.
> +
> +  @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentBitFieldRead8 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit
> +  )
> +{
> +  return BitFieldRead8 (PciSegmentRead8 (Address), StartBit, EndBit);
> +}
> +
> +/**
> +  Writes a bit field to a PCI configuration register.
> +
> +  Writes Value to the bit field of the PCI configuration register. The bit
> +  field is specified by the StartBit and the EndBit. All other bits in the
> +  destination PCI configuration register are preserved. The new value of the
> +  8-bit register is returned.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If Value is larger than the bitmask value range specified by StartBit
> +  and EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  Value     The new value of the bit field.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentBitFieldWrite8 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit,
> +  IN UINT8  Value
> +  )
> +{
> +  return PciSegmentWrite8 (
> +           Address,
> +           BitFieldWrite8 (PciSegmentRead8 (Address), StartBit, EndBit, Value)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
> +  writes the result back to the bit field in the 8-bit port.
> +
> +  Reads the 8-bit PCI configuration register specified by Address, performs a
> +  bitwise OR between the read result and the value specified by
> +  OrData, and writes the result to the 8-bit PCI configuration register
> +  specified by Address. The value written to the PCI configuration register is
> +  returned. This function must guarantee that all PCI read and write operations
> +  are serialized. Extra left bits in OrData are stripped.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  OrData    The value to OR with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentBitFieldOr8 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit,
> +  IN UINT8  OrData
> +  )
> +{
> +  return PciSegmentWrite8 (
> +           Address,
> +           BitFieldOr8 (PciSegmentRead8 (Address), StartBit, EndBit, OrData)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
> +  AND, and writes the result back to the bit field in the 8-bit register.
> +
> +  Reads the 8-bit PCI configuration register specified by Address, performs a
> +  bitwise AND between the read result and the value specified by AndData, and
> +  writes the result to the 8-bit PCI configuration register specified by
> +  Address. The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations are
> +  serialized. Extra left bits in AndData are stripped.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentBitFieldAnd8 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit,
> +  IN UINT8  AndData
> +  )
> +{
> +  return PciSegmentWrite8 (
> +           Address,
> +           BitFieldAnd8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
> +  bitwise OR, and writes the result back to the bit field in the
> +  8-bit port.
> +
> +  Reads the 8-bit PCI configuration register specified by Address, performs a
> +  bitwise AND followed by a bitwise OR between the read result and
> +  the value specified by AndData, and writes the result to the 8-bit PCI
> +  configuration register specified by Address. The value written to the PCI
> +  configuration register is returned. This function must guarantee that all PCI
> +  read and write operations are serialized. Extra left bits in both AndData and
> +  OrData are stripped.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit
> +  and EndBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit
> +  and EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +  @param [in]  OrData    The value to OR with the result of the AND operation.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentBitFieldAndThenOr8 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit,
> +  IN UINT8  AndData,
> +  IN UINT8  OrData
> +  )
> +{
> +  return PciSegmentWrite8 (
> +           Address,
> +           BitFieldAndThenOr8 (
> +             PciSegmentRead8 (Address),
> +             StartBit,
> +             EndBit,
> +             AndData,
> +             OrData
> +             )
> +           );
> +}
> +
> +/**
> +  Reads a 16-bit PCI configuration register.
> +
> +  Reads and returns the 16-bit PCI configuration register specified by Address.
> +  This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
> +                         Function, and Register.
> +
> +  @return The 16-bit PCI configuration register specified by Address.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentRead16 (
> +  IN UINT64 Address
> +  )
> +{
> +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
> +
> +  return (UINT16)PciSegmentLibReadWorker (Address, PciCfgWidthUint16);
> +}
> +
> +/**
> +  Writes a 16-bit PCI configuration register.
> +
> +  Writes the 16-bit PCI configuration register specified by Address with the
> +  value specified by Value. Value is returned.
> +  This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param [in]  Address     The address that encodes the PCI Segment, Bus, Device,
> +                           Function, and Register.
> +  @param [in]  Value       The value to write.
> +
> +  @return The Value written is returned.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentWrite16 (
> +  IN UINT64 Address,
> +  IN UINT16 Value
> +  )
> +{
> +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
> +
> +  return (UINT16)PciSegmentLibWriteWorker (Address, PciCfgWidthUint16, Value);
> +}
> +
> +/**
> +  Performs a bitwise OR of a 16-bit PCI configuration register with
> +  a 16-bit value.
> +
> +  Reads the 16-bit PCI configuration register specified by Address, performs a
> +  bitwise OR between the read result and the value specified by
> +  OrData, and writes the result to the 16-bit PCI configuration register
> +  specified by Address. The value written to the PCI configuration register is
> +  returned. This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Segment, Bus, Device,
> +                       Function and Register.
> +  @param [in]  OrData  The value to OR with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentOr16 (
> +  IN UINT64 Address,
> +  IN UINT16 OrData
> +  )
> +{
> +  return PciSegmentWrite16 (
> +           Address,
> +           (UINT16)(PciSegmentRead16 (Address) | OrData)
> +           );
> +}
> +
> +/**
> +  Performs a bitwise AND of a 16-bit PCI configuration register with
> +  a 16-bit value.
> +
> +  Reads the 16-bit PCI configuration register specified by Address,
> +  performs a bitwise AND between the read result and the value specified
> +  by AndData, and writes the result to the 16-bit PCI configuration register
> +  specified by the Address.
> +
> +  The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
> +                         Function, and Register.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +
> +  @return The value written to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentAnd16 (
> +  IN UINT64 Address,
> +  IN UINT16 AndData
> +  )
> +{
> +  return PciSegmentWrite16 (
> +           Address,
> +           (UINT16)(PciSegmentRead16 (Address) & AndData)
> +           );
> +}
> +
> +/**
> +  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
> +  value, followed a  bitwise OR with another 16-bit value.
> +
> +  Reads the 16-bit PCI configuration register specified by Address,
> +  performs a bitwise AND between the read result and the value specified by
> +  AndData, performs a bitwise OR between the result of the AND operation and
> +  the value specified by OrData, and writes the result to the 16-bit PCI
> +  configuration register specified by the Address.
> +
> +  The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
> +                         Function, and Register.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +  @param [in]  OrData    The value to OR with the PCI configuration register.
> +
> +  @return The value written to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentAndThenOr16 (
> +  IN UINT64 Address,
> +  IN UINT16 AndData,
> +  IN UINT16 OrData
> +  )
> +{
> +  return PciSegmentWrite16 (
> +           Address,
> +           (UINT16)((PciSegmentRead16 (Address) & AndData) | OrData)
> +           );
> +}
> +
> +/**
> +  Reads a bit field of a PCI configuration register.
> +
> +  Reads the bit field in a 16-bit PCI configuration register. The bit field is
> +  specified by the StartBit and the EndBit. The value of the bit field is
> +  returned.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +  If StartBit is greater than 15, then ASSERT().
> +  If EndBit is greater than 15, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to read.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..15.
> +
> +  @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentBitFieldRead16 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit
> +  )
> +{
> +  return BitFieldRead16 (PciSegmentRead16 (Address), StartBit, EndBit);
> +}
> +
> +/**
> +  Writes a bit field to a PCI configuration register.
> +
> +  Writes Value to the bit field of the PCI configuration register. The bit
> +  field is specified by the StartBit and the EndBit. All other bits in the
> +  destination PCI configuration register are preserved. The new value of the
> +  16-bit register is returned.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +  If StartBit is greater than 15, then ASSERT().
> +  If EndBit is greater than 15, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If Value is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  Value     The new value of the bit field.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentBitFieldWrite16 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit,
> +  IN UINT16 Value
> +  )
> +{
> +  return PciSegmentWrite16 (
> +           Address,
> +           BitFieldWrite16 (PciSegmentRead16 (Address), StartBit, EndBit, Value)
> +           );
> +}
> +
> +/**
> +  Reads the 16-bit PCI configuration register specified by Address,
> +  performs a bitwise OR between the read result and the value specified
> +  by OrData, and writes the result to the 16-bit PCI configuration register
> +  specified by the Address.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +  If StartBit is greater than 15, then ASSERT().
> +  If EndBit is greater than 15, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  OrData    The value to OR with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentBitFieldOr16 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit,
> +  IN UINT16 OrData
> +  )
> +{
> +  return PciSegmentWrite16 (
> +           Address,
> +           BitFieldOr16 (PciSegmentRead16 (Address), StartBit, EndBit, OrData)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,
> +  and writes the result back to the bit field in the 16-bit port.
> +
> +  Reads the 16-bit PCI configuration register specified by Address,
> +  performs a bitwise OR between the read result and the value specified by
> +  OrData, and writes the result to the 16-bit PCI configuration register
> +  specified by the Address.
> +
> +  The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations are
> +  serialized. Extra left bits in OrData are stripped.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
> +                         Function, and Register.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. The ordinal of the least significant bit in a
> +                         byte is bit 0.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. The ordinal of the most significant bit in a
> +                         byte is bit 7.
> +  @param [in]  AndData   The value to AND with the read value from the PCI
> +                         configuration register.
> +
> +  @return The value written to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentBitFieldAnd16 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit,
> +  IN UINT16 AndData
> +  )
> +{
> +  return PciSegmentWrite16 (
> +           Address,
> +           BitFieldAnd16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
> +  bitwise OR, and writes the result back to the bit field in the
> +  16-bit port.
> +
> +  Reads the 16-bit PCI configuration register specified by Address, performs a
> +  bitwise AND followed by a bitwise OR between the read result and
> +  the value specified by AndData, and writes the result to the 16-bit PCI
> +  configuration register specified by Address. The value written to the PCI
> +  configuration register is returned. This function must guarantee that all PCI
> +  read and write operations are serialized. Extra left bits in both AndData and
> +  OrData are stripped.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If StartBit is greater than 15, then ASSERT().
> +  If EndBit is greater than 15, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +  @param [in]  OrData    The value to OR with the result of the AND operation.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentBitFieldAndThenOr16 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit,
> +  IN UINT16 AndData,
> +  IN UINT16 OrData
> +  )
> +{
> +  return PciSegmentWrite16 (
> +           Address,
> +           BitFieldAndThenOr16 (
> +             PciSegmentRead16 (Address),
> +             StartBit,
> +             EndBit,
> +             AndData,
> +             OrData
> +             )
> +           );
> +}
> +
> +/**
> +  Reads a 32-bit PCI configuration register.
> +
> +  Reads and returns the 32-bit PCI configuration register specified by Address.
> +  This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
> +                         Function and Register.
> +
> +  @return The 32-bit PCI configuration register specified by Address.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentRead32 (
> +  IN UINT64 Address
> +  )
> +{
> +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
> +
> +  return PciSegmentLibReadWorker (Address, PciCfgWidthUint32);
> +}
> +
> +/**
> +  Writes a 32-bit PCI configuration register.
> +
> +  Writes the 32-bit PCI configuration register specified by Address with the
> +  value specified by Value.  Value is returned. This function must guarantee
> +  that all PCI read and write operations are serialized.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param [in]  Address     The address that encodes the PCI Segment, Bus, Device,
> +                           Function, and Register.
> +  @param [in]  Value       The value to write.
> +
> +  @return The parameter of Value.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentWrite32 (
> +  IN UINT64 Address,
> +  IN UINT32 Value
> +  )
> +{
> +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
> +
> +  return PciSegmentLibWriteWorker (Address, PciCfgWidthUint32, Value);
> +}
> +
> +/**
> +  Performs a bitwise OR of a 32-bit PCI configuration register with a
> +  32-bit value.
> +
> +  Reads the 32-bit PCI configuration register specified by Address,
> +  performs a bitwise OR between the read result and the value specified
> +  by OrData, and writes the result to the 32-bit PCI configuration register
> +  specified by Address.
> +
> +  The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
> +                         Function, and Register.
> +  @param [in]  OrData    The value to OR with the PCI configuration register.
> +
> +  @return The value written to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentOr32 (
> +  IN UINT64 Address,
> +  IN UINT32 OrData
> +  )
> +{
> +  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) | OrData);
> +}
> +
> +/**
> +  Performs a bitwise AND of a 32-bit PCI configuration register with
> +  a 32-bit value.
> +
> +  Reads the 32-bit PCI configuration register specified by Address,
> +  performs a bitwise AND between the read result and the value specified
> +  by AndData, and writes the result to the 32-bit PCI configuration register
> +  specified by Address.
> +  The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
> +                         Function and Register.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +
> +  @return The value written to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentAnd32 (
> +  IN UINT64 Address,
> +  IN UINT32 AndData
> +  )
> +{
> +  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) & AndData);
> +}
> +
> +/**
> +  Performs a bitwise AND of a 32-bit PCI configuration register with
> +  a 32-bit value, followed by a bitwise OR with another 32-bit value.
> +
> +  Reads the 32-bit PCI configuration register specified by Address,
> +  performs a bitwise AND between the read result and the value specified
> +  by AndData, performs a bitwise OR between the result of the AND operation
> +  and the value specified by OrData, and writes the result to the 32-bit
> +  PCI configuration register specified by Address.
> +
> +  The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param [in]  Address   The address that encodes the PCI Segment, Bus, Device,
> +                         Function and Register.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +  @param [in]  OrData    The value to OR with the PCI configuration register.
> +
> +  @return The value written to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentAndThenOr32 (
> +  IN UINT64 Address,
> +  IN UINT32 AndData,
> +  IN UINT32 OrData
> +  )
> +{
> +  return PciSegmentWrite32 (
> +           Address,
> +           (PciSegmentRead32 (Address) & AndData) | OrData
> +           );
> +}
> +
> +/**
> +  Reads a bit field of a PCI configuration register.
> +
> +  Reads the bit field in a 32-bit PCI configuration register. The bit field is
> +  specified by the StartBit and the EndBit. The value of the bit field is
> +  returned.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to read.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..31.
> +
> +  @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentBitFieldRead32 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit
> +  )
> +{
> +  return BitFieldRead32 (PciSegmentRead32 (Address), StartBit, EndBit);
> +}
> +
> +/**
> +  Writes a bit field to a PCI configuration register.
> +
> +  Writes Value to the bit field of the PCI configuration register. The bit
> +  field is specified by the StartBit and the EndBit. All other bits in the
> +  destination PCI configuration register are preserved. The new value of the
> +  32-bit register is returned.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If Value is larger than the bitmask value range specified by StartBit
> +  and EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  Value     The new value of the bit field.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentBitFieldWrite32 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit,
> +  IN UINT32 Value
> +  )
> +{
> +  return PciSegmentWrite32 (
> +           Address,
> +           BitFieldWrite32 (PciSegmentRead32 (Address), StartBit, EndBit, Value)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
> +  writes the result back to the bit field in the 32-bit port.
> +
> +  Reads the 32-bit PCI configuration register specified by Address, performs a
> +  bitwise OR between the read result and the value specified by
> +  OrData, and writes the result to the 32-bit PCI configuration register
> +  specified by Address. The value written to the PCI configuration register is
> +  returned. This function must guarantee that all PCI read and write operations
> +  are serialized. Extra left bits in OrData are stripped.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  OrData    The value to OR with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentBitFieldOr32 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit,
> +  IN UINT32 OrData
> +  )
> +{
> +  return PciSegmentWrite32 (
> +           Address,
> +           BitFieldOr32 (PciSegmentRead32 (Address), StartBit, EndBit, OrData)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
> +  AND, and writes the result back to the bit field in the 32-bit register.
> +
> +  Reads the 32-bit PCI configuration register specified by Address,
> +  performs a bitwise AND between the read result and the value specified
> +  by AndData, and writes the result to the 32-bit PCI configuration register
> +  specified by Address. The value written to the PCI configuration register
> +  is returned.  This function must guarantee that all PCI read and write
> +  operations are serialized.  Extra left bits in AndData are stripped.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentBitFieldAnd32 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit,
> +  IN UINT32 AndData
> +  )
> +{
> +  return PciSegmentWrite32 (
> +           Address,
> +           BitFieldAnd32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
> +  bitwise OR, and writes the result back to the bit field in the
> +  32-bit port.
> +
> +  Reads the 32-bit PCI configuration register specified by Address, performs a
> +  bitwise AND followed by a bitwise OR between the read result and
> +  the value specified by AndData, and writes the result to the 32-bit PCI
> +  configuration register specified by Address. The value written to the PCI
> +  configuration register is returned. This function must guarantee that all PCI
> +  read and write operations are serialized. Extra left bits in both AndData and
> +  OrData are stripped.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit
> +  and EndBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit
> +  and EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +  @param [in]  OrData    The value to OR with the result of the AND operation.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentBitFieldAndThenOr32 (
> +  IN UINT64 Address,
> +  IN UINTN  StartBit,
> +  IN UINTN  EndBit,
> +  IN UINT32 AndData,
> +  IN UINT32 OrData
> +  )
> +{
> +  return PciSegmentWrite32 (
> +           Address,
> +           BitFieldAndThenOr32 (
> +             PciSegmentRead32 (Address),
> +             StartBit,
> +             EndBit,
> +             AndData,
> +             OrData
> +             )
> +           );
> +}
> +
> +/**
> +  Reads a range of PCI configuration registers into a caller supplied buffer.
> +
> +  Reads the range of PCI configuration registers specified by StartAddress and
> +  Size into the buffer specified by Buffer. This function only allows the PCI
> +  configuration registers from a single PCI function to be read. Size is
> +  returned. When possible 32-bit PCI configuration read cycles are used to read
> +  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
> +  and 16-bit PCI configuration read cycles may be used at the beginning and the
> +  end of the range.
> +
> +  If any reserved bits in StartAddress are set, then ASSERT().
> +  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> +  If Size > 0 and Buffer is NULL, then ASSERT().
> +
> +  @param [in]   StartAddress  The starting address that encodes the PCI Segment,
> +                              Bus, Device, Function and Register.
> +  @param [in]   Size          The size in bytes of the transfer.
> +  @param [out]  Buffer        The pointer to a buffer receiving the data read.
> +
> +  @return Size
> +
> +**/
> +UINTN
> +EFIAPI
> +PciSegmentReadBuffer (
> +  IN  UINT64 StartAddress,
> +  IN  UINTN  Size,
> +  OUT VOID   *Buffer
> +  )
> +{
> +  UINTN  ReturnValue;
> +
> +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
> +  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
> +
> +  if (Size == 0) {
> +    return Size;
[SAMI] I think it should be possible to return 0 from here.
> +  }
> +
> +  ASSERT (Buffer != NULL);
> +
> +  // Save Size for return
> +  ReturnValue = Size;
> +
> +  if ((StartAddress & BIT0) != 0) {
> +    // Read a byte if StartAddress is byte aligned
> +    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
> +    StartAddress += sizeof (UINT8);
> +    Size  -= sizeof (UINT8);
> +    Buffer = (UINT8 *)Buffer + 1;
> +  }
> +
> +  if ((Size >= sizeof (UINT16)) && ((StartAddress & BIT1) != 0)) {
> +    // Read a word if StartAddress is word aligned
> +    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
> +    StartAddress += sizeof (UINT16);
> +    Size  -= sizeof (UINT16);
> +    Buffer = (UINT16 *)Buffer + 1;
> +  }
> +
> +  while (Size >= sizeof (UINT32)) {
> +    // Read as many double words as possible
> +    WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));
> +    StartAddress += sizeof (UINT32);
> +    Size  -= sizeof (UINT32);
> +    Buffer = (UINT32 *)Buffer + 1;
> +  }
> +
> +  if (Size >= sizeof (UINT16)) {
> +    // Read the last remaining word if exist
> +    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
> +    StartAddress += sizeof (UINT16);
> +    Size  -= sizeof (UINT16);
> +    Buffer = (UINT16 *)Buffer + 1;
> +  }
> +
> +  if (Size >= sizeof (UINT8)) {
> +    // Read the last remaining byte if exist
> +    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
> +  }
> +
> +  return ReturnValue;
> +}
> +
> +/**
> +  Copies the data in a caller supplied buffer to a specified range of PCI
> +  configuration space.
> +
> +  Writes the range of PCI configuration registers specified by StartAddress and
> +  Size from the buffer specified by Buffer. This function only allows the PCI
> +  configuration registers from a single PCI function to be written. Size is
> +  returned. When possible 32-bit PCI configuration write cycles are used to
> +  write from StartAdress to StartAddress + Size. Due to alignment restrictions,
> +  8-bit and 16-bit PCI configuration write cycles may be used at the beginning
> +  and the end of the range.
> +
> +  If any reserved bits in StartAddress are set, then ASSERT().
> +  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> +  If Size > 0 and Buffer is NULL, then ASSERT().
> +
> +  @param [in]  StartAddress  The starting address that encodes the PCI Segment,
> +                             Bus, Device, Function and Register.
> +  @param [in]  Size          The size in bytes of the transfer.
> +  @param [in]  Buffer        The pointer to a buffer containing the data to write.
> +
> +  @return The parameter of Size.
> +
> +**/
> +UINTN
> +EFIAPI
> +PciSegmentWriteBuffer (
> +  IN UINT64 StartAddress,
> +  IN UINTN  Size,
> +  IN VOID   *Buffer
> +  )
> +{
> +  UINTN  ReturnValue;
> +
> +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
> +  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
> +
> +  if (Size == 0) {
> +    return 0;
> +  }
> +
> +  ASSERT (Buffer != NULL);
> +
> +  // Save Size for return
> +  ReturnValue = Size;
> +
> +  if ((StartAddress & BIT0) != 0) {
> +    // Write a byte if StartAddress is byte aligned
> +    PciSegmentWrite8 (StartAddress, *(UINT8 *)Buffer);
> +    StartAddress += sizeof (UINT8);
> +    Size  -= sizeof (UINT8);
> +    Buffer = (UINT8 *)Buffer + 1;
> +  }
> +
> +  if ((Size >= sizeof (UINT16)) && ((StartAddress & BIT1) != 0)) {
> +    // Write a word if StartAddress is word aligned
> +    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
> +    StartAddress += sizeof (UINT16);
> +    Size  -= sizeof (UINT16);
> +    Buffer = (UINT16 *)Buffer + 1;
> +  }
> +
> +  while (Size >= sizeof (UINT32)) {
> +    // Write as many double words as possible
> +    PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));
> +    StartAddress += sizeof (UINT32);
> +    Size  -= sizeof (UINT32);
> +    Buffer = (UINT32 *)Buffer + 1;
> +  }
> +
> +  if (Size >= sizeof (UINT16)) {
> +    // Write the last remaining word if exist
> +    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
> +    StartAddress += sizeof (UINT16);
> +    Size  -= sizeof (UINT16);
> +    Buffer = (UINT16 *)Buffer + 1;
> +  }
> +
> +  if (Size >= sizeof (UINT8)) {
> +    // Write the last remaining byte if exist
> +    PciSegmentWrite8 (StartAddress, *(UINT8 *)Buffer);
> +  }
> +
> +  return ReturnValue;
> +}


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-platforms][PATCH V1 07/11] Platform/ARM/Morello: Port PCI Express library
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 07/11] Platform/ARM/Morello: Port PCI Express library chandni cherukuri
@ 2021-12-07 20:58   ` Sami Mujawar
  2021-12-08  2:55     ` [edk2-devel] " Khasim Mohammed
  0 siblings, 1 reply; 31+ messages in thread
From: Sami Mujawar @ 2021-12-07 20:58 UTC (permalink / raw)
  To: Chandni Cherukuri, devel; +Cc: Ard Biesheuvel, Leif Lindholm

Hi Chandni,

Thank you for this patch.

Please find my feedback inline marked [SAMI].

With those addressed.

Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>

Regards,

Sami Mujawar


On 04/12/2021 12:30 PM, Chandni Cherukuri wrote:
> From: Anurag Koul <anurag.koul@arm.com>
>
> Morello platform requires a custom platform-specific PCI Express
> library because the native PCI Express Library only allows for a
> single ECAM config address to be supplied to it. If there is more
> than one PCIe root port, it expects the ECAM regions for all the
> root ports to be contiguous. This is not the case with Morello where
> the two RPs have their ECAM regions mapped to non-contiguous address
> ranges and reside in separate PCIe segments.
>
> This custom plaform-specific PCI Express library, inherited from
> MdePkg/BasePciExpressLib, routes the ECAM accesses to the appropriate
> ECAM region based on the PCIe segment number in the incoming PCIe
> address.
>
> Signed-off-by: Anurag Koul <anurag.koul@arm.com>
> Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
> ---
>   Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf |   49 +
>   Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.c   | 1431 ++++++++++++++++++++
>   Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.uni |   18 +
>   3 files changed, 1498 insertions(+)
>
> diff --git a/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf
> new file mode 100644
> index 000000000000..71a2cf3a6276
> --- /dev/null
> +++ b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf
> @@ -0,0 +1,49 @@
> +## @file
> +#  Instance of PCI Express Library using the 256 MB PCI Express MMIO window.
> +#
> +#  PCI Express Library that uses the 256 MB PCI Express MMIO window to perform
> +#  PCI Configuration cycles. Layers on top of an I/O Library instance.
> +#
> +#  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  This library is inherited from MdePkg/Library/BasePciExpressLib to work with
> +#  non-contiguous ECAM regions for the two supported PCIe root ports. The
> +#  base PCI Express library expects the ECAM space for all the available root
> +#  ports to be contiguous and hence exposes only a single hook(variable) to
> +#  hold the ECAM base address informaion in.
> +
> +#  This library reinterprets the ECAM accesses and routes them to the
> +#  appropriate Root Port Config based on the PCIe segment number in the
> +#  incoming PCIe address.
[SAMI] Is it possible to keep the copyright list together, please? Maybe
it would be good to move the comment above at the beginning of the file.
[/SAMI]
> +#
> +#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = PciExpressLib
> +  MODULE_UNI_FILE                = PciExpressLib.uni
> +  FILE_GUID                      = 795fad20-e353-45f8-b77f-c59eb7907370
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PciExpressLib
> +
> +[Sources]
> +  PciExpressLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  Platform/ARM/Morello/MorelloPlatform.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  IoLib
> +  PcdLib
> +
> +[Pcd]
> +  gArmMorelloTokenSpaceGuid.PcdCcixExpressBaseAddress  ## CONSUMES
> +  gArmMorelloTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
> diff --git a/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.c b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.c
> new file mode 100644
> index 000000000000..8f0652dc6678
> --- /dev/null
> +++ b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.c
> @@ -0,0 +1,1431 @@
> +/** @file
> +  Functions in this library instance make use of MMIO functions in IoLib to
> +  access memory mapped PCI configuration space.
> +
> +  All assertions for I/O operations are handled in MMIO functions in the IoLib
> +  Library.
> +
> +  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
> +
> +  On Morello platform, the PCIe ECAM regions for the two supported Root Ports,
> +  which lie in separate PCIe segments, are not contiguous. As such, any ECAM
> +  access from the PCI Express library should ideally be routed based on the
> +  segment number within the incoming address, which is configured in the
> +  platform PCI Host Bridge library.
> +
> +  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Base.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciExpressLib.h>
> +#include <Library/PcdLib.h>
> +#include <MorelloPlatform.h>
> +
> +/**
> +  Assert the validity of a PCI address. A valid PCI address may contain 1's
> +  only in the low 33 bits. Bit 32 carries the segment number which could be
> +  either 0 or 1.
> +
> +  @param  A The address to validate.
> +
> +**/
> +#define ASSERT_INVALID_PCI_ADDRESS(A) \
> +        ASSERT (((A) & ~0x1ffffffffULL) == 0)
> +
> +#define GET_SEG_NUM(Address)  ((Address >> 32ULL) & 0x1)
> +
> +/**
> +  Registers a PCI device so PCI configuration registers may be accessed after
> +  SetVirtualAddressMap().
> +
> +  Registers the PCI device specified by Address so all the PCI configuration
> +  registers associated with that PCI device may be accessed after
> +  SetVirtualAddressMap() is called.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +
> +  @retval RETURN_UNSUPPORTED       An attempt was made to call this function
> +                                   after ExitBootServices().
> +                                   The resources required to access the PCI
> +                                   device at runtime could not be mapped.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +PciExpressRegisterForRuntimeAccess (
> +  IN UINTN Address
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return RETURN_UNSUPPORTED;
> +}
> +
> +/**
> +  Gets the base address of PCI Express.
> +
> +  This internal functions retrieves PCI Express Base Address via a PCD entry.
> +
> +  @param [in]  Address The address that encodes the PCI Segment, Bus, Device,
> +                       Function and Register.
> +
> +  @return The converted address relative to PCI Root's ECAM base address.
> +
> +**/
> +STATIC
> +VOID *
[SAMI] Can the return type be changed to UINTN? It would remove the need
to typecase every time this function is used.
> +GetPciExpressAddress (
> +  IN      UINTN Address
> +  )
> +{
> +  UINTN  ConvAddress;
> +
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +
> +  if (GET_SEG_NUM (Address) == 0) {
> +    ConvAddress = PcdGet64 (PcdPciExpressBaseAddress) + (UINT32)Address;
> +  } else if (GET_SEG_NUM (Address) == 1) {
> +    ConvAddress = PcdGet64 (PcdCcixExpressBaseAddress) + (UINT32)Address;
> +  } else {
> +    DEBUG ((DEBUG_ERROR, "PciExpressLib: Invalid PCIe Address.\n"));
> +    ASSERT (FALSE);
> +    return NULL;
> +  }
> +
> +  return (VOID *)ConvAddress;
> +}
> +
> +/**
> +  Reads an 8-bit PCI configuration register.
> +
> +  Reads and returns the 8-bit PCI configuration register specified by Address.
> +  This function must guarantee that all PCI read and write operations are
> +  serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +
> +  @return The read value from the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciExpressRead8 (
> +  IN      UINTN Address
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioRead8 ((UINTN)GetPciExpressAddress (Address));
> +}
> +
> +/**
> +  Writes an 8-bit PCI configuration register.
> +
> +  Writes the 8-bit PCI configuration register specified by Address with the
> +  value specified by Value. Value is returned. This function must guarantee
> +  that all PCI read and write operations are serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +  @param [in]  Value   The value to write.
> +
> +  @return The value written to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciExpressWrite8 (
> +  IN      UINTN Address,
> +  IN      UINT8 Value
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +
> +  return MmioWrite8 ((UINTN)GetPciExpressAddress (Address), Value);
> +}
> +
> +/**
> +  Performs a bitwise OR of an 8-bit PCI configuration register with
> +  an 8-bit value.
> +
> +  Reads the 8-bit PCI configuration register specified by Address, performs a
> +  bitwise OR between the read result and the value specified by
> +  OrData, and writes the result to the 8-bit PCI configuration register
> +  specified by Address. The value written to the PCI configuration register is
> +  returned. This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +  @param [in]  OrData  The value to OR with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciExpressOr8 (
> +  IN      UINTN Address,
> +  IN      UINT8 OrData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioOr8 ((UINTN)GetPciExpressAddress (Address), OrData);
> +}
> +
> +/**
> +  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
> +  value.
> +
> +  Reads the 8-bit PCI configuration register specified by Address, performs a
> +  bitwise AND between the read result and the value specified by AndData, and
> +  writes the result to the 8-bit PCI configuration register specified by
> +  Address. The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations are
> +  serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +  @param [in]  AndData The value to AND with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciExpressAnd8 (
> +  IN      UINTN Address,
> +  IN      UINT8 AndData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioAnd8 ((UINTN)GetPciExpressAddress (Address), AndData);
> +}
> +
> +/**
> +  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
> +  value, followed a  bitwise OR with another 8-bit value.
> +
> +  Reads the 8-bit PCI configuration register specified by Address, performs a
> +  bitwise AND between the read result and the value specified by AndData,
> +  performs a bitwise OR between the result of the AND operation and
> +  the value specified by OrData, and writes the result to the 8-bit PCI
> +  configuration register specified by Address. The value written to the PCI
> +  configuration register is returned. This function must guarantee that all PCI
> +  read and write operations are serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +  @param [in]  AndData The value to AND with the PCI configuration register.
> +  @param [in]  OrData  The value to OR with the result of the AND operation.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciExpressAndThenOr8 (
> +  IN      UINTN Address,
> +  IN      UINT8 AndData,
> +  IN      UINT8 OrData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioAndThenOr8 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           AndData,
> +           OrData
> +           );
> +}
> +
> +/**
> +  Reads a bit field of a PCI configuration register.
> +
> +  Reads the bit field in an 8-bit PCI configuration register. The bit field is
> +  specified by the StartBit and the EndBit. The value of the bit field is
> +  returned.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to read.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..7.
> +
> +  @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciExpressBitFieldRead8 (
> +  IN      UINTN Address,
> +  IN      UINTN StartBit,
> +  IN      UINTN EndBit
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldRead8 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit
> +           );
> +}
> +
> +/**
> +  Writes a bit field to a PCI configuration register.
> +
> +  Writes Value to the bit field of the PCI configuration register. The bit
> +  field is specified by the StartBit and the EndBit. All other bits in the
> +  destination PCI configuration register are preserved. The new value of the
> +  8-bit register is returned.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If Value is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  Value     The new value of the bit field.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciExpressBitFieldWrite8 (
> +  IN      UINTN Address,
> +  IN      UINTN StartBit,
> +  IN      UINTN EndBit,
> +  IN      UINT8 Value
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldWrite8 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit,
> +           Value
> +           );
> +}
> +
> +/**
> +  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
> +  writes the result back to the bit field in the 8-bit port.
> +
> +  Reads the 8-bit PCI configuration register specified by Address, performs a
> +  bitwise OR between the read result and the value specified by
> +  OrData, and writes the result to the 8-bit PCI configuration register
> +  specified by Address. The value written to the PCI configuration register is
> +  returned. This function must guarantee that all PCI read and write operations
> +  are serialized. Extra left bits in OrData are stripped.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  OrData    The value to OR with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciExpressBitFieldOr8 (
> +  IN      UINTN Address,
> +  IN      UINTN StartBit,
> +  IN      UINTN EndBit,
> +  IN      UINT8 OrData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldOr8 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit,
> +           OrData
> +           );
> +}
> +
> +/**
> +  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
> +  AND, and writes the result back to the bit field in the 8-bit register.
> +
> +  Reads the 8-bit PCI configuration register specified by Address, performs a
> +  bitwise AND between the read result and the value specified by AndData, and
> +  writes the result to the 8-bit PCI configuration register specified by
> +  Address. The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations are
> +  serialized. Extra left bits in AndData are stripped.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciExpressBitFieldAnd8 (
> +  IN      UINTN Address,
> +  IN      UINTN StartBit,
> +  IN      UINTN EndBit,
> +  IN      UINT8 AndData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldAnd8 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit,
> +           AndData
> +           );
> +}
> +
> +/**
> +  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
> +  bitwise OR, and writes the result back to the bit field in the
> +  8-bit port.
> +
> +  Reads the 8-bit PCI configuration register specified by Address, performs a
> +  bitwise AND followed by a bitwise OR between the read result and
> +  the value specified by AndData, and writes the result to the 8-bit PCI
> +  configuration register specified by Address. The value written to the PCI
> +  configuration register is returned. This function must guarantee that all PCI
> +  read and write operations are serialized. Extra left bits in both AndData and
> +  OrData are stripped.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..7.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +  @param [in]  OrData    The value to OR with the result of the AND operation.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciExpressBitFieldAndThenOr8 (
> +  IN      UINTN Address,
> +  IN      UINTN StartBit,
> +  IN      UINTN EndBit,
> +  IN      UINT8 AndData,
> +  IN      UINT8 OrData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldAndThenOr8 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit,
> +           AndData,
> +           OrData
> +           );
> +}
> +
> +/**
> +  Reads a 16-bit PCI configuration register.
> +
> +  Reads and returns the 16-bit PCI configuration register specified by Address.
> +  This function must guarantee that all PCI read and write operations are
> +  serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +
> +  @return The read value from the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciExpressRead16 (
> +  IN      UINTN Address
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioRead16 ((UINTN)GetPciExpressAddress (Address));
> +}
> +
> +/**
> +  Writes a 16-bit PCI configuration register.
> +
> +  Writes the 16-bit PCI configuration register specified by Address with the
> +  value specified by Value. Value is returned. This function must guarantee
> +  that all PCI read and write operations are serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +  @param [in]  Value   The value to write.
> +
> +  @return The value written to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciExpressWrite16 (
> +  IN      UINTN  Address,
> +  IN      UINT16 Value
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +
> +  return MmioWrite16 ((UINTN)GetPciExpressAddress (Address), Value);
> +}
> +
> +/**
> +  Performs a bitwise OR of a 16-bit PCI configuration register with
> +  a 16-bit value.
> +
> +  Reads the 16-bit PCI configuration register specified by Address, performs a
> +  bitwise OR between the read result and the value specified by
> +  OrData, and writes the result to the 16-bit PCI configuration register
> +  specified by Address. The value written to the PCI configuration register is
> +  returned. This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +  @param [in]  OrData  The value to OR with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciExpressOr16 (
> +  IN      UINTN  Address,
> +  IN      UINT16 OrData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioOr16 ((UINTN)GetPciExpressAddress (Address), OrData);
> +}
> +
> +/**
> +  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
> +  value.
> +
> +  Reads the 16-bit PCI configuration register specified by Address, performs a
> +  bitwise AND between the read result and the value specified by AndData, and
> +  writes the result to the 16-bit PCI configuration register specified by
> +  Address. The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations are
> +  serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +  @param [in]  AndData The value to AND with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciExpressAnd16 (
> +  IN      UINTN  Address,
> +  IN      UINT16 AndData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioAnd16 ((UINTN)GetPciExpressAddress (Address), AndData);
> +}
> +
> +/**
> +  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
> +  value, followed a  bitwise OR with another 16-bit value.
> +
> +  Reads the 16-bit PCI configuration register specified by Address, performs a
> +  bitwise AND between the read result and the value specified by AndData,
> +  performs a bitwise OR between the result of the AND operation and
> +  the value specified by OrData, and writes the result to the 16-bit PCI
> +  configuration register specified by Address. The value written to the PCI
> +  configuration register is returned. This function must guarantee that all PCI
> +  read and write operations are serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +  @param [in]  AndData The value to AND with the PCI configuration register.
> +  @param [in]  OrData  The value to OR with the result of the AND operation.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciExpressAndThenOr16 (
> +  IN      UINTN  Address,
> +  IN      UINT16 AndData,
> +  IN      UINT16 OrData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioAndThenOr16 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           AndData,
> +           OrData
> +           );
> +}
> +
> +/**
> +  Reads a bit field of a PCI configuration register.
> +
> +  Reads the bit field in a 16-bit PCI configuration register. The bit field is
> +  specified by the StartBit and the EndBit. The value of the bit field is
> +  returned.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +  If StartBit is greater than 15, then ASSERT().
> +  If EndBit is greater than 15, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to read.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..15.
> +
> +  @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciExpressBitFieldRead16 (
> +  IN      UINTN Address,
> +  IN      UINTN StartBit,
> +  IN      UINTN EndBit
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldRead16 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit
> +           );
> +}
> +
> +/**
> +  Writes a bit field to a PCI configuration register.
> +
> +  Writes Value to the bit field of the PCI configuration register. The bit
> +  field is specified by the StartBit and the EndBit. All other bits in the
> +  destination PCI configuration register are preserved. The new value of the
> +  16-bit register is returned.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +  If StartBit is greater than 15, then ASSERT().
> +  If EndBit is greater than 15, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If Value is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  Value     The new value of the bit field.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciExpressBitFieldWrite16 (
> +  IN      UINTN  Address,
> +  IN      UINTN  StartBit,
> +  IN      UINTN  EndBit,
> +  IN      UINT16 Value
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldWrite16 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit,
> +           Value
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
> +  writes the result back to the bit field in the 16-bit port.
> +
> +  Reads the 16-bit PCI configuration register specified by Address, performs a
> +  bitwise OR between the read result and the value specified by
> +  OrData, and writes the result to the 16-bit PCI configuration register
> +  specified by Address. The value written to the PCI configuration register is
> +  returned. This function must guarantee that all PCI read and write operations
> +  are serialized. Extra left bits in OrData are stripped.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +  If StartBit is greater than 15, then ASSERT().
> +  If EndBit is greater than 15, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  OrData    The value to OR with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciExpressBitFieldOr16 (
> +  IN      UINTN  Address,
> +  IN      UINTN  StartBit,
> +  IN      UINTN  EndBit,
> +  IN      UINT16 OrData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldOr16 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit,
> +           OrData
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
> +  AND, and writes the result back to the bit field in the 16-bit register.
> +
> +  Reads the 16-bit PCI configuration register specified by Address, performs a
> +  bitwise AND between the read result and the value specified by AndData, and
> +  writes the result to the 16-bit PCI configuration register specified by
> +  Address. The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations are
> +  serialized. Extra left bits in AndData are stripped.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +  If StartBit is greater than 15, then ASSERT().
> +  If EndBit is greater than 15, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciExpressBitFieldAnd16 (
> +  IN      UINTN  Address,
> +  IN      UINTN  StartBit,
> +  IN      UINTN  EndBit,
> +  IN      UINT16 AndData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldAnd16 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit,
> +           AndData
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
> +  bitwise OR, and writes the result back to the bit field in the
> +  16-bit port.
> +
> +  Reads the 16-bit PCI configuration register specified by Address, performs a
> +  bitwise AND followed by a bitwise OR between the read result and
> +  the value specified by AndData, and writes the result to the 16-bit PCI
> +  configuration register specified by Address. The value written to the PCI
> +  configuration register is returned. This function must guarantee that all PCI
> +  read and write operations are serialized. Extra left bits in both AndData and
> +  OrData are stripped.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +  If StartBit is greater than 15, then ASSERT().
> +  If EndBit is greater than 15, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..15.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +  @param [in]  OrData    The value to OR with the result of the AND operation.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciExpressBitFieldAndThenOr16 (
> +  IN      UINTN  Address,
> +  IN      UINTN  StartBit,
> +  IN      UINTN  EndBit,
> +  IN      UINT16 AndData,
> +  IN      UINT16 OrData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldAndThenOr16 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit,
> +           AndData,
> +           OrData
> +           );
> +}
> +
> +/**
> +  Reads a 32-bit PCI configuration register.
> +
> +  Reads and returns the 32-bit PCI configuration register specified by Address.
> +  This function must guarantee that all PCI read and write operations are
> +  serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +
> +  @return The read value from the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciExpressRead32 (
> +  IN      UINTN Address
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioRead32 ((UINTN)GetPciExpressAddress (Address));
> +}
> +
> +/**
> +  Writes a 32-bit PCI configuration register.
> +
> +  Writes the 32-bit PCI configuration register specified by Address with the
> +  value specified by Value. Value is returned. This function must guarantee
> +  that all PCI read and write operations are serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +  @param [in]  Value   The value to write.
> +
> +  @return The value written to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciExpressWrite32 (
> +  IN      UINTN  Address,
> +  IN      UINT32 Value
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioWrite32 ((UINTN)GetPciExpressAddress (Address), Value);
> +}
> +
> +/**
> +  Performs a bitwise OR of a 32-bit PCI configuration register with
> +  a 32-bit value.
> +
> +  Reads the 32-bit PCI configuration register specified by Address, performs a
> +  bitwise OR between the read result and the value specified by
> +  OrData, and writes the result to the 32-bit PCI configuration register
> +  specified by Address. The value written to the PCI configuration register is
> +  returned. This function must guarantee that all PCI read and write operations
> +  are serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +  @param [in]  OrData  The value to OR with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciExpressOr32 (
> +  IN      UINTN  Address,
> +  IN      UINT32 OrData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioOr32 ((UINTN)GetPciExpressAddress (Address), OrData);
> +}
> +
> +/**
> +  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
> +  value.
> +
> +  Reads the 32-bit PCI configuration register specified by Address, performs a
> +  bitwise AND between the read result and the value specified by AndData, and
> +  writes the result to the 32-bit PCI configuration register specified by
> +  Address. The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations are
> +  serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +  @param [in]  AndData The value to AND with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciExpressAnd32 (
> +  IN      UINTN  Address,
> +  IN      UINT32 AndData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioAnd32 ((UINTN)GetPciExpressAddress (Address), AndData);
> +}
> +
> +/**
> +  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
> +  value, followed a  bitwise OR with another 32-bit value.
> +
> +  Reads the 32-bit PCI configuration register specified by Address, performs a
> +  bitwise AND between the read result and the value specified by AndData,
> +  performs a bitwise OR between the result of the AND operation and
> +  the value specified by OrData, and writes the result to the 32-bit PCI
> +  configuration register specified by Address. The value written to the PCI
> +  configuration register is returned. This function must guarantee that all PCI
> +  read and write operations are serialized.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param [in]  Address The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +  @param [in]  AndData The value to AND with the PCI configuration register.
> +  @param [in]  OrData  The value to OR with the result of the AND operation.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciExpressAndThenOr32 (
> +  IN      UINTN  Address,
> +  IN      UINT32 AndData,
> +  IN      UINT32 OrData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioAndThenOr32 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           AndData,
> +           OrData
> +           );
> +}
> +
> +/**
> +  Reads a bit field of a PCI configuration register.
> +
> +  Reads the bit field in a 32-bit PCI configuration register. The bit field is
> +  specified by the StartBit and the EndBit. The value of the bit field is
> +  returned.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to read.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..31.
> +
> +  @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciExpressBitFieldRead32 (
> +  IN      UINTN Address,
> +  IN      UINTN StartBit,
> +  IN      UINTN EndBit
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldRead32 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit
> +           );
> +}
> +
> +/**
> +  Writes a bit field to a PCI configuration register.
> +
> +  Writes Value to the bit field of the PCI configuration register. The bit
> +  field is specified by the StartBit and the EndBit. All other bits in the
> +  destination PCI configuration register are preserved. The new value of the
> +  32-bit register is returned.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If Value is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  Value     The new value of the bit field.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciExpressBitFieldWrite32 (
> +  IN      UINTN  Address,
> +  IN      UINTN  StartBit,
> +  IN      UINTN  EndBit,
> +  IN      UINT32 Value
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldWrite32 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit,
> +           Value
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
> +  writes the result back to the bit field in the 32-bit port.
> +
> +  Reads the 32-bit PCI configuration register specified by Address, performs a
> +  bitwise OR between the read result and the value specified by
> +  OrData, and writes the result to the 32-bit PCI configuration register
> +  specified by Address. The value written to the PCI configuration register is
> +  returned. This function must guarantee that all PCI read and write operations
> +  are serialized. Extra left bits in OrData are stripped.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  OrData    The value to OR with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciExpressBitFieldOr32 (
> +  IN      UINTN  Address,
> +  IN      UINTN  StartBit,
> +  IN      UINTN  EndBit,
> +  IN      UINT32 OrData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldOr32 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit,
> +           OrData
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
> +  AND, and writes the result back to the bit field in the 32-bit register.
> +
> +  Reads the 32-bit PCI configuration register specified by Address, performs a
> +  bitwise AND between the read result and the value specified by AndData, and
> +  writes the result to the 32-bit PCI configuration register specified by
> +  Address. The value written to the PCI configuration register is returned.
> +  This function must guarantee that all PCI read and write operations are
> +  serialized. Extra left bits in AndData are stripped.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciExpressBitFieldAnd32 (
> +  IN      UINTN  Address,
> +  IN      UINTN  StartBit,
> +  IN      UINTN  EndBit,
> +  IN      UINT32 AndData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldAnd32 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit,
> +           AndData
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
> +  bitwise OR, and writes the result back to the bit field in the
> +  32-bit port.
> +
> +  Reads the 32-bit PCI configuration register specified by Address, performs a
> +  bitwise AND followed by a bitwise OR between the read result and
> +  the value specified by AndData, and writes the result to the 32-bit PCI
> +  configuration register specified by Address. The value written to the PCI
> +  configuration register is returned. This function must guarantee that all PCI
> +  read and write operations are serialized. Extra left bits in both AndData and
> +  OrData are stripped.
> +
> +  If Address > 0x1FFFFFFFF, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and
> +  EndBit, then ASSERT().
> +
> +  @param [in]  Address   The PCI configuration register to write.
> +  @param [in]  StartBit  The ordinal of the least significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  EndBit    The ordinal of the most significant bit in the bit
> +                         field. Range 0..31.
> +  @param [in]  AndData   The value to AND with the PCI configuration register.
> +  @param [in]  OrData    The value to OR with the result of the AND operation.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciExpressBitFieldAndThenOr32 (
> +  IN      UINTN  Address,
> +  IN      UINTN  StartBit,
> +  IN      UINTN  EndBit,
> +  IN      UINT32 AndData,
> +  IN      UINT32 OrData
> +  )
> +{
> +  ASSERT_INVALID_PCI_ADDRESS (Address);
> +  return MmioBitFieldAndThenOr32 (
> +           (UINTN)GetPciExpressAddress (Address),
> +           StartBit,
> +           EndBit,
> +           AndData,
> +           OrData
> +           );
> +}
> +
> +/**
> +  Reads a range of PCI configuration registers into a caller supplied buffer.
> +
> +  Reads the range of PCI configuration registers specified by StartAddress and
> +  Size into the buffer specified by Buffer. This function only allows the PCI
> +  configuration registers from a single PCI function to be read. Size is
> +  returned. When possible 32-bit PCI configuration read cycles are used to read
> +  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
> +  and 16-bit PCI configuration read cycles may be used at the beginning and the
> +  end of the range.
> +
> +  If StartAddress > 0x1FFFFFFFF, then ASSERT().
> +  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> +  If Size > 0 and Buffer is NULL, then ASSERT().
> +
> +  @param [in]   StartAddress  The starting address that encodes the PCI Bus,
> +                              Device, Function and Register.
> +  @param [in]   Size          The size in bytes of the transfer.
> +  @param [out]  Buffer        The pointer to a buffer receiving the data read.
> +
> +  @return Size read data from StartAddress.
> +
> +**/
> +UINTN
> +EFIAPI
> +PciExpressReadBuffer (
> +  IN      UINTN StartAddress,
> +  IN      UINTN Size,
> +  OUT     VOID  *Buffer
> +  )
> +{
> +  UINTN  ReturnValue;
> +
> +  ASSERT_INVALID_PCI_ADDRESS (StartAddress);
> +  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
> +
> +  if (Size == 0) {
> +    return Size;
[SAMI] return 0; ?
> +  }
> +
> +  ASSERT (Buffer != NULL);
> +
> +  // Save Size for return
> +  ReturnValue = Size;
> +
> +  if ((StartAddress & 1) != 0) {
> +    // Read a byte if StartAddress is byte aligned
> +    *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);
> +    StartAddress += sizeof (UINT8);
> +    Size  -= sizeof (UINT8);
> +    Buffer = (UINT8 *)Buffer + 1;
> +  }
> +
> +  if ((Size >= sizeof (UINT16)) && ((StartAddress & 2) != 0)) {
> +    // Read a word if StartAddress is word aligned
> +    WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)PciExpressRead16 (StartAddress));
> +
> +    StartAddress += sizeof (UINT16);
> +    Size  -= sizeof (UINT16);
> +    Buffer = (UINT16 *)Buffer + 1;
> +  }
> +
> +  while (Size >= sizeof (UINT32)) {
> +    // Read as many double words as possible
> +    WriteUnaligned32 ((UINT32 *)Buffer, (UINT32)PciExpressRead32 (StartAddress));
> +
> +    StartAddress += sizeof (UINT32);
> +    Size  -= sizeof (UINT32);
> +    Buffer = (UINT32 *)Buffer + 1;
> +  }
> +
> +  if (Size >= sizeof (UINT16)) {
> +    // Read the last remaining word if exist
> +    WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)PciExpressRead16 (StartAddress));
> +    StartAddress += sizeof (UINT16);
> +    Size  -= sizeof (UINT16);
> +    Buffer = (UINT16 *)Buffer + 1;
> +  }
> +
> +  if (Size >= sizeof (UINT8)) {
> +    // Read the last remaining byte if exist
> +    *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);
> +  }
> +
> +  return ReturnValue;
> +}
> +
> +/**
> +  Copies the data in a caller supplied buffer to a specified range of PCI
> +  configuration space.
> +
> +  Writes the range of PCI configuration registers specified by StartAddress and
> +  Size from the buffer specified by Buffer. This function only allows the PCI
> +  configuration registers from a single PCI function to be written. Size is
> +  returned. When possible 32-bit PCI configuration write cycles are used to
> +  write from StartAdress to StartAddress + Size. Due to alignment restrictions,
> +  8-bit and 16-bit PCI configuration write cycles may be used at the beginning
> +  and the end of the range.
> +
> +  If StartAddress > 0x1FFFFFFFF, then ASSERT().
> +  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> +  If Size > 0 and Buffer is NULL, then ASSERT().
> +
> +  @param [in]  StartAddress  The starting address that encodes the PCI Bus,
> +                             Device, Function and Register.
> +  @param [in]  Size          The size in bytes of the transfer.
> +  @param [in]  Buffer        The pointer to a buffer containing the data to write.
> +
> +  @return Size written to StartAddress.
> +
> +**/
> +UINTN
> +EFIAPI
> +PciExpressWriteBuffer (
> +  IN      UINTN StartAddress,
> +  IN      UINTN Size,
> +  IN      VOID  *Buffer
> +  )
> +{
> +  UINTN  ReturnValue;
> +
> +  ASSERT_INVALID_PCI_ADDRESS (StartAddress);
> +  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
> +
> +  if (Size == 0) {
> +    return 0;
> +  }
> +
> +  ASSERT (Buffer != NULL);
> +
> +  // Save Size for return
> +  ReturnValue = Size;
> +
> +  if ((StartAddress & 1) != 0) {
> +    // Write a byte if StartAddress is byte aligned
> +    PciExpressWrite8 (StartAddress, *(UINT8 *)Buffer);
> +    StartAddress += sizeof (UINT8);
> +    Size  -= sizeof (UINT8);
> +    Buffer = (UINT8 *)Buffer + 1;
> +  }
> +
> +  if ((Size >= sizeof (UINT16)) && ((StartAddress & 2) != 0)) {
> +    // Write a word if StartAddress is word aligned
> +    PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16 *)Buffer));
> +    StartAddress += sizeof (UINT16);
> +    Size  -= sizeof (UINT16);
> +    Buffer = (UINT16 *)Buffer + 1;
> +  }
> +
> +  while (Size >= sizeof (UINT32)) {
> +    // Write as many double words as possible
> +    PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32 *)Buffer));
> +    StartAddress += sizeof (UINT32);
> +    Size  -= sizeof (UINT32);
> +    Buffer = (UINT32 *)Buffer + 1;
> +  }
> +
> +  if (Size >= sizeof (UINT16)) {
> +    // Write the last remaining word if exist
> +    PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16 *)Buffer));
> +    StartAddress += sizeof (UINT16);
> +    Size  -= sizeof (UINT16);
> +    Buffer = (UINT16 *)Buffer + 1;
> +  }
> +
> +  if (Size >= sizeof (UINT8)) {
> +    // Write the last remaining byte if exist
> +    PciExpressWrite8 (StartAddress, *(UINT8 *)Buffer);
> +  }
> +
> +  return ReturnValue;
> +}
> diff --git a/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.uni b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.uni
> new file mode 100644
> index 000000000000..540453d4a189
> --- /dev/null
> +++ b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.uni
> @@ -0,0 +1,18 @@
> +// /** @file
> +// Instance of PCI Express Library using the 256 MB PCI Express MMIO window.
> +//
> +// PCI Express Library that uses the 256 MB PCI Express MMIO window to perform
> +// PCI Configuration cycles. Layers on top of an I/O Library instance.
> +//
> +// Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
> +//
> +// Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT             #language en-US "Instance of PCI Express Library using the 256 MB PCI Express MMIO window"
> +
> +#string STR_MODULE_DESCRIPTION          #language en-US "PCI Express Library that uses the 256 MB PCI Express MMIO window to perform PCI Configuration cycles. Layers on top of an I/O Library instance."
[SAMI] Does this comment need updating? Same for the file header
documentation.

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-platforms][PATCH V1 08/11] Platform/ARM/Morello: Enable PCIe and CCIX Root Ports
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 08/11] Platform/ARM/Morello: Enable PCIe and CCIX Root Ports chandni cherukuri
@ 2021-12-07 20:59   ` Sami Mujawar
  0 siblings, 0 replies; 31+ messages in thread
From: Sami Mujawar @ 2021-12-07 20:59 UTC (permalink / raw)
  To: Chandni Cherukuri, devel; +Cc: Ard Biesheuvel, Leif Lindholm, nd

Hi Chandni,

Please find my feedback marked inline as [SAMI].

With that fixed,

Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>

Regards,

Sami Mujawar


On 04/12/2021 12:30 PM, Chandni Cherukuri wrote:
> From: Anurag Koul <anurag.koul@arm.com>
>
> Add definitions for both PCIe and CCIX Root Complex in PciHostBridge
> Library. Also, use platform-specific PCI Segment Library and PCI
> Express Library to enable PCIe support for Morello SoC.
>
> With PCIe support added, various other modules dependent on PCIe
> for instance, USB, AHCI, SATA, NVMe, etc., have also been enabled in
> the platform definition files.
>
> Signed-off-by: Anurag Koul <anurag.koul@arm.com>
> Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
> ---
>   Platform/ARM/Morello/MorelloPlatform.dec                              |  46 ++--
>   Platform/ARM/Morello/MorelloPlatform.dsc.inc                          |  17 ++
>   Platform/ARM/Morello/MorelloPlatformFvp.dsc                           |  21 +-
>   Platform/ARM/Morello/MorelloPlatformSoc.dsc                           |  27 +++
>   Platform/ARM/Morello/MorelloPlatformSoc.fdf                           |  25 ++
>   Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.inf |  57 +++++
>   Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf           |  18 ++
>   Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.c   | 247 ++++++++++++++++++++
>   Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c          |  50 +++-
>   9 files changed, 479 insertions(+), 29 deletions(-)
>
> diff --git a/Platform/ARM/Morello/MorelloPlatform.dec b/Platform/ARM/Morello/MorelloPlatform.dec
> index 6f5c1c1b59fc..07701e7611b8 100644
> --- a/Platform/ARM/Morello/MorelloPlatform.dec
> +++ b/Platform/ARM/Morello/MorelloPlatform.dec
> @@ -39,28 +39,46 @@
>   
>     # PCIe
>     gArmMorelloTokenSpaceGuid.PcdPciBusMin|0|UINT32|0x00000009
> -  gArmMorelloTokenSpaceGuid.PcdPciBusMax|15|UINT32|0x0000000A
> -  gArmMorelloTokenSpaceGuid.PcdPciBusCount|16|UINT32|0x0000000B
> +  gArmMorelloTokenSpaceGuid.PcdPciBusMax|255|UINT32|0x0000000A
> +  gArmMorelloTokenSpaceGuid.PcdPciBusCount|256|UINT32|0x0000000B
>     gArmMorelloTokenSpaceGuid.PcdPciIoBase|0x0|UINT32|0x0000000C
> -  gArmMorelloTokenSpaceGuid.PcdPciIoSize|0x00800000|UINT32|0x0000000D
> -  gArmMorelloTokenSpaceGuid.PcdPciIoMaxBase|0x007FFFFF|UINT32|0x0000000E
> -  gArmMorelloTokenSpaceGuid.PcdPciIoTranslation|0x67800000|UINT32|0x0000000F
> +  gArmMorelloTokenSpaceGuid.PcdPciIoSize|0x00400000|UINT32|0x0000000D
> +  gArmMorelloTokenSpaceGuid.PcdPciIoMaxBase|0x003FFFFF|UINT32|0x0000000E
> +  gArmMorelloTokenSpaceGuid.PcdPciIoTranslation|0x6F000000|UINT32|0x0000000F
>     gArmMorelloTokenSpaceGuid.PcdPciMmio32Base|0x60000000|UINT32|0x00000010
> -  gArmMorelloTokenSpaceGuid.PcdPciMmio32Size|0x07800000|UINT32|0x00000011
> -  gArmMorelloTokenSpaceGuid.PcdPciMmio32MaxBase|0x677FFFFF|UINT32|0x00000012
> +  gArmMorelloTokenSpaceGuid.PcdPciMmio32Size|0x0F000000|UINT32|0x00000011
> +  gArmMorelloTokenSpaceGuid.PcdPciMmio32MaxBase|0x6EFFFFFF|UINT32|0x00000012
>     gArmMorelloTokenSpaceGuid.PcdPciMmio32Translation|0x0|UINT32|0x00000013
>     gArmMorelloTokenSpaceGuid.PcdPciMmio64Base|0x900000000|UINT64|0x00000014
> -  gArmMorelloTokenSpaceGuid.PcdPciMmio64Size|0x2000000000|UINT64|0x00000015
> -  gArmMorelloTokenSpaceGuid.PcdPciMmio64MaxBase|0x28FFFFFFFF|UINT64|0x00000016
> +  gArmMorelloTokenSpaceGuid.PcdPciMmio64Size|0x1FC0000000|UINT64|0x00000015
> +  gArmMorelloTokenSpaceGuid.PcdPciMmio64MaxBase|0x28BFFFFFFF|UINT64|0x00000016
>     gArmMorelloTokenSpaceGuid.PcdPciMmio64Translation|0x0|UINT64|0x00000017
> -  gArmMorelloTokenSpaceGuid.PcdPciExpressBaseAddress|0x20000000|UINT64|0x00000018
> +  gArmMorelloTokenSpaceGuid.PcdPciExpressBaseAddress|0x28C0000000|UINT64|0x00000018
> +
> +  # CCIX
> +  gArmMorelloTokenSpaceGuid.PcdCcixBusMin|0|UINT32|0x0000019
> +  gArmMorelloTokenSpaceGuid.PcdCcixBusMax|255|UINT32|0x000001A
> +  gArmMorelloTokenSpaceGuid.PcdCcixBusCount|256|UINT32|0x000001B
> +  gArmMorelloTokenSpaceGuid.PcdCcixIoBase|0x0|UINT32|0x000001C
> +  gArmMorelloTokenSpaceGuid.PcdCcixIoSize|0x0400000|UINT32|0x000001D
> +  gArmMorelloTokenSpaceGuid.PcdCcixIoMaxBase|0x003FFFFF|UINT32|0x000001E
> +  gArmMorelloTokenSpaceGuid.PcdCcixIoTranslation|0x7F000000|UINT32|0x00000001F
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Base|0x70000000|UINT32|0x00000020
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Size|0x0F000000|UINT32|0x00000021
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio32MaxBase|0x7EFFFFFF|UINT32|0x000000022
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Translation|0x0|UINT32|0x00000023
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Base|0x3000000000|UINT64|0x00000024
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Size|0x1FC0000000|UINT64|0x00000025
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio64MaxBase|0x4FBFFFFFFF|UINT64|0x00000026
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Translation|0x0|UINT64|0x00000027
> +  gArmMorelloTokenSpaceGuid.PcdCcixExpressBaseAddress|0x4FC0000000|UINT64|0x0000028
>   
>     # Virtio Net device
> -  gArmMorelloTokenSpaceGuid.PcdVirtioNetBaseAddress|0x00000000|UINT32|0x00000019
> -  gArmMorelloTokenSpaceGuid.PcdVirtioNetSize|0x00000000|UINT32|0x0000001A
> -  gArmMorelloTokenSpaceGuid.PcdVirtioNetInterrupt|0x00000000|UINT32|0x0000001B
> +  gArmMorelloTokenSpaceGuid.PcdVirtioNetBaseAddress|0x00000000|UINT32|0x00000029
> +  gArmMorelloTokenSpaceGuid.PcdVirtioNetSize|0x00000000|UINT32|0x0000002A
> +  gArmMorelloTokenSpaceGuid.PcdVirtioNetInterrupt|0x00000000|UINT32|0x0000002B
>   
>   [PcdsFeatureFlag.common]
>     gArmMorelloTokenSpaceGuid.PcdRamDiskSupported|FALSE|BOOLEAN|0x00000007
>     gArmMorelloTokenSpaceGuid.PcdVirtioBlkSupported|FALSE|BOOLEAN|0x00000008
> -  gArmMorelloTokenSpaceGuid.PcdVirtioNetSupported|FALSE|BOOLEAN|0x0000001C
> +  gArmMorelloTokenSpaceGuid.PcdVirtioNetSupported|FALSE|BOOLEAN|0x0000002C
> diff --git a/Platform/ARM/Morello/MorelloPlatform.dsc.inc b/Platform/ARM/Morello/MorelloPlatform.dsc.inc
> index 862d5f2da1b0..e855c1ba0350 100644
> --- a/Platform/ARM/Morello/MorelloPlatform.dsc.inc
> +++ b/Platform/ARM/Morello/MorelloPlatform.dsc.inc
> @@ -209,3 +209,20 @@
>   
>     # RAM Disk
>     MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
> +
> +  # Required by PCI
> +  ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
> +
> +  # PCI Support
> +  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
> +   <PcdsFixedAtBuild>
> +     gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8010004F
> +  }
> +
> +  # AHCI Support
> +  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> +  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +
> +  # SATA Controller
> +  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
> diff --git a/Platform/ARM/Morello/MorelloPlatformFvp.dsc b/Platform/ARM/Morello/MorelloPlatformFvp.dsc
> index 1f9199fba2dc..61f54b891059 100644
> --- a/Platform/ARM/Morello/MorelloPlatformFvp.dsc
> +++ b/Platform/ARM/Morello/MorelloPlatformFvp.dsc
> @@ -72,6 +72,13 @@
>     gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
>     gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x20000000
>   
> +  #FVP Specific PCD values for PCIe
> +  gArmMorelloTokenSpaceGuid.PcdPciBusMax|15
> +  gArmMorelloTokenSpaceGuid.PcdPciBusCount|16
> +  gArmMorelloTokenSpaceGuid.PcdPciMmio64Size|0x2000000000
> +  gArmMorelloTokenSpaceGuid.PcdPciMmio64MaxBase|0x28FFFFFFFF
> +  gArmMorelloTokenSpaceGuid.PcdPciExpressBaseAddress|0x20000000
> +
>   [Components.common]
>     OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
>     OvmfPkg/VirtioNetDxe/VirtioNet.inf
> @@ -81,17 +88,3 @@
>   
>     # Required by PCI
>     ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
> -
> -  # PCI Support
> -  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> -  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
> -    <PcdsFixedAtBuild>
> -      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8010004F
> -  }
> -
> -  # AHCI Support
> -  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> -  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> -
> -  # SATA Controller
> -  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
> diff --git a/Platform/ARM/Morello/MorelloPlatformSoc.dsc b/Platform/ARM/Morello/MorelloPlatformSoc.dsc
> index 8335c50803b3..b6fe74ec6fdd 100644
> --- a/Platform/ARM/Morello/MorelloPlatformSoc.dsc
> +++ b/Platform/ARM/Morello/MorelloPlatformSoc.dsc
> @@ -42,6 +42,33 @@
>     # Platform Library
>     ArmPlatformLib|Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
>   
> +  #USB Requirement
> +  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
> +
> +  [LibraryClasses.common.DXE_DRIVER]
[SAMI] Please align.
> +  PciHostBridgeLib|Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.inf
> +  FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
> +  PciSegmentLib|Platform/ARM/Morello/Library/PciSegmentLib/PciSegmentLib.inf
> +  PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
> +  PciExpressLib|Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf
> +
> +[PcdsFixedAtBuild.common]
> +  # PCIe
> +  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|24
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
> +
>   [Components.common]
>     # Platform driver
>     Platform/ARM/Morello/Drivers/PlatformDxe/PlatformDxeSoc.inf
> +
> +  # Usb Support
> +  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
> +  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
> +  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
> +
> +  # NVMe boot devices
> +  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
> +
> diff --git a/Platform/ARM/Morello/MorelloPlatformSoc.fdf b/Platform/ARM/Morello/MorelloPlatformSoc.fdf
> index e7d4a6a9828d..ec0297fdbca6 100644
> --- a/Platform/ARM/Morello/MorelloPlatformSoc.fdf
> +++ b/Platform/ARM/Morello/MorelloPlatformSoc.fdf
> @@ -141,6 +141,31 @@ READ_LOCK_STATUS   = TRUE
>     INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
>     INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
>   
> +  # Required by PCI
> +  INF ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
> +
> +  # PCI Support
> +  INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +  INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> +
> +  # AHCI Support
> +  INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> +  INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +
> +  # SATA Controller
> +  INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
> +
> +  # Usb Support
> +  INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
> +  INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
> +  INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
> +  INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
> +  INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
> +  INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
> +
> +  # NVMe boot devices
> +  INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
> +
>   [FV.FVMAIN_COMPACT]
>   FvAlignment        = 8
>   BlockSize          = 0x1000
> diff --git a/Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.inf b/Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.inf
> new file mode 100644
> index 000000000000..3187e4b34087
> --- /dev/null
> +++ b/Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.inf
> @@ -0,0 +1,57 @@
> +## @file
> +#  PCI Host Bridge Library instance for ARM Morello SoC platform.
> +#
> +#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = PciHostBridgeLib
> +  FILE_GUID                      = 82f5bd18-4e07-11ec-81d3-0242ac130003
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PciHostBridgeLib|DXE_DRIVER
> +
> +#
> +# The following information is for reference only and not required by the build
> +# tools.
> +#
> +#  VALID_ARCHITECTURES           = AARCH64
> +#
> +
> +[Sources]
> +  PciHostBridgeLibSoc.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Platform/ARM/Morello/MorelloPlatform.dec
> +
> +[FixedPcd]
> +  gArmMorelloTokenSpaceGuid.PcdPciBusMax
> +  gArmMorelloTokenSpaceGuid.PcdPciBusMin
> +  gArmMorelloTokenSpaceGuid.PcdPciIoBase
> +  gArmMorelloTokenSpaceGuid.PcdPciIoSize
> +  gArmMorelloTokenSpaceGuid.PcdPciMmio32Base
> +  gArmMorelloTokenSpaceGuid.PcdPciMmio32Size
> +  gArmMorelloTokenSpaceGuid.PcdPciMmio64Base
> +  gArmMorelloTokenSpaceGuid.PcdPciMmio64Size
> +
> +  gArmMorelloTokenSpaceGuid.PcdCcixBusMin
> +  gArmMorelloTokenSpaceGuid.PcdCcixBusMax
> +  gArmMorelloTokenSpaceGuid.PcdCcixIoBase
> +  gArmMorelloTokenSpaceGuid.PcdCcixIoSize
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Base
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Size
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Base
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Size
> +
> +[Protocols]
> +  gEfiCpuIo2ProtocolGuid          ## CONSUMES
> +
> +[Depex]
> +  gEfiCpuIo2ProtocolGuid
> diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
> index bc31b8709152..0a36a5fe50a5 100644
> --- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
> +++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
> @@ -32,6 +32,24 @@
>   [FixedPcd]
>     gArmMorelloTokenSpaceGuid.PcdDramBlock2Base
>   
> +  gArmMorelloTokenSpaceGuid.PcdPciBusMax
> +  gArmMorelloTokenSpaceGuid.PcdPciBusMin
> +  gArmMorelloTokenSpaceGuid.PcdPciExpressBaseAddress
> +  gArmMorelloTokenSpaceGuid.PcdPciIoSize
> +  gArmMorelloTokenSpaceGuid.PcdPciMmio32Base
> +  gArmMorelloTokenSpaceGuid.PcdPciMmio32Size
> +  gArmMorelloTokenSpaceGuid.PcdPciMmio64Base
> +  gArmMorelloTokenSpaceGuid.PcdPciMmio64Size
> +
> +  gArmMorelloTokenSpaceGuid.PcdCcixBusMax
> +  gArmMorelloTokenSpaceGuid.PcdCcixBusMin
> +  gArmMorelloTokenSpaceGuid.PcdCcixExpressBaseAddress
> +  gArmMorelloTokenSpaceGuid.PcdCcixIoSize
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Base
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio32Size
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Base
> +  gArmMorelloTokenSpaceGuid.PcdCcixMmio64Size
> +
>     gArmTokenSpaceGuid.PcdArmPrimaryCore
>     gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
>     gArmTokenSpaceGuid.PcdSystemMemoryBase
> diff --git a/Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.c b/Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.c
> new file mode 100644
> index 000000000000..4d97474821df
> --- /dev/null
> +++ b/Platform/ARM/Morello/Library/PciHostBridgeLib/PciHostBridgeLibSoc.c
> @@ -0,0 +1,247 @@
> +/** @file
> +  PCI Host Bridge Library instance for ARM Morello SoC platform.
> +
> +  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +
> +#define ROOT_COMPLEX_NUM  2
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +STATIC CHAR16 CONST *CONST  mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
> +  L"Mem", L"I/O", L"Bus"
> +};
> +
> +#pragma pack(1)
> +typedef struct {
> +  ACPI_HID_DEVICE_PATH        AcpiDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL    EndDevicePath;
> +} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
> +#pragma pack ()
> +
> +STATIC EFI_PCI_ROOT_BRIDGE_DEVICE_PATH  mEfiPciRootBridgeDevicePath[ROOT_COMPLEX_NUM] = {
> +  {
> +    {
> +      {
> +        ACPI_DEVICE_PATH,
> +        ACPI_DP,
> +        {
> +          (UINT8)sizeof (ACPI_HID_DEVICE_PATH),
> +          (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
> +        }
> +      },
> +      EISA_PNP_ID (0x0A08),
> +      0
> +    },
> +    {
> +      END_DEVICE_PATH_TYPE,
> +      END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +      {
> +        END_DEVICE_PATH_LENGTH,
> +        0
> +      }
> +    }
> +  },
> +  {
> +    {
> +      {
> +        ACPI_DEVICE_PATH,
> +        ACPI_DP,
> +        {
> +          (UINT8)sizeof (ACPI_HID_DEVICE_PATH),
> +          (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
> +        }
> +      },
> +      EISA_PNP_ID (0x0A09),
[SAMI] Can you check if the EISA PNP ID 0X0A09 is correct, please?
> +      0
> +    },
> +    {
> +      END_DEVICE_PATH_TYPE,
> +      END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +      {
> +        END_DEVICE_PATH_LENGTH,
> +        0
> +      }
> +    }
> +  },
> +};
> +
> +STATIC PCI_ROOT_BRIDGE  mPciRootBridge[ROOT_COMPLEX_NUM] = {
> +  {
> +    0,                                              // Segment
> +    0,                                              // Supports
> +    0,                                              // Attributes
> +    TRUE,                                           // DmaAbove4G
> +    FALSE,                                          // NoExtendedConfigSpace
> +    FALSE,                                          // ResourceAssigned
> +    EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM |          // AllocationAttributes
> +    EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
> +    {
> +      // Bus
> +      FixedPcdGet32 (PcdPciBusMin),
> +      FixedPcdGet32 (PcdPciBusMax)
> +    },{
> +      // Io
> +      FixedPcdGet64 (PcdPciIoBase),
> +      FixedPcdGet64 (PcdPciIoBase) + FixedPcdGet64 (PcdPciIoSize) - 1
> +    },{
> +      // Mem
> +      FixedPcdGet32 (PcdPciMmio32Base),
> +      FixedPcdGet32 (PcdPciMmio32Base) + FixedPcdGet32 (PcdPciMmio32Size) - 1
> +    },{
> +      // MemAbove4G
> +      FixedPcdGet64 (PcdPciMmio64Base),
> +      FixedPcdGet64 (PcdPciMmio64Base) + FixedPcdGet64 (PcdPciMmio64Size) - 1
> +    },{
> +      // PMem
> +      MAX_UINT64,
> +      0
> +    },{
> +      // PMemAbove4G
> +      MAX_UINT64,
> +      0
> +    },
> +    (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[0]
> +  },
> +  {
> +    1,                                              // Segment
> +    0,                                              // Supports
> +    0,                                              // Attributes
> +    TRUE,                                           // DmaAbove4G
> +    FALSE,                                          // NoExtendedConfigSpace
> +    FALSE,                                          // ResourceAssigned
> +    EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM |          // AllocationAttributes
> +    EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
> +    {
> +      // Bus
> +      FixedPcdGet32 (PcdCcixBusMin),
> +      FixedPcdGet32 (PcdCcixBusMax)
> +    },{
> +      // Io
> +      FixedPcdGet64 (PcdCcixIoBase),
> +      FixedPcdGet64 (PcdCcixIoBase) + FixedPcdGet64 (PcdCcixIoSize) - 1
> +    },{
> +      // Mem
> +      FixedPcdGet32 (PcdCcixMmio32Base),
> +      FixedPcdGet32 (PcdCcixMmio32Base) + FixedPcdGet32 (PcdCcixMmio32Size) - 1
> +    },{
> +      // MemAbove4G
> +      FixedPcdGet64 (PcdCcixMmio64Base),
> +      FixedPcdGet64 (PcdCcixMmio64Base) + FixedPcdGet64 (PcdCcixMmio64Size) - 1
> +    },{
> +      // PMem
> +      MAX_UINT64,
> +      0
> +    },{
> +      // PMemAbove4G
> +      MAX_UINT64,
> +      0
> +    },
> +    (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[1]
> +  },
> +};
> +
> +/**
> +  Return all the root bridge instances in an array.
> +
> +  @param Count  Return the count of root bridge instances.
> +
> +  @return All the root bridge instances in an array.
> +          The array should be passed into PciHostBridgeFreeRootBridges()
> +          when it's not used.
> +**/
> +PCI_ROOT_BRIDGE *
> +EFIAPI
> +PciHostBridgeGetRootBridges (
> +  UINTN *Count
> +  )
> +{
> +  *Count = ARRAY_SIZE (mPciRootBridge);
> +  return mPciRootBridge;
> +}
> +
> +/**
> +  Free the root bridge instances array returned from PciHostBridgeGetRootBridges().
> +
> +  @param Bridges The root bridge instances array.
> +  @param Count   The count of the array.
> +**/
> +VOID
> +EFIAPI
> +PciHostBridgeFreeRootBridges (
> +  PCI_ROOT_BRIDGE *Bridges,
> +  UINTN           Count
> +  )
> +{
> +}
> +
> +/**
> +  Inform the platform that the resource conflict happens.
> +
> +  @param HostBridgeHandle Handle of the Host Bridge.
> +  @param Configuration    Pointer to PCI I/O and PCI memory resource
> +                          descriptors. The Configuration contains the resources
> +                          for all the root bridges. The resource for each root
> +                          bridge is terminated with END descriptor and an
> +                          additional END is appended indicating the end of the
> +                          entire resources. The resource descriptor field
> +                          values follow the description in
> +                          EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
> +                          .SubmitResources().
> +**/
> +VOID
> +EFIAPI
> +PciHostBridgeResourceConflict (
> +  EFI_HANDLE HostBridgeHandle,
> +  VOID       *Configuration
> +  )
> +{
> +  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Descriptor;
> +  UINTN                              RootBridgeIndex;
> +
> +  DEBUG ((DEBUG_ERROR, "PciHostBridge: Resource conflict happens!\n"));
> +
> +  RootBridgeIndex = 0;
> +  Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Configuration;
> +  while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
> +    DEBUG ((DEBUG_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
> +    for ( ; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
> +      ASSERT (
> +        Descriptor->ResType <
> +        (ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr))
> +        );
> +      DEBUG ((
> +        DEBUG_ERROR,
> +        "%s: Length/Alignment = 0x%lx / 0x%lx\n",
> +        mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
> +        Descriptor->AddrLen,
> +        Descriptor->AddrRangeMax
> +        ));
> +      if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
> +        DEBUG ((
> +          DEBUG_ERROR,
> +          "Granularity/SpecificFlag = %ld / %02x%s\n",
> +          Descriptor->AddrSpaceGranularity,
> +          Descriptor->SpecificFlag,
> +          ((Descriptor->SpecificFlag &
> +            EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
> +            ) != 0) ? L" (Prefetchable)" : L""
> +          ));
> +      }
> +    }
> +
> +    //
> +    // Skip the END descriptor for root bridge
> +    //
> +    ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
> +    Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
> +                   (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
> +                   );
> +  }
> +}
> diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
> index 67dd8469feb8..5140764c54bc 100644
> --- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
> +++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
> @@ -12,7 +12,7 @@
>   #include <MorelloPlatform.h>
>   
>   // The total number of descriptors, including the final "end-of-table" descriptor.
> -#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS  9
> +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS  15
>   
>   #if !defined (MDEPKG_NDEBUG)
>     STATIC CONST CHAR8  *gTblAttrDesc[] = {
> @@ -163,6 +163,54 @@ ArmPlatformGetVirtualMemoryMap (
>     VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>     LOG_MEM ("Expansion Peripherals           : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
>   
> +  // PCIe ECAM Configuration Space
> +  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdPciExpressBaseAddress);
> +  VirtualMemoryTable[Index].VirtualBase    = PcdGet64 (PcdPciExpressBaseAddress);
> +  VirtualMemoryTable[Index].Length = (FixedPcdGet32 (PcdPciBusMax) -
> +                                      FixedPcdGet32 (PcdPciBusMin) + 1) *
> +                                     SIZE_1MB;
> +  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +  LOG_MEM ("PCIe ECAM Region                : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
> +
> +  // PCIe MMIO32 Memory Space
> +  VirtualMemoryTable[++Index].PhysicalBase = PcdGet32 (PcdPciMmio32Base);
> +  VirtualMemoryTable[Index].VirtualBase    = PcdGet32 (PcdPciMmio32Base);
> +  VirtualMemoryTable[Index].Length = (PcdGet32 (PcdPciMmio32Size) +
> +                                      PcdGet32 (PcdPciIoSize));
> +  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +  LOG_MEM ("PCIe MMIO32 & IO Region         : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
> +
> +  // PCIe MMIO64 Memory Space
> +  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdPciMmio64Base);
> +  VirtualMemoryTable[Index].VirtualBase    = PcdGet64 (PcdPciMmio64Base);
> +  VirtualMemoryTable[Index].Length     = PcdGet64 (PcdPciMmio64Size);
> +  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +  LOG_MEM ("PCIe MMIO64 Region              : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
> +
> +  // CCIX ECAM Configuration Space
> +  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdCcixExpressBaseAddress);
> +  VirtualMemoryTable[Index].VirtualBase    = PcdGet64 (PcdCcixExpressBaseAddress);
> +  VirtualMemoryTable[Index].Length = (FixedPcdGet32 (PcdCcixBusMax) -
> +                                      FixedPcdGet32 (PcdCcixBusMin) + 1) *
> +                                     SIZE_1MB;
> +  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +  LOG_MEM ("CCIX ECAM Region                : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
> +
> +  // CCIX MMIO32 Memory Space
> +  VirtualMemoryTable[++Index].PhysicalBase = PcdGet32 (PcdCcixMmio32Base);
> +  VirtualMemoryTable[Index].VirtualBase    = PcdGet32 (PcdCcixMmio32Base);
> +  VirtualMemoryTable[Index].Length = (PcdGet32 (PcdCcixMmio32Size) +
> +                                      PcdGet32 (PcdCcixIoSize));
> +  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +  LOG_MEM ("CCIX MMIO32 & IO Region         : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
> +
> +  // CCIX MMIO64 Memory Space
> +  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdCcixMmio64Base);
> +  VirtualMemoryTable[Index].VirtualBase    = PcdGet64 (PcdCcixMmio64Base);
> +  VirtualMemoryTable[Index].Length     = PcdGet64 (PcdCcixMmio64Size);
> +  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +  LOG_MEM ("CCIX MMIO64 Region              : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
> +
>     // End of Table
>     VirtualMemoryTable[++Index].PhysicalBase = 0;
>     VirtualMemoryTable[Index].VirtualBase    = 0;


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-platforms][PATCH V1 10/11] Platform/ARM/Morello: Add support to parse NT_FW_CONFIG
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 10/11] Platform/ARM/Morello: Add support to parse NT_FW_CONFIG chandni cherukuri
@ 2021-12-07 20:59   ` Sami Mujawar
  0 siblings, 0 replies; 31+ messages in thread
From: Sami Mujawar @ 2021-12-07 20:59 UTC (permalink / raw)
  To: Chandni Cherukuri, devel; +Cc: Ard Biesheuvel, Leif Lindholm, nd

Hi Chandni,

Please find my feedback inline marked [SAMI].

With those fixed,

Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>

Regards,

Sami Mujawar


On 04/12/2021 12:30 PM, Chandni Cherukuri wrote:
> From: sah01 <sahil@arm.com>
>
> Support has been added to parse NT_FW_CONFIG DTB to get the
> platform information.
>
> Signed-off-by: sahil <sahil@arm.com>
> Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
> ---
>   Platform/ARM/Morello/MorelloPlatform.dec                     |   5 +
>   Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf  |   6 ++
>   Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf  |   6 ++
>   Platform/ARM/Morello/Include/MorelloPlatform.h               |  18 +++-
>   Platform/ARM/Morello/Library/PlatformLib/PlatformLib.c       |   9 ++
>   Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemFvp.c |  74 ++++++++++++-
>   Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c | 113 +++++++++++++++++++-
>   Platform/ARM/Morello/Library/PlatformLib/AArch64/Helper.S    |   2 +
>   8 files changed, 225 insertions(+), 8 deletions(-)
>
> diff --git a/Platform/ARM/Morello/MorelloPlatform.dec b/Platform/ARM/Morello/MorelloPlatform.dec
> index 07701e7611b8..3aec23b03b00 100644
> --- a/Platform/ARM/Morello/MorelloPlatform.dec
> +++ b/Platform/ARM/Morello/MorelloPlatform.dec
> @@ -22,6 +22,8 @@
>     Include                        # Root include for the package
>   
>   [Guids.common]
> +  # ARM Morello Platform Info descriptor
> +  gArmMorelloPlatformInfoDescriptorGuid = { 0x891422EF, 0x5377, 0x459E, { 0xA5, 0x42, 0x7A, 0xA2, 0x1A, 0x55, 0x54, 0x7F } }
>     gArmMorelloTokenSpaceGuid =  { 0x0A8C3A78, 0xA56F, 0x4788, { 0x83, 0xB4, 0xCD, 0x29, 0x62, 0x96, 0x77, 0x51 } }
>   
>   [PcdsFixedAtBuild]
> @@ -82,3 +84,6 @@
>     gArmMorelloTokenSpaceGuid.PcdRamDiskSupported|FALSE|BOOLEAN|0x00000007
>     gArmMorelloTokenSpaceGuid.PcdVirtioBlkSupported|FALSE|BOOLEAN|0x00000008
>     gArmMorelloTokenSpaceGuid.PcdVirtioNetSupported|FALSE|BOOLEAN|0x0000002C
> +
> +[Ppis]
> +  gNtFwConfigDtInfoPpiGuid =  { 0x8E289A83, 0x44E1, 0x41CF, { 0xA7, 0x41, 0x83, 0x80, 0x89, 0x23, 0x43, 0xA3 } }
> diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf
> index d4c8744c0954..0f87a18da184 100644
> --- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf
> +++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibFvp.inf
> @@ -18,10 +18,14 @@
>   [Packages]
>     ArmPkg/ArmPkg.dec
>     ArmPlatformPkg/ArmPlatformPkg.dec
> +  EmbeddedPkg/EmbeddedPkg.dec
>     MdeModulePkg/MdeModulePkg.dec
>     MdePkg/MdePkg.dec
>     Platform/ARM/Morello/MorelloPlatform.dec
>   
> +[LibraryClasses]
> +  FdtLib
> +
>   [Sources.common]
>     PlatformLib.c
>     PlatformLibMemFvp.c
> @@ -46,7 +50,9 @@
>     gArmTokenSpaceGuid.PcdSystemMemorySize
>   
>   [Guids]
> +  gArmMorelloPlatformInfoDescriptorGuid
>     gEfiHobListGuid          ## CONSUMES  ## SystemTable
>   
>   [Ppis]
>     gArmMpCoreInfoPpiGuid
> +  gNtFwConfigDtInfoPpiGuid
> diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
> index 0a36a5fe50a5..cc0687ebcaaa 100644
> --- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
> +++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibSoc.inf
> @@ -18,10 +18,14 @@
>   [Packages]
>     ArmPkg/ArmPkg.dec
>     ArmPlatformPkg/ArmPlatformPkg.dec
> +  EmbeddedPkg/EmbeddedPkg.dec
>     MdeModulePkg/MdeModulePkg.dec
>     MdePkg/MdePkg.dec
>     Platform/ARM/Morello/MorelloPlatform.dec
>   
> +[LibraryClasses]
> +  FdtLib
> +
>   [Sources.common]
>     PlatformLib.c
>     PlatformLibMemSoc.c
> @@ -56,7 +60,9 @@
>     gArmTokenSpaceGuid.PcdSystemMemorySize
>   
>   [Guids]
> +  gArmMorelloPlatformInfoDescriptorGuid
>     gEfiHobListGuid          ## CONSUMES  ## SystemTable
>   
>   [Ppis]
>     gArmMpCoreInfoPpiGuid
> +  gNtFwConfigDtInfoPpiGuid
> diff --git a/Platform/ARM/Morello/Include/MorelloPlatform.h b/Platform/ARM/Morello/Include/MorelloPlatform.h
> index 8b3233025958..c55bb04445cb 100644
> --- a/Platform/ARM/Morello/Include/MorelloPlatform.h
> +++ b/Platform/ARM/Morello/Include/MorelloPlatform.h
> @@ -51,13 +51,23 @@
>    */
>   #pragma pack(1)
>   
> +typedef struct {
> +  UINT64  LocalDdrSize;    ///< Local DDR memory size in Bytes
> +  UINT64  RemoteDdrSize;   ///< Remote DDR memory size in Bytes
> +  UINT8   RemoteChipCount; ///< Remote chip count in C2C mode
> +  UINT8   Mode;            ///< 0 - Single Chip, 1 - Chip to Chip (C2C)
> +  UINT32  SccConfig;       ///< Contains SCC configuration from BOOT_GPR1 register
> +} MORELLO_PLAT_INFO_SOC;
> +
>   typedef struct {
>     UINT64  LocalDdrSize;  ///< Local DDR memory size in Bytes
> -  UINT64  RemoteDdrSize; ///< Remote DDR memory size in Bytes
> -  UINT8   SlaveCount;    ///< Slave count in C2C mode
> -  UINT8   Mode;          ///< 0 - Single Chip, 1 - Chip to Chip (C2C)
> -} MORELLO_PLAT_INFO;
> +} MORELLO_PLAT_INFO_FVP;
>   
>   #pragma pack()
>   
> +// NT_FW_CONFIG DT structure
> +typedef struct {
> +  UINT64                  NtFwConfigDtAddr;
> +} MORELLO_NT_FW_CONFIG_INFO_PPI;
> +
>   #endif //MORELLO_PLATFORM_H_
> diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLib.c b/Platform/ARM/Morello/Library/PlatformLib/PlatformLib.c
> index 52318a62911a..b46b3fcc2a7b 100644
> --- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLib.c
> +++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLib.c
> @@ -8,7 +8,10 @@
>   #include <Library/ArmPlatformLib.h>
>   #include <Library/BaseLib.h>
>   #include <Ppi/ArmMpCoreInfo.h>
> +#include <MorelloPlatform.h>
>   
> +UINT64 NtFwConfigDtBlob;
> +STATIC MORELLO_NT_FW_CONFIG_INFO_PPI mNtFwConfigDtInfoPpi;
>   STATIC ARM_CORE_INFO mCoreInfoTable[] = {
>     { 0x0, 0x0 }, // Cluster 0, Core 0
>     { 0x0, 0x1 }, // Cluster 0, Core 1
> @@ -44,6 +47,7 @@ ArmPlatformInitialize (
>     IN  UINTN                     MpId
>     )
>   {
> +  mNtFwConfigDtInfoPpi.NtFwConfigDtAddr = NtFwConfigDtBlob;
>     return RETURN_SUCCESS;
>   }
>   
> @@ -76,6 +80,11 @@ STATIC EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = {
>       EFI_PEI_PPI_DESCRIPTOR_PPI,
>       &gArmMpCoreInfoPpiGuid,
>       &mMpCoreInfoPpi
> +  },
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_PPI,
> +    &gNtFwConfigDtInfoPpiGuid,
> +    &mNtFwConfigDtInfoPpi
>     }
>   };
>   
> diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemFvp.c b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemFvp.c
> index 54a870cfb3ba..9c1da9a25fcd 100644
> --- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemFvp.c
> +++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemFvp.c
> @@ -9,6 +9,8 @@
>   #include <Library/DebugLib.h>
>   #include <Library/HobLib.h>
>   #include <Library/MemoryAllocationLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <libfdt.h>
>   #include <MorelloPlatform.h>
>   
>   // The total number of descriptors, including the final "end-of-table" descriptor.
> @@ -39,6 +41,60 @@ STATIC CONST CHAR8 *gTblAttrDesc[] = {
>                           gTblAttrDesc[VirtualMemoryTable[Index].Attributes]  \
>                           ));
>   
> +/** A helper function to locate the NtFwConfig PPI and get the base address of
> +  NT_FW_CONFIG DT from which values are obtained using FDT helper functions.
> +
> +  @param [out]  plat_info  Pointer to the MORELLO PLATFORM_INFO HOB
> +
> +  @retval EFI_SUCCESS            Success.
> +  returns EFI_INVALID_PARAMETER  A parameter is invalid.
> +**/
> +EFI_STATUS
> +GetMorelloPlatInfo (
> +  OUT MORELLO_PLAT_INFO_FVP *plat_info
[SAMI] Please rename variable according to edk2 coding standard.
> +)
> +{
> +  CONST UINT64                  *Property;
> +  INT32                         Offset;
> +  CONST VOID                    *NtFwCfgDtBlob;
> +  MORELLO_NT_FW_CONFIG_INFO_PPI *NtFwConfigInfoPpi;
> +  EFI_STATUS                    Status;
> +
> +  Status = PeiServicesLocatePpi (
> +             &gNtFwConfigDtInfoPpiGuid,
> +             0,
> +             NULL,
> +             (VOID**)&NtFwConfigInfoPpi
> +             );
> +
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR,
> +      "PeiServicesLocatePpi failed with error %r\n", Status));
[SAMI] In the current scenario the status code traced and returned do 
not match. Can the status code returned by PeiServicesLocatePpi() be 
returned here? [/SAMI]
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  NtFwCfgDtBlob = (VOID *)(UINTN)NtFwConfigInfoPpi->NtFwConfigDtAddr;
> +  if (fdt_check_header (NtFwCfgDtBlob) != 0) {
> +    DEBUG ((DEBUG_ERROR, "Invalid DTB file %p passed\n", NtFwCfgDtBlob));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Offset = fdt_subnode_offset (NtFwCfgDtBlob, 0, "platform-info");
> +  if (Offset == -FDT_ERR_NOTFOUND) {
> +    DEBUG ((DEBUG_ERROR, "Invalid DTB : platform-info node not found\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Property = fdt_getprop (NtFwCfgDtBlob, Offset, "local-ddr-size", NULL);
> +  if (Property == NULL) {
> +    DEBUG ((DEBUG_ERROR, "local-ddr-size property not found\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  plat_info->LocalDdrSize = fdt64_to_cpu (ReadUnaligned64 (Property));
> +  return EFI_SUCCESS;
> +}
> +
>   /**
>     Returns the Virtual Memory Map of the platform.
>   
> @@ -57,13 +113,27 @@ ArmPlatformGetVirtualMemoryMap (
>     UINTN                           Index;
>     ARM_MEMORY_REGION_DESCRIPTOR  * VirtualMemoryTable;
>     EFI_RESOURCE_ATTRIBUTE_TYPE     ResourceAttributes;
> -  MORELLO_PLAT_INFO             * PlatInfo;
> +  MORELLO_PLAT_INFO_FVP         * PlatInfo;
>     UINT64                          DramBlock2Size;
> +  EFI_STATUS                      Status;
>   
>     Index = 0;
>     DramBlock2Size = 0;
>   
> -  PlatInfo = (MORELLO_PLAT_INFO *)MORELLO_PLAT_INFO_STRUCT_BASE;
> +  // Create platform info HOB
> +  PlatInfo = (MORELLO_PLAT_INFO_FVP *)BuildGuidHob (
> +                                        &gArmMorelloPlatformInfoDescriptorGuid,
> +                                        sizeof (MORELLO_PLAT_INFO_FVP)
> +                                        );
> +  if (PlatInfo == NULL) {
> +    DEBUG ((DEBUG_ERROR, "Platform HOB is NULL\n"));
> +    ASSERT (FALSE);
> +    return;
> +  }
> +
> +  Status = GetMorelloPlatInfo (PlatInfo);
> +  ASSERT (Status == 0);
[SAMI] The assert should be 'ASSERT_EFI_STATUS (Status)'.
              More importantly the code should not progress if there is 
a failure.
              Think about what happens for release builds. I think the 
code should return in case of failure.
[/SAMI]
> +
>     if (PlatInfo->LocalDdrSize > MORELLO_DRAM_BLOCK1_SIZE) {
>       DramBlock2Size = PlatInfo->LocalDdrSize - MORELLO_DRAM_BLOCK1_SIZE;
>     }
> diff --git a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
> index 5140764c54bc..49e4994176a9 100644
> --- a/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
> +++ b/Platform/ARM/Morello/Library/PlatformLib/PlatformLibMemSoc.c
> @@ -9,6 +9,8 @@
>   #include <Library/DebugLib.h>
>   #include <Library/HobLib.h>
>   #include <Library/MemoryAllocationLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <libfdt.h>
>   #include <MorelloPlatform.h>
>   
>   // The total number of descriptors, including the final "end-of-table" descriptor.
> @@ -39,6 +41,97 @@
>                           gTblAttrDesc[VirtualMemoryTable[Index].Attributes]  \
>                           ));
>   
> +/** A helper function to locate the NtFwConfig PPI and get the base address of
> +  NT_FW_CONFIG DT from which values are obtained using FDT helper functions.
> +
> +  @param [out]  plat_info  Pointer to the MORELLO PLATFORM_INFO HOB
> +
> +  @retval EFI_SUCCESS            Success.
> +  returns EFI_INVALID_PARAMETER  A parameter is invalid.
> +**/
> +EFI_STATUS
> +GetMorelloPlatInfo (
> +  OUT MORELLO_PLAT_INFO_SOC *plat_info
[SAMI] Please rename variable according to edk2 coding standard.
> +  )
> +{
> +  CONST UINT32                   *Property;
> +  CONST UINT64                   *DdrProperty;
> +  INT32                          Offset;
> +  CONST VOID                     *NtFwCfgDtBlob;
> +  MORELLO_NT_FW_CONFIG_INFO_PPI  *NtFwConfigInfoPpi;
> +  EFI_STATUS                     Status;
> +
> +  Status = PeiServicesLocatePpi (
> +             &gNtFwConfigDtInfoPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **)&NtFwConfigInfoPpi
> +             );
> +
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "PeiServicesLocatePpi failed with error %r\n",
> +      Status
> +      ));
> +    return EFI_INVALID_PARAMETER;
[SAMI] In the current scenario the status code traced and returned do 
not match. Can the status code returned by PeiServicesLocatePpi() be 
returned here? [/SAMI]
> +  }
> +
> +  NtFwCfgDtBlob = (VOID *)(UINTN)NtFwConfigInfoPpi->NtFwConfigDtAddr;
> +  if (fdt_check_header (NtFwCfgDtBlob) != 0) {
> +    DEBUG ((DEBUG_ERROR, "Invalid DTB file %p passed\n", NtFwCfgDtBlob));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Offset = fdt_subnode_offset (NtFwCfgDtBlob, 0, "platform-info");
> +  if (Offset == -FDT_ERR_NOTFOUND) {
> +    DEBUG ((DEBUG_ERROR, "Invalid DTB : platform-info node not found\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  DdrProperty = fdt_getprop (NtFwCfgDtBlob, Offset, "local-ddr-size", NULL);
> +  if (DdrProperty == NULL) {
> +    DEBUG ((DEBUG_ERROR, "local-ddr-size property not found\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  plat_info->LocalDdrSize = fdt64_to_cpu (ReadUnaligned64 (DdrProperty));
> +
> +  DdrProperty = fdt_getprop (NtFwCfgDtBlob, Offset, "remote-ddr-size", NULL);
> +  if (DdrProperty == NULL) {
> +    DEBUG ((DEBUG_ERROR, "remote-ddr-size property not found\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  plat_info->RemoteDdrSize = fdt64_to_cpu (ReadUnaligned64 (DdrProperty));
> +
> +  Property = fdt_getprop (NtFwCfgDtBlob, Offset, "remote-chip-count", NULL);
> +  if (Property == NULL) {
> +    DEBUG ((DEBUG_ERROR, "remote-chip-count property not found\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  plat_info->RemoteChipCount = fdt32_to_cpu (*Property);
> +
> +  Property = fdt_getprop (NtFwCfgDtBlob, Offset, "multichip-mode", NULL);
> +  if (Property == NULL) {
> +    DEBUG ((DEBUG_ERROR, "multichip-mode property not found\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  plat_info->Mode = fdt32_to_cpu (*Property);
> +
> +  Property = fdt_getprop (NtFwCfgDtBlob, Offset, "scc-config", NULL);
> +  if (Property == NULL) {
> +    DEBUG ((DEBUG_ERROR, "scc-config property not found\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  plat_info->SccConfig = fdt32_to_cpu (*Property);
> +
> +  return EFI_SUCCESS;
> +}
> +
>   /**
>     Returns the Virtual Memory Map of the platform.
>   
> @@ -57,17 +150,33 @@ ArmPlatformGetVirtualMemoryMap (
>     UINTN                         Index;
>     ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
>     EFI_RESOURCE_ATTRIBUTE_TYPE   ResourceAttributes;
> -  MORELLO_PLAT_INFO             *PlatInfo;
> +  MORELLO_PLAT_INFO_SOC         *PlatInfo;
>     UINT64                        DramBlock2Size;
> +  EFI_STATUS                    Status;
>   
>     Index = 0;
>     DramBlock2Size = 0;
>   
> -  PlatInfo = (MORELLO_PLAT_INFO *)MORELLO_PLAT_INFO_STRUCT_BASE;
> +  // Create platform info HOB
> +  PlatInfo = (MORELLO_PLAT_INFO_SOC *)BuildGuidHob (
> +                                        &gArmMorelloPlatformInfoDescriptorGuid,
> +                                        sizeof (MORELLO_PLAT_INFO_SOC)
> +                                        );
> +
> +  if (PlatInfo == NULL) {
> +    DEBUG ((DEBUG_ERROR, "Platform HOB is NULL\n"));
> +    ASSERT (FALSE);
> +    return;
> +  }
> +
> +  Status = GetMorelloPlatInfo (PlatInfo);
> +  ASSERT (Status == 0);
[SAMI] The assert should be 'ASSERT_EFI_STATUS (Status)'.
              More importantly the code should not progress if there is 
a failure.
              Think about what happens for release builds. I think the 
code should return in case of failure.
[/SAMI]
> +
>     if (PlatInfo->LocalDdrSize > MORELLO_DRAM_BLOCK1_SIZE) {
>       DramBlock2Size = PlatInfo->LocalDdrSize - MORELLO_DRAM_BLOCK1_SIZE;
>     }
>   
> +  DEBUG ((DEBUG_ERROR, "DramBlock2Size is 0x%lx\n", DramBlock2Size));
>     if (DramBlock2Size != 0) {
>       ResourceAttributes =
>         EFI_RESOURCE_ATTRIBUTE_PRESENT |
> diff --git a/Platform/ARM/Morello/Library/PlatformLib/AArch64/Helper.S b/Platform/ARM/Morello/Library/PlatformLib/AArch64/Helper.S
> index 0bc624dfd2b4..d71cab916c75 100644
> --- a/Platform/ARM/Morello/Library/PlatformLib/AArch64/Helper.S
> +++ b/Platform/ARM/Morello/Library/PlatformLib/AArch64/Helper.S
> @@ -19,6 +19,8 @@
>   // the UEFI firmware through the CPU registers.
>   //
>   ASM_FUNC(ArmPlatformPeiBootAction)
> +  adr  x10, NtFwConfigDtBlob
> +  str  x0, [x10]
>     ret
>   
>   //


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-platforms][PATCH V1 11/11] Platform/ARM/Morello: Update Readme.md
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 11/11] Platform/ARM/Morello: Update Readme.md chandni cherukuri
@ 2021-12-07 21:01   ` Sami Mujawar
  0 siblings, 0 replies; 31+ messages in thread
From: Sami Mujawar @ 2021-12-07 21:01 UTC (permalink / raw)
  To: Chandni Cherukuri, devel; +Cc: Ard Biesheuvel, Leif Lindholm, nd

Hi Chandni,

Thank you for this patch.

Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>

Regards,

Sami Mujawar


On 04/12/2021 12:30 PM, Chandni Cherukuri wrote:
> Morello SoC platform support has added and also
> boot flow modified to reflect the new boot flow
> for both Morello FVP and Morello SoC platforms
>
> Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
> ---
>   Platform/ARM/Morello/Readme.md | 12 +++++++++---
>   1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/Platform/ARM/Morello/Readme.md b/Platform/ARM/Morello/Readme.md
> index 8d441234f3b8..a5ecab5cdb51 100644
> --- a/Platform/ARM/Morello/Readme.md
> +++ b/Platform/ARM/Morello/Readme.md
> @@ -7,6 +7,11 @@ The platform port in UEFI firmware provides ARMv8-A architecture enablement.
>   
>   Platform code is located at Platform/ARM/Morello.
>   
> +The following platforms are supported
> +
> +- Morello FVP
> +- Morello SoC
> +
>   # Documentation
>   
>   Further information on Morello Platform is available at this [page](https://developer.arm.com/architectures/cpu-architecture/a-profile/morello).
> @@ -26,9 +31,10 @@ Please refer to the `edk2-platforms/Readme.md` for build instructions.
>   
>   # Dependencies
>   
> -Once the FVP is running, the SCP will be the first to boot and will bring the AP
> -core out of reset. The AP core will start executing Trusted Firmware-A at BL31
> -and once it completes the execution, it will start executing UEFI.
> +The SCP will be the first to boot and will bring the AP core out of reset. The AP
> +core will start executing Trusted Firmware-A at BL1. BL1 authenticates and then loads
> +BL2 and starts executing it. BL2 authenticates and loads BL31. Once BL31 finishes
> +execution BL2 authenticates and loads BL33 (UEFI) and passes control to it.
>   
>   The SCP and TF-A binaries are required to boot to the UEFI Shell.
>   


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-devel] [edk2-platforms][PATCH V1 07/11] Platform/ARM/Morello: Port PCI Express library
  2021-12-07 20:58   ` Sami Mujawar
@ 2021-12-08  2:55     ` Khasim Mohammed
  2021-12-09 12:30       ` chandni cherukuri
  0 siblings, 1 reply; 31+ messages in thread
From: Khasim Mohammed @ 2021-12-08  2:55 UTC (permalink / raw)
  To: Sami Mujawar, devel

[-- Attachment #1: Type: text/plain, Size: 428 bytes --]

Hi Sami, Chandni,

There was a suggestion from Pierre on a similar patch for N1SDP to remove PCIExpressLib.c and move to workarounds to PCISegmentLib.c,

https://edk2.groups.io/g/devel/message/84165?p=%2C%2C%2C20%2C0%2C0%2C0%3A%3Arecentpostdate%2Fsticky%2C%2Ckhasim%2C20%2C2%2C0%2C87257273

I think we should discuss this implementation for both N1SDP and Morello as they have similar implementation.

Regards,
Khasim

[-- Attachment #2: Type: text/html, Size: 465 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-devel] [edk2-platforms][PATCH V1 04/11] Platform/ARM/Morello: Add ConfigurationManager for Morello SoC
  2021-12-04 12:30 ` [edk2-platforms][PATCH V1 04/11] Platform/ARM/Morello: Add ConfigurationManager " chandni cherukuri
  2021-12-07 20:51   ` Sami Mujawar
@ 2021-12-08  3:02   ` Khasim Mohammed
  2021-12-08 12:32     ` chandni cherukuri
  1 sibling, 1 reply; 31+ messages in thread
From: Khasim Mohammed @ 2021-12-08  3:02 UTC (permalink / raw)
  To: chandni cherukuri, devel

[-- Attachment #1: Type: text/plain, Size: 15245 bytes --]

Hi Chandni,

One input,

On Sat, Dec 4, 2021 at 04:31 AM, chandni cherukuri wrote:

> 
> This patch implements the configuration manager for Morello
> SoC platform. It enables support for generating the following
> ACPI tables for Morello SoC Platform:
> 1. FADT
> 2. DSDT
> 3. GTDT
> 4. MADT
> 5. SPCR
> 6. DBG2
> 7. PPTT
> 
> Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
> ---
> Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
> | 16 ++
> Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> | 72 +++++++++
> Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
> | 97 ++++++++++++
> Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
> | 161 ++++++++++++++++++++
> Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl
> | 41 +++++
> 5 files changed, 387 insertions(+)
> 
> diff --git
> a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
> b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
> 
> new file mode 100644
> index 000000000000..f7e58185696e
> --- /dev/null
> +++
> b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
> 

I think there is no need for this separate .dsc.inc file, can you please refer to the N1SDP implementation, I had received a suggestion from Pierre after which I had removed a similar file in N1SDP patch set.

> 
> @@ -0,0 +1,16 @@
> +## @file
> +# dsc include file for Configuration Manager
> +#
> +# Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +
> +[BuildOptions]
> +
> +[Components.common]
> + # Configuration Manager
> +
> Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> 
> diff --git
> a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> 
> new file mode 100644
> index 000000000000..6f9199a6fda2
> --- /dev/null
> +++
> b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> 
> @@ -0,0 +1,72 @@
> +## @file
> +# Configuration Manager Dxe
> +#
> +# Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x0001001B
> + BASE_NAME = ConfigurationManagerDxe
> + FILE_GUID = BF8FBCEE-AD95-466B-9185-50A1BB651DDA
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = ConfigurationManagerDxeInitialize
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = AARCH64
> +#
> +
> +[Sources]
> + AslTables/DsdtSoc.asl
> + ConfigurationManager.c
> + ConfigurationManager.h
> + ConfigurationManagerSoc.c
> + ConfigurationManagerSoc.h
> + Platform.h
> +
> +[Packages]
> + ArmPkg/ArmPkg.dec
> + ArmPlatformPkg/ArmPlatformPkg.dec
> + DynamicTablesPkg/DynamicTablesPkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + MdePkg/MdePkg.dec
> + Platform/ARM/Morello/MorelloPlatform.dec
> +
> +[LibraryClasses]
> + UefiDriverEntryPoint
> +
> +[Protocols]
> + gEdkiiConfigurationManagerProtocolGuid
> +
> +[FixedPcd]
> + ## PL011 Serial Debug UART
> + gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
> + gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate
> + gArmPlatformTokenSpaceGuid.PcdSerialDbgUartClkInHz
> +
> + gArmPlatformTokenSpaceGuid.PL011UartClkInHz
> + gArmPlatformTokenSpaceGuid.PL011UartInterrupt
> +
> + gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum
> + gArmTokenSpaceGuid.PcdArmArchTimerIntrNum
> + gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum
> + gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum
> +
> + # SBSA Generic Watchdog
> + gArmTokenSpaceGuid.PcdGenericWatchdogControlBase
> + gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum
> + gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase
> +
> + gArmTokenSpaceGuid.PcdGicDistributorBase
> + gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
> + gArmTokenSpaceGuid.PcdGicRedistributorsBase
> +
> + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
> + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
> +
> +[Depex]
> + TRUE
> diff --git
> a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
> b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
> 
> new file mode 100644
> index 000000000000..8a521b83c8dc
> --- /dev/null
> +++
> b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
> 
> @@ -0,0 +1,97 @@
> +/** @file
> +
> + Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Glossary:
> + - Cm or CM - Configuration Manager
> + - Obj or OBJ - Object
> +**/
> +
> +#ifndef SOC_CONFIGURATION_MANAGER_H_
> +#define SOC_CONFIGURATION_MANAGER_H_
> +
> +#include "ConfigurationManager.h"
> +
> +/** The number of ACPI tables to install
> +*/
> +#define PLAT_ACPI_TABLE_COUNT 7
> +
> +/** A helper macro for mapping a reference token
> +*/
> +#define REFERENCE_TOKEN_SOC(Field) \
> + (CM_OBJECT_TOKEN)((UINT8*)&MorelloSocRepositoryInfo + \
> + OFFSET_OF (EDKII_SOC_PLATFORM_REPOSITORY_INFO, Field))
> +
> +/** C array containing the compiled AML template.
> + These symbols are defined in the auto generated C file
> + containing the AML bytecode array.
> +*/
> +extern CHAR8 dsdtsoc_aml_code[];
> +
> +/** A structure describing the SoC Platform specific information
> +*/
> +typedef struct SocPlatformRepositoryInfo {
> + /// List of ACPI tables
> + CM_STD_OBJ_ACPI_TABLE_INFO CmAcpiTableList[PLAT_ACPI_TABLE_COUNT];
> +} EDKII_SOC_PLATFORM_REPOSITORY_INFO;
> +
> +/** A structure describing the platform configuration
> + manager repository information
> +*/
> +typedef struct PlatformRepositoryInfo {
> + /// Common information
> + EDKII_COMMON_PLATFORM_REPOSITORY_INFO *CommonPlatRepoInfo;
> +
> + /// SoC Platform specific information
> + EDKII_SOC_PLATFORM_REPOSITORY_INFO *SocPlatRepoInfo;
> +} EDKII_PLATFORM_REPOSITORY_INFO;
> +
> +extern EDKII_COMMON_PLATFORM_REPOSITORY_INFO CommonPlatformInfo;
> +
> +/** Return platform specific ARM namespace object.
> +
> + @param [in] This Pointer to the Configuration Manager Protocol.
> + @param [in] CmObjectId The Configuration Manager Object ID.
> + @param [in] Token An optional token identifying the object. If
> + unused this must be CM_NULL_TOKEN.
> + @param [in, 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
> +GetArmNameSpaceObjectPlat (
> + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
> + IN CONST CM_OBJECT_ID CmObjectId,
> + IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
> + IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject
> + );
> +
> +/** Return platform specific standard namespace object.
> +
> + @param [in] This Pointer to the Configuration Manager Protocol.
> + @param [in] CmObjectId The Configuration Manager Object ID.
> + @param [in] Token An optional token identifying the object. If
> + unused this must be CM_NULL_TOKEN.
> + @param [in, 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
> +GetStandardNameSpaceObjectPlat (
> + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
> + IN CONST CM_OBJECT_ID CmObjectId,
> + IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
> + IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject
> + );
> +
> +#endif // SOC_CONFIGURATION_MANAGER_H_
> diff --git
> a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
> b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
> 
> new file mode 100644
> index 000000000000..7ca8ae212a61
> --- /dev/null
> +++
> b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
> 
> @@ -0,0 +1,161 @@
> +/** @file
> + Configuration Manager Dxe
> +
> + Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Glossary:
> + - Cm or CM - Configuration Manager
> + - Obj or OBJ - Object
> +**/
> +
> +#include <IndustryStandard/DebugPort2Table.h>
> +#include <IndustryStandard/IoRemappingTable.h>
> +#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
> +#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +
> +#include "ConfigurationManagerSoc.h"
> +#include "Platform.h"
> +
> +EDKII_SOC_PLATFORM_REPOSITORY_INFO MorelloSocRepositoryInfo = {
> + // ACPI Table List
> + {
> + // FADT Table
> + {
> + EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
> + EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
> + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt),
> + NULL
> + },
> + // GTDT Table
> + {
> + EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
> + EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION,
> + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdGtdt),
> + NULL
> + },
> + // MADT Table
> + {
> + EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
> + EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
> + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMadt),
> + NULL
> + },
> + // SPCR Table
> + {
> + EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
> + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION,
> + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSpcr),
> + NULL
> + },
> + // DSDT Table
> + {
> + EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
> + 0, // Unused
> + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDsdt),
> + (EFI_ACPI_DESCRIPTION_HEADER *)dsdtsoc_aml_code
> + },
> + // DBG2 Table
> + {
> + EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE,
> + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,
> + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDbg2),
> + NULL
> + },
> + // PPTT Table
> + {
> + EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
> + EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION,
> + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdPptt),
> + NULL
> + },
> + },
> +};
> +
> +EDKII_PLATFORM_REPOSITORY_INFO MorelloRepositoryInfo = {
> + &CommonPlatformInfo,
> + &MorelloSocRepositoryInfo
> +};
> +
> +/** Return platform specific ARM namespace object.
> +
> + @param [in] This Pointer to the Configuration Manager Protocol.
> + @param [in] CmObjectId The Configuration Manager Object ID.
> + @param [in] Token An optional token identifying the object. If
> + unused this must be CM_NULL_TOKEN.
> + @param [in, 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
> +GetArmNameSpaceObjectPlat (
> + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
> + IN CONST CM_OBJECT_ID CmObjectId,
> + IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
> + IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject
> + )
> +{
> + return EFI_NOT_FOUND;
> +}
> +
> +/** Return platform specific standard namespace object.
> +
> + @param [in] This Pointer to the Configuration Manager Protocol.
> + @param [in] CmObjectId The Configuration Manager Object ID.
> + @param [in] Token An optional token identifying the object. If
> + unused this must be CM_NULL_TOKEN.
> + @param [in, 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
> +GetStandardNameSpaceObjectPlat (
> + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
> + IN CONST CM_OBJECT_ID CmObjectId,
> + IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
> + IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject
> + )
> +{
> + EFI_STATUS Status;
> + EDKII_SOC_PLATFORM_REPOSITORY_INFO *PlatformRepo;
> +
> + if ((This == NULL) || (CmObject == NULL)) {
> + ASSERT (This != NULL);
> + ASSERT (CmObject != NULL);
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Status = EFI_NOT_FOUND;
> + PlatformRepo = This->PlatRepoInfo->SocPlatRepoInfo;
> +
> + switch (GET_CM_OBJECT_ID (CmObjectId)) {
> + case EStdObjAcpiTableList:
> + Status = HandleCmObject (
> + CmObjectId,
> + PlatformRepo->CmAcpiTableList,
> + sizeof (PlatformRepo->CmAcpiTableList),
> + ARRAY_SIZE (PlatformRepo->CmAcpiTableList),
> + CmObject
> + );
> + break;
> +
> + default:
> + {
> + break;
> + }
> + }
> +
> + return Status;
> +}
> diff --git
> a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl
> b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl
> 
> new file mode 100644
> index 000000000000..806e170515b7
> --- /dev/null
> +++
> b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl
> 
> @@ -0,0 +1,41 @@
> +/** @file
> + Differentiated System Description Table Fields (DSDT)
> +
> + Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Reference(s):
> + - ACPI for Arm Components 1.0, Platform Design Document
> +
> +**/
> +
> +#include "ConfigurationManager.h"
> +
> +DefinitionBlock("Dsdt.aml", "DSDT", 1, "ARMLTD", "MORELLO",
> CFG_MGR_OEM_REVISION) {
> + Scope(_SB) {
> + Device(CP00) { // Cluster 0, Cpu 0
> + Name(_HID, "ACPI0007")
> + Name(_UID, 0)
> + Name(_STA, 0xF)
> + }
> +
> + Device(CP01) { // Cluster 0, Cpu 1
> + Name(_HID, "ACPI0007")
> + Name(_UID, 1)
> + Name(_STA, 0xF)
> + }
> +
> + Device(CP02) { // Cluster 1, Cpu 0
> + Name(_HID, "ACPI0007")
> + Name(_UID, 2)
> + Name(_STA, 0xF)
> + }
> +
> + Device(CP03) { // Cluster 1, Cpu 1
> + Name(_HID, "ACPI0007")
> + Name(_UID, 3)
> + Name(_STA, 0xF)
> + }
> + } // Scope(_SB)
> +}
> --
> 2.17.1

[-- Attachment #2: Type: text/html, Size: 16190 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-devel] [edk2-platforms][PATCH V1 04/11] Platform/ARM/Morello: Add ConfigurationManager for Morello SoC
  2021-12-07 20:51   ` Sami Mujawar
@ 2021-12-08 12:28     ` chandni cherukuri
  0 siblings, 0 replies; 31+ messages in thread
From: chandni cherukuri @ 2021-12-08 12:28 UTC (permalink / raw)
  To: devel, Sami Mujawar

Hi Sami,

Thanks for reviewing the patch.
Sure, will try to use the SSDT CPU generator for both the Morello FVP
and Morello SoC platforms.

Thanks
Chandni

On Wed, Dec 8, 2021 at 2:22 AM Sami Mujawar <sami.mujawar@arm.com> wrote:
>
> Hi Chandni,
>
> Since you have the CPU information in MADT.GICC and the PPTT table, it
> should be possible to use the SSDT CPU generator to create the AML
> description for the CPUs. This patch series can go ahead. However, you
> may want to consider using the SSDT Cpu Generator in the furture.
>
> Otherwise, these changes look good to me.
>
> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
>
> Regards,
>
> Sami Mujawar
>
>
>
> On 04/12/2021 12:30 PM, Chandni Cherukuri wrote:
> > This patch implements the configuration manager for Morello
> > SoC platform. It enables support for generating the following
> > ACPI tables for Morello SoC Platform:
> >                 1. FADT
> >                 2. DSDT
> >                 3. GTDT
> >                 4. MADT
> >                 5. SPCR
> >                 6. DBG2
> >                 7. PPTT
> >
> > Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
> > ---
> >   Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc                        |  16 ++
> >   Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf |  72 +++++++++
> >   Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h      |  97 ++++++++++++
> >   Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c      | 161 ++++++++++++++++++++
> >   Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl          |  41 +++++
> >   5 files changed, 387 insertions(+)
> >
> > diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
> > new file mode 100644
> > index 000000000000..f7e58185696e
> > --- /dev/null
> > +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
> > @@ -0,0 +1,16 @@
> > +## @file
> > +#  dsc include file for Configuration Manager
> > +#
> > +#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +
> > +[BuildOptions]
> > +
> > +[Components.common]
> > +  # Configuration Manager
> > +  Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> > diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> > new file mode 100644
> > index 000000000000..6f9199a6fda2
> > --- /dev/null
> > +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> > @@ -0,0 +1,72 @@
> > +## @file
> > +#  Configuration Manager Dxe
> > +#
> > +#  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x0001001B
> > +  BASE_NAME                      = ConfigurationManagerDxe
> > +  FILE_GUID                      = BF8FBCEE-AD95-466B-9185-50A1BB651DDA
> > +  MODULE_TYPE                    = DXE_DRIVER
> > +  VERSION_STRING                 = 1.0
> > +  ENTRY_POINT                    = ConfigurationManagerDxeInitialize
> > +
> > +#
> > +# The following information is for reference only and not required by the build tools.
> > +#
> > +#  VALID_ARCHITECTURES           = AARCH64
> > +#
> > +
> > +[Sources]
> > +  AslTables/DsdtSoc.asl
> > +  ConfigurationManager.c
> > +  ConfigurationManager.h
> > +  ConfigurationManagerSoc.c
> > +  ConfigurationManagerSoc.h
> > +  Platform.h
> > +
> > +[Packages]
> > +  ArmPkg/ArmPkg.dec
> > +  ArmPlatformPkg/ArmPlatformPkg.dec
> > +  DynamicTablesPkg/DynamicTablesPkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  MdePkg/MdePkg.dec
> > +  Platform/ARM/Morello/MorelloPlatform.dec
> > +
> > +[LibraryClasses]
> > +  UefiDriverEntryPoint
> > +
> > +[Protocols]
> > +  gEdkiiConfigurationManagerProtocolGuid
> > +
> > +[FixedPcd]
> > +  ## PL011 Serial Debug UART
> > +  gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
> > +  gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate
> > +  gArmPlatformTokenSpaceGuid.PcdSerialDbgUartClkInHz
> > +
> > +  gArmPlatformTokenSpaceGuid.PL011UartClkInHz
> > +  gArmPlatformTokenSpaceGuid.PL011UartInterrupt
> > +
> > +  gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum
> > +  gArmTokenSpaceGuid.PcdArmArchTimerIntrNum
> > +  gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum
> > +  gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum
> > +
> > +  # SBSA Generic Watchdog
> > +  gArmTokenSpaceGuid.PcdGenericWatchdogControlBase
> > +  gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum
> > +  gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase
> > +
> > +  gArmTokenSpaceGuid.PcdGicDistributorBase
> > +  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
> > +  gArmTokenSpaceGuid.PcdGicRedistributorsBase
> > +
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
> > +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
> > +
> > +[Depex]
> > +  TRUE
> > diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
> > new file mode 100644
> > index 000000000000..8a521b83c8dc
> > --- /dev/null
> > +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
> > @@ -0,0 +1,97 @@
> > +/** @file
> > +
> > +  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +  @par Glossary:
> > +    - Cm or CM   - Configuration Manager
> > +    - Obj or OBJ - Object
> > +**/
> > +
> > +#ifndef SOC_CONFIGURATION_MANAGER_H_
> > +#define SOC_CONFIGURATION_MANAGER_H_
> > +
> > +#include "ConfigurationManager.h"
> > +
> > +/** The number of ACPI tables to install
> > +*/
> > +#define PLAT_ACPI_TABLE_COUNT  7
> > +
> > +/** A helper macro for mapping a reference token
> > +*/
> > +#define REFERENCE_TOKEN_SOC(Field)                                \
> > +  (CM_OBJECT_TOKEN)((UINT8*)&MorelloSocRepositoryInfo +           \
> > +    OFFSET_OF (EDKII_SOC_PLATFORM_REPOSITORY_INFO, Field))
> > +
> > +/** C array containing the compiled AML template.
> > +    These symbols are defined in the auto generated C file
> > +    containing the AML bytecode array.
> > +*/
> > +extern CHAR8  dsdtsoc_aml_code[];
> > +
> > +/** A structure describing the SoC Platform specific information
> > +*/
> > +typedef struct SocPlatformRepositoryInfo {
> > +  /// List of ACPI tables
> > +  CM_STD_OBJ_ACPI_TABLE_INFO    CmAcpiTableList[PLAT_ACPI_TABLE_COUNT];
> > +} EDKII_SOC_PLATFORM_REPOSITORY_INFO;
> > +
> > +/** A structure describing the platform configuration
> > +    manager repository information
> > +*/
> > +typedef struct PlatformRepositoryInfo {
> > +  /// Common information
> > +  EDKII_COMMON_PLATFORM_REPOSITORY_INFO    *CommonPlatRepoInfo;
> > +
> > +  /// SoC Platform specific information
> > +  EDKII_SOC_PLATFORM_REPOSITORY_INFO       *SocPlatRepoInfo;
> > +} EDKII_PLATFORM_REPOSITORY_INFO;
> > +
> > +extern EDKII_COMMON_PLATFORM_REPOSITORY_INFO  CommonPlatformInfo;
> > +
> > +/** Return platform specific ARM namespace object.
> > +
> > +  @param [in]      This        Pointer to the Configuration Manager Protocol.
> > +  @param [in]      CmObjectId  The Configuration Manager Object ID.
> > +  @param [in]      Token       An optional token identifying the object. If
> > +                               unused this must be CM_NULL_TOKEN.
> > +  @param [in, 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
> > +GetArmNameSpaceObjectPlat (
> > +  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST This,
> > +  IN  CONST CM_OBJECT_ID                                 CmObjectId,
> > +  IN  CONST CM_OBJECT_TOKEN                              Token OPTIONAL,
> > +  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST CmObject
> > +  );
> > +
> > +/** Return platform specific standard namespace object.
> > +
> > +  @param [in]      This        Pointer to the Configuration Manager Protocol.
> > +  @param [in]      CmObjectId  The Configuration Manager Object ID.
> > +  @param [in]      Token       An optional token identifying the object. If
> > +                               unused this must be CM_NULL_TOKEN.
> > +  @param [in, 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
> > +GetStandardNameSpaceObjectPlat (
> > +  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST This,
> > +  IN  CONST CM_OBJECT_ID                                 CmObjectId,
> > +  IN  CONST CM_OBJECT_TOKEN                              Token OPTIONAL,
> > +  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST CmObject
> > +  );
> > +
> > +#endif // SOC_CONFIGURATION_MANAGER_H_
> > diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
> > new file mode 100644
> > index 000000000000..7ca8ae212a61
> > --- /dev/null
> > +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
> > @@ -0,0 +1,161 @@
> > +/** @file
> > +  Configuration Manager Dxe
> > +
> > +  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +  @par Glossary:
> > +    - Cm or CM   - Configuration Manager
> > +    - Obj or OBJ - Object
> > +**/
> > +
> > +#include <IndustryStandard/DebugPort2Table.h>
> > +#include <IndustryStandard/IoRemappingTable.h>
> > +#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
> > +#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Protocol/ConfigurationManagerProtocol.h>
> > +
> > +#include "ConfigurationManagerSoc.h"
> > +#include "Platform.h"
> > +
> > +EDKII_SOC_PLATFORM_REPOSITORY_INFO  MorelloSocRepositoryInfo = {
> > +  // ACPI Table List
> > +  {
> > +    // FADT Table
> > +    {
> > +      EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
> > +      EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
> > +      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt),
> > +      NULL
> > +    },
> > +    // GTDT Table
> > +    {
> > +      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
> > +      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION,
> > +      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdGtdt),
> > +      NULL
> > +    },
> > +    // MADT Table
> > +    {
> > +      EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
> > +      EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
> > +      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMadt),
> > +      NULL
> > +    },
> > +    // SPCR Table
> > +    {
> > +      EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
> > +      EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION,
> > +      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSpcr),
> > +      NULL
> > +    },
> > +    // DSDT Table
> > +    {
> > +      EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
> > +      0, // Unused
> > +      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDsdt),
> > +      (EFI_ACPI_DESCRIPTION_HEADER *)dsdtsoc_aml_code
> > +    },
> > +    // DBG2 Table
> > +    {
> > +      EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE,
> > +      EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,
> > +      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDbg2),
> > +      NULL
> > +    },
> > +    // PPTT Table
> > +    {
> > +      EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
> > +      EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION,
> > +      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdPptt),
> > +      NULL
> > +    },
> > +  },
> > +};
> > +
> > +EDKII_PLATFORM_REPOSITORY_INFO  MorelloRepositoryInfo = {
> > +  &CommonPlatformInfo,
> > +  &MorelloSocRepositoryInfo
> > +};
> > +
> > +/** Return platform specific ARM namespace object.
> > +
> > +  @param [in]      This        Pointer to the Configuration Manager Protocol.
> > +  @param [in]      CmObjectId  The Configuration Manager Object ID.
> > +  @param [in]      Token       An optional token identifying the object. If
> > +                               unused this must be CM_NULL_TOKEN.
> > +  @param [in, 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
> > +GetArmNameSpaceObjectPlat (
> > +  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST This,
> > +  IN  CONST CM_OBJECT_ID                                 CmObjectId,
> > +  IN  CONST CM_OBJECT_TOKEN                              Token OPTIONAL,
> > +  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST CmObject
> > +  )
> > +{
> > +  return EFI_NOT_FOUND;
> > +}
> > +
> > +/** Return platform specific standard namespace object.
> > +
> > +  @param [in]      This        Pointer to the Configuration Manager Protocol.
> > +  @param [in]      CmObjectId  The Configuration Manager Object ID.
> > +  @param [in]      Token       An optional token identifying the object. If
> > +                               unused this must be CM_NULL_TOKEN.
> > +  @param [in, 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
> > +GetStandardNameSpaceObjectPlat (
> > +  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST This,
> > +  IN  CONST CM_OBJECT_ID                                 CmObjectId,
> > +  IN  CONST CM_OBJECT_TOKEN                              Token OPTIONAL,
> > +  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST CmObject
> > +  )
> > +{
> > +  EFI_STATUS                          Status;
> > +  EDKII_SOC_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
> > +
> > +  if ((This == NULL) || (CmObject == NULL)) {
> > +    ASSERT (This != NULL);
> > +    ASSERT (CmObject != NULL);
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  Status = EFI_NOT_FOUND;
> > +  PlatformRepo = This->PlatRepoInfo->SocPlatRepoInfo;
> > +
> > +  switch (GET_CM_OBJECT_ID (CmObjectId)) {
> > +    case EStdObjAcpiTableList:
> > +      Status = HandleCmObject (
> > +                 CmObjectId,
> > +                 PlatformRepo->CmAcpiTableList,
> > +                 sizeof (PlatformRepo->CmAcpiTableList),
> > +                 ARRAY_SIZE (PlatformRepo->CmAcpiTableList),
> > +                 CmObject
> > +                 );
> > +      break;
> > +
> > +    default:
> > +    {
> > +      break;
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl
> > new file mode 100644
> > index 000000000000..806e170515b7
> > --- /dev/null
> > +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl
> > @@ -0,0 +1,41 @@
> > +/** @file
> > +  Differentiated System Description Table Fields (DSDT)
> > +
> > +  Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +  @par Reference(s):
> > +  - ACPI for Arm Components  1.0, Platform Design Document
> > +
> > +**/
> > +
> > +#include "ConfigurationManager.h"
> > +
> > +DefinitionBlock("Dsdt.aml", "DSDT", 1, "ARMLTD", "MORELLO", CFG_MGR_OEM_REVISION) {
> > +  Scope(_SB) {
> > +    Device(CP00) { // Cluster 0, Cpu 0
> > +      Name(_HID, "ACPI0007")
> > +      Name(_UID, 0)
> > +      Name(_STA, 0xF)
> > +    }
> > +
> > +    Device(CP01) { // Cluster 0, Cpu 1
> > +      Name(_HID, "ACPI0007")
> > +      Name(_UID, 1)
> > +      Name(_STA, 0xF)
> > +    }
> > +
> > +    Device(CP02) { // Cluster 1, Cpu 0
> > +      Name(_HID, "ACPI0007")
> > +      Name(_UID, 2)
> > +      Name(_STA, 0xF)
> > +    }
> > +
> > +    Device(CP03) { // Cluster 1, Cpu 1
> > +      Name(_HID, "ACPI0007")
> > +      Name(_UID, 3)
> > +      Name(_STA, 0xF)
> > +    }
> > +  } // Scope(_SB)
> > +}
>
>
>
> 
>
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-devel] [edk2-platforms][PATCH V1 04/11] Platform/ARM/Morello: Add ConfigurationManager for Morello SoC
  2021-12-08  3:02   ` Khasim Mohammed
@ 2021-12-08 12:32     ` chandni cherukuri
  0 siblings, 0 replies; 31+ messages in thread
From: chandni cherukuri @ 2021-12-08 12:32 UTC (permalink / raw)
  To: devel, khasim.mohammed

Hi Khasim,

The modifications would have to be done for both Morello FVP and
Morello SoC platforms and
can be taken up as part of changes to align both the platforms.

Thanks
Chandni

On Wed, Dec 8, 2021 at 8:32 AM Khasim Mohammed <khasim.mohammed@arm.com> wrote:
>
> Hi Chandni,
>
> One input,
>
> On Sat, Dec 4, 2021 at 04:31 AM, chandni cherukuri wrote:
>
> This patch implements the configuration manager for Morello
> SoC platform. It enables support for generating the following
> ACPI tables for Morello SoC Platform:
> 1. FADT
> 2. DSDT
> 3. GTDT
> 4. MADT
> 5. SPCR
> 6. DBG2
> 7. PPTT
>
> Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
> ---
> Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc | 16 ++
> Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf | 72 +++++++++
> Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h | 97 ++++++++++++
> Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c | 161 ++++++++++++++++++++
> Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl | 41 +++++
> 5 files changed, 387 insertions(+)
>
> diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
> new file mode 100644
> index 000000000000..f7e58185696e
> --- /dev/null
> +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerSoc.dsc.inc
>
> I think there is no need for this separate .dsc.inc file, can you please refer to the N1SDP implementation, I had received a suggestion from Pierre after which I had removed a similar file in N1SDP patch set.
>
>
>
> @@ -0,0 +1,16 @@
> +## @file
> +# dsc include file for Configuration Manager
> +#
> +# Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +
> +[BuildOptions]
> +
> +[Components.common]
> + # Configuration Manager
> + Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> new file mode 100644
> index 000000000000..6f9199a6fda2
> --- /dev/null
> +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxeSoc.inf
> @@ -0,0 +1,72 @@
> +## @file
> +# Configuration Manager Dxe
> +#
> +# Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x0001001B
> + BASE_NAME = ConfigurationManagerDxe
> + FILE_GUID = BF8FBCEE-AD95-466B-9185-50A1BB651DDA
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = ConfigurationManagerDxeInitialize
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = AARCH64
> +#
> +
> +[Sources]
> + AslTables/DsdtSoc.asl
> + ConfigurationManager.c
> + ConfigurationManager.h
> + ConfigurationManagerSoc.c
> + ConfigurationManagerSoc.h
> + Platform.h
> +
> +[Packages]
> + ArmPkg/ArmPkg.dec
> + ArmPlatformPkg/ArmPlatformPkg.dec
> + DynamicTablesPkg/DynamicTablesPkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + MdePkg/MdePkg.dec
> + Platform/ARM/Morello/MorelloPlatform.dec
> +
> +[LibraryClasses]
> + UefiDriverEntryPoint
> +
> +[Protocols]
> + gEdkiiConfigurationManagerProtocolGuid
> +
> +[FixedPcd]
> + ## PL011 Serial Debug UART
> + gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
> + gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate
> + gArmPlatformTokenSpaceGuid.PcdSerialDbgUartClkInHz
> +
> + gArmPlatformTokenSpaceGuid.PL011UartClkInHz
> + gArmPlatformTokenSpaceGuid.PL011UartInterrupt
> +
> + gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum
> + gArmTokenSpaceGuid.PcdArmArchTimerIntrNum
> + gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum
> + gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum
> +
> + # SBSA Generic Watchdog
> + gArmTokenSpaceGuid.PcdGenericWatchdogControlBase
> + gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum
> + gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase
> +
> + gArmTokenSpaceGuid.PcdGicDistributorBase
> + gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
> + gArmTokenSpaceGuid.PcdGicRedistributorsBase
> +
> + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
> + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
> +
> +[Depex]
> + TRUE
> diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
> new file mode 100644
> index 000000000000..8a521b83c8dc
> --- /dev/null
> +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.h
> @@ -0,0 +1,97 @@
> +/** @file
> +
> + Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Glossary:
> + - Cm or CM - Configuration Manager
> + - Obj or OBJ - Object
> +**/
> +
> +#ifndef SOC_CONFIGURATION_MANAGER_H_
> +#define SOC_CONFIGURATION_MANAGER_H_
> +
> +#include "ConfigurationManager.h"
> +
> +/** The number of ACPI tables to install
> +*/
> +#define PLAT_ACPI_TABLE_COUNT 7
> +
> +/** A helper macro for mapping a reference token
> +*/
> +#define REFERENCE_TOKEN_SOC(Field) \
> + (CM_OBJECT_TOKEN)((UINT8*)&MorelloSocRepositoryInfo + \
> + OFFSET_OF (EDKII_SOC_PLATFORM_REPOSITORY_INFO, Field))
> +
> +/** C array containing the compiled AML template.
> + These symbols are defined in the auto generated C file
> + containing the AML bytecode array.
> +*/
> +extern CHAR8 dsdtsoc_aml_code[];
> +
> +/** A structure describing the SoC Platform specific information
> +*/
> +typedef struct SocPlatformRepositoryInfo {
> + /// List of ACPI tables
> + CM_STD_OBJ_ACPI_TABLE_INFO CmAcpiTableList[PLAT_ACPI_TABLE_COUNT];
> +} EDKII_SOC_PLATFORM_REPOSITORY_INFO;
> +
> +/** A structure describing the platform configuration
> + manager repository information
> +*/
> +typedef struct PlatformRepositoryInfo {
> + /// Common information
> + EDKII_COMMON_PLATFORM_REPOSITORY_INFO *CommonPlatRepoInfo;
> +
> + /// SoC Platform specific information
> + EDKII_SOC_PLATFORM_REPOSITORY_INFO *SocPlatRepoInfo;
> +} EDKII_PLATFORM_REPOSITORY_INFO;
> +
> +extern EDKII_COMMON_PLATFORM_REPOSITORY_INFO CommonPlatformInfo;
> +
> +/** Return platform specific ARM namespace object.
> +
> + @param [in] This Pointer to the Configuration Manager Protocol.
> + @param [in] CmObjectId The Configuration Manager Object ID.
> + @param [in] Token An optional token identifying the object. If
> + unused this must be CM_NULL_TOKEN.
> + @param [in, 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
> +GetArmNameSpaceObjectPlat (
> + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
> + IN CONST CM_OBJECT_ID CmObjectId,
> + IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
> + IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject
> + );
> +
> +/** Return platform specific standard namespace object.
> +
> + @param [in] This Pointer to the Configuration Manager Protocol.
> + @param [in] CmObjectId The Configuration Manager Object ID.
> + @param [in] Token An optional token identifying the object. If
> + unused this must be CM_NULL_TOKEN.
> + @param [in, 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
> +GetStandardNameSpaceObjectPlat (
> + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
> + IN CONST CM_OBJECT_ID CmObjectId,
> + IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
> + IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject
> + );
> +
> +#endif // SOC_CONFIGURATION_MANAGER_H_
> diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
> new file mode 100644
> index 000000000000..7ca8ae212a61
> --- /dev/null
> +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerSoc.c
> @@ -0,0 +1,161 @@
> +/** @file
> + Configuration Manager Dxe
> +
> + Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Glossary:
> + - Cm or CM - Configuration Manager
> + - Obj or OBJ - Object
> +**/
> +
> +#include <IndustryStandard/DebugPort2Table.h>
> +#include <IndustryStandard/IoRemappingTable.h>
> +#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
> +#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +
> +#include "ConfigurationManagerSoc.h"
> +#include "Platform.h"
> +
> +EDKII_SOC_PLATFORM_REPOSITORY_INFO MorelloSocRepositoryInfo = {
> + // ACPI Table List
> + {
> + // FADT Table
> + {
> + EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
> + EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
> + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt),
> + NULL
> + },
> + // GTDT Table
> + {
> + EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
> + EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION,
> + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdGtdt),
> + NULL
> + },
> + // MADT Table
> + {
> + EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
> + EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
> + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMadt),
> + NULL
> + },
> + // SPCR Table
> + {
> + EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
> + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION,
> + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSpcr),
> + NULL
> + },
> + // DSDT Table
> + {
> + EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
> + 0, // Unused
> + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDsdt),
> + (EFI_ACPI_DESCRIPTION_HEADER *)dsdtsoc_aml_code
> + },
> + // DBG2 Table
> + {
> + EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE,
> + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,
> + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDbg2),
> + NULL
> + },
> + // PPTT Table
> + {
> + EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
> + EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION,
> + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdPptt),
> + NULL
> + },
> + },
> +};
> +
> +EDKII_PLATFORM_REPOSITORY_INFO MorelloRepositoryInfo = {
> + &CommonPlatformInfo,
> + &MorelloSocRepositoryInfo
> +};
> +
> +/** Return platform specific ARM namespace object.
> +
> + @param [in] This Pointer to the Configuration Manager Protocol.
> + @param [in] CmObjectId The Configuration Manager Object ID.
> + @param [in] Token An optional token identifying the object. If
> + unused this must be CM_NULL_TOKEN.
> + @param [in, 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
> +GetArmNameSpaceObjectPlat (
> + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
> + IN CONST CM_OBJECT_ID CmObjectId,
> + IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
> + IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject
> + )
> +{
> + return EFI_NOT_FOUND;
> +}
> +
> +/** Return platform specific standard namespace object.
> +
> + @param [in] This Pointer to the Configuration Manager Protocol.
> + @param [in] CmObjectId The Configuration Manager Object ID.
> + @param [in] Token An optional token identifying the object. If
> + unused this must be CM_NULL_TOKEN.
> + @param [in, 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
> +GetStandardNameSpaceObjectPlat (
> + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
> + IN CONST CM_OBJECT_ID CmObjectId,
> + IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
> + IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject
> + )
> +{
> + EFI_STATUS Status;
> + EDKII_SOC_PLATFORM_REPOSITORY_INFO *PlatformRepo;
> +
> + if ((This == NULL) || (CmObject == NULL)) {
> + ASSERT (This != NULL);
> + ASSERT (CmObject != NULL);
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Status = EFI_NOT_FOUND;
> + PlatformRepo = This->PlatRepoInfo->SocPlatRepoInfo;
> +
> + switch (GET_CM_OBJECT_ID (CmObjectId)) {
> + case EStdObjAcpiTableList:
> + Status = HandleCmObject (
> + CmObjectId,
> + PlatformRepo->CmAcpiTableList,
> + sizeof (PlatformRepo->CmAcpiTableList),
> + ARRAY_SIZE (PlatformRepo->CmAcpiTableList),
> + CmObject
> + );
> + break;
> +
> + default:
> + {
> + break;
> + }
> + }
> +
> + return Status;
> +}
> diff --git a/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl
> new file mode 100644
> index 000000000000..806e170515b7
> --- /dev/null
> +++ b/Platform/ARM/Morello/ConfigurationManager/ConfigurationManagerDxe/AslTables/DsdtSoc.asl
> @@ -0,0 +1,41 @@
> +/** @file
> + Differentiated System Description Table Fields (DSDT)
> +
> + Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Reference(s):
> + - ACPI for Arm Components 1.0, Platform Design Document
> +
> +**/
> +
> +#include "ConfigurationManager.h"
> +
> +DefinitionBlock("Dsdt.aml", "DSDT", 1, "ARMLTD", "MORELLO", CFG_MGR_OEM_REVISION) {
> + Scope(_SB) {
> + Device(CP00) { // Cluster 0, Cpu 0
> + Name(_HID, "ACPI0007")
> + Name(_UID, 0)
> + Name(_STA, 0xF)
> + }
> +
> + Device(CP01) { // Cluster 0, Cpu 1
> + Name(_HID, "ACPI0007")
> + Name(_UID, 1)
> + Name(_STA, 0xF)
> + }
> +
> + Device(CP02) { // Cluster 1, Cpu 0
> + Name(_HID, "ACPI0007")
> + Name(_UID, 2)
> + Name(_STA, 0xF)
> + }
> +
> + Device(CP03) { // Cluster 1, Cpu 1
> + Name(_HID, "ACPI0007")
> + Name(_UID, 3)
> + Name(_STA, 0xF)
> + }
> + } // Scope(_SB)
> +}
> --
> 2.17.1
>
> 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-devel] [edk2-platforms][PATCH V1 07/11] Platform/ARM/Morello: Port PCI Express library
  2021-12-08  2:55     ` [edk2-devel] " Khasim Mohammed
@ 2021-12-09 12:30       ` chandni cherukuri
  2021-12-10 10:41         ` Ard Biesheuvel
  0 siblings, 1 reply; 31+ messages in thread
From: chandni cherukuri @ 2021-12-09 12:30 UTC (permalink / raw)
  To: devel, khasim.mohammed, Sami Mujawar, Ard Biesheuvel,
	Leif Lindholm, pierre.gondois

Hi Ard, Leif, Sami, Pierre,

For Morello platform, we created two custom libraries based on the
below two native libraries:
-          https://github.com/tianocore/edk2/tree/master/MdePkg/Library/BasePciSegmentLibPci
-          https://github.com/tianocore/edk2/tree/master/MdePkg/Library/BasePciExpressLib

because of the following reasons.
1.       In Morello platform, the ECAM region of the two root ports
are placed in non-contiguous memory as per the memory map architecture
of the Morello platform. The native PCI Express Library expects both
the ECAM regions for all the root ports to be contiguous.
2.       IORT and kernel currently require each root port to be in a
separate segment. You can refer to the code for more details -
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/acpi/arm64/iort.c#n307.
The native PCI Segment Library supports only a single segment.

Because of these reasons, the current patch series adapts the native
libraries as follows:

The custom PCI Segment Library passes the complete address which is
consumed by the custom PCI Express library where based on the Segment
number, the base address of the PCI Express is returned.

The rationale behind maintaining two separate libraries is that when
the software evolves and support for multiple segments is adapted in
the native PCI Segment Library the custom library could be removed.
Also, we might have other protocols which might try to use the PCI
Express library directly. However, there are some other platforms
where all the platform specific changes have gone in a single custom
PCI library

Could you please provide some inputs as to which of two approaches
would be better to follow as there is one more platform to follow
based on the decision taken?

Thanks
Chandni

On Wed, Dec 8, 2021 at 8:25 AM Khasim Mohammed <khasim.mohammed@arm.com> wrote:
>
> Hi Sami, Chandni,
>
> There was a suggestion from Pierre on a similar patch for N1SDP to remove PCIExpressLib.c and move to workarounds to PCISegmentLib.c,
>
> https://edk2.groups.io/g/devel/message/84165?p=%2C%2C%2C20%2C0%2C0%2C0%3A%3Arecentpostdate%2Fsticky%2C%2Ckhasim%2C20%2C2%2C0%2C87257273
>
> I think we should discuss this implementation for both N1SDP and Morello as they have similar implementation.
>
> Regards,
> Khasim
> 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-devel] [edk2-platforms][PATCH V1 07/11] Platform/ARM/Morello: Port PCI Express library
  2021-12-09 12:30       ` chandni cherukuri
@ 2021-12-10 10:41         ` Ard Biesheuvel
  2021-12-13 12:41           ` chandni cherukuri
  0 siblings, 1 reply; 31+ messages in thread
From: Ard Biesheuvel @ 2021-12-10 10:41 UTC (permalink / raw)
  To: chandni cherukuri
  Cc: edk2-devel-groups-io, khasim.mohammed, Sami Mujawar,
	Ard Biesheuvel, Leif Lindholm, Pierre

On Thu, 9 Dec 2021 at 13:30, chandni cherukuri <ch.chandni@gmail.com> wrote:
>
> Hi Ard, Leif, Sami, Pierre,
>
> For Morello platform, we created two custom libraries based on the
> below two native libraries:
> -          https://github.com/tianocore/edk2/tree/master/MdePkg/Library/BasePciSegmentLibPci
> -          https://github.com/tianocore/edk2/tree/master/MdePkg/Library/BasePciExpressLib
>
> because of the following reasons.
> 1.       In Morello platform, the ECAM region of the two root ports
> are placed in non-contiguous memory as per the memory map architecture
> of the Morello platform. The native PCI Express Library expects both
> the ECAM regions for all the root ports to be contiguous.

Do you mean root ports or host bridges? If root ports don't share the
MMIO resource windows provided by the respective host bridges, they
are really different host bridges and should be modeled as such.

Note that the Cadence and Synopsys IP usually does not implement a
root port at all, and gets away with this because it only implements a
single link.

> 2.       IORT and kernel currently require each root port to be in a
> separate segment. You can refer to the code for more details -
>

Please take a look at the SynQuaecer platform for inspiration. That
platform is very similar in this respect.

 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/acpi/arm64/iort.c#n307.
> The native PCI Segment Library supports only a single segment.
>
> Because of these reasons, the current patch series adapts the native
> libraries as follows:
>
> The custom PCI Segment Library passes the complete address which is
> consumed by the custom PCI Express library where based on the Segment
> number, the base address of the PCI Express is returned.
>
> The rationale behind maintaining two separate libraries is that when
> the software evolves and support for multiple segments is adapted in
> the native PCI Segment Library the custom library could be removed.
> Also, we might have other protocols which might try to use the PCI
> Express library directly. However, there are some other platforms
> where all the platform specific changes have gone in a single custom
> PCI library
>
> Could you please provide some inputs as to which of two approaches
> would be better to follow as there is one more platform to follow
> based on the decision taken?
>
> Thanks
> Chandni
>
> On Wed, Dec 8, 2021 at 8:25 AM Khasim Mohammed <khasim.mohammed@arm.com> wrote:
> >
> > Hi Sami, Chandni,
> >
> > There was a suggestion from Pierre on a similar patch for N1SDP to remove PCIExpressLib.c and move to workarounds to PCISegmentLib.c,
> >
> > https://edk2.groups.io/g/devel/message/84165?p=%2C%2C%2C20%2C0%2C0%2C0%3A%3Arecentpostdate%2Fsticky%2C%2Ckhasim%2C20%2C2%2C0%2C87257273
> >
> > I think we should discuss this implementation for both N1SDP and Morello as they have similar implementation.
> >
> > Regards,
> > Khasim
> > 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-devel] [edk2-platforms][PATCH V1 07/11] Platform/ARM/Morello: Port PCI Express library
  2021-12-10 10:41         ` Ard Biesheuvel
@ 2021-12-13 12:41           ` chandni cherukuri
  2021-12-13 14:37             ` Ard Biesheuvel
  0 siblings, 1 reply; 31+ messages in thread
From: chandni cherukuri @ 2021-12-13 12:41 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel-groups-io
  Cc: khasim.mohammed, Sami Mujawar, Ard Biesheuvel, Leif Lindholm,
	Pierre

Hi Ard,

Thanks for the response.

I had a look at the Synquacer platform where there is a single custom
PCIe library implemented.
So, is it better to implement a single custom PCIe library instead of
two custom PCIe libraries?

If that is the case then will implement a single custom PCIe library
for Morello.

Thanks
Chandni
On Fri, Dec 10, 2021 at 4:12 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Thu, 9 Dec 2021 at 13:30, chandni cherukuri <ch.chandni@gmail.com> wrote:
> >
> > Hi Ard, Leif, Sami, Pierre,
> >
> > For Morello platform, we created two custom libraries based on the
> > below two native libraries:
> > -          https://github.com/tianocore/edk2/tree/master/MdePkg/Library/BasePciSegmentLibPci
> > -          https://github.com/tianocore/edk2/tree/master/MdePkg/Library/BasePciExpressLib
> >
> > because of the following reasons.
> > 1.       In Morello platform, the ECAM region of the two root ports
> > are placed in non-contiguous memory as per the memory map architecture
> > of the Morello platform. The native PCI Express Library expects both
> > the ECAM regions for all the root ports to be contiguous.
>
> Do you mean root ports or host bridges? If root ports don't share the
> MMIO resource windows provided by the respective host bridges, they
> are really different host bridges and should be modeled as such.
>
> Note that the Cadence and Synopsys IP usually does not implement a
> root port at all, and gets away with this because it only implements a
> single link.
>
> > 2.       IORT and kernel currently require each root port to be in a
> > separate segment. You can refer to the code for more details -
> >
>
> Please take a look at the SynQuaecer platform for inspiration. That
> platform is very similar in this respect.
>
>  https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/acpi/arm64/iort.c#n307.
> > The native PCI Segment Library supports only a single segment.
> >
> > Because of these reasons, the current patch series adapts the native
> > libraries as follows:
> >
> > The custom PCI Segment Library passes the complete address which is
> > consumed by the custom PCI Express library where based on the Segment
> > number, the base address of the PCI Express is returned.
> >
> > The rationale behind maintaining two separate libraries is that when
> > the software evolves and support for multiple segments is adapted in
> > the native PCI Segment Library the custom library could be removed.
> > Also, we might have other protocols which might try to use the PCI
> > Express library directly. However, there are some other platforms
> > where all the platform specific changes have gone in a single custom
> > PCI library
> >
> > Could you please provide some inputs as to which of two approaches
> > would be better to follow as there is one more platform to follow
> > based on the decision taken?
> >
> > Thanks
> > Chandni
> >
> > On Wed, Dec 8, 2021 at 8:25 AM Khasim Mohammed <khasim.mohammed@arm.com> wrote:
> > >
> > > Hi Sami, Chandni,
> > >
> > > There was a suggestion from Pierre on a similar patch for N1SDP to remove PCIExpressLib.c and move to workarounds to PCISegmentLib.c,
> > >
> > > https://edk2.groups.io/g/devel/message/84165?p=%2C%2C%2C20%2C0%2C0%2C0%3A%3Arecentpostdate%2Fsticky%2C%2Ckhasim%2C20%2C2%2C0%2C87257273
> > >
> > > I think we should discuss this implementation for both N1SDP and Morello as they have similar implementation.
> > >
> > > Regards,
> > > Khasim
> > > 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-devel] [edk2-platforms][PATCH V1 07/11] Platform/ARM/Morello: Port PCI Express library
  2021-12-13 12:41           ` chandni cherukuri
@ 2021-12-13 14:37             ` Ard Biesheuvel
  2021-12-13 17:44               ` chandni cherukuri
  0 siblings, 1 reply; 31+ messages in thread
From: Ard Biesheuvel @ 2021-12-13 14:37 UTC (permalink / raw)
  To: chandni cherukuri
  Cc: edk2-devel-groups-io, khasim.mohammed, Sami Mujawar,
	Ard Biesheuvel, Leif Lindholm, Pierre

On Mon, 13 Dec 2021 at 13:41, chandni cherukuri <ch.chandni@gmail.com> wrote:
>
> Hi Ard,
>
> Thanks for the response.
>
> I had a look at the Synquacer platform where there is a single custom
> PCIe library implemented.
> So, is it better to implement a single custom PCIe library instead of
> two custom PCIe libraries?
>

Yes, for two reasons:
- there is prior art for this solution, and solving the same problem
in two different ways in the same codebase is bad form;
- those two libraries are layered one on top of the other, which means
that your fix requires changes to two different layers, making the
interface between those two layers obviously unfit to represent the
hardware in question.


> If that is the case then will implement a single custom PCIe library
> for Morello.
>
> Thanks
> Chandni
> On Fri, Dec 10, 2021 at 4:12 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Thu, 9 Dec 2021 at 13:30, chandni cherukuri <ch.chandni@gmail.com> wrote:
> > >
> > > Hi Ard, Leif, Sami, Pierre,
> > >
> > > For Morello platform, we created two custom libraries based on the
> > > below two native libraries:
> > > -          https://github.com/tianocore/edk2/tree/master/MdePkg/Library/BasePciSegmentLibPci
> > > -          https://github.com/tianocore/edk2/tree/master/MdePkg/Library/BasePciExpressLib
> > >
> > > because of the following reasons.
> > > 1.       In Morello platform, the ECAM region of the two root ports
> > > are placed in non-contiguous memory as per the memory map architecture
> > > of the Morello platform. The native PCI Express Library expects both
> > > the ECAM regions for all the root ports to be contiguous.
> >
> > Do you mean root ports or host bridges? If root ports don't share the
> > MMIO resource windows provided by the respective host bridges, they
> > are really different host bridges and should be modeled as such.
> >
> > Note that the Cadence and Synopsys IP usually does not implement a
> > root port at all, and gets away with this because it only implements a
> > single link.
> >
> > > 2.       IORT and kernel currently require each root port to be in a
> > > separate segment. You can refer to the code for more details -
> > >
> >
> > Please take a look at the SynQuaecer platform for inspiration. That
> > platform is very similar in this respect.
> >
> >  https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/acpi/arm64/iort.c#n307.
> > > The native PCI Segment Library supports only a single segment.
> > >
> > > Because of these reasons, the current patch series adapts the native
> > > libraries as follows:
> > >
> > > The custom PCI Segment Library passes the complete address which is
> > > consumed by the custom PCI Express library where based on the Segment
> > > number, the base address of the PCI Express is returned.
> > >
> > > The rationale behind maintaining two separate libraries is that when
> > > the software evolves and support for multiple segments is adapted in
> > > the native PCI Segment Library the custom library could be removed.
> > > Also, we might have other protocols which might try to use the PCI
> > > Express library directly. However, there are some other platforms
> > > where all the platform specific changes have gone in a single custom
> > > PCI library
> > >
> > > Could you please provide some inputs as to which of two approaches
> > > would be better to follow as there is one more platform to follow
> > > based on the decision taken?
> > >
> > > Thanks
> > > Chandni
> > >
> > > On Wed, Dec 8, 2021 at 8:25 AM Khasim Mohammed <khasim.mohammed@arm.com> wrote:
> > > >
> > > > Hi Sami, Chandni,
> > > >
> > > > There was a suggestion from Pierre on a similar patch for N1SDP to remove PCIExpressLib.c and move to workarounds to PCISegmentLib.c,
> > > >
> > > > https://edk2.groups.io/g/devel/message/84165?p=%2C%2C%2C20%2C0%2C0%2C0%3A%3Arecentpostdate%2Fsticky%2C%2Ckhasim%2C20%2C2%2C0%2C87257273
> > > >
> > > > I think we should discuss this implementation for both N1SDP and Morello as they have similar implementation.
> > > >
> > > > Regards,
> > > > Khasim
> > > > 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [edk2-devel] [edk2-platforms][PATCH V1 07/11] Platform/ARM/Morello: Port PCI Express library
  2021-12-13 14:37             ` Ard Biesheuvel
@ 2021-12-13 17:44               ` chandni cherukuri
  0 siblings, 0 replies; 31+ messages in thread
From: chandni cherukuri @ 2021-12-13 17:44 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel-groups-io
  Cc: khasim.mohammed, Sami Mujawar, Ard Biesheuvel, Leif Lindholm,
	Pierre

On Mon, Dec 13, 2021 at 8:08 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Mon, 13 Dec 2021 at 13:41, chandni cherukuri <ch.chandni@gmail.com> wrote:
> >
> > Hi Ard,
> >
> > Thanks for the response.
> >
> > I had a look at the Synquacer platform where there is a single custom
> > PCIe library implemented.
> > So, is it better to implement a single custom PCIe library instead of
> > two custom PCIe libraries?
> >
>
> Yes, for two reasons:
> - there is prior art for this solution, and solving the same problem
> in two different ways in the same codebase is bad form;
> - those two libraries are layered one on top of the other, which means
> that your fix requires changes to two different layers, making the
> interface between those two layers obviously unfit to represent the
> hardware in question.
>
>
Thanks for the response.
Will implement a single custom PCIe library and post a new patchset.

Thanks
Chandni

> > If that is the case then will implement a single custom PCIe library
> > for Morello.
> >
> > Thanks
> > Chandni
> > On Fri, Dec 10, 2021 at 4:12 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > On Thu, 9 Dec 2021 at 13:30, chandni cherukuri <ch.chandni@gmail.com> wrote:
> > > >
> > > > Hi Ard, Leif, Sami, Pierre,
> > > >
> > > > For Morello platform, we created two custom libraries based on the
> > > > below two native libraries:
> > > > -          https://github.com/tianocore/edk2/tree/master/MdePkg/Library/BasePciSegmentLibPci
> > > > -          https://github.com/tianocore/edk2/tree/master/MdePkg/Library/BasePciExpressLib
> > > >
> > > > because of the following reasons.
> > > > 1.       In Morello platform, the ECAM region of the two root ports
> > > > are placed in non-contiguous memory as per the memory map architecture
> > > > of the Morello platform. The native PCI Express Library expects both
> > > > the ECAM regions for all the root ports to be contiguous.
> > >
> > > Do you mean root ports or host bridges? If root ports don't share the
> > > MMIO resource windows provided by the respective host bridges, they
> > > are really different host bridges and should be modeled as such.
> > >
> > > Note that the Cadence and Synopsys IP usually does not implement a
> > > root port at all, and gets away with this because it only implements a
> > > single link.
> > >
> > > > 2.       IORT and kernel currently require each root port to be in a
> > > > separate segment. You can refer to the code for more details -
> > > >
> > >
> > > Please take a look at the SynQuaecer platform for inspiration. That
> > > platform is very similar in this respect.
> > >
> > >  https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/acpi/arm64/iort.c#n307.
> > > > The native PCI Segment Library supports only a single segment.
> > > >
> > > > Because of these reasons, the current patch series adapts the native
> > > > libraries as follows:
> > > >
> > > > The custom PCI Segment Library passes the complete address which is
> > > > consumed by the custom PCI Express library where based on the Segment
> > > > number, the base address of the PCI Express is returned.
> > > >
> > > > The rationale behind maintaining two separate libraries is that when
> > > > the software evolves and support for multiple segments is adapted in
> > > > the native PCI Segment Library the custom library could be removed.
> > > > Also, we might have other protocols which might try to use the PCI
> > > > Express library directly. However, there are some other platforms
> > > > where all the platform specific changes have gone in a single custom
> > > > PCI library
> > > >
> > > > Could you please provide some inputs as to which of two approaches
> > > > would be better to follow as there is one more platform to follow
> > > > based on the decision taken?
> > > >
> > > > Thanks
> > > > Chandni
> > > >
> > > > On Wed, Dec 8, 2021 at 8:25 AM Khasim Mohammed <khasim.mohammed@arm.com> wrote:
> > > > >
> > > > > Hi Sami, Chandni,
> > > > >
> > > > > There was a suggestion from Pierre on a similar patch for N1SDP to remove PCIExpressLib.c and move to workarounds to PCISegmentLib.c,
> > > > >
> > > > > https://edk2.groups.io/g/devel/message/84165?p=%2C%2C%2C20%2C0%2C0%2C0%3A%3Arecentpostdate%2Fsticky%2C%2Ckhasim%2C20%2C2%2C0%2C87257273
> > > > >
> > > > > I think we should discuss this implementation for both N1SDP and Morello as they have similar implementation.
> > > > >
> > > > > Regards,
> > > > > Khasim
> > > > > 

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2021-12-13 17:44 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-12-04 12:30 [edk2-platforms][PATCH V1 00/11] Add Support for Morello SoC chandni cherukuri
2021-12-04 12:30 ` [edk2-platforms][PATCH V1 01/11] Platform/ARM/Morello: Rename PlatformLib.inf file chandni cherukuri
2021-12-07 20:44   ` Sami Mujawar
2021-12-04 12:30 ` [edk2-platforms][PATCH V1 02/11] Platform/ARM/Morello: Add Platform Library support for Morello SoC chandni cherukuri
2021-12-07 20:44   ` Sami Mujawar
2021-12-04 12:30 ` [edk2-platforms][PATCH V1 03/11] Platform/ARM/Morello: Add PlatformDxe " chandni cherukuri
2021-12-07 20:44   ` Sami Mujawar
2021-12-04 12:30 ` [edk2-platforms][PATCH V1 04/11] Platform/ARM/Morello: Add ConfigurationManager " chandni cherukuri
2021-12-07 20:51   ` Sami Mujawar
2021-12-08 12:28     ` [edk2-devel] " chandni cherukuri
2021-12-08  3:02   ` Khasim Mohammed
2021-12-08 12:32     ` chandni cherukuri
2021-12-04 12:30 ` [edk2-platforms][PATCH V1 05/11] Platform/ARM/Morello: Add initial support " chandni cherukuri
2021-12-07 20:54   ` Sami Mujawar
2021-12-04 12:30 ` [edk2-platforms][PATCH V1 06/11] Platform/ARM/Morello: Port PCI Segment Library chandni cherukuri
2021-12-07 20:54   ` Sami Mujawar
2021-12-04 12:30 ` [edk2-platforms][PATCH V1 07/11] Platform/ARM/Morello: Port PCI Express library chandni cherukuri
2021-12-07 20:58   ` Sami Mujawar
2021-12-08  2:55     ` [edk2-devel] " Khasim Mohammed
2021-12-09 12:30       ` chandni cherukuri
2021-12-10 10:41         ` Ard Biesheuvel
2021-12-13 12:41           ` chandni cherukuri
2021-12-13 14:37             ` Ard Biesheuvel
2021-12-13 17:44               ` chandni cherukuri
2021-12-04 12:30 ` [edk2-platforms][PATCH V1 08/11] Platform/ARM/Morello: Enable PCIe and CCIX Root Ports chandni cherukuri
2021-12-07 20:59   ` Sami Mujawar
2021-12-04 12:30 ` [edk2-platforms][PATCH V1 09/11] Platform/ARM/Morello: Add ACPI bindings for PCIe & CCIX chandni cherukuri
2021-12-04 12:30 ` [edk2-platforms][PATCH V1 10/11] Platform/ARM/Morello: Add support to parse NT_FW_CONFIG chandni cherukuri
2021-12-07 20:59   ` Sami Mujawar
2021-12-04 12:30 ` [edk2-platforms][PATCH V1 11/11] Platform/ARM/Morello: Update Readme.md chandni cherukuri
2021-12-07 21:01   ` Sami Mujawar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox