public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
@ 2018-03-21  1:03 Heyi Guo
  2018-03-21  1:03 ` [PATCH edk2-platforms 01/12] Hisilicon: Enable WARN and INFO debug message Heyi Guo
                   ` (12 more replies)
  0 siblings, 13 replies; 33+ messages in thread
From: Heyi Guo @ 2018-03-21  1:03 UTC (permalink / raw)
  To: edk2-devel
  Cc: Heyi Guo, Ard Biesheuvel, Leif Lindholm, Michael D Kinney,
	Haojian Zhuang

For BAR address translation support was added to edk2 generic PciHostBridge by
commit 74d0a33, now we can also use it for D03/D05 platforms.
This series of patches include 3 parts of change:
- Preparation for the switch, moving platform specific code out of PciHostBridge
  driver.
- Add depending libraries and protocol implementations, like PciHostBridgeLib,
  PciSegmentLib and CpuIo2 Protocol.
- Other enhancement and refinement.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Haojian Zhuang <haojian.zhuang@linaro.org>

Heyi Guo (12):
  Hisilicon: Enable WARN and INFO debug message
  Hisilicon/D05/PlatformPciLib: fix misuse of macro
  Hisilicon/Pci: move ATU configuration to PcieInitDxe
  Hisilicon/Pci: Merge PciPlatform into PcieInit Driver
  Hisilicon/Pci: Move EnlargeAtuConfig0() to PcieInitDxe
  Hisilicon/PlatformPciLib: add segment for each root bridge
  Hisilicon: add PciHostBridgeLib
  Hisilicon: add PciCpuIo2Dxe
  Hisilicon: add PciSegmentLib for Hi161x
  Hisilicon/D0x: Switch to generic PciHostBridge driver
  Hisilicon: remove platform specific PciHostBridge
  Hisilicon/PlatformPciLib: clear redundant felds in RESOURCE_APPETURE

 Silicon/Hisilicon/Hisilicon.dsc.inc                                                                         |    8 +-
 Platform/Hisilicon/D03/D03.dsc                                                                              |    7 +-
 Platform/Hisilicon/D05/D05.dsc                                                                              |    7 +-
 Platform/Hisilicon/D03/D03.fdf                                                                              |    4 +-
 Platform/Hisilicon/D05/D05.fdf                                                                              |    4 +-
 Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf                                                  |   53 -
 Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf                                            |   51 +
 Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf                                               |   48 +
 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf                                             |   74 -
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf                                               |    9 +-
 Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/Hi161xPciSegmentLib.inf                                |   36 +
 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h                                                  |  528 -----
 {Platform/Hisilicon/D03/Drivers/PciPlatform => Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610}/PciPlatform.h |    0
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h                                                 |   13 +
 Silicon/Hisilicon/Include/Library/PlatformPciLib.h                                                          |    3 +-
 Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.c                                              |   24 +-
 Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c                                              |   66 +-
 Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.c                                              |  304 +++
 Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.c                                                 |  557 +++++
 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c                                                  | 1659 --------------
 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c                                                | 2404 --------------------
 {Platform/Hisilicon/D03/Drivers/PciPlatform => Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610}/PciPlatform.c |   12 +
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c                                                    |    7 +-
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c                                                 |  309 +++
 Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/PciSegmentLib.c                                        | 1503 ++++++++++++
 25 files changed, 2897 insertions(+), 4793 deletions(-)
 delete mode 100644 Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf
 create mode 100644 Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf
 create mode 100644 Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
 delete mode 100644 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
 create mode 100644 Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/Hi161xPciSegmentLib.inf
 delete mode 100644 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h
 rename {Platform/Hisilicon/D03/Drivers/PciPlatform => Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610}/PciPlatform.h (100%)
 create mode 100644 Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.c
 create mode 100644 Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.c
 delete mode 100644 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c
 delete mode 100644 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
 rename {Platform/Hisilicon/D03/Drivers/PciPlatform => Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610}/PciPlatform.c (93%)
 create mode 100644 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
 create mode 100644 Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/PciSegmentLib.c

-- 
2.7.4



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

* [PATCH edk2-platforms 01/12] Hisilicon: Enable WARN and INFO debug message
  2018-03-21  1:03 [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Heyi Guo
@ 2018-03-21  1:03 ` Heyi Guo
  2018-03-21  1:03 ` [PATCH edk2-platforms 02/12] Hisilicon/D05/PlatformPciLib: fix misuse of macro Heyi Guo
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Heyi Guo @ 2018-03-21  1:03 UTC (permalink / raw)
  To: edk2-devel
  Cc: Heyi Guo, Ard Biesheuvel, Leif Lindholm, Michael D Kinney,
	Haojian Zhuang

INFO and WARN messages are useful when we are debugging, something
like PCI enumeration process, and more debug messages should not
impact much for they will only be displayed in DEBUG version, not
RELEASE one.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 Silicon/Hisilicon/Hisilicon.dsc.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Silicon/Hisilicon/Hisilicon.dsc.inc b/Silicon/Hisilicon/Hisilicon.dsc.inc
index f8d5f0b270b3..77585933179e 100644
--- a/Silicon/Hisilicon/Hisilicon.dsc.inc
+++ b/Silicon/Hisilicon/Hisilicon.dsc.inc
@@ -293,7 +293,7 @@ [PcdsFixedAtBuild.common]
   #  DEBUG_EVENT     0x00080000  // Event messages
   #  DEBUG_ERROR     0x80000000  // Error
 
-  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000004
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
   gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x06
 
   #
-- 
2.7.4



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

* [PATCH edk2-platforms 02/12] Hisilicon/D05/PlatformPciLib: fix misuse of macro
  2018-03-21  1:03 [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Heyi Guo
  2018-03-21  1:03 ` [PATCH edk2-platforms 01/12] Hisilicon: Enable WARN and INFO debug message Heyi Guo
@ 2018-03-21  1:03 ` Heyi Guo
  2018-03-21  1:03 ` [PATCH edk2-platforms 03/12] Hisilicon/Pci: move ATU configuration to PcieInitDxe Heyi Guo
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Heyi Guo @ 2018-03-21  1:03 UTC (permalink / raw)
  To: edk2-devel; +Cc: Heyi Guo, Ard Biesheuvel, Leif Lindholm, Michael D Kinney

Each PCI root bridge has its own macro definitions for its resource
aperture, so that one root bridge should not use macro definitions of
other root bridges.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c b/Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c
index 57283a1053df..c8e20356f818 100644
--- a/Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c
+++ b/Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c
@@ -159,7 +159,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       (PCI_HB1RB0_ECAM_BASE),  //MemBase
       (PCI_HB1RB0_CPUMEMREGIONBASE + PCI_HB1RB0_PCIREGION_SIZE - 1), //MemLimit
       PCI_HB1RB0_IO_BASE, //IoBase
-      (PCI_HB0RB0_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      (PCI_HB1RB0_CPUIOREGIONBASE + PCI_HB1RB0_IO_SIZE - 1), //IoLimit
       PCI_HB1RB0_CPUMEMREGIONBASE, //CpuMemRegionBase
       PCI_HB1RB0_CPUIOREGIONBASE,  //CpuIoRegionBase
       (PCI_HB1RB0_PCI_BASE),  //RbPciBar
@@ -174,7 +174,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       (PCI_HB1RB1_ECAM_BASE),  //MemBase
       (PCI_HB1RB1_CPUMEMREGIONBASE + PCI_HB1RB1_PCIREGION_SIZE - 1), //MemLimit
       PCI_HB1RB1_IO_BASE, //IoBase
-      (PCI_HB0RB1_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      (PCI_HB1RB1_CPUIOREGIONBASE + PCI_HB1RB1_IO_SIZE - 1), //IoLimit
       PCI_HB1RB1_CPUMEMREGIONBASE, //CpuMemRegionBase
       PCI_HB1RB1_CPUIOREGIONBASE,  //CpuIoRegionBase
       (PCI_HB1RB1_PCI_BASE),  //RbPciBar
@@ -189,7 +189,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB2_CPUMEMREGIONBASE,  //MemBase
       PCI_HB1RB2_CPUMEMREGIONBASE + PCI_HB1RB2_PCIREGION_SIZE - 1, //MemLimit
       PCI_HB1RB2_IO_BASE, //IoBase
-      (PCI_HB0RB2_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      (PCI_HB1RB2_CPUIOREGIONBASE + PCI_HB1RB2_IO_SIZE - 1), //IoLimit
       PCI_HB1RB2_CPUMEMREGIONBASE, //CpuMemRegionBase
       PCI_HB1RB2_CPUIOREGIONBASE,  //CpuIoRegionBase
       (PCI_HB1RB2_PCI_BASE),  //RbPciBar
@@ -205,7 +205,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       (PCI_HB1RB3_ECAM_BASE),  //MemBase
       (PCI_HB1RB3_CPUMEMREGIONBASE + PCI_HB1RB3_PCIREGION_SIZE - 1), //MemLimit
       PCI_HB1RB3_IO_BASE, //IoBase
-      (PCI_HB0RB3_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      (PCI_HB1RB3_CPUIOREGIONBASE + PCI_HB1RB3_IO_SIZE - 1), //IoLimit
       PCI_HB1RB3_CPUMEMREGIONBASE, //CpuMemRegionBase
       PCI_HB1RB3_CPUIOREGIONBASE,  //CpuIoRegionBase
       (PCI_HB1RB3_PCI_BASE),  //RbPciBar
@@ -220,7 +220,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB4_CPUMEMREGIONBASE,  //MemBase
       PCI_HB1RB4_CPUMEMREGIONBASE + PCI_HB1RB4_PCIREGION_SIZE - 1, //MemLimit
       PCI_HB1RB4_IO_BASE, //IoBase
-      (PCI_HB0RB4_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      (PCI_HB1RB4_CPUIOREGIONBASE + PCI_HB1RB4_IO_SIZE - 1), //IoLimit
       PCI_HB1RB4_CPUMEMREGIONBASE, //CpuMemRegionBase
       PCI_HB1RB4_CPUIOREGIONBASE,  //CpuIoRegionBase
       (PCI_HB1RB4_PCI_BASE),  //RbPciBar
@@ -235,7 +235,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB5_CPUMEMREGIONBASE,  //MemBase
       PCI_HB1RB5_CPUMEMREGIONBASE + PCI_HB1RB5_PCIREGION_SIZE - 1, //MemLimit
       PCI_HB1RB5_IO_BASE, //IoBase
-      (PCI_HB0RB5_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      (PCI_HB1RB5_CPUIOREGIONBASE + PCI_HB1RB5_IO_SIZE - 1), //IoLimit
       PCI_HB1RB5_CPUMEMREGIONBASE, //CpuMemRegionBase
       PCI_HB1RB5_CPUIOREGIONBASE,  //CpuIoRegionBase
       (PCI_HB1RB5_PCI_BASE),  //RbPciBar
@@ -250,12 +250,12 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       (PCI_HB1RB6_ECAM_BASE),  //MemBase
       PCI_HB1RB6_CPUMEMREGIONBASE + PCI_HB1RB6_PCIREGION_SIZE - 1, //MemLimit
       PCI_HB1RB6_IO_BASE, //IoBase
-      (PCI_HB0RB6_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      (PCI_HB1RB6_CPUIOREGIONBASE + PCI_HB1RB6_IO_SIZE - 1), //IoLimit
       PCI_HB1RB6_CPUMEMREGIONBASE, //CpuMemRegionBase
       PCI_HB1RB6_CPUIOREGIONBASE,  //CpuIoRegionBase
       (PCI_HB1RB6_PCI_BASE),  //RbPciBar
       PCI_HB1RB6_PCIREGION_BASE, //PciRegionbase
-      PCI_HB1RB0_PCIREGION_BASE + PCI_HB1RB0_PCIREGION_SIZE - 1 //PciRegionlimit
+      PCI_HB1RB6_PCIREGION_BASE + PCI_HB1RB6_PCIREGION_SIZE - 1 //PciRegionlimit
   },
 
   /* Port 7 */
@@ -266,7 +266,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       (PCI_HB1RB7_ECAM_BASE),  //MemBase
       PCI_HB1RB7_CPUMEMREGIONBASE + PCI_HB1RB7_PCIREGION_SIZE - 1, //MemLimit
       PCI_HB1RB7_IO_BASE, //IoBase
-      (PCI_HB0RB7_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      (PCI_HB1RB7_CPUIOREGIONBASE + PCI_HB1RB7_IO_SIZE - 1), //IoLimit
       PCI_HB1RB7_CPUMEMREGIONBASE, //CpuMemRegionBase
       PCI_HB1RB7_CPUIOREGIONBASE,  //CpuIoRegionBase
       (PCI_HB1RB7_PCI_BASE),  //RbPciBar
-- 
2.7.4



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

* [PATCH edk2-platforms 03/12] Hisilicon/Pci: move ATU configuration to PcieInitDxe
  2018-03-21  1:03 [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Heyi Guo
  2018-03-21  1:03 ` [PATCH edk2-platforms 01/12] Hisilicon: Enable WARN and INFO debug message Heyi Guo
  2018-03-21  1:03 ` [PATCH edk2-platforms 02/12] Hisilicon/D05/PlatformPciLib: fix misuse of macro Heyi Guo
@ 2018-03-21  1:03 ` Heyi Guo
  2018-03-30 15:19   ` Ard Biesheuvel
  2018-03-21  1:03 ` [PATCH edk2-platforms 04/12] Hisilicon/Pci: Merge PciPlatform into PcieInit Driver Heyi Guo
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Heyi Guo @ 2018-03-21  1:03 UTC (permalink / raw)
  To: edk2-devel; +Cc: Heyi Guo, Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This is to prepare for switching to generic PciHostBridge driver, so
we move all platform specific code to platform specific drivers, not
in PciHostBridge driver.

This patch moves ATU initialization to PcieInitDxe driver.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf |   1 +
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h   |   2 +
 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c  | 106 ---------------
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c      |   3 +
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c   | 141 ++++++++++++++++++++
 5 files changed, 147 insertions(+), 106 deletions(-)

diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
index 61b091f659b3..cb0a63f9a84e 100644
--- a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
+++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
@@ -25,6 +25,7 @@ [Defines]
 [Sources]
   PcieInit.c
   PcieInitLib.c
+  PcieInitAtu.c
 
 [Packages]
   MdePkg/MdePkg.dec
diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h
index e96c53c4fe4e..87700ae8b9aa 100644
--- a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h
+++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h
@@ -246,4 +246,6 @@ EFI_STATUS PcieWaitLinkUp(UINT32 Port);
 
 EFI_STATUS PcieSetDBICS2Enable(UINT32 HostBridgeNum, UINT32 Port, UINT32 Enable);
 
+VOID InitAtu (PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private);
+
 #endif
diff --git a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c b/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
index 55b80aa4e49a..273a322ee48f 100644
--- a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
+++ b/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
@@ -633,111 +633,6 @@ UINT64 GetPcieCfgAddress (
 }
 
 
-void SetAtuConfig0RW (
-    PCI_ROOT_BRIDGE_INSTANCE *Private,
-    UINT32 Index
-    )
-{
-    UINTN RbPciBase = Private->RbPciBar;
-    UINT64 MemLimit = GetPcieCfgAddress (Private->Ecam, Private->BusBase + 1, 1, 0, 0) - 1;
-
-
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(Private->Ecam));
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(Private->Ecam) >> 32));
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, 0);
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, 0);
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_CONFIG0);
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_SHIIF_MODE);
-
-    {
-      UINTN i;
-      for (i=0; i<0x20; i+=4) {
-        DEBUG ((EFI_D_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
-      }
-    }
-}
-
-void SetAtuConfig1RW (
-    PCI_ROOT_BRIDGE_INSTANCE *Private,
-    UINT32 Index
-    )
-{
-    UINTN RbPciBase = Private->RbPciBar;
-    UINT64 MemLimit = GetPcieCfgAddress (Private->Ecam, Private->BusLimit + 1, 0, 0, 0) - 1;
-
-
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_CONFIG1);
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(Private->Ecam));
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(Private->Ecam) >> 32));
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, 0);
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, 0);
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_SHIIF_MODE);
-
-    {
-      UINTN i;
-      for (i=0; i<0x20; i+=4) {
-        DEBUG ((EFI_D_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
-      }
-    }
-}
-
-void SetAtuIoRW(UINT64 RbPciBase,UINT64 IoBase,UINT64 CpuIoRegionLimit, UINT64 CpuIoRegionBase, UINT32 Index)
-{
-
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_IO);
-
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(CpuIoRegionBase));
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)CpuIoRegionBase >> 32));
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32)(CpuIoRegionLimit));
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, (UINT32)(IoBase));
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, (UINT32)((UINT64)(IoBase) >> 32));
-
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_NORMAL_MODE);
-
-    {
-      UINTN i;
-      for (i=0; i<0x20; i+=4) {
-        DEBUG ((EFI_D_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
-      }
-    }
-}
-
-void SetAtuMemRW(UINT64 RbPciBase,UINT64 MemBase,UINT64 CpuMemRegionLimit, UINT64 CpuMemRegionBase, UINT32 Index)
-{
-
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_MEM);
-
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(CpuMemRegionBase));
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(CpuMemRegionBase) >> 32));
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32)(CpuMemRegionLimit));
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, (UINT32)(MemBase));
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, (UINT32)((UINT64)(MemBase) >> 32));
-
-    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_NORMAL_MODE);
-
-    {
-      UINTN i;
-      for (i=0; i<0x20; i+=4) {
-        DEBUG ((EFI_D_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
-      }
-    }
-}
-
-VOID InitAtu (PCI_ROOT_BRIDGE_INSTANCE *Private)
-{
-  SetAtuMemRW (Private->RbPciBar, Private->PciRegionBase, Private->PciRegionLimit, Private->CpuMemRegionBase, 0);
-  SetAtuConfig0RW (Private, 1);
-  SetAtuConfig1RW (Private, 2);
-  SetAtuIoRW (Private->RbPciBar, Private->IoBase, Private->IoLimit, Private->CpuIoRegionBase, 3);
-}
-
-
 BOOLEAN PcieIsLinkUp (UINT32 SocType, UINTN RbPciBar, UINTN Port)
 {
     UINT32                     Value = 0;
@@ -860,7 +755,6 @@ RootBridgeConstructor (
 
   Protocol->SegmentNumber  = Seg;
 
-  InitAtu (PrivateData);
 
   Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)&mMetronome);
   if (EFI_ERROR(Status))
diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c
index 5fc0ead5c1d5..de297e67e2e1 100644
--- a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c
+++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c
@@ -17,6 +17,7 @@
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/PcdLib.h>
 #include <Library/OemMiscLib.h>
+#include <Library/PciExpressLib.h>
 #include <Library/PlatformPciLib.h>
 
 
@@ -154,6 +155,8 @@ PcieInitEntry (
                 DEBUG((EFI_D_ERROR, "HostBridge %d, Pcie Port %d Init Failed! \n", HostBridgeNum, Port));
             }
 
+            InitAtu (&mResAppeture[HostBridgeNum][Port]);
+
         }
     }
 
diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
new file mode 100644
index 000000000000..9eb3451f7402
--- /dev/null
+++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
@@ -0,0 +1,141 @@
+/** @file
+*
+*  Copyright (c) 2018, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2018, Linaro Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/OemMiscLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciExpressLib.h>
+#include <Library/PlatformPciLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include "PcieInit.h"
+
+STATIC
+UINT64
+GetPcieCfgAddress (
+    UINT64 Ecam,
+    UINTN Bus,
+    UINTN Device,
+    UINTN Function,
+    UINTN Reg
+    )
+{
+  return Ecam + PCI_EXPRESS_LIB_ADDRESS (Bus, Device, Function, Reg);
+}
+
+STATIC
+VOID
+SetAtuConfig0RW (
+    PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private,
+    UINT32 Index
+    )
+{
+  UINTN RbPciBase = Private->RbPciBar;
+  UINT64 MemLimit = GetPcieCfgAddress (Private->Ecam, Private->BusBase + 1, 1, 0, 0) - 1;
+
+
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(Private->Ecam));
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(Private->Ecam) >> 32));
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, 0);
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, 0);
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_CONFIG0);
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_SHIIF_MODE);
+
+  {
+    UINTN i;
+    for (i=0; i<0x20; i+=4) {
+      DEBUG ((DEBUG_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
+    }
+  }
+}
+
+void SetAtuConfig1RW (
+    PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private,
+    UINT32 Index
+    )
+{
+  UINTN RbPciBase = Private->RbPciBar;
+  UINT64 MemLimit = GetPcieCfgAddress (Private->Ecam, Private->BusLimit + 1, 0, 0, 0) - 1;
+
+
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_CONFIG1);
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(Private->Ecam));
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(Private->Ecam) >> 32));
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, 0);
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, 0);
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_SHIIF_MODE);
+
+  {
+    UINTN i;
+    for (i=0; i<0x20; i+=4) {
+      DEBUG ((DEBUG_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
+    }
+  }
+}
+
+void SetAtuIoRW(UINT64 RbPciBase,UINT64 IoBase,UINT64 CpuIoRegionLimit, UINT64 CpuIoRegionBase, UINT32 Index)
+{
+
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_IO);
+
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(CpuIoRegionBase));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)CpuIoRegionBase >> 32));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32)(CpuIoRegionLimit));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, (UINT32)(IoBase));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, (UINT32)((UINT64)(IoBase) >> 32));
+
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_NORMAL_MODE);
+
+    {
+      UINTN i;
+      for (i=0; i<0x20; i+=4) {
+        DEBUG ((DEBUG_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
+      }
+    }
+}
+
+void SetAtuMemRW(UINT64 RbPciBase,UINT64 MemBase,UINT64 CpuMemRegionLimit, UINT64 CpuMemRegionBase, UINT32 Index)
+{
+
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_MEM);
+
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(CpuMemRegionBase));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(CpuMemRegionBase) >> 32));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32)(CpuMemRegionLimit));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, (UINT32)(MemBase));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, (UINT32)((UINT64)(MemBase) >> 32));
+
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_NORMAL_MODE);
+
+    {
+      UINTN i;
+      for (i=0; i<0x20; i+=4) {
+        DEBUG ((DEBUG_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
+      }
+    }
+}
+
+VOID InitAtu (PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private)
+{
+  SetAtuMemRW (Private->RbPciBar, Private->PciRegionBase, Private->PciRegionLimit, Private->CpuMemRegionBase, 0);
+  SetAtuConfig0RW (Private, 1);
+  SetAtuConfig1RW (Private, 2);
+  SetAtuIoRW (Private->RbPciBar, Private->IoBase, Private->IoLimit, Private->CpuIoRegionBase, 3);
+}
+
-- 
2.7.4



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

* [PATCH edk2-platforms 04/12] Hisilicon/Pci: Merge PciPlatform into PcieInit Driver
  2018-03-21  1:03 [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Heyi Guo
                   ` (2 preceding siblings ...)
  2018-03-21  1:03 ` [PATCH edk2-platforms 03/12] Hisilicon/Pci: move ATU configuration to PcieInitDxe Heyi Guo
@ 2018-03-21  1:03 ` Heyi Guo
  2018-03-21  1:03 ` [PATCH edk2-platforms 05/12] Hisilicon/Pci: Move EnlargeAtuConfig0() to PcieInitDxe Heyi Guo
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Heyi Guo @ 2018-03-21  1:03 UTC (permalink / raw)
  To: edk2-devel; +Cc: Heyi Guo, Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This is to prepare for switching to generic PciHostBridge driver, so
we move all platform specific code to platform specific drivers, not
in PciHostBridge driver.

This patch is to prepare moving EnlargeAtuConfig0() out of
PciHostBridge. Since the function was originally called in
NotifyPhase() of phase EfiPciHostBridgeEndEnumeration, so we propose
to move it to EFI_PCI_PLATFORM_PROTOCOL->PlatformNotify(). To reduce
redundant ATU definitions, we merge PciPlatform into PcieInitDxe
driver since ATU initialization is done in PcieInitDxe.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Platform/Hisilicon/D03/D03.dsc                                                                              |  1 -
 Platform/Hisilicon/D05/D05.dsc                                                                              |  1 -
 Platform/Hisilicon/D03/D03.fdf                                                                              |  1 -
 Platform/Hisilicon/D05/D05.fdf                                                                              |  1 -
 Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf                                                  | 53 --------------------
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf                                               |  5 ++
 {Platform/Hisilicon/D03/Drivers/PciPlatform => Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610}/PciPlatform.h |  0
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h                                                 |  6 +++
 {Platform/Hisilicon/D03/Drivers/PciPlatform => Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610}/PciPlatform.c | 12 +++++
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c                                                    |  4 +-
 10 files changed, 24 insertions(+), 60 deletions(-)

diff --git a/Platform/Hisilicon/D03/D03.dsc b/Platform/Hisilicon/D03/D03.dsc
index c4963063794b..0b2bd29cdf83 100644
--- a/Platform/Hisilicon/D03/D03.dsc
+++ b/Platform/Hisilicon/D03/D03.dsc
@@ -457,7 +457,6 @@ [Components.common]
     <LibraryClasses>
       NULL|Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.inf
   }
-  Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf
   Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf {
     <LibraryClasses>
       DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf
diff --git a/Platform/Hisilicon/D05/D05.dsc b/Platform/Hisilicon/D05/D05.dsc
index 0792b0814ea1..2150a6f4c0e9 100644
--- a/Platform/Hisilicon/D05/D05.dsc
+++ b/Platform/Hisilicon/D05/D05.dsc
@@ -611,7 +611,6 @@ [Components.common]
     <LibraryClasses>
       NULL|Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.inf
   }
-  Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf
   Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf {
     <LibraryClasses>
       DmaLib|EmbeddedPkg/Library/CoherentDmaLib/CoherentDmaLib.inf
diff --git a/Platform/Hisilicon/D03/D03.fdf b/Platform/Hisilicon/D03/D03.fdf
index 09613fb8f6ea..e430d5c08982 100644
--- a/Platform/Hisilicon/D03/D03.fdf
+++ b/Platform/Hisilicon/D03/D03.fdf
@@ -263,7 +263,6 @@ [FV.FvMain]
   # PCI Support
   #
   INF Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
-  INF Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf
   INF Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
   INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
 
diff --git a/Platform/Hisilicon/D05/D05.fdf b/Platform/Hisilicon/D05/D05.fdf
index 17a43d8edbd0..13a60837a607 100644
--- a/Platform/Hisilicon/D05/D05.fdf
+++ b/Platform/Hisilicon/D05/D05.fdf
@@ -285,7 +285,6 @@ [FV.FvMain]
   # PCI Support
   #
   INF Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
-  INF Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf
   INF Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
   INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
 
diff --git a/Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf b/Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf
deleted file mode 100644
index 8b170d265485..000000000000
--- a/Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf
+++ /dev/null
@@ -1,53 +0,0 @@
-#/** @file
-#
-#    Copyright (c) 2016, Hisilicon Limited. All rights reserved.
-#    Copyright (c) 2016, Linaro Limited. All rights reserved.
-#
-#    This program and the accompanying materials
-#    are licensed and made available under the terms and conditions of the BSD License
-#    which accompanies this distribution. The full text of the license may be found at
-#    http://opensource.org/licenses/bsd-license.php
-#
-#    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-#    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-#**/
-
-[defines]
-  INF_VERSION          = 0x00010005
-  BASE_NAME            = PciPlatform
-  FILE_GUID            = E2441B64-7EF4-41fe-B3A3-8CAA7F8D3017
-  MODULE_TYPE          = DXE_DRIVER
-  VERSION_STRING       = 1.0
-  ENTRY_POINT          = PciPlatformDriverEntry
-
-[sources.common]
-  PciPlatform.c
-
-[Packages]
-  MdePkg/MdePkg.dec
-  MdeModulePkg/MdeModulePkg.dec
-  ArmPkg/ArmPkg.dec
-  Silicon/Hisilicon/HisiPkg.dec
-
-[LibraryClasses]
-  UefiDriverEntryPoint
-  UefiLib
-  BaseLib
-  DebugLib
-  ArmLib
-  IoLib
-  MemoryAllocationLib
-
-[Protocols]
-  gEfiPciPlatformProtocolGuid
-  gEfiFirmwareVolume2ProtocolGuid
-  gEfiPciIoProtocolGuid
-
-[Pcd]
-
-[FixedPcd]
-
-[Depex]
-  TRUE
-
diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
index cb0a63f9a84e..94d0fc8c028b 100644
--- a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
+++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
@@ -26,6 +26,7 @@ [Sources]
   PcieInit.c
   PcieInitLib.c
   PcieInitAtu.c
+  PciPlatform.c
 
 [Packages]
   MdePkg/MdePkg.dec
@@ -40,6 +41,7 @@ [LibraryClasses]
   BaseLib
   DebugLib
   ArmLib
+  MemoryAllocationLib
   TimerLib
   PcdLib
   IoLib
@@ -47,6 +49,9 @@ [LibraryClasses]
 
 [Protocols]
   #gEfiPcieRootBridgeProtocolGuid
+  gEfiFirmwareVolume2ProtocolGuid
+  gEfiPciIoProtocolGuid
+  gEfiPciPlatformProtocolGuid
 
 [Pcd]
   gHisiTokenSpaceGuid.PcdPcieRootBridgeMask
diff --git a/Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.h b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PciPlatform.h
similarity index 100%
rename from Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.h
rename to Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PciPlatform.h
diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h
index 87700ae8b9aa..ab0c7ab8bfa7 100644
--- a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h
+++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h
@@ -248,4 +248,10 @@ EFI_STATUS PcieSetDBICS2Enable(UINT32 HostBridgeNum, UINT32 Port, UINT32 Enable)
 
 VOID InitAtu (PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private);
 
+EFI_STATUS
+PciPlatformDriverEntry (
+  IN EFI_HANDLE                         ImageHandle,
+  IN EFI_SYSTEM_TABLE                   *SystemTable
+  );
+
 #endif
diff --git a/Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.c b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PciPlatform.c
similarity index 93%
rename from Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.c
rename to Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PciPlatform.c
index 8bfac2d99fc4..35faa9caf022 100644
--- a/Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.c
+++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PciPlatform.c
@@ -25,6 +25,7 @@
 #include <Library/BaseMemoryLib.h>
 #include <Library/UefiDriverEntryPoint.h>
 #include <Library/MemoryAllocationLib.h>
+#include "PcieInitLib.h"
 
 //
 // Global variables for Option ROMs
@@ -387,6 +388,17 @@ Returns:
 
 --*/
 {
+  switch (Phase) {
+  case EfiPciHostBridgeEndEnumeration:
+    // Only do once
+    if (ChipsetPhase == ChipsetEntry) {
+      DEBUG ((DEBUG_INFO, "PCI end enumeration platform hook\n"));
+      EnlargeAtuConfig0 (HostBridge);
+    }
+    break;
+  default:
+    break;
+  }
 
   return EFI_SUCCESS;
 }
diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c
index de297e67e2e1..6ee0cf845dee 100644
--- a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c
+++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c
@@ -160,9 +160,7 @@ PcieInitEntry (
         }
     }
 
-
-    return EFI_SUCCESS;
-
+    return PciPlatformDriverEntry (ImageHandle, SystemTable);
 }
 
 
-- 
2.7.4



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

* [PATCH edk2-platforms 05/12] Hisilicon/Pci: Move EnlargeAtuConfig0() to PcieInitDxe
  2018-03-21  1:03 [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Heyi Guo
                   ` (3 preceding siblings ...)
  2018-03-21  1:03 ` [PATCH edk2-platforms 04/12] Hisilicon/Pci: Merge PciPlatform into PcieInit Driver Heyi Guo
@ 2018-03-21  1:03 ` Heyi Guo
  2018-03-21  1:03 ` [PATCH edk2-platforms 06/12] Hisilicon/PlatformPciLib: add segment for each root bridge Heyi Guo
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Heyi Guo @ 2018-03-21  1:03 UTC (permalink / raw)
  To: edk2-devel; +Cc: Heyi Guo, Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This is to prepare for switching to generic PciHostBridge driver, so
we move all platform specific code to platform specific drivers, not
in PciHostBridge driver.

This patch is to move EnlargeAtuConfig0() into PcieInitDxe, in
PlatformNotify() of EFI_PCI_PLATFORM_PROTOCOL.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf |   3 +-
 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h    |   8 -
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h   |   5 +
 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c    |   1 -
 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c  |  78 ---------
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c   | 176 +++++++++++++++++++-
 6 files changed, 179 insertions(+), 92 deletions(-)

diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
index 94d0fc8c028b..d1efdf39131a 100644
--- a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
+++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
@@ -48,10 +48,11 @@ [LibraryClasses]
   OemMiscLib
 
 [Protocols]
-  #gEfiPcieRootBridgeProtocolGuid
   gEfiFirmwareVolume2ProtocolGuid
+  gEfiPciHostBridgeResourceAllocationProtocolGuid
   gEfiPciIoProtocolGuid
   gEfiPciPlatformProtocolGuid
+  gEfiPciRootBridgeIoProtocolGuid
 
 [Pcd]
   gHisiTokenSpaceGuid.PcdPcieRootBridgeMask
diff --git a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h b/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h
index c04361fceee6..435385491a17 100644
--- a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h
+++ b/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h
@@ -401,10 +401,6 @@ PreprocessController (
 #define EFI_RESOURCE_NONEXISTENT   0xFFFFFFFFFFFFFFFFULL
 #define EFI_RESOURCE_LESS          0xFFFFFFFFFFFFFFFEULL
 
-#define	INVALID_CAPABILITY_00       0x00
-#define	INVALID_CAPABILITY_FF       0xFF
-#define	PCI_CAPABILITY_POINTER_MASK 0xFC
-
 //
 // Driver Instance Data Prototypes
 //
@@ -521,8 +517,4 @@ RootBridgeConstructor (
   IN UINT32                             Seg
   );
 
-VOID
-EnlargeAtuConfig0 (
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This
-  );
 #endif
diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h
index ab0c7ab8bfa7..ead926b4c4f3 100644
--- a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h
+++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h
@@ -248,6 +248,11 @@ EFI_STATUS PcieSetDBICS2Enable(UINT32 HostBridgeNum, UINT32 Port, UINT32 Enable)
 
 VOID InitAtu (PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private);
 
+VOID
+EnlargeAtuConfig0 (
+  IN EFI_HANDLE HostBridge
+  );
+
 EFI_STATUS
 PciPlatformDriverEntry (
   IN EFI_HANDLE                         ImageHandle,
diff --git a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c b/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c
index 9fa3f8409813..e3d3988a64c1 100644
--- a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c
+++ b/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c
@@ -839,7 +839,6 @@ NotifyPhase(
 
   case EfiPciHostBridgeEndEnumeration:
     PCIE_DEBUG("Case EfiPciHostBridgeEndEnumeration\n");
-    EnlargeAtuConfig0 (This);
     break;
 
   case EfiPciHostBridgeBeginBusAllocation:
diff --git a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c b/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
index 273a322ee48f..3c265ea43378 100644
--- a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
+++ b/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
@@ -2218,81 +2218,3 @@ RootBridgeIoConfiguration (
   return EFI_SUCCESS;
 }
 
-BOOLEAN
-PcieCheckAriFwdEn (
-  UINTN  PciBaseAddr
-  )
-{
-  UINT8   PciPrimaryStatus;
-  UINT8   CapabilityOffset;
-  UINT8   CapId;
-  UINT8   TempData;
-
-  PciPrimaryStatus = MmioRead16 (PciBaseAddr + PCI_PRIMARY_STATUS_OFFSET);
-
-  if (PciPrimaryStatus & EFI_PCI_STATUS_CAPABILITY) {
-    CapabilityOffset = MmioRead8 (PciBaseAddr + PCI_CAPBILITY_POINTER_OFFSET);
-    CapabilityOffset &= PCI_CAPABILITY_POINTER_MASK;
-
-    while ((CapabilityOffset != INVALID_CAPABILITY_00) && (CapabilityOffset != INVALID_CAPABILITY_FF)) {
-      CapId = MmioRead8 (PciBaseAddr + CapabilityOffset);
-      if (CapId == EFI_PCI_CAPABILITY_ID_PCIEXP) {
-        break;
-      }
-      CapabilityOffset = MmioRead8 (PciBaseAddr + CapabilityOffset + 1);
-      CapabilityOffset &= PCI_CAPABILITY_POINTER_MASK;
-    }
-  } else {
-    PCIE_DEBUG ("[%a:%d] - No PCIE Capability.\n", __FUNCTION__, __LINE__);
-    return FALSE;
-  }
-
-  if ((CapabilityOffset == INVALID_CAPABILITY_FF) || (CapabilityOffset == INVALID_CAPABILITY_00)) {
-    PCIE_DEBUG ("[%a:%d] - No PCIE Capability.\n", __FUNCTION__, __LINE__);
-    return FALSE;
-  }
-
-  TempData = MmioRead16 (PciBaseAddr + CapabilityOffset +
-                          EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET);
-  TempData &= EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING;
-
-  if (TempData == EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING) {
-    return TRUE;
-  } else {
-    return FALSE;
-  }
-}
-
-VOID
-EnlargeAtuConfig0 (
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This
-  )
-{
-  UINTN                           RbPciBase;
-  UINT64                          MemLimit;
-  LIST_ENTRY                      *List;
-  PCI_HOST_BRIDGE_INSTANCE        *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE        *RootBridgeInstance;
-
-  PCIE_DEBUG ("In Enlarge RP iatu Config 0.\n");
-
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  while (List != &HostBridgeInstance->Head) {
-    PCIE_DEBUG ("HostBridge has data.\n");
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-
-    RbPciBase = RootBridgeInstance->RbPciBar;
-
-    // Those ARI FWD Enable Root Bridge, need enlarge iatu window.
-    if (PcieCheckAriFwdEn (RbPciBase)) {
-      MemLimit = GetPcieCfgAddress (RootBridgeInstance->Ecam,
-                                    RootBridgeInstance->BusBase + 2, 0, 0, 0)
-	               - 1;
-      MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, 1);
-      MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
-    }
-    List = List->ForwardLink;
-  }
-}
diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
index 9eb3451f7402..f2365b5f3e49 100644
--- a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
+++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
@@ -13,13 +13,20 @@
 *
 **/
 
+#include <IndustryStandard/Acpi.h>
 #include <Library/OemMiscLib.h>
 #include <Library/PcdLib.h>
 #include <Library/PciExpressLib.h>
 #include <Library/PlatformPciLib.h>
 #include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
 #include "PcieInit.h"
 
+#define INVALID_CAPABILITY_00       0x00
+#define INVALID_CAPABILITY_FF       0xFF
+#define PCI_CAPABILITY_POINTER_MASK 0xFC
+
 STATIC
 UINT64
 GetPcieCfgAddress (
@@ -34,6 +41,53 @@ GetPcieCfgAddress (
 }
 
 STATIC
+PCI_ROOT_BRIDGE_RESOURCE_APPETURE *
+GetAppetureByRootBridgeIo (
+    IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *RootBridge
+    )
+{
+  EFI_STATUS Status;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration = NULL;
+  UINTN Hb;
+  UINTN Rb;
+
+  Status = RootBridge->Configuration (
+      RootBridge,
+      (VOID **)&Configuration
+      );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[%a:%d] RootBridgeIo->Configuration failed %r\n",
+          __FUNCTION__, __LINE__, Status));
+    return NULL;
+  };
+
+  while (Configuration->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+    if (Configuration->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {
+      break;
+    }
+    Configuration++;
+  }
+
+  if (Configuration->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+    DEBUG ((DEBUG_ERROR, "[%a:%d] Can't find bus descriptor\n", __FUNCTION__, __LINE__));
+    return NULL;
+  }
+
+  for (Hb = 0; Hb < PCIE_MAX_HOSTBRIDGE; Hb++) {
+    for (Rb = 0; Rb < PCIE_MAX_ROOTBRIDGE; Rb++) {
+      if (RootBridge->SegmentNumber == mResAppeture[Hb][Rb].Segment &&
+          Configuration->AddrRangeMin >= mResAppeture[Hb][Rb].BusBase &&
+          Configuration->AddrRangeMax <= mResAppeture[Hb][Rb].BusLimit) {
+        return &mResAppeture[Hb][Rb];
+      }
+    }
+  }
+
+  DEBUG ((DEBUG_ERROR, "[%a:%d] Can't find PCI appeture\n", __FUNCTION__, __LINE__));
+  return NULL;
+}
+
+STATIC
 VOID
 SetAtuConfig0RW (
     PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private,
@@ -61,7 +115,9 @@ SetAtuConfig0RW (
   }
 }
 
-void SetAtuConfig1RW (
+STATIC
+VOID
+SetAtuConfig1RW (
     PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private,
     UINT32 Index
     )
@@ -87,7 +143,9 @@ void SetAtuConfig1RW (
   }
 }
 
-void SetAtuIoRW(UINT64 RbPciBase,UINT64 IoBase,UINT64 CpuIoRegionLimit, UINT64 CpuIoRegionBase, UINT32 Index)
+STATIC
+VOID
+SetAtuIoRW (UINT64 RbPciBase,UINT64 IoBase,UINT64 CpuIoRegionLimit, UINT64 CpuIoRegionBase, UINT32 Index)
 {
 
     MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
@@ -109,7 +167,9 @@ void SetAtuIoRW(UINT64 RbPciBase,UINT64 IoBase,UINT64 CpuIoRegionLimit, UINT64 C
     }
 }
 
-void SetAtuMemRW(UINT64 RbPciBase,UINT64 MemBase,UINT64 CpuMemRegionLimit, UINT64 CpuMemRegionBase, UINT32 Index)
+STATIC
+VOID
+SetAtuMemRW(UINT64 RbPciBase,UINT64 MemBase,UINT64 CpuMemRegionLimit, UINT64 CpuMemRegionBase, UINT32 Index)
 {
 
     MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
@@ -131,7 +191,8 @@ void SetAtuMemRW(UINT64 RbPciBase,UINT64 MemBase,UINT64 CpuMemRegionLimit, UINT6
     }
 }
 
-VOID InitAtu (PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private)
+VOID
+InitAtu (PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private)
 {
   SetAtuMemRW (Private->RbPciBar, Private->PciRegionBase, Private->PciRegionLimit, Private->CpuMemRegionBase, 0);
   SetAtuConfig0RW (Private, 1);
@@ -139,3 +200,110 @@ VOID InitAtu (PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private)
   SetAtuIoRW (Private->RbPciBar, Private->IoBase, Private->IoLimit, Private->CpuIoRegionBase, 3);
 }
 
+STATIC
+BOOLEAN
+PcieCheckAriFwdEn (
+  UINTN  PciBaseAddr
+  )
+{
+  UINT8   PciPrimaryStatus;
+  UINT8   CapabilityOffset;
+  UINT8   CapId;
+  UINT8   TempData;
+
+  PciPrimaryStatus = MmioRead16 (PciBaseAddr + PCI_PRIMARY_STATUS_OFFSET);
+
+  if (PciPrimaryStatus & EFI_PCI_STATUS_CAPABILITY) {
+    CapabilityOffset = MmioRead8 (PciBaseAddr + PCI_CAPBILITY_POINTER_OFFSET);
+    CapabilityOffset &= PCI_CAPABILITY_POINTER_MASK;
+
+    while ((CapabilityOffset != INVALID_CAPABILITY_00) && (CapabilityOffset != INVALID_CAPABILITY_FF)) {
+      CapId = MmioRead8 (PciBaseAddr + CapabilityOffset);
+      if (CapId == EFI_PCI_CAPABILITY_ID_PCIEXP) {
+        break;
+      }
+      CapabilityOffset = MmioRead8 (PciBaseAddr + CapabilityOffset + 1);
+      CapabilityOffset &= PCI_CAPABILITY_POINTER_MASK;
+    }
+  } else {
+    return FALSE;
+  }
+
+  if ((CapabilityOffset == INVALID_CAPABILITY_FF) || (CapabilityOffset == INVALID_CAPABILITY_00)) {
+    return FALSE;
+  }
+
+  TempData = MmioRead16 (PciBaseAddr + CapabilityOffset +
+                          EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET);
+  TempData &= EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING;
+
+  if (TempData == EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+VOID
+EnlargeAtuConfig0 (
+  IN EFI_HANDLE HostBridge
+  )
+{
+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL    *ResAlloc = NULL;
+  EFI_STATUS                                          Status;
+  EFI_HANDLE RootBridgeHandle = NULL;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo = NULL;
+  PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Appeture;
+  UINTN                           RbPciBase;
+  UINT64                          MemLimit;
+
+  DEBUG ((DEBUG_INFO, "In Enlarge RP iATU Config 0.\n"));
+
+  Status = gBS->HandleProtocol (
+      HostBridge,
+      &gEfiPciHostBridgeResourceAllocationProtocolGuid,
+      (VOID **)&ResAlloc
+      );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[%a:%d] - HandleProtocol failed %r\n", __FUNCTION__,
+          __LINE__, Status));
+    return;
+  }
+
+  while (TRUE) {
+    Status = ResAlloc->GetNextRootBridge (
+        ResAlloc,
+        &RootBridgeHandle
+        );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+    Status = gBS->HandleProtocol (
+        RootBridgeHandle,
+        &gEfiPciRootBridgeIoProtocolGuid,
+        (VOID **)&RootBridgeIo
+        );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "[%a:%d] - HandleProtocol failed %r\n", __FUNCTION__, __LINE__, Status));
+      // This should never happen so that it is a fatal error and we don't try
+      // to continue
+      break;
+    }
+
+    Appeture = GetAppetureByRootBridgeIo (RootBridgeIo);
+    if (Appeture == NULL) {
+      DEBUG ((DEBUG_ERROR, "[%a:%d] Get appeture failed\n", __FUNCTION__,
+            __LINE__));
+      continue;
+    }
+
+    RbPciBase = Appeture->RbPciBar;
+    // Those ARI FWD Enable Root Bridge, need enlarge iATU window.
+    if (PcieCheckAriFwdEn (RbPciBase)) {
+      MemLimit = GetPcieCfgAddress (Appeture->Ecam, Appeture->BusBase + 2, 0, 0, 0) - 1;
+      MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, 1);
+      MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
+    }
+  }
+}
+
-- 
2.7.4



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

* [PATCH edk2-platforms 06/12] Hisilicon/PlatformPciLib: add segment for each root bridge
  2018-03-21  1:03 [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Heyi Guo
                   ` (4 preceding siblings ...)
  2018-03-21  1:03 ` [PATCH edk2-platforms 05/12] Hisilicon/Pci: Move EnlargeAtuConfig0() to PcieInitDxe Heyi Guo
@ 2018-03-21  1:03 ` Heyi Guo
  2018-03-21  1:03 ` [PATCH edk2-platforms 07/12] Hisilicon: add PciHostBridgeLib Heyi Guo
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Heyi Guo @ 2018-03-21  1:03 UTC (permalink / raw)
  To: edk2-devel; +Cc: Heyi Guo

This is to prepare for switching to generic PciHostBridge driver. We
are going to create a PciHostBridgeLib instance for D0x and fetch
PCI root bridge informance from PlatformPciLib, so we add Segment to
PCI_ROOT_BRIDGE_RESOURCE_APPETURE along with other PCI resource
information. Segment numbers are kept the same as ACPI MCFG.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
---
 Silicon/Hisilicon/Include/Library/PlatformPciLib.h             |  1 +
 Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.c |  8 ++++++++
 Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c | 16 ++++++++++++++++
 3 files changed, 25 insertions(+)

diff --git a/Silicon/Hisilicon/Include/Library/PlatformPciLib.h b/Silicon/Hisilicon/Include/Library/PlatformPciLib.h
index 9d28fec37546..6725a547d54f 100644
--- a/Silicon/Hisilicon/Include/Library/PlatformPciLib.h
+++ b/Silicon/Hisilicon/Include/Library/PlatformPciLib.h
@@ -190,6 +190,7 @@ extern UINT64 PCIE_ITS_1610[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE];
 
 
 typedef struct {
+  UINT32          Segment;
   UINT64          Ecam;
   UINT64          BusBase;
   UINT64          BusLimit;
diff --git a/Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.c b/Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.c
index c58118fe5e7a..3a770d17bb3d 100644
--- a/Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.c
+++ b/Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.c
@@ -28,6 +28,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
  {// HostBridge 0
   /* Port 0 */
   {
+      0,                    //Segment
       PCI_HB0RB0_ECAM_BASE, //ecam
       0,  //BusBase
       31, //BusLimit
@@ -44,6 +45,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
   },
   /* Port 1 */
   {
+      1,                    //Segment
       PCI_HB0RB1_ECAM_BASE,//ecam
       224,  //BusBase
       254, //BusLimit
@@ -59,6 +61,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
   },
   /* Port 2 */
   {
+      2,                    //Segment
       PCI_HB0RB2_ECAM_BASE,
       128,  //BusBase
       159, //BusLimit
@@ -75,6 +78,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
 
   /* Port 3 */
   {
+      3,                    //Segment
       PCI_HB0RB3_ECAM_BASE,
       96,  //BusBase
       127, //BusLimit
@@ -92,6 +96,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
 {// HostBridge 1
   /* Port 0 */
   {
+      4,                    //Segment
       PCI_HB1RB0_ECAM_BASE,
       128,  //BusBase
       159, //BusLimit
@@ -107,6 +112,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
   },
   /* Port 1 */
   {
+      5,                    //Segment
       PCI_HB1RB1_ECAM_BASE,
       160,  //BusBase
       191, //BusLimit
@@ -122,6 +128,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
   },
   /* Port 2 */
   {
+      6,                    //Segment
       PCI_HB1RB2_ECAM_BASE,
       192,  //BusBase
       223, //BusLimit
@@ -138,6 +145,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
 
   /* Port 3 */
   {
+      7,                    //Segment
       PCI_HB1RB3_ECAM_BASE,
       224,  //BusBase
       255, //BusLimit
diff --git a/Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c b/Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c
index c8e20356f818..c511a0ecbb52 100644
--- a/Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c
+++ b/Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c
@@ -29,6 +29,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
  {// HostBridge 0
   /* Port 0 */
   {
+      0,                    //Segment
       PCI_HB0RB0_ECAM_BASE, //ecam
       0x80,  //BusBase
       0x87, //BusLimit
@@ -44,6 +45,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
   },
   /* Port 1 */
   {
+      1,                   //Segment
       PCI_HB0RB1_ECAM_BASE,//ecam
       0x90,  //BusBase
       0x97, //BusLimit
@@ -59,6 +61,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
   },
   /* Port 2 */
   {
+      2,                   //Segment
       PCI_HB0RB2_ECAM_BASE,
       0x80,  //BusBase
       0x87, //BusLimit
@@ -75,6 +78,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
 
   /* Port 3 */
   {
+      3,                   //Segment
       PCI_HB0RB3_ECAM_BASE,
       0xb0,  //BusBase
       0xb7, //BusLimit
@@ -90,6 +94,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
   },
   /* Port 4 */
   {
+      4,                   //Segment
       PCI_HB0RB4_ECAM_BASE, //ecam
       0x88,  //BusBase
       0x8f, //BusLimit
@@ -105,6 +110,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
   },
   /* Port 5 */
   {
+      5,                   //Segment
       PCI_HB0RB5_ECAM_BASE,//ecam
       0x0,  //BusBase
       0x7, //BusLimit
@@ -120,6 +126,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
   },
   /* Port 6 */
   {
+      6,                   //Segment
       PCI_HB0RB6_ECAM_BASE,
       0xC0,  //BusBase
       0xC7, //BusLimit
@@ -136,6 +143,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
 
   /* Port 7 */
   {
+      7,                   //Segment
       PCI_HB0RB7_ECAM_BASE,
       0x90,  //BusBase
       0x97, //BusLimit
@@ -153,6 +161,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
 {// HostBridge 1
   /* Port 0 */
   {
+      8,                   //Segment
       PCI_HB1RB0_ECAM_BASE,
       0x80,  //BusBase
       0x87, //BusLimit
@@ -168,6 +177,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
   },
   /* Port 1 */
   {
+      9,                   //Segment
       PCI_HB1RB1_ECAM_BASE,
       0x90,  //BusBase
       0x97, //BusLimit
@@ -183,6 +193,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
   },
   /* Port 2 */
   {
+      0xa,                  //Segment
       PCI_HB1RB2_ECAM_BASE,
       0x10,  //BusBase
       0x1f, //BusLimit
@@ -199,6 +210,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
 
   /* Port 3 */
   {
+      0xb,                  //Segment
       PCI_HB1RB3_ECAM_BASE,
       0xb0,  //BusBase
       0xb7, //BusLimit
@@ -214,6 +226,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
   },
   /* Port 4 */
   {
+      0xc,                  //Segment
       PCI_HB1RB4_ECAM_BASE,
       0x20,  //BusBase
       0x2f, //BusLimit
@@ -229,6 +242,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
   },
   /* Port 5 */
   {
+      0xd,                  //Segment
       PCI_HB1RB5_ECAM_BASE,
       0x30,  //BusBase
       0x3f, //BusLimit
@@ -244,6 +258,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
   },
   /* Port 6 */
   {
+      0xe,                  //Segment
       PCI_HB1RB6_ECAM_BASE,
       0xa8,  //BusBase
       0xaf, //BusLimit
@@ -260,6 +275,7 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
 
   /* Port 7 */
   {
+      0xf,                  //Segment
       PCI_HB1RB7_ECAM_BASE,
       0xb8,  //BusBase
       0xbf, //BusLimit
-- 
2.7.4



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

* [PATCH edk2-platforms 07/12] Hisilicon: add PciHostBridgeLib
  2018-03-21  1:03 [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Heyi Guo
                   ` (5 preceding siblings ...)
  2018-03-21  1:03 ` [PATCH edk2-platforms 06/12] Hisilicon/PlatformPciLib: add segment for each root bridge Heyi Guo
@ 2018-03-21  1:03 ` Heyi Guo
  2018-03-30 15:28   ` Ard Biesheuvel
  2018-03-21  1:03 ` [PATCH edk2-platforms 08/12] Hisilicon: add PciCpuIo2Dxe Heyi Guo
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Heyi Guo @ 2018-03-21  1:03 UTC (permalink / raw)
  To: edk2-devel; +Cc: Heyi Guo, Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This is to prepare for switching to generic PciHostBridge, and
PciHostBridgeLib is needed by PciHostBridge driver.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf |  51 ++++
 Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.c   | 304 ++++++++++++++++++++
 2 files changed, 355 insertions(+)

diff --git a/Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf
new file mode 100644
index 000000000000..dd451cff332c
--- /dev/null
+++ b/Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -0,0 +1,51 @@
+## @file
+#  PCI Host Bridge Library instance for Hisilicon D0x
+#
+#  Copyright (c) 2018, Hisilicon Limited. All rights reserved.<BR>
+#  Copyright (c) 2017 - 2018, Linaro Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials are licensed and made available
+#  under the terms and conditions of the BSD License which accompanies this
+#  distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+#  IMPLIED.
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001000A
+  BASE_NAME                      = PciHostBridgeLib
+  FILE_GUID                      = e5c91e8a-0b2b-11e8-9533-286ed489ee9b
+  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 ARM
+#
+
+[Sources]
+  PciHostBridgeLib.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  MemoryAllocationLib
+  OemMiscLib
+
+[Pcd]
+  gHisiTokenSpaceGuid.PcdPcieRootBridgeMask
+  gHisiTokenSpaceGuid.PcdPcieRootBridgeMask2P
diff --git a/Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.c
new file mode 100644
index 000000000000..6aff5cdd3d76
--- /dev/null
+++ b/Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -0,0 +1,304 @@
+/** @file
+  PCI Host Bridge Library instance for Hisilicon D0x
+
+  Copyright (c) 2018, Hisilicon Limited. All rights reserved.<BR>
+  Copyright (c) 2017 - 2018, Linaro Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <PiDxe.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/OemMiscLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/PlatformPciLib.h>
+
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+
+#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 = {
+  {
+    {
+      ACPI_DEVICE_PATH,
+      ACPI_DP,
+      {
+        (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+        (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+      }
+    },
+    EISA_PNP_ID(0x0A03), // PCI
+    0
+  }, {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      END_DEVICE_PATH_LENGTH,
+      0
+    }
+  }
+};
+
+STATIC PCI_ROOT_BRIDGE mRootBridgeTemplate = {
+  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
+    0,
+    0
+  }, {
+    // Io
+    0,
+    0,
+    0
+  }, {
+    // Mem
+    MAX_UINT64,
+    0,
+    0
+  }, {
+    // MemAbove4G
+    MAX_UINT64,
+    0,
+    0
+  }, {
+    // PMem
+    MAX_UINT64,
+    0,
+    0
+  }, {
+    // PMemAbove4G
+    MAX_UINT64,
+    0,
+    0
+  },
+  (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath
+};
+
+STATIC
+EFI_STATUS
+ConstructRootBridge (
+    PCI_ROOT_BRIDGE                     *Bridge,
+    PCI_ROOT_BRIDGE_RESOURCE_APPETURE   *Appeture
+    )
+{
+  EFI_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;
+  CopyMem (Bridge, &mRootBridgeTemplate, sizeof *Bridge);
+  Bridge->Segment = Appeture->Segment;
+  Bridge->Bus.Base = Appeture->BusBase;
+  Bridge->Bus.Limit = Appeture->BusLimit;
+  Bridge->Io.Base = Appeture->IoBase;
+  // According to UEFI 2.7, device address = host address + translation
+  Bridge->Io.Translation = Appeture->IoBase - Appeture->CpuIoRegionBase;
+  // IoLimit is actually an address in CPU view
+  // TODO: improve the definition of PCI_ROOT_BRIDGE_RESOURCE_APPETURE
+  Bridge->Io.Limit = Appeture->IoLimit + Bridge->Io.Translation;
+  if (Appeture->PciRegionBase > MAX_UINT32) {
+    Bridge->MemAbove4G.Base = Appeture->PciRegionBase;
+    Bridge->MemAbove4G.Limit = Appeture->PciRegionLimit;
+    Bridge->MemAbove4G.Translation = Appeture->PciRegionBase - Appeture->CpuMemRegionBase;
+  } else {
+    Bridge->Mem.Base = Appeture->PciRegionBase;
+    Bridge->Mem.Limit = Appeture->PciRegionLimit;
+    Bridge->Mem.Translation = Appeture->PciRegionBase - Appeture->CpuMemRegionBase;
+  }
+
+  DevicePath = AllocateCopyPool(sizeof mEfiPciRootBridgeDevicePath, &mEfiPciRootBridgeDevicePath);
+  if (DevicePath == NULL) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] AllocatePool failed!\n", __FUNCTION__, __LINE__));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  DevicePath->AcpiDevicePath.UID = Bridge->Segment;
+  Bridge->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  EFI_STATUS                  Status;
+  UINTN                       Loop1;
+  UINTN                       Loop2;
+  UINT32                      PcieRootBridgeMask;
+  UINTN                       RootBridgeCount = 0;
+  PCI_ROOT_BRIDGE             *Bridges;
+
+  // Set default value to 0 in case we got any error.
+  *Count = 0;
+
+
+  if (!OemIsMpBoot())
+  {
+    PcieRootBridgeMask = PcdGet32(PcdPcieRootBridgeMask);
+  }
+  else
+  {
+    PcieRootBridgeMask = PcdGet32(PcdPcieRootBridgeMask2P);
+  }
+
+  for (Loop1 = 0; Loop1 < PCIE_MAX_HOSTBRIDGE; Loop1++) {
+    if (((PcieRootBridgeMask >> (PCIE_MAX_ROOTBRIDGE * Loop1)) & 0xFF ) == 0) {
+      continue;
+    }
+
+    for (Loop2 = 0; Loop2 < PCIE_MAX_ROOTBRIDGE; Loop2++) {
+      if (!(((PcieRootBridgeMask >> (PCIE_MAX_ROOTBRIDGE * Loop1)) >> Loop2 ) & 0x01)) {
+        continue;
+      }
+      RootBridgeCount++;
+    }
+  }
+
+  Bridges = AllocatePool (RootBridgeCount * sizeof *Bridges);
+  if (Bridges == NULL) {
+    DEBUG ((DEBUG_ERROR, "[%a:%d] - AllocatePool failed!\n", __FUNCTION__, __LINE__));
+    return NULL;
+  }
+
+  for (Loop1 = 0; Loop1 < PCIE_MAX_HOSTBRIDGE; Loop1++) {
+    if (((PcieRootBridgeMask >> (PCIE_MAX_ROOTBRIDGE * Loop1)) & 0xFF ) == 0) {
+      continue;
+    }
+
+    for (Loop2 = 0; Loop2 < PCIE_MAX_ROOTBRIDGE; Loop2++) {
+      if (!(((PcieRootBridgeMask >> (PCIE_MAX_ROOTBRIDGE * Loop1)) >> Loop2 ) & 0x01)) {
+        continue;
+      }
+      Status = ConstructRootBridge (&Bridges[*Count], &mResAppeture[Loop1][Loop2]);
+      if (EFI_ERROR (Status)) {
+        continue;
+      }
+      (*Count)++;
+    }
+  }
+
+  if (*Count == 0) {
+    FreePool (Bridges);
+    return NULL;
+  }
+  return Bridges;
+}
+
+/**
+  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
+  )
+{
+  UINTN Index;
+
+  for (Index = 0; Index < Count; Index++) {
+    FreePool (Bridges[Index].DevicePath);
+  }
+
+  if (Bridges != NULL) {
+    FreePool (Bridges);
+  }
+}
+
+
+#ifndef MDEPKG_NDEBUG
+STATIC CONST CHAR16 mPciHostBridgeLibAcpiAddressSpaceTypeStr[][4] = {
+  L"Mem", L"I/O", L"Bus"
+};
+#endif
+
+/**
+  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
+                   );
+  }
+}
-- 
2.7.4



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

* [PATCH edk2-platforms 08/12] Hisilicon: add PciCpuIo2Dxe
  2018-03-21  1:03 [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Heyi Guo
                   ` (6 preceding siblings ...)
  2018-03-21  1:03 ` [PATCH edk2-platforms 07/12] Hisilicon: add PciHostBridgeLib Heyi Guo
@ 2018-03-21  1:03 ` Heyi Guo
  2018-03-30 15:30   ` Ard Biesheuvel
  2018-03-21  1:03 ` [PATCH edk2-platforms 09/12] Hisilicon: add PciSegmentLib for Hi161x Heyi Guo
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Heyi Guo @ 2018-03-21  1:03 UTC (permalink / raw)
  To: edk2-devel; +Cc: Heyi Guo, Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This is to prepare for switching to generic PciHostBridge, and
CpuIo2Dxe is needed by generic PciHostBridge driver.

The driver is copied from ArmPkg/Drivers/ArmPciCpuIo2Dxe and changed
for D0x.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf |  48 ++
 Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.c   | 557 ++++++++++++++++++++
 2 files changed, 605 insertions(+)

diff --git a/Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf b/Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
new file mode 100644
index 000000000000..fbb28319ca87
--- /dev/null
+++ b/Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
@@ -0,0 +1,48 @@
+## @file
+#  Produces the CPU I/O 2 Protocol by using the services of the I/O Library.
+#
+# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2018, Linaro Ltd. All rights reserved.<BR>
+# Copyright (c) 2018, Hisilicon Ltd. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = ArmPciCpuIo2Dxe
+  FILE_GUID                      = 94577c7e-0bce-11e8-b4e8-286ed489ee9b
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = ArmPciCpuIo2Initialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = ARM AARCH64
+#
+
+[Sources]
+  ArmPciCpuIo2Dxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  BaseLib
+  DebugLib
+  IoLib
+
+[Protocols]
+  gEfiCpuIo2ProtocolGuid                         ## PRODUCES
+
+[Depex]
+  TRUE
diff --git a/Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.c b/Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.c
new file mode 100644
index 000000000000..8426c5935c8a
--- /dev/null
+++ b/Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.c
@@ -0,0 +1,557 @@
+/** @file
+  Produces the CPU I/O 2 Protocol.
+
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2016 - 2018, Linaro Ltd. All rights reserved.<BR>
+Copyright (c) 2018, Hisilicon Ltd. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiDxe.h>
+
+#include <Protocol/CpuIo2.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+// The translated IO PORT address is already a MMIO address, so we make it the
+// same as memory address for range check.
+#define MAX_IO_PORT_ADDRESS   MAX_ADDRESS
+
+//
+// Lookup table for increment values based on transfer widths
+//
+STATIC CONST UINT8 mInStride[] = {
+  1, // EfiCpuIoWidthUint8
+  2, // EfiCpuIoWidthUint16
+  4, // EfiCpuIoWidthUint32
+  8, // EfiCpuIoWidthUint64
+  0, // EfiCpuIoWidthFifoUint8
+  0, // EfiCpuIoWidthFifoUint16
+  0, // EfiCpuIoWidthFifoUint32
+  0, // EfiCpuIoWidthFifoUint64
+  1, // EfiCpuIoWidthFillUint8
+  2, // EfiCpuIoWidthFillUint16
+  4, // EfiCpuIoWidthFillUint32
+  8  // EfiCpuIoWidthFillUint64
+};
+
+//
+// Lookup table for increment values based on transfer widths
+//
+STATIC CONST UINT8 mOutStride[] = {
+  1, // EfiCpuIoWidthUint8
+  2, // EfiCpuIoWidthUint16
+  4, // EfiCpuIoWidthUint32
+  8, // EfiCpuIoWidthUint64
+  1, // EfiCpuIoWidthFifoUint8
+  2, // EfiCpuIoWidthFifoUint16
+  4, // EfiCpuIoWidthFifoUint32
+  8, // EfiCpuIoWidthFifoUint64
+  0, // EfiCpuIoWidthFillUint8
+  0, // EfiCpuIoWidthFillUint16
+  0, // EfiCpuIoWidthFillUint32
+  0  // EfiCpuIoWidthFillUint64
+};
+
+/**
+  Check parameters to a CPU I/O 2 Protocol service request.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
+  be handled by the driver.
+
+  @param[in] MmioOperation  TRUE for an MMIO operation, FALSE for I/O Port operation.
+  @param[in] Width          Signifies the width of the I/O or Memory operation.
+  @param[in] Address        The base address of the I/O operation.
+  @param[in] Count          The number of I/O operations to perform. The number of
+                            bytes moved is Width size * Count, starting at Address.
+  @param[in] Buffer         For read operations, the destination buffer to store the results.
+                            For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The parameters for this request pass the checks.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+CpuIoCheckParameter (
+  IN BOOLEAN                    MmioOperation,
+  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                     Address,
+  IN UINTN                      Count,
+  IN VOID                       *Buffer
+  )
+{
+  UINT64  MaxCount;
+  UINT64  Limit;
+
+  //
+  // Check to see if Buffer is NULL
+  //
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to see if Width is in the valid range
+  //
+  if ((UINT32)Width >= EfiCpuIoWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // For FIFO type, the target address won't increase during the access,
+  // so treat Count as 1
+  //
+  if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
+    Count = 1;
+  }
+
+  //
+  // Check to see if Width is in the valid range for I/O Port operations
+  //
+  Width = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+  if (!MmioOperation && (Width == EfiCpuIoWidthUint64)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to see if Address is aligned
+  //
+  if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check to see if any address associated with this transfer exceeds the maximum
+  // allowed address.  The maximum address implied by the parameters passed in is
+  // Address + Size * Count.  If the following condition is met, then the transfer
+  // is not supported.
+  //
+  //    Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
+  //
+  // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count
+  // can also be the maximum integer value supported by the CPU, this range
+  // check must be adjusted to avoid all oveflow conditions.
+  //
+  // The following form of the range check is equivalent but assumes that
+  // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
+  //
+  Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);
+  if (Count == 0) {
+    if (Address > Limit) {
+      return EFI_UNSUPPORTED;
+    }
+  } else {
+    MaxCount = RShiftU64 (Limit, Width);
+    if (MaxCount < (Count - 1)) {
+      return EFI_UNSUPPORTED;
+    }
+    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Check to see if Buffer is aligned
+  //
+  if (((UINTN)Buffer & ((MIN (sizeof (UINTN), mInStride[Width])  - 1))) != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads memory-mapped registers.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
+  be handled by the driver.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[out] Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceRead (
+  IN  EFI_CPU_IO2_PROTOCOL       *This,
+  IN  EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                     Address,
+  IN  UINTN                      Count,
+  OUT VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride = mInStride[Width];
+  OutStride = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      *Uint8Buffer = MmioRead8 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint64) {
+      *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Writes memory-mapped registers.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
+  be handled by the driver.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[in]  Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceWrite (
+  IN EFI_CPU_IO2_PROTOCOL       *This,
+  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                     Address,
+  IN UINTN                      Count,
+  IN VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride = mInStride[Width];
+  OutStride = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+    } else if (OperationWidth == EfiCpuIoWidthUint64) {
+      MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads I/O registers.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
+  be handled by the driver.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[out] Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuIoServiceRead (
+  IN  EFI_CPU_IO2_PROTOCOL       *This,
+  IN  EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                     Address,
+  IN  UINTN                      Count,
+  OUT VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride = mInStride[Width];
+  OutStride = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+
+  // Assuming address has already been translated into MMIO address by PCI host
+  // bridge driver, so we call MmioRead/Write directly.
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      *Uint8Buffer = MmioRead8 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Write I/O registers.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
+  be handled by the driver.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[in]  Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuIoServiceWrite (
+  IN EFI_CPU_IO2_PROTOCOL       *This,
+  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                     Address,
+  IN UINTN                      Count,
+  IN VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  //
+  // Make sure the parameters are valid
+  //
+  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride = mInStride[Width];
+  OutStride = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+
+  // Assuming address has already been translated into MMIO address by PCI host
+  // bridge driver, so we call MmioRead/Write directly.
+  for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+//
+// CPU I/O 2 Protocol instance
+//
+STATIC EFI_CPU_IO2_PROTOCOL mCpuIo2 = {
+  {
+    CpuMemoryServiceRead,
+    CpuMemoryServiceWrite
+  },
+  {
+    CpuIoServiceRead,
+    CpuIoServiceWrite
+  }
+};
+
+
+/**
+  The user Entry Point for module CpuIo2Dxe. The user code starts with this function.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+  @retval other             Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+ArmPciCpuIo2Initialize (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS Status;
+
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid);
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gEfiCpuIo2ProtocolGuid, &mCpuIo2,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
-- 
2.7.4



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

* [PATCH edk2-platforms 09/12] Hisilicon: add PciSegmentLib for Hi161x
  2018-03-21  1:03 [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Heyi Guo
                   ` (7 preceding siblings ...)
  2018-03-21  1:03 ` [PATCH edk2-platforms 08/12] Hisilicon: add PciCpuIo2Dxe Heyi Guo
@ 2018-03-21  1:03 ` Heyi Guo
  2018-03-21  1:03 ` [PATCH edk2-platforms 10/12] Hisilicon/D0x: Switch to generic PciHostBridge driver Heyi Guo
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Heyi Guo @ 2018-03-21  1:03 UTC (permalink / raw)
  To: edk2-devel; +Cc: Heyi Guo, Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This is to prepare for switching to generic PciHostBridge, and
PciSegmentLib is needed by generic PciHostBridge driver.

This module copied from
edk2-platforms/Silicon/Socionext/SynQuacer/Library/SynQuacerPciSegmentLib.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/Hi161xPciSegmentLib.inf |   36 +
 Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/PciSegmentLib.c         | 1503 ++++++++++++++++++++
 2 files changed, 1539 insertions(+)

diff --git a/Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/Hi161xPciSegmentLib.inf b/Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/Hi161xPciSegmentLib.inf
new file mode 100644
index 000000000000..cd2ae8810224
--- /dev/null
+++ b/Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/Hi161xPciSegmentLib.inf
@@ -0,0 +1,36 @@
+## @file
+# PCI Segment Library for Hisilicon Hi1610/Hi1616 SoC with multiple RCs
+#
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2017 - 2018, Linaro Ltd. All rights reserved.<BR>
+# Copyright (c) 2018, Hisilicon Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php.
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = Hi161xPciSegmentLib
+  FILE_GUID                      = 22447df4-0baa-11e8-b6de-286ed489ee9b
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PciSegmentLib
+
+[Sources]
+  PciSegmentLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
diff --git a/Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/PciSegmentLib.c b/Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/PciSegmentLib.c
new file mode 100644
index 000000000000..2e66244a4728
--- /dev/null
+++ b/Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/PciSegmentLib.c
@@ -0,0 +1,1503 @@
+/** @file
+  PCI Segment Library for SynQuacer SoC with multiple RCs
+
+  Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2017, Linaro, Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials are
+  licensed and made available under the terms and conditions of
+  the BSD License which accompanies this distribution.  The full
+  text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+
+#include <Library/PciSegmentLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PlatformPciLib.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)
+
+#define EXTRACT_PCIE_ADDRESS(Address, Segment, Bus, Device, Function, Register) \
+{ \
+  (Segment)  = (RShiftU64 (Address, 32) & 0xffff);   \
+  (Bus)      = (((Address) >> 20) & 0xff);   \
+  (Device)   = (((Address) >> 15) & 0x1f);   \
+  (Function) = (((Address) >> 12) & 0x07);   \
+  (Register) = ((Address)       & 0xfff);  \
+}
+
+STATIC
+PCI_ROOT_BRIDGE_RESOURCE_APPETURE *
+PciSegmentLibGetAppeture (
+  IN  UINT32     Segment
+  )
+{
+  UINTN Hb;
+  UINTN Rb;
+
+  for (Hb = 0; Hb < PCIE_MAX_HOSTBRIDGE; Hb++) {
+    for (Rb = 0; Rb < PCIE_MAX_ROOTBRIDGE; Rb++) {
+      if (Segment == mResAppeture[Hb][Rb].Segment) {
+        return &mResAppeture[Hb][Rb];
+      }
+    }
+  }
+
+  // Shouldn't reach here
+  ASSERT (FALSE);
+  return NULL;
+}
+
+BOOLEAN PcieIsLinkUp (UINTN RbPciBar)
+{
+  UINT32 Value;
+
+  Value = MmioRead32(RbPciBar + 0x131C);
+  if ((Value & 0x3F) == 0x11) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+STATIC
+UINT32
+CpuMemoryServiceRead (
+  IN  UINT64                     Address,
+  IN  PCI_CFG_WIDTH              Width
+  )
+{
+
+  UINT32                     Uint32Buffer;
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  if (Width == PciCfgWidthUint8) {
+    Uint32Buffer = MmioRead32((UINTN)(Address & (~0x3)));
+    return BitFieldRead32 (Uint32Buffer, (Address & 0x3) * 8, (Address & 0x3) * 8 + 7);
+  } else if (Width == PciCfgWidthUint16) {
+    if (((Address & 0x3) == 1) || ((Address & 0x3) == 3)) {
+      return 0xffff;
+    }
+    Uint32Buffer = MmioRead32((UINTN)(Address & (~0x3)));
+    return BitFieldRead32 (Uint32Buffer, (Address & 0x3) * 8, (Address & 0x3) * 8 + 15);
+  } else if (Width == PciCfgWidthUint32) {
+    return MmioRead32 ((UINTN)Address);
+  } else {
+    return 0xffffffff;
+  }
+}
+
+STATIC
+UINT32
+CpuMemoryServiceWrite (
+  IN  UINT64                     Address,
+  IN  PCI_CFG_WIDTH              Width,
+  IN  UINT32                     Data
+  )
+{
+
+  UINT32                     Uint32Buffer;
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  if (Width == PciCfgWidthUint8) {
+    Uint32Buffer = MmioRead32((UINTN)(Address & (~0x3)));
+    Uint32Buffer = BitFieldWrite32 (Uint32Buffer, (Address & 0x3) * 8, (Address & 0x3) * 8 + 7, Data);
+    MmioWrite32 ((UINTN)(Address & (~0x3)), Uint32Buffer);
+  } else if (Width == PciCfgWidthUint16) {
+    if (((Address & 0x3) == 1) || ((Address & 0x3) == 3)) {
+      return 0xffffffff;
+    }
+    Uint32Buffer = MmioRead32((UINTN)(Address & (~0x3)));
+    Uint32Buffer = BitFieldWrite32 (Uint32Buffer, (Address & 0x3) * 8, (Address & 0x3) * 8 + 15, Data);
+    MmioWrite32 ((UINTN)(Address & (~0x3)), Uint32Buffer);
+  } else if (Width == PciCfgWidthUint32) {
+    MmioWrite32 ((UINTN)Address, Data);
+  } else {
+    return 0xffffffff;
+  }
+  return Data;
+}
+/**
+  Internal worker function to read a PCI configuration register.
+
+  @param  Address The address that encodes the PCI Bus, Device, Function and
+                  Register.
+  @param  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
+  )
+{
+  PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Appeture;
+  UINT32    Segment;
+  UINT8     Bus;
+  UINT8     Device;
+  UINT8     Function;
+  UINT32    Register;
+
+  UINT64    MmioAddress;
+
+  EXTRACT_PCIE_ADDRESS (Address, Segment, Bus, Device, Function, Register);
+  Appeture = PciSegmentLibGetAppeture (Segment);
+  if (Appeture == NULL) {
+    return 0xffffffff;
+  }
+
+  if (Bus == Appeture->BusBase) {
+    // ignore device > 0 or function > 0 on base bus
+    if (Device != 0 || Function != 0) {
+      return 0xffffffff;
+    }
+    MmioAddress = Appeture->RbPciBar + Register;
+  } else {
+    // Cannot read from device under root port when link is not up
+    if (Bus == Appeture->BusBase + 1 && !PcieIsLinkUp (Appeture->RbPciBar)) {
+      return 0xffffffff;
+    }
+
+    MmioAddress = Appeture->Ecam + (UINT32)Address;
+  }
+
+  return CpuMemoryServiceRead (MmioAddress, Width);
+}
+
+/**
+  Internal worker function to writes a PCI configuration register.
+
+  @param  Address The address that encodes the PCI Bus, Device, Function and
+                  Register.
+  @param  Width   The width of data to write
+  @param  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
+  )
+{
+  PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Appeture;
+  UINT32    Segment;
+  UINT8     Bus;
+  UINT8     Device;
+  UINT8     Function;
+  UINT32    Register;
+
+  UINT64    MmioAddress;
+
+  EXTRACT_PCIE_ADDRESS (Address, Segment, Bus, Device, Function, Register);
+  Appeture = PciSegmentLibGetAppeture (Segment);
+  if (Appeture == NULL) {
+    return 0xffffffff;
+  }
+
+  if (Bus == Appeture->BusBase) {
+    // ignore device > 0 or function > 0 on base bus
+    if (Device != 0 || Function != 0) {
+      return Data;
+    }
+    // Ignore writing to root port BAR registers, in case we get wrong BAR length
+    if ((Register & ~0x3) == 0x14 || (Register & ~0x3) == 0x10) {
+      return Data;
+    }
+    MmioAddress = Appeture->RbPciBar + Register;
+  } else {
+    // Cannot read from device under root port when link is not up
+    if (Bus == Appeture->BusBase + 1 && !PcieIsLinkUp (Appeture->RbPciBar)) {
+      return 0xffffffff;
+    }
+    MmioAddress = Appeture->Ecam + (UINT32)Address;
+  }
+
+  return CpuMemoryServiceWrite (MmioAddress, Width, Data);
+}
+
+/**
+  Register a PCI device so PCI configuration registers may be accessed after
+  SetVirtualAddressMap().
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address The address that encodes the PCI Bus, Device, Function and
+                  Register.
+
+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.
+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function
+                                   after ExitBootServices().
+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device
+                                   at runtime could not be mapped.
+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to
+                                   complete the registration.
+
+**/
+RETURN_STATUS
+EFIAPI
+PciSegmentRegisterForRuntimeAccess (
+  IN UINTN  Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+  return RETURN_UNSUPPORTED;
+}
+
+/**
+  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  Address   The address that encodes the PCI Segment, Bus, Device, Function,
+                    and Register.
+
+  @return The 8-bit PCI configuration register specified by 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 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().
+
+  @param  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  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  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  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  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  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 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  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData    The value to AND with the PCI configuration register.
+  @param  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  Address   The PCI configuration register to read.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  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  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param  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  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param  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  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param  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  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param  AndData   The value to AND with the PCI configuration register.
+  @param  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  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  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  Value       The value to write.
+
+  @return The parameter of Value.
+
+**/
+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  Address The address that encodes the PCI Segment, Bus, Device, Function and
+                  Register.
+  @param  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 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  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  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 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  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData   The value to AND with the PCI configuration register.
+  @param  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  Address   The PCI configuration register to read.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param  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  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+  @param  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 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  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+  @param  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 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  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  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  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  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  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+  @param  AndData   The value to AND with the PCI configuration register.
+  @param  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  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  Address     The address that encodes the PCI Segment, Bus, Device,
+                      Function, and Register.
+  @param  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  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  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  Address   The address that encodes the PCI Segment, Bus, Device, Function,
+                    and Register.
+  @param  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 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  Address   The address that encodes the PCI Segment, Bus, Device, Function,
+                    and Register.
+  @param  AndData   The value to AND with the PCI configuration register.
+  @param  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  Address   The PCI configuration register to read.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  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  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  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  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  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  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  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  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  AndData   The value to AND with the PCI configuration register.
+  @param  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  StartAddress  The starting address that encodes the PCI Segment, Bus,
+                        Device, Function and Register.
+  @param  Size          The size in bytes of the transfer.
+  @param  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  StartAddress  The starting address that encodes the PCI Segment, Bus,
+                        Device, Function and Register.
+  @param  Size          The size in bytes of the transfer.
+  @param  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.7.4



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

* [PATCH edk2-platforms 10/12] Hisilicon/D0x: Switch to generic PciHostBridge driver
  2018-03-21  1:03 [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Heyi Guo
                   ` (8 preceding siblings ...)
  2018-03-21  1:03 ` [PATCH edk2-platforms 09/12] Hisilicon: add PciSegmentLib for Hi161x Heyi Guo
@ 2018-03-21  1:03 ` Heyi Guo
  2018-03-30 15:34   ` Ard Biesheuvel
  2018-03-21  1:03 ` [PATCH edk2-platforms 11/12] Hisilicon: remove platform specific PciHostBridge Heyi Guo
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Heyi Guo @ 2018-03-21  1:03 UTC (permalink / raw)
  To: edk2-devel
  Cc: Heyi Guo, Ard Biesheuvel, Leif Lindholm, Michael D Kinney,
	Haojian Zhuang

Address translation support is added to generic PciHostBridge driver
in edk2 by commit 74d0a33, so we can switch to it for Hisilicon D03
and D05 which are using address translation between device address and
host address for resource BAR.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 Silicon/Hisilicon/Hisilicon.dsc.inc | 6 +++++-
 Platform/Hisilicon/D03/D03.dsc      | 6 ++++--
 Platform/Hisilicon/D05/D05.dsc      | 6 ++++--
 Platform/Hisilicon/D03/D03.fdf      | 3 ++-
 Platform/Hisilicon/D05/D05.fdf      | 3 ++-
 5 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/Silicon/Hisilicon/Hisilicon.dsc.inc b/Silicon/Hisilicon/Hisilicon.dsc.inc
index 77585933179e..8ee74a830e74 100644
--- a/Silicon/Hisilicon/Hisilicon.dsc.inc
+++ b/Silicon/Hisilicon/Hisilicon.dsc.inc
@@ -253,7 +253,11 @@ [PcdsFeatureFlag.common]
 
 [PcdsFixedAtBuild.common]
   gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|44
-  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0
+  #
+  # IO is mapped to memory space, so we use the same size of
+  # PcdPrePiCpuMemorySize
+  #
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|44
   gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
   gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
   gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
diff --git a/Platform/Hisilicon/D03/D03.dsc b/Platform/Hisilicon/D03/D03.dsc
index 0b2bd29cdf83..26081a33a00a 100644
--- a/Platform/Hisilicon/D03/D03.dsc
+++ b/Platform/Hisilicon/D03/D03.dsc
@@ -82,6 +82,8 @@ [LibraryClasses.common]
 
   LpcLib|Silicon/Hisilicon/Hi1610/Library/LpcLib/LpcLib.inf
   SerialPortLib|Silicon/Hisilicon/Hi1610/Library/Uart/LpcSerialPortLib/LpcSerialPortLib.inf
+  PciHostBridgeLib|Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+  PciSegmentLib|Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/Hi161xPciSegmentLib.inf
 
 ## GIC on D02/D03 is not fully ARM GIC compatible: IRQ cannot be cancelled when
 ## input signal is de-asserted, except for virtual timer interrupt IRQ #27.
@@ -336,6 +338,7 @@ [Components.common]
   ArmPkg/Drivers/CpuDxe/CpuDxe.inf
   MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
 
+  Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
   Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.inf
 
   Platform/Hisilicon/D03/Drivers/SFC/SfcDxeDriver.inf
@@ -457,9 +460,8 @@ [Components.common]
     <LibraryClasses>
       NULL|Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.inf
   }
-  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf {
+  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
     <LibraryClasses>
-      DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf
       NULL|Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.inf
   }
 
diff --git a/Platform/Hisilicon/D05/D05.dsc b/Platform/Hisilicon/D05/D05.dsc
index 2150a6f4c0e9..d6febf471630 100644
--- a/Platform/Hisilicon/D05/D05.dsc
+++ b/Platform/Hisilicon/D05/D05.dsc
@@ -97,6 +97,8 @@ [LibraryClasses.common]
 
   LpcLib|Silicon/Hisilicon/Hi1610/Library/LpcLib/LpcLib.inf
   SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
+  PciHostBridgeLib|Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+  PciSegmentLib|Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/Hi161xPciSegmentLib.inf
 
 [LibraryClasses.common.SEC]
   ArmPlatformLib|Silicon/Hisilicon/Library/ArmPlatformLibHisilicon/ArmPlatformLibSec.inf
@@ -472,6 +474,7 @@ [Components.common]
   ArmPkg/Drivers/CpuDxe/CpuDxe.inf
   MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
 
+  Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
   Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.inf
 
   Platform/Hisilicon/D05/Drivers/SFC/SfcDxeDriver.inf
@@ -611,9 +614,8 @@ [Components.common]
     <LibraryClasses>
       NULL|Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.inf
   }
-  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf {
+  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
     <LibraryClasses>
-      DmaLib|EmbeddedPkg/Library/CoherentDmaLib/CoherentDmaLib.inf
       NULL|Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.inf
   }
 
diff --git a/Platform/Hisilicon/D03/D03.fdf b/Platform/Hisilicon/D03/D03.fdf
index e430d5c08982..0c843a3ce671 100644
--- a/Platform/Hisilicon/D03/D03.fdf
+++ b/Platform/Hisilicon/D03/D03.fdf
@@ -157,6 +157,7 @@ [FV.FvMain]
   INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
 
   INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  INF Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
   INF Platform/Hisilicon/D03/Drivers/SFC/SfcDxeDriver.inf
 
   INF Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.inf
@@ -263,7 +264,7 @@ [FV.FvMain]
   # PCI Support
   #
   INF Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
-  INF Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
+  INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
   INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
 
   INF Platform/Hisilicon/D03/Drivers/ReportPciePlugDidVidToBmc/ReportPciePlugDidVidToBmc.inf
diff --git a/Platform/Hisilicon/D05/D05.fdf b/Platform/Hisilicon/D05/D05.fdf
index 13a60837a607..b530e8e785a4 100644
--- a/Platform/Hisilicon/D05/D05.fdf
+++ b/Platform/Hisilicon/D05/D05.fdf
@@ -161,6 +161,7 @@ [FV.FvMain]
   INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
 
   INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  INF Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
   INF Platform/Hisilicon/D05/Drivers/SFC/SfcDxeDriver.inf
 
   INF Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.inf
@@ -285,7 +286,7 @@ [FV.FvMain]
   # PCI Support
   #
   INF Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
-  INF Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
+  INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
   INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
 
   INF Platform/Hisilicon/D05/Drivers/ReportPciePlugDidVidToBmc/ReportPciePlugDidVidToBmc.inf
-- 
2.7.4



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

* [PATCH edk2-platforms 11/12] Hisilicon: remove platform specific PciHostBridge
  2018-03-21  1:03 [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Heyi Guo
                   ` (9 preceding siblings ...)
  2018-03-21  1:03 ` [PATCH edk2-platforms 10/12] Hisilicon/D0x: Switch to generic PciHostBridge driver Heyi Guo
@ 2018-03-21  1:03 ` Heyi Guo
  2018-03-30 15:37   ` Ard Biesheuvel
  2018-03-21  1:03 ` [PATCH edk2-platforms 12/12] Hisilicon/PlatformPciLib: clear redundant felds in RESOURCE_APPETURE Heyi Guo
  2018-03-28  1:05 ` [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Guo Heyi
  12 siblings, 1 reply; 33+ messages in thread
From: Heyi Guo @ 2018-03-21  1:03 UTC (permalink / raw)
  To: edk2-devel
  Cc: Heyi Guo, Yi Li, Ard Biesheuvel, Leif Lindholm, Michael D Kinney

PciHostBridge in Silicon/Hisilicon is specific for D03/D05. After we
switch to generic PciHostBridge in MdeModulePkg, this driver is
useless and can be removed.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Signed-off-by: Yi Li <phoenix.liyi@huawei.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf |   74 -
 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h      |  520 -----
 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c      | 1658 ---------------
 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c    | 2220 --------------------
 4 files changed, 4472 deletions(-)

diff --git a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf b/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
deleted file mode 100644
index 7f5e1751ec9f..000000000000
--- a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
+++ /dev/null
@@ -1,74 +0,0 @@
-## @file
-#
-#  Component description file PCI Host Bridge driver.
-#  Copyright (c) 2014, AppliedMicro Corp. All rights reserved.
-#  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
-#  Copyright (c) 2016, Linaro Limited. All rights reserved.
-#
-#  This program and the accompanying materials
-#  are licensed and made available under the terms and conditions of the BSD License
-#  which accompanies this distribution.  The full text of the license may be found at
-#  http://opensource.org/licenses/bsd-license.php
-#
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-##
-
-[Defines]
-  INF_VERSION                    = 0x00010005
-  BASE_NAME                      = PciHostBridge
-  FILE_GUID                      = B0E61270-263F-11E3-8224-0800200C9A66
-  MODULE_TYPE                    = DXE_DRIVER
-  VERSION_STRING                 = 1.0
-
-  ENTRY_POINT                    = InitializePciHostBridge
-
-[Packages]
-  MdePkg/MdePkg.dec
-  ArmPkg/ArmPkg.dec
-  ArmPlatformPkg/ArmPlatformPkg.dec
-  EmbeddedPkg/EmbeddedPkg.dec
-  Silicon/Hisilicon/HisiPkg.dec
-
-[LibraryClasses]
-  UefiDriverEntryPoint
-  UefiBootServicesTableLib
-  MemoryAllocationLib
-  DxeServicesTableLib
-  CacheMaintenanceLib
-  DmaLib
-  BaseMemoryLib
-  BaseLib
-  DebugLib
-  TimerLib
-  ArmLib
-  DevicePathLib
-  PcdLib
-  OemMiscLib
-
-[Sources]
-  PciHostBridge.c
-  PciRootBridgeIo.c
-  PciHostBridge.h
-
-[Protocols]
-  gEfiPciHostBridgeResourceAllocationProtocolGuid
-  gEfiPciRootBridgeIoProtocolGuid
-  gEfiMetronomeArchProtocolGuid
-  gEfiDevicePathProtocolGuid
-  gEmbeddedGpioProtocolGuid
-
-[depex]
-  gEfiMetronomeArchProtocolGuid
-
-[FeaturePcd]
-
-[Pcd]
-
-[FixedPcd]
-  gHisiTokenSpaceGuid.PcdPcieRootBridgeMask
-  gHisiTokenSpaceGuid.PcdPcieRootBridgeMask2P
-  gHisiTokenSpaceGuid.Pcdsoctype
-
-[Guids]
-  gEfiEventExitBootServicesGuid                 ## PRODUCES ## Event
diff --git a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h b/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h
deleted file mode 100644
index 435385491a17..000000000000
--- a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h
+++ /dev/null
@@ -1,520 +0,0 @@
-/**
- * Copyright (c) 2014, AppliedMicro Corp. All rights reserved.
- * Copyright (c) 2016, Hisilicon Limited. All rights reserved.
- * Copyright (c) 2016, Linaro Limited. All rights reserved.
- *
- * This program and the accompanying materials
- * are licensed and made available under the terms and conditions of the BSD License
- * which accompanies this distribution.  The full text of the license may be found at
- * http://opensource.org/licenses/bsd-license.php
- *
- * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
- *
- **/
-
-#ifndef _PCI_HOST_BRIDGE_H_
-#define _PCI_HOST_BRIDGE_H_
-
-#include <PiDxe.h>
-
-#include <IndustryStandard/Pci.h>
-#include <IndustryStandard/Acpi.h>
-
-#include <Protocol/PciHostBridgeResourceAllocation.h>
-#include <Protocol/PciRootBridgeIo.h>
-#include <Protocol/Metronome.h>
-#include <Protocol/DevicePath.h>
-#include <Protocol/PciIo.h>
-#include <Protocol/CpuIo2.h>
-
-
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/DxeServicesTableLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/IoLib.h>
-#include <Library/PciLib.h>
-#include <Library/PcdLib.h>
-#include <Library/PlatformPciLib.h>
-
-// Enable below statments to enable PCIE debug
-//#define  PCIE_DEBUG_ENABLE
-//#define  PCIE_VDEBUG_ENABLE
-//#define  PCIE_CDEBUG_ENABLE
-
-#ifdef PCIE_CDEBUG_ENABLE
-# define PCIE_CSR_DEBUG(arg...) DEBUG((EFI_D_VERBOSE,## arg))
-#else
-# define PCIE_CSR_DEBUG(arg...)
-#endif
-
-#ifdef PCIE_VDEBUG_ENABLE
-# define PCIE_VDEBUG(arg...) DEBUG((EFI_D_VERBOSE,## arg))
-#else
-# define PCIE_VDEBUG(arg...)
-#endif
-
-#ifdef PCIE_DEBUG_ENABLE
-# define PCIE_DEBUG(arg...) DEBUG((EFI_D_VERBOSE,## arg))
-#else
-# define PCIE_DEBUG(arg...)
-#endif
-#define PCIE_WARN(arg...) DEBUG((EFI_D_WARN,## arg))
-#define PCIE_ERR(arg...) DEBUG((EFI_D_ERROR,## arg))
-#define PCIE_INFO(arg...) DEBUG((EFI_D_INFO,## arg))
-
-#define MAX_PCI_DEVICE_NUMBER      31
-#define MAX_PCI_FUNCTION_NUMBER    7
-#define MAX_PCI_REG_ADDRESS        0xFFFF
-
-typedef enum {
-  IoOperation,
-  MemOperation,
-  PciOperation
-} OPERATION_TYPE;
-
-#define PCI_HOST_BRIDGE_SIGNATURE  SIGNATURE_32('e', 'h', 's', 't')
-typedef struct {
-  UINTN                                             Signature;
-  EFI_HANDLE                                        HostBridgeHandle;
-  UINTN                                             RootBridgeNumber;
-  LIST_ENTRY                                        Head;
-  BOOLEAN                                           ResourceSubmited;
-  BOOLEAN                                           CanRestarted;
-  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  ResAlloc;
-} PCI_HOST_BRIDGE_INSTANCE;
-
-#define INSTANCE_FROM_RESOURCE_ALLOCATION_THIS(a) \
-  CR(a, PCI_HOST_BRIDGE_INSTANCE, ResAlloc, PCI_HOST_BRIDGE_SIGNATURE)
-
-//
-//  HostBridge Resource Allocation interface
-//
-
-/**
-   These are the notifications from the PCI bus driver that it is about to enter a certain
-   phase of the PCI enumeration process.
-
-   This member function can be used to notify the host bridge driver to perform specific actions,
-   including any chipset-specific initialization, so that the chipset is ready to enter the next phase.
-   Eight notification points are defined at this time. See belows:
-   EfiPciHostBridgeBeginEnumeration       Resets the host bridge PCI apertures and internal data
-                                          structures. The PCI enumerator should issue this notification
-                                          before starting a fresh enumeration process. Enumeration cannot
-                                          be restarted after sending any other notification such as
-                                          EfiPciHostBridgeBeginBusAllocation.
-   EfiPciHostBridgeBeginBusAllocation     The bus allocation phase is about to begin. No specific action is
-                                          required here. This notification can be used to perform any
-                                          chipset-specific programming.
-   EfiPciHostBridgeEndBusAllocation       The bus allocation and bus programming phase is complete. No
-                                          specific action is required here. This notification can be used to
-                                          perform any chipset-specific programming.
-   EfiPciHostBridgeBeginResourceAllocation
-                                          The resource allocation phase is about to begin. No specific
-                                          action is required here. This notification can be used to perform
-                                          any chipset-specific programming.
-   EfiPciHostBridgeAllocateResources      Allocates resources per previously submitted requests for all the PCI
-                                          root bridges. These resource settings are returned on the next call to
-                                          GetProposedResources(). Before calling NotifyPhase() with a Phase of
-                                          EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible
-                                          for gathering I/O and memory requests for
-                                          all the PCI root bridges and submitting these requests using
-                                          SubmitResources(). This function pads the resource amount
-                                          to suit the root bridge hardware, takes care of dependencies between
-                                          the PCI root bridges, and calls the Global Coherency Domain (GCD)
-                                          with the allocation request. In the case of padding, the allocated range
-                                          could be bigger than what was requested.
-   EfiPciHostBridgeSetResources           Programs the host bridge hardware to decode previously allocated
-                                          resources (proposed resources) for all the PCI root bridges. After the
-                                          hardware is programmed, reassigning resources will not be supported.
-                                          The bus settings are not affected.
-   EfiPciHostBridgeFreeResources          Deallocates resources that were previously allocated for all the PCI
-                                          root bridges and resets the I/O and memory apertures to their initial
-                                          state. The bus settings are not affected. If the request to allocate
-                                          resources fails, the PCI enumerator can use this notification to
-                                          deallocate previous resources, adjust the requests, and retry
-                                          allocation.
-   EfiPciHostBridgeEndResourceAllocation  The resource allocation phase is completed. No specific action is
-                                          required here. This notification can be used to perform any chipsetspecific
-                                          programming.
-
-   @param[in] This                The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
-   @param[in] Phase               The phase during enumeration
-
-   @retval EFI_NOT_READY          This phase cannot be entered at this time. For example, this error
-                                  is valid for a Phase of EfiPciHostBridgeAllocateResources if
-                                  SubmitResources() has not been called for one or more
-                                  PCI root bridges before this call
-   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error. This error is valid
-                                  for a Phase of EfiPciHostBridgeSetResources.
-   @retval EFI_INVALID_PARAMETER  Invalid phase parameter
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-                                  This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the
-                                  previously submitted resource requests cannot be fulfilled or
-                                  were only partially fulfilled.
-   @retval EFI_SUCCESS            The notification was accepted without any errors.
-
-**/
-EFI_STATUS
-EFIAPI
-NotifyPhase(
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase
-  );
-
-/**
-   Return the device handle of the next PCI root bridge that is associated with this Host Bridge.
-
-   This function is called multiple times to retrieve the device handles of all the PCI root bridges that
-   are associated with this PCI host bridge. Each PCI host bridge is associated with one or more PCI
-   root bridges. On each call, the handle that was returned by the previous call is passed into the
-   interface, and on output the interface returns the device handle of the next PCI root bridge. The
-   caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
-   for that root bridge. When there are no more PCI root bridges to report, the interface returns
-   EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in the order that they
-   are returned by this function.
-   For D945 implementation, there is only one root bridge in PCI host bridge.
-
-   @param[in]       This              The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
-   @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI root bridge.
-
-   @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then return the first Rootbridge handle of the
-                                  specific Host bridge and return EFI_SUCCESS.
-   @retval EFI_NOT_FOUND          Can not find the any more root bridge in specific host bridge.
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was
-                                  returned on a previous call to GetNextRootBridge().
-**/
-EFI_STATUS
-EFIAPI
-GetNextRootBridge(
-  IN       EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN OUT   EFI_HANDLE                                       *RootBridgeHandle
-  );
-
-/**
-   Returns the allocation attributes of a PCI root bridge.
-
-   The function returns the allocation attributes of a specific PCI root bridge. The attributes can vary
-   from one PCI root bridge to another. These attributes are different from the decode-related
-   attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
-   RootBridgeHandle parameter is used to specify the instance of the PCI root bridge. The device
-   handles of all the root bridges that are associated with this host bridge must be obtained by calling
-   GetNextRootBridge(). The attributes are static in the sense that they do not change during or
-   after the enumeration process. The hardware may provide mechanisms to change the attributes on
-   the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is
-   installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
-   "Related Definitions" below. The caller uses these attributes to combine multiple resource requests.
-   For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI bus enumerator needs to
-   include requests for the prefetchable memory in the nonprefetchable memory pool and not request any
-   prefetchable memory.
-      Attribute                                 Description
-   ------------------------------------         ----------------------------------------------------------------------
-   EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM         If this bit is set, then the PCI root bridge does not support separate
-                                                windows for nonprefetchable and prefetchable memory. A PCI bus
-                                                driver needs to include requests for prefetchable memory in the
-                                                nonprefetchable memory pool.
-
-   EFI_PCI_HOST_BRIDGE_MEM64_DECODE             If this bit is set, then the PCI root bridge supports 64-bit memory
-                                                windows. If this bit is not set, the PCI bus driver needs to include
-                                                requests for a 64-bit memory address in the corresponding 32-bit
-                                                memory pool.
-
-   @param[in]   This               The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
-   @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in which the caller is interested. Type
-                                   EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
-   @param[out]  Attributes         The pointer to attribte of root bridge, it is output parameter
-
-   @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL
-   @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.
-   @retval EFI_SUCCESS             Success to get attribute of interested root bridge.
-
-**/
-EFI_STATUS
-EFIAPI
-GetAttributes(
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN  EFI_HANDLE                                       RootBridgeHandle,
-  OUT UINT64                                           *Attributes
-  );
-
-/**
-   Sets up the specified PCI root bridge for the bus enumeration process.
-
-   This member function sets up the root bridge for bus enumeration and returns the PCI bus range
-   over which the search should be performed in ACPI 2.0 resource descriptor format.
-
-   @param[in]   This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
-   @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.
-   @param[out]  Configuration     Pointer to the pointer to the PCI bus resource descriptor.
-
-   @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
-   @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.
-   @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.
-
-**/
-EFI_STATUS
-EFIAPI
-StartBusEnumeration(
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN  EFI_HANDLE                                       RootBridgeHandle,
-  OUT VOID                                             **Configuration
-  );
-
-/**
-   Programs the PCI root bridge hardware so that it decodes the specified PCI bus range.
-
-   This member function programs the specified PCI root bridge to decode the bus range that is
-   specified by the input parameter Configuration.
-   The bus range information is specified in terms of the ACPI 2.0 resource descriptor format.
-
-   @param[in] This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
-   @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be programmed
-   @param[in] Configuration     The pointer to the PCI bus resource descriptor
-
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
-   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
-   @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI 2.0 bus resource descriptor.
-   @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource descriptors other than
-                                  bus descriptors.
-   @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid ACPI resource descriptors.
-   @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this root bridge.
-   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this root bridge.
-   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
-   @retval EFI_SUCCESS            The bus range for the PCI root bridge was programmed.
-
-**/
-EFI_STATUS
-EFIAPI
-SetBusNumbers(
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN EFI_HANDLE                                       RootBridgeHandle,
-  IN VOID                                             *Configuration
-  );
-
-/**
-   Submits the I/O and memory resource requirements for the specified PCI root bridge.
-
-   This function is used to submit all the I/O and memory resources that are required by the specified
-   PCI root bridge. The input parameter Configuration is used to specify the following:
-   - The various types of resources that are required
-   - The associated lengths in terms of ACPI 2.0 resource descriptor format
-
-   @param[in] This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
-   @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory resource requirements are being submitted.
-   @param[in] Configuration     The pointer to the PCI I/O and PCI memory resource descriptor.
-
-   @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI root bridge were accepted.
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
-   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
-   @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or more resource types that are
-                                  not supported by this PCI root bridge. This error will happen if the caller
-                                  did not combine resources according to Attributes that were returned by
-                                  GetAllocAttributes().
-   @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.
-   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for this PCI root bridge.
-
-**/
-EFI_STATUS
-EFIAPI
-SubmitResources(
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN EFI_HANDLE                                       RootBridgeHandle,
-  IN VOID                                             *Configuration
-  );
-
-/**
-   Returns the proposed resource settings for the specified PCI root bridge.
-
-   This member function returns the proposed resource settings for the specified PCI root bridge. The
-   proposed resource settings are prepared when NotifyPhase() is called with a Phase of
-   EfiPciHostBridgeAllocateResources. The output parameter Configuration
-   specifies the following:
-   - The various types of resources, excluding bus resources, that are allocated
-   - The associated lengths in terms of ACPI 2.0 resource descriptor format
-
-   @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
-   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
-   @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.
-
-   @retval EFI_SUCCESS            The requested parameters were returned.
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-GetProposedResources(
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN  EFI_HANDLE                                       RootBridgeHandle,
-  OUT VOID                                             **Configuration
-  );
-
-/**
-   Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various
-   stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual
-   PCI controllers before enumeration.
-
-   This function is called during the PCI enumeration process. No specific action is expected from this
-   member function. It allows the host bridge driver to preinitialize individual PCI controllers before
-   enumeration.
-
-   @param This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
-   @param RootBridgeHandle  The associated PCI root bridge handle. Type EFI_HANDLE is defined in
-                            InstallProtocolInterface() in the UEFI 2.0 Specification.
-   @param PciAddress        The address of the PCI device on the PCI bus. This address can be passed to the
-                            EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to access the PCI
-                            configuration space of the device. See Table 12-1 in the UEFI 2.0 Specification for
-                            the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
-   @param Phase             The phase of the PCI device enumeration.
-
-   @retval EFI_SUCCESS              The requested parameters were returned.
-   @retval EFI_INVALID_PARAMETER    RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_INVALID_PARAMETER    Phase is not a valid phase that is defined in
-                                    EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
-   @retval EFI_DEVICE_ERROR         Programming failed due to a hardware error. The PCI enumerator should
-                                    not enumerate this device, including its child devices if it is a PCI-to-PCI
-                                    bridge.
-
-**/
-EFI_STATUS
-EFIAPI
-PreprocessController (
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
-  IN  EFI_HANDLE                                        RootBridgeHandle,
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS       PciAddress,
-  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE      Phase
-  );
-
-
-//
-// Define resource status constant
-//
-#define EFI_RESOURCE_NONEXISTENT   0xFFFFFFFFFFFFFFFFULL
-#define EFI_RESOURCE_LESS          0xFFFFFFFFFFFFFFFEULL
-
-//
-// Driver Instance Data Prototypes
-//
-
-typedef struct {
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation;
-  UINTN                                      NumberOfBytes;
-  UINTN                                      NumberOfPages;
-  EFI_PHYSICAL_ADDRESS                       HostAddress;
-  EFI_PHYSICAL_ADDRESS                       MappedHostAddress;
-} MAP_INFO;
-
-typedef struct {
-  ACPI_HID_DEVICE_PATH              AcpiDevicePath;
-  EFI_DEVICE_PATH_PROTOCOL          EndDevicePath;
-} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
-
-typedef enum {
-  TypeIo = 0,
-  TypeMem32,
-  TypePMem32,
-  TypeMem64,
-  TypePMem64,
-  TypeBus,
-  TypeMax
-} PCI_RESOURCE_TYPE;
-
-typedef enum {
-  ResNone = 0,
-  ResSubmitted,
-  ResRequested,
-  ResAllocated,
-  ResStatusMax
-} RES_STATUS;
-
-typedef struct {
-  PCI_RESOURCE_TYPE Type;
-  UINT64            Base;
-  UINT64            Length;
-  UINT64            Alignment;
-  RES_STATUS        Status;
-} PCI_RES_NODE;
-
-#define PCI_ROOT_BRIDGE_SIGNATURE  SIGNATURE_32('e', '2', 'p', 'b')
-
-typedef struct {
-  UINT32                 Signature;
-  LIST_ENTRY             Link;
-  EFI_HANDLE             Handle;
-  UINT64                 RootBridgeAttrib;
-  UINT64                 Attributes;
-  UINT64                 Supports;
-
-  //
-  // Specific for this memory controller: Bus, I/O, Mem
-  //
-  PCI_RES_NODE           ResAllocNode[6];
-
-  //
-  // Addressing for Memory and I/O and Bus arrange
-  //
-  UINT64                 BusBase;
-  UINT64                 MemBase;
-  UINT64                 IoBase;
-  UINT64                 BusLimit;
-  UINT64                 MemLimit;
-  UINT64                 IoLimit;
-  UINT64                 RbPciBar;
-  UINT64                 Ecam;
-
-  UINTN                  PciAddress;
-  UINTN                  PciData;
-  UINTN                  Port;
-  UINT32                 SocType;
-  UINT64                 CpuMemRegionBase;
-  UINT64                 CpuIoRegionBase;
-  UINT64                 PciRegionBase;
-  UINT64                 PciRegionLimit;
-
-  EFI_DEVICE_PATH_PROTOCOL                *DevicePath;
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         Io;
-
-} PCI_ROOT_BRIDGE_INSTANCE;
-
-
-//
-// Driver Instance Data Macros
-//
-#define DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(a) \
-  CR(a, PCI_ROOT_BRIDGE_INSTANCE, Io, PCI_ROOT_BRIDGE_SIGNATURE)
-
-
-#define DRIVER_INSTANCE_FROM_LIST_ENTRY(a) \
-  CR(a, PCI_ROOT_BRIDGE_INSTANCE, Link, PCI_ROOT_BRIDGE_SIGNATURE)
-
-/**
-
-  Construct the Pci Root Bridge Io protocol
-
-  @param Protocol         Point to protocol instance
-  @param HostBridgeHandle Handle of host bridge
-  @param Attri            Attribute of host bridge
-  @param ResAppeture      ResourceAppeture for host bridge
-
-  @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.
-
-**/
-EFI_STATUS
-RootBridgeConstructor (
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *Protocol,
-  IN EFI_HANDLE                         HostBridgeHandle,
-  IN UINT64                             Attri,
-  IN PCI_ROOT_BRIDGE_RESOURCE_APPETURE  *ResAppeture,
-  IN UINT32                             Seg
-  );
-
-#endif
diff --git a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c b/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c
deleted file mode 100644
index e3d3988a64c1..000000000000
--- a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c
+++ /dev/null
@@ -1,1658 +0,0 @@
-/**
- * Copyright (c) 2014, AppliedMicro Corp. All rights reserved.
- * Copyright (c) 2016, Hisilicon Limited. All rights reserved.
- * Copyright (c) 2016, Linaro Limited. All rights reserved.
- *
- * This program and the accompanying materials
- * are licensed and made available under the terms and conditions of the BSD License
- * which accompanies this distribution.  The full text of the license may be found at
- * http://opensource.org/licenses/bsd-license.php
- *
- * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
- *
- **/
-
-#include <Uefi.h>
-#include <Protocol/EmbeddedGpio.h>
-#include <Guid/EventGroup.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/OemMiscLib.h>
-
-#include "PciHostBridge.h"
-
-UINTN RootBridgeNumber[PCIE_MAX_HOSTBRIDGE] = { PCIE_MAX_ROOTBRIDGE,PCIE_MAX_ROOTBRIDGE };
-
-UINT64 RootBridgeAttribute[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {
-    { //Host Bridge0
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-    },
-    { //Host Bridge1
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
-    }
-    };
-
-EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {
-  { //Host Bridge0
-  /* Port 0 */
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A03),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    },
-  /* Port 1 */
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A04),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    },
-  /* Port 2 */
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A05),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    },
-  /* Port 3 */
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A06),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    },
-    /* Port 4 */
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A07),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    },
-    /* Port 5 */
-    {
-      {
-        {
-          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
-        }
-      }
-    },
-    /* Port 6 */
-    {
-      {
-        {
-          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
-        }
-      }
-    },
-    /* Port 7 */
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A0A),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    }
-},
-{ // Host Bridge1
-  /* Port 0 */
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A0B),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    },
-  /* Port 1 */
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A0C),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    },
-  /* Port 2 */
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A0D),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    },
-  /* Port 3 */
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A0E),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    },
-   /* Port 4 */
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A0F),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    },
-    /* Port 5 */
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A10),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    },
-    /* Port 6 */
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A11),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    },
-    /* Port 7 */
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A12),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    }
-  }
-};
-
-EFI_HANDLE mDriverImageHandle;
-
-PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate = {
-  PCI_HOST_BRIDGE_SIGNATURE,  // Signature
-  NULL,                       // HostBridgeHandle
-  0,                          // RootBridgeNumber
-  {NULL, NULL},               // Head
-  FALSE,                      // ResourceSubiteed
-  TRUE,                       // CanRestarted
-  {
-    NotifyPhase,
-    GetNextRootBridge,
-    GetAttributes,
-    StartBusEnumeration,
-    SetBusNumbers,
-    SubmitResources,
-    GetProposedResources,
-    PreprocessController
-  }
-};
-
-/**
-  Entry point of this driver
-
-  @param ImageHandle     Handle of driver image
-  @param SystemTable     Point to EFI_SYSTEM_TABLE
-
-  @retval EFI_OUT_OF_RESOURCES  Can not allocate memory resource
-  @retval EFI_DEVICE_ERROR      Can not install the protocol instance
-  @retval EFI_SUCCESS           Success to initialize the Pci host bridge.
-**/
-EFI_STATUS
-EFIAPI
-InitializePciHostBridge (
-  IN EFI_HANDLE        ImageHandle,
-  IN EFI_SYSTEM_TABLE  *SystemTable
-  )
-{
-  EFI_STATUS                  Status;
-  UINTN                       Loop1;
-  UINTN                       Loop2;
-  PCI_HOST_BRIDGE_INSTANCE    *HostBridge = NULL;
-  PCI_ROOT_BRIDGE_INSTANCE    *PrivateData;
-  UINT32       PcieRootBridgeMask;
-
-  if (!OemIsMpBoot())
-  {
-    PcieRootBridgeMask = PcdGet32(PcdPcieRootBridgeMask);
-  }
-  else
-  {
-    PcieRootBridgeMask = PcdGet32(PcdPcieRootBridgeMask2P);
-  }
-
-  mDriverImageHandle = ImageHandle;
-  //
-  // Create Host Bridge Device Handle
-  //
-  //Each Host Bridge have 8 Root Bridges max, every bits of 0xFF(8 bit) stands for the according PCIe Port
-  //is enable or not
-  for (Loop1 = 0; Loop1 < PCIE_MAX_HOSTBRIDGE; Loop1++) {
-    if (((PcieRootBridgeMask >> (PCIE_MAX_ROOTBRIDGE * Loop1)) & 0xFF ) == 0) {
-      continue;
-    }
-
-
-    HostBridge = AllocateCopyPool (sizeof(PCI_HOST_BRIDGE_INSTANCE), &mPciHostBridgeInstanceTemplate);
-    if (HostBridge == NULL) {
-      return EFI_OUT_OF_RESOURCES;
-    }
-
-    HostBridge->RootBridgeNumber = RootBridgeNumber[Loop1];
-    InitializeListHead (&HostBridge->Head);
-
-    Status = gBS->InstallMultipleProtocolInterfaces (
-                  &HostBridge->HostBridgeHandle,
-                  &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,
-                  NULL
-                  );
-    if (EFI_ERROR (Status)) {
-      FreePool (HostBridge);
-      return EFI_DEVICE_ERROR;
-    }
-
-    //
-    // Create Root Bridge Device Handle in this Host Bridge
-    //
-    for (Loop2 = 0; Loop2 < HostBridge->RootBridgeNumber; Loop2++) {
-      if (!(((PcieRootBridgeMask >> (PCIE_MAX_ROOTBRIDGE * Loop1)) >> Loop2 ) & 0x01)) {
-        continue;
-      }
-
-      PrivateData = AllocateZeroPool (sizeof(PCI_ROOT_BRIDGE_INSTANCE));
-      if (PrivateData == NULL) {
-        FreePool (HostBridge);
-        return EFI_OUT_OF_RESOURCES;
-      }
-      PrivateData->Port = Loop2;
-      PrivateData->SocType = PcdGet32(Pcdsoctype);
-      PrivateData->Signature = PCI_ROOT_BRIDGE_SIGNATURE;
-      PrivateData->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[Loop1][Loop2];
-
-      (VOID)RootBridgeConstructor (
-           &PrivateData->Io,
-           HostBridge->HostBridgeHandle,
-           RootBridgeAttribute[Loop1][Loop2],
-           &mResAppeture[Loop1][Loop2],
-           Loop1
-      );
-
-      Status = gBS->InstallMultipleProtocolInterfaces(
-                      &PrivateData->Handle,
-                      &gEfiDevicePathProtocolGuid,      PrivateData->DevicePath,
-                      &gEfiPciRootBridgeIoProtocolGuid, &PrivateData->Io,
-                      NULL
-                      );
-      if (EFI_ERROR (Status)) {
-        (VOID)gBS->UninstallMultipleProtocolInterfaces (
-                HostBridge->HostBridgeHandle,
-                &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,
-                NULL
-                );
-        FreePool(PrivateData);
-        FreePool (HostBridge);
-        return EFI_DEVICE_ERROR;
-      }
-      // PCI  Memory Space
-      Status = gDS->AddMemorySpace (
-             EfiGcdMemoryTypeMemoryMappedIo,
-             mResAppeture[Loop1][Loop2] .MemBase,
-             mResAppeture[Loop1][Loop2] .MemLimit -mResAppeture[Loop1][Loop2] .MemBase + 1,
-             0
-      );
-      if (EFI_ERROR (Status)) {
-        DEBUG((EFI_D_ERROR,"PCIE AddMemorySpace Error\n"));
-      }
-      InsertTailList (&HostBridge->Head, &PrivateData->Link);
-    }
-  }
-
-  return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-NotifyAllocateMemResources(
- IN PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance,
- IN PCI_RESOURCE_TYPE                     Index,
- IN OUT UINT64                            *AllocatedLenMem
-)
-{
-  EFI_PHYSICAL_ADDRESS                  BaseAddress;
-  EFI_STATUS                            ReturnStatus;
-  UINT64                                AddrLen;
-  UINTN                                 BitsOfAlignment;
-
-  AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
-  PCIE_DEBUG("Addrlen:%llx\n", AddrLen);
-  // Get the number of '1' in Alignment.
-  BitsOfAlignment = (UINTN) (HighBitSet64 (RootBridgeInstance->ResAllocNode[Index].Alignment) + 1);
-
-  BaseAddress = (RootBridgeInstance->MemBase + *AllocatedLenMem +
-                       RootBridgeInstance->ResAllocNode[Index].Alignment)
-                        & ~(RootBridgeInstance->ResAllocNode[Index].Alignment);
-  if ((BaseAddress + AddrLen - 1) > RootBridgeInstance->MemLimit) {
-          ReturnStatus = EFI_OUT_OF_RESOURCES;
-          RootBridgeInstance->ResAllocNode[Index].Length = 0;
-          return ReturnStatus;
-  }
-
-  PCIE_DEBUG("(P)Mem32/64 request memory at:%llx\n", BaseAddress);
-  ReturnStatus = gDS->AllocateMemorySpace (
-                     EfiGcdAllocateAddress,
-                     EfiGcdMemoryTypeMemoryMappedIo,
-                     BitsOfAlignment,
-                     AddrLen,
-                     &BaseAddress,
-                     mDriverImageHandle,
-                     NULL
-                 );
-
-  if (!EFI_ERROR (ReturnStatus)) {
-     // We were able to allocate the PCI memory
-     RootBridgeInstance->ResAllocNode[Index].Base   = (UINTN)BaseAddress;
-     RootBridgeInstance->ResAllocNode[Index].Status = ResAllocated;
-     *AllocatedLenMem += AddrLen;
-     PCIE_DEBUG("(P)Mem32/64 resource allocated:%llx\n", BaseAddress);
-
-  } else {
-      // Not able to allocate enough PCI memory
-      if (ReturnStatus != EFI_OUT_OF_RESOURCES) {
-        RootBridgeInstance->ResAllocNode[Index].Length = 0;
-      }
-    }
-  return ReturnStatus;
-}
-
-EFI_STATUS
-EFIAPI
-NotifyAllocateResources(
- IN PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance
-)
-{
-  EFI_STATUS                            ReturnStatus;
-  LIST_ENTRY                            *List;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-  PCI_RESOURCE_TYPE                     Index;
-
-  ReturnStatus = EFI_SUCCESS;
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-
-    UINT64 AllocatedLenMem = 0;
-    for (Index = TypeIo; Index < TypeBus; Index++) {
-      if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
-        if(Index == TypeIo) {
-          PCIE_DEBUG("NOT SUPPOER IO RESOURCES ON THIS PLATFORM\n");
-        } else if ((Index >= TypeMem32) && (Index <= TypePMem64)) {
-          ReturnStatus = NotifyAllocateMemResources(RootBridgeInstance,Index,&AllocatedLenMem);
-        } else {
-               ASSERT (FALSE);
-        }
-      }
-    }
-
-    List = List->ForwardLink;
-  }
-
-  return ReturnStatus;
-}
-
-EFI_STATUS
-EFIAPI
-NotifyFreeResources(
-  IN PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance
-)
-{
-  EFI_STATUS                            ReturnStatus;
-  LIST_ENTRY                            *List;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-  PCI_RESOURCE_TYPE                     Index;
-  UINT64                                AddrLen;
-  EFI_PHYSICAL_ADDRESS                  BaseAddress;
-
-  ReturnStatus = EFI_SUCCESS;
-  List = HostBridgeInstance->Head.ForwardLink;
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    for (Index = TypeIo; Index < TypeBus; Index++) {
-      if (RootBridgeInstance->ResAllocNode[Index].Status == ResAllocated) {
-        AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
-        BaseAddress = RootBridgeInstance->ResAllocNode[Index].Base;
-
-        if(Index <= TypePMem64){
-          ReturnStatus = gDS->FreeMemorySpace (BaseAddress, AddrLen);
-        }else{
-          ASSERT (FALSE);
-        }
-
-        RootBridgeInstance->ResAllocNode[Index].Type      = Index;
-        RootBridgeInstance->ResAllocNode[Index].Base      = 0;
-        RootBridgeInstance->ResAllocNode[Index].Length    = 0;
-        RootBridgeInstance->ResAllocNode[Index].Status    = ResNone;
-      }
-    }
-
-    List = List->ForwardLink;
-  }
-
-  HostBridgeInstance->ResourceSubmited = FALSE;
-  HostBridgeInstance->CanRestarted     = TRUE;
-  return ReturnStatus;
-
-}
-
-VOID
-EFIAPI
-NotifyBeginEnumeration(
-  IN PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance
-)
-{
-  LIST_ENTRY                            *List;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-  PCI_RESOURCE_TYPE                     Index;
-
-  //
-  // Reset the Each Root Bridge
-  //
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    for (Index = TypeIo; Index < TypeMax; Index++) {
-      RootBridgeInstance->ResAllocNode[Index].Type      = Index;
-      RootBridgeInstance->ResAllocNode[Index].Base      = 0;
-      RootBridgeInstance->ResAllocNode[Index].Length    = 0;
-      RootBridgeInstance->ResAllocNode[Index].Status    = ResNone;
-    }
-
-    List = List->ForwardLink;
-  }
-
-  HostBridgeInstance->ResourceSubmited = FALSE;
-  HostBridgeInstance->CanRestarted     = TRUE;
-}
-
-/**
-   These are the notifications from the PCI bus driver that it is about to enter a certain
-   phase of the PCI enumeration process.
-
-   This member function can be used to notify the host bridge driver to perform specific actions,
-   including any chipset-specific initialization, so that the chipset is ready to enter the next phase.
-   Eight notification points are defined at this time. See belows:
-   EfiPciHostBridgeBeginEnumeration       Resets the host bridge PCI apertures and internal data
-                                          structures. The PCI enumerator should issue this notification
-                                          before starting a fresh enumeration process. Enumeration cannot
-                                          be restarted after sending any other notification such as
-                                          EfiPciHostBridgeBeginBusAllocation.
-   EfiPciHostBridgeBeginBusAllocation     The bus allocation phase is about to begin. No specific action is
-                                          required here. This notification can be used to perform any
-                                          chipset-specific programming.
-   EfiPciHostBridgeEndBusAllocation       The bus allocation and bus programming phase is complete. No
-                                          specific action is required here. This notification can be used to
-                                          perform any chipset-specific programming.
-   EfiPciHostBridgeBeginResourceAllocation
-                                          The resource allocation phase is about to begin. No specific
-                                          action is required here. This notification can be used to perform
-                                          any chipset-specific programming.
-   EfiPciHostBridgeAllocateResources      Allocates resources per previously submitted requests for all the PCI
-                                          root bridges. These resource settings are returned on the next call to
-                                          GetProposedResources(). Before calling NotifyPhase() with a Phase of
-                                          EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible
-                                          for gathering I/O and memory requests for
-                                          all the PCI root bridges and submitting these requests using
-                                          SubmitResources(). This function pads the resource amount
-                                          to suit the root bridge hardware, takes care of dependencies between
-                                          the PCI root bridges, and calls the Global Coherency Domain (GCD)
-                                          with the allocation request. In the case of padding, the allocated range
-                                          could be bigger than what was requested.
-   EfiPciHostBridgeSetResources           Programs the host bridge hardware to decode previously allocated
-                                          resources (proposed resources) for all the PCI root bridges. After the
-                                          hardware is programmed, reassigning resources will not be supported.
-                                          The bus settings are not affected.
-   EfiPciHostBridgeFreeResources          Deallocates resources that were previously allocated for all the PCI
-                                          root bridges and resets the I/O and memory apertures to their initial
-                                          state. The bus settings are not affected. If the request to allocate
-                                          resources fails, the PCI enumerator can use this notification to
-                                          deallocate previous resources, adjust the requests, and retry
-                                          allocation.
-   EfiPciHostBridgeEndResourceAllocation  The resource allocation phase is completed. No specific action is
-                                          required here. This notification can be used to perform any chipsetspecific
-                                          programming.
-
-   @param[in] This                The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
-   @param[in] Phase               The phase during enumeration
-
-   @retval EFI_NOT_READY          This phase cannot be entered at this time. For example, this error
-                                  is valid for a Phase of EfiPciHostBridgeAllocateResources if
-                                  SubmitResources() has not been called for one or more
-                                  PCI root bridges before this call
-   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error. This error is valid
-                                  for a Phase of EfiPciHostBridgeSetResources.
-   @retval EFI_INVALID_PARAMETER  Invalid phase parameter
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-                                  This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the
-                                  previously submitted resource requests cannot be fulfilled or
-                                  were only partially fulfilled.
-   @retval EFI_SUCCESS            The notification was accepted without any errors.
-
-**/
-EFI_STATUS
-EFIAPI
-NotifyPhase(
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase
-  )
-{
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  EFI_STATUS                            ReturnStatus;
-
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  ReturnStatus = EFI_SUCCESS;
-
-  switch (Phase) {
-
-  case EfiPciHostBridgeBeginEnumeration:
-  PCIE_DEBUG("Case EfiPciHostBridgeBeginEnumeration\n");
-    if (HostBridgeInstance->CanRestarted) {
-      NotifyBeginEnumeration(HostBridgeInstance);
-    } else {
-      //
-      // Can not restart
-      //
-      return EFI_NOT_READY;
-    }
-    break;
-
-  case EfiPciHostBridgeEndEnumeration:
-    PCIE_DEBUG("Case EfiPciHostBridgeEndEnumeration\n");
-    break;
-
-  case EfiPciHostBridgeBeginBusAllocation:
-    PCIE_DEBUG("Case EfiPciHostBridgeBeginBusAllocation\n");
-    //
-    // No specific action is required here, can perform any chipset specific programing
-    //
-
-    HostBridgeInstance->CanRestarted = FALSE;
-    break;
-
-  case EfiPciHostBridgeEndBusAllocation:
-    PCIE_DEBUG("Case EfiPciHostBridgeEndBusAllocation\n");
-    //
-    // No specific action is required here, can perform any chipset specific programing
-    //
-    break;
-
-  case EfiPciHostBridgeBeginResourceAllocation:
-    PCIE_DEBUG("Case EfiPciHostBridgeBeginResourceAllocation\n");
-    //
-    // No specific action is required here, can perform any chipset specific programing
-    //
-    break;
-
-  case EfiPciHostBridgeAllocateResources:
-    PCIE_DEBUG("Case EfiPciHostBridgeAllocateResources\n");
-
-    if (HostBridgeInstance->ResourceSubmited) {
-      //
-      // Take care of the resource dependencies between the root bridges
-      //
-     ReturnStatus = NotifyAllocateResources(HostBridgeInstance);
-    } else {
-      return EFI_NOT_READY;
-    }
-    //break;
-
-  case EfiPciHostBridgeSetResources:
-    PCIE_DEBUG("Case EfiPciHostBridgeSetResources\n");
-    break;
-
-  case EfiPciHostBridgeFreeResources:
-    PCIE_DEBUG("Case EfiPciHostBridgeFreeResources\n");
-
-    ReturnStatus = NotifyFreeResources(HostBridgeInstance);
-    break;
-
-  case EfiPciHostBridgeEndResourceAllocation:
-    PCIE_DEBUG("Case EfiPciHostBridgeEndResourceAllocation\n");
-    HostBridgeInstance->CanRestarted = FALSE;
-    break;
-
-  default:
-    return EFI_INVALID_PARAMETER;
-  }
-
-  return ReturnStatus;
-}
-
-/**
-   Return the device handle of the next PCI root bridge that is associated with this Host Bridge.
-
-   This function is called multiple times to retrieve the device handles of all the PCI root bridges that
-   are associated with this PCI host bridge. Each PCI host bridge is associated with one or more PCI
-   root bridges. On each call, the handle that was returned by the previous call is passed into the
-   interface, and on output the interface returns the device handle of the next PCI root bridge. The
-   caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
-   for that root bridge. When there are no more PCI root bridges to report, the interface returns
-   EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in the order that they
-   are returned by this function.
-   For D945 implementation, there is only one root bridge in PCI host bridge.
-
-   @param[in]       This              The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
-   @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI root bridge.
-
-   @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then return the first Rootbridge handle of the
-                                  specific Host bridge and return EFI_SUCCESS.
-   @retval EFI_NOT_FOUND          Can not find the any more root bridge in specific host bridge.
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was
-                                  returned on a previous call to GetNextRootBridge().
-**/
-EFI_STATUS
-EFIAPI
-GetNextRootBridge(
-  IN       EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN OUT   EFI_HANDLE                                       *RootBridgeHandle
-  )
-{
-  BOOLEAN                               NoRootBridge;
-  LIST_ENTRY                            *List;
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-
-  NoRootBridge = TRUE;
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-
-  while (List != &HostBridgeInstance->Head) {
-    NoRootBridge = FALSE;
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    if (*RootBridgeHandle == NULL) {
-      //
-      // Return the first Root Bridge Handle of the Host Bridge
-      //
-      *RootBridgeHandle = RootBridgeInstance->Handle;
-      return EFI_SUCCESS;
-    } else {
-      if (*RootBridgeHandle == RootBridgeInstance->Handle) {
-        //
-        // Get next if have
-        //
-        List = List->ForwardLink;
-        if (List!=&HostBridgeInstance->Head) {
-          RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-          *RootBridgeHandle = RootBridgeInstance->Handle;
-          return EFI_SUCCESS;
-        } else {
-          return EFI_NOT_FOUND;
-        }
-      }
-    }
-
-    List = List->ForwardLink;
-  } //end while
-
-  if (NoRootBridge) {
-    return EFI_NOT_FOUND;
-  } else {
-    return EFI_INVALID_PARAMETER;
-  }
-}
-
-/**
-   Returns the allocation attributes of a PCI root bridge.
-
-   The function returns the allocation attributes of a specific PCI root bridge. The attributes can vary
-   from one PCI root bridge to another. These attributes are different from the decode-related
-   attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
-   RootBridgeHandle parameter is used to specify the instance of the PCI root bridge. The device
-   handles of all the root bridges that are associated with this host bridge must be obtained by calling
-   GetNextRootBridge(). The attributes are static in the sense that they do not change during or
-   after the enumeration process. The hardware may provide mechanisms to change the attributes on
-   the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is
-   installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
-   "Related Definitions" below. The caller uses these attributes to combine multiple resource requests.
-   For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI bus enumerator needs to
-   include requests for the prefetchable memory in the nonprefetchable memory pool and not request any
-   prefetchable memory.
-      Attribute                                 Description
-   ------------------------------------         ----------------------------------------------------------------------
-   EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM         If this bit is set, then the PCI root bridge does not support separate
-                                                windows for nonprefetchable and prefetchable memory. A PCI bus
-                                                driver needs to include requests for prefetchable memory in the
-                                                nonprefetchable memory pool.
-
-   EFI_PCI_HOST_BRIDGE_MEM64_DECODE             If this bit is set, then the PCI root bridge supports 64-bit memory
-                                                windows. If this bit is not set, the PCI bus driver needs to include
-                                                requests for a 64-bit memory address in the corresponding 32-bit
-                                                memory pool.
-
-   @param[in]   This               The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
-   @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in which the caller is interested. Type
-                                   EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
-   @param[out]  Attributes         The pointer to attribte of root bridge, it is output parameter
-
-   @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL
-   @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.
-   @retval EFI_SUCCESS             Success to get attribute of interested root bridge.
-
-**/
-EFI_STATUS
-EFIAPI
-GetAttributes(
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN  EFI_HANDLE                                       RootBridgeHandle,
-  OUT UINT64                                           *Attributes
-  )
-{
-  LIST_ENTRY                            *List;
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-
-  if (Attributes == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    if (RootBridgeHandle == RootBridgeInstance->Handle) {
-      *Attributes = RootBridgeInstance->RootBridgeAttrib;
-      return EFI_SUCCESS;
-    }
-
-    List = List->ForwardLink;
-  }
-
-  //
-  // RootBridgeHandle is not an EFI_HANDLE
-  // that was returned on a previous call to GetNextRootBridge()
-  //
-  return EFI_INVALID_PARAMETER;
-}
-
-/**
-   Sets up the specified PCI root bridge for the bus enumeration process.
-
-   This member function sets up the root bridge for bus enumeration and returns the PCI bus range
-   over which the search should be performed in ACPI 2.0 resource descriptor format.
-
-   @param[in]   This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
-   @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.
-   @param[out]  Configuration     Pointer to the pointer to the PCI bus resource descriptor.
-
-   @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
-   @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.
-   @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.
-
-**/
-EFI_STATUS
-EFIAPI
-StartBusEnumeration(
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN  EFI_HANDLE                                       RootBridgeHandle,
-  OUT VOID                                             **Configuration
-  )
-{
-  LIST_ENTRY                            *List;
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-  VOID                                  *Buffer;
-  UINT8                                 *Temp;
-  UINT64                                BusStart;
-  UINT64                                BusEnd;
-
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    if (RootBridgeHandle == RootBridgeInstance->Handle) {
-      //
-      // Set up the Root Bridge for Bus Enumeration
-      //
-      BusStart = RootBridgeInstance->BusBase;
-      BusEnd   = RootBridgeInstance->BusLimit;
-      //
-      // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR
-      //
-
-      Buffer = AllocatePool (sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR));
-      if (Buffer == NULL) {
-        return EFI_OUT_OF_RESOURCES;
-      }
-
-      Temp = (UINT8 *)Buffer;
-
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Desc = 0x8A;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Len  = 0x2B;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->ResType = 2;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->GenFlag = 0;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->SpecificFlag = 0;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrSpaceGranularity = 0;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMin = BusStart;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMax = 0;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrTranslationOffset = 0;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrLen = BusEnd - BusStart + 1;
-
-      Temp = Temp + sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
-      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc = 0x79;
-      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;
-
-      *Configuration = Buffer;
-      return EFI_SUCCESS;
-    }
-    List = List->ForwardLink;
-  }
-
-  return EFI_INVALID_PARAMETER;
-}
-
-/**
-   Programs the PCI root bridge hardware so that it decodes the specified PCI bus range.
-
-   This member function programs the specified PCI root bridge to decode the bus range that is
-   specified by the input parameter Configuration.
-   The bus range information is specified in terms of the ACPI 2.0 resource descriptor format.
-
-   @param[in] This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
-   @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be programmed
-   @param[in] Configuration     The pointer to the PCI bus resource descriptor
-
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
-   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
-   @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI 2.0 bus resource descriptor.
-   @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource descriptors other than
-                                  bus descriptors.
-   @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid ACPI resource descriptors.
-   @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this root bridge.
-   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this root bridge.
-   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
-   @retval EFI_SUCCESS            The bus range for the PCI root bridge was programmed.
-
-**/
-EFI_STATUS
-EFIAPI
-SetBusNumbers(
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN EFI_HANDLE                                       RootBridgeHandle,
-  IN VOID                                             *Configuration
-  )
-{
-  LIST_ENTRY                            *List;
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-  UINT8                                 *Ptr;
-  UINTN                                 BusStart;
-  UINTN                                 BusEnd;
-  UINTN                                 BusLen;
-
-  if (Configuration == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Ptr = Configuration;
-
-  //
-  // Check the Configuration is valid
-  //
-  if(*Ptr != ACPI_ADDRESS_SPACE_DESCRIPTOR) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType != 2) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Ptr += sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
-  if (*Ptr != ACPI_END_TAG_DESCRIPTOR) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  Ptr = Configuration;
-
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    if (RootBridgeHandle == RootBridgeInstance->Handle) {
-      BusStart = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin;
-      BusLen = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen;
-      BusEnd = BusStart + BusLen - 1;
-
-      if (BusStart > BusEnd) {
-        return EFI_INVALID_PARAMETER;
-      }
-
-      if ((BusStart < RootBridgeInstance->BusBase) || (BusEnd > RootBridgeInstance->BusLimit)) {
-        return EFI_INVALID_PARAMETER;
-      }
-
-      //
-      // Update the Bus Range
-      //
-      RootBridgeInstance->ResAllocNode[TypeBus].Base   = BusStart;
-      RootBridgeInstance->ResAllocNode[TypeBus].Length = BusLen;
-      RootBridgeInstance->ResAllocNode[TypeBus].Status = ResAllocated;
-
-      //
-      // Program the Root Bridge Hardware
-      //
-
-      return EFI_SUCCESS;
-    }
-
-    List = List->ForwardLink;
-  }
-
-  return EFI_INVALID_PARAMETER;
-}
-
-VOID
-EFIAPI
-SubmitGetResourceType(
- IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *Ptr,
- OUT   UINT64*                            Index
-)
-{
-  switch (Ptr->ResType) {
-    case 0:
-      if (Ptr->AddrSpaceGranularity == 32) {
-        if (Ptr->SpecificFlag == 0x06)
-          *Index = TypePMem32;
-        else
-          *Index = TypeMem32;
-      }
-
-      if (Ptr->AddrSpaceGranularity == 64) {
-        if (Ptr->SpecificFlag == 0x06)
-          *Index = TypePMem64;
-        else
-          *Index = TypeMem64;
-      }
-      break;
-
-    case 1:
-      *Index = TypeIo;
-      break;
-
-    default:
-      break;
-  };
-
-}
-
-/**
-   Submits the I/O and memory resource requirements for the specified PCI root bridge.
-
-   This function is used to submit all the I/O and memory resources that are required by the specified
-   PCI root bridge. The input parameter Configuration is used to specify the following:
-   - The various types of resources that are required
-   - The associated lengths in terms of ACPI 2.0 resource descriptor format
-
-   @param[in] This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
-   @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory resource requirements are being submitted.
-   @param[in] Configuration     The pointer to the PCI I/O and PCI memory resource descriptor.
-
-   @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI root bridge were accepted.
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
-   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
-   @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or more resource types that are
-                                  not supported by this PCI root bridge. This error will happen if the caller
-                                  did not combine resources according to Attributes that were returned by
-                                  GetAllocAttributes().
-   @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.
-   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for this PCI root bridge.
-
-**/
-EFI_STATUS
-EFIAPI
-SubmitResources(
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN EFI_HANDLE                                       RootBridgeHandle,
-  IN VOID                                             *Configuration
-  )
-{
-  LIST_ENTRY                            *List;
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-  UINT8                                 *Temp;
-  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *Ptr;
-  UINT64                                AddrLen;
-  UINT64                                Alignment;
-  UINTN                                 Index;
-
-  PCIE_DEBUG("In SubmitResources\n");
-  //
-  // Check the input parameter: Configuration
-  //
-  if (Configuration == NULL)
-    return EFI_INVALID_PARAMETER;
-
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  Temp = (UINT8 *)Configuration;
-  while ( *Temp == 0x8A)
-    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;
-
-  if (*Temp != 0x79)
-    return EFI_INVALID_PARAMETER;
-
-  Temp = (UINT8 *)Configuration;
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    if (RootBridgeHandle == RootBridgeInstance->Handle) {
-      while ( *Temp == 0x8A) {
-        Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp ;
-        PCIE_DEBUG("Ptr->ResType:%d\n", Ptr->ResType);
-        PCIE_DEBUG("Ptr->Addrlen:%llx\n", Ptr->AddrLen);
-        PCIE_DEBUG("Ptr->AddrRangeMax:%llx\n", Ptr->AddrRangeMax);
-        PCIE_DEBUG("Ptr->AddrRangeMin:%llx\n", Ptr->AddrRangeMin);
-        PCIE_DEBUG("Ptr->SpecificFlag:%llx\n", Ptr->SpecificFlag);
-        PCIE_DEBUG("Ptr->AddrSpaceGranularity:%d\n", Ptr->AddrSpaceGranularity);
-        PCIE_DEBUG("RootBridgeInstance->RootBridgeAttrib:%llx\n", RootBridgeInstance->RootBridgeAttrib);
-        //
-        // Check address range alignment
-        //
-        if (Ptr->AddrRangeMax != (GetPowerOfTwo64 (Ptr->AddrRangeMax + 1) - 1)) {
-          return EFI_INVALID_PARAMETER;
-        }
-        Index = 0;
-        SubmitGetResourceType(Ptr,&Index);
-        AddrLen = (UINTN) Ptr->AddrLen;
-        Alignment = (UINTN) Ptr->AddrRangeMax;
-        RootBridgeInstance->ResAllocNode[Index].Length  = AddrLen;
-        RootBridgeInstance->ResAllocNode[Index].Alignment = Alignment;
-        RootBridgeInstance->ResAllocNode[Index].Status  = ResRequested;
-        HostBridgeInstance->ResourceSubmited = TRUE;
-
-        Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;
-      }
-
-      return EFI_SUCCESS;
-    }
-
-    List = List->ForwardLink;
-  }
-  return EFI_INVALID_PARAMETER;
-}
-
-/**
-   Returns the proposed resource settings for the specified PCI root bridge.
-
-   This member function returns the proposed resource settings for the specified PCI root bridge. The
-   proposed resource settings are prepared when NotifyPhase() is called with a Phase of
-   EfiPciHostBridgeAllocateResources. The output parameter Configuration
-   specifies the following:
-   - The various types of resources, excluding bus resources, that are allocated
-   - The associated lengths in terms of ACPI 2.0 resource descriptor format
-
-   @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
-   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
-   @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.
-
-   @retval EFI_SUCCESS            The requested parameters were returned.
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-SetResource(
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance,
-  VOID                                  *Buffer
-
-)
-{
-  UINTN                                 Index;
-  UINT8                                 *Temp;
-  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *Ptr;
-  UINT64                                ResStatus;
-
-  Temp = Buffer;
-
-  for (Index = 0; Index < TypeBus; Index ++)
-  {
-    if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
-      Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp ;
-      ResStatus = RootBridgeInstance->ResAllocNode[Index].Status;
-
-      switch (Index) {
-
-      case TypeIo:
-        //
-        // Io
-        //
-        Ptr->Desc = 0x8A;
-        Ptr->Len  = 0x2B;
-        Ptr->ResType = 1;
-        Ptr->GenFlag = 0;
-        Ptr->SpecificFlag = 0;
-        /* PCIE Device Iobar address should be based on IoBase */
-        Ptr->AddrRangeMin = RootBridgeInstance->IoBase;
-        Ptr->AddrRangeMax = 0;
-        Ptr->AddrTranslationOffset = \
-             (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
-        Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
-        break;
-
-      case TypeMem32:
-        //
-        // Memory 32
-        //
-        Ptr->Desc = 0x8A;
-        Ptr->Len  = 0x2B;
-        Ptr->ResType = 0;
-        Ptr->GenFlag = 0;
-        Ptr->SpecificFlag = 0;
-        Ptr->AddrSpaceGranularity = 32;
-        /* PCIE device Bar should be based on PciRegionBase */
-        if (RootBridgeInstance->PciRegionBase > MAX_UINT32) {
-          DEBUG((DEBUG_ERROR, "PCIE Res(TypeMem32) unsupported.\n"));
-          return EFI_UNSUPPORTED;
-        }
-        Ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base - RootBridgeInstance->MemBase +
-                            RootBridgeInstance->PciRegionBase;
-        Ptr->AddrRangeMax = 0;
-        Ptr->AddrTranslationOffset = \
-             (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
-        Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
-        break;
-
-      case TypePMem32:
-        //
-        // Prefetch memory 32
-        //
-        Ptr->Desc = 0x8A;
-        Ptr->Len  = 0x2B;
-        Ptr->ResType = 0;
-        Ptr->GenFlag = 0;
-        Ptr->SpecificFlag = 6;
-        Ptr->AddrSpaceGranularity = 32;
-        /* PCIE device Bar should be based on PciRegionBase */
-        if (RootBridgeInstance->PciRegionBase > MAX_UINT32) {
-          DEBUG((DEBUG_ERROR, "PCIE Res(TypePMem32) unsupported.\n"));
-          return EFI_UNSUPPORTED;
-        }
-        Ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base - RootBridgeInstance->MemBase +
-                            RootBridgeInstance->PciRegionBase;
-        Ptr->AddrRangeMax = 0;
-        Ptr->AddrTranslationOffset = \
-             (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
-        Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
-        break;
-
-      case TypeMem64:
-        //
-        // Memory 64
-        //
-        Ptr->Desc = 0x8A;
-        Ptr->Len  = 0x2B;
-        Ptr->ResType = 0;
-        Ptr->GenFlag = 0;
-        Ptr->SpecificFlag = 0;
-        Ptr->AddrSpaceGranularity = 64;
-        /* PCIE device Bar should be based on PciRegionBase */
-        Ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base - RootBridgeInstance->MemBase +
-                            RootBridgeInstance->PciRegionBase;
-        Ptr->AddrRangeMax = 0;
-        Ptr->AddrTranslationOffset = \
-             (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
-        Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
-        break;
-
-      case TypePMem64:
-        //
-        // Prefetch memory 64
-        //
-        Ptr->Desc = 0x8A;
-        Ptr->Len  = 0x2B;
-        Ptr->ResType = 0;
-        Ptr->GenFlag = 0;
-        Ptr->SpecificFlag = 6;
-        Ptr->AddrSpaceGranularity = 64;
-        /* PCIE device Bar should be based on PciRegionBase */
-        Ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base - RootBridgeInstance->MemBase +
-                            RootBridgeInstance->PciRegionBase;
-        Ptr->AddrRangeMax = 0;
-        Ptr->AddrTranslationOffset = \
-             (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
-        Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
-        break;
-      };
-      PCIE_DEBUG("Ptr->ResType:%d\n", Ptr->ResType);
-      PCIE_DEBUG("Ptr->Addrlen:%llx\n", Ptr->AddrLen);
-      PCIE_DEBUG("Ptr->AddrRangeMax:%llx\n", Ptr->AddrRangeMax);
-      PCIE_DEBUG("Ptr->AddrRangeMin:%llx\n", Ptr->AddrRangeMin);
-      PCIE_DEBUG("Ptr->SpecificFlag:%llx\n", Ptr->SpecificFlag);
-      PCIE_DEBUG("Ptr->AddrTranslationOffset:%d\n", Ptr->AddrTranslationOffset);
-      PCIE_DEBUG("Ptr->AddrSpaceGranularity:%d\n", Ptr->AddrSpaceGranularity);
-
-      Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
-    }
-  }
-  ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc = 0x79;
-  ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;
-
-  return EFI_SUCCESS;
-}
-/**
-   Returns the proposed resource settings for the specified PCI root bridge.
-
-   This member function returns the proposed resource settings for the specified PCI root bridge. The
-   proposed resource settings are prepared when NotifyPhase() is called with a Phase of
-   EfiPciHostBridgeAllocateResources. The output parameter Configuration
-   specifies the following:
-   - The various types of resources, excluding bus resources, that are allocated
-   - The associated lengths in terms of ACPI 2.0 resource descriptor format
-
-   @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
-   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
-   @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.
-
-   @retval EFI_SUCCESS            The requested parameters were returned.
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-GetProposedResources(
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN  EFI_HANDLE                                       RootBridgeHandle,
-  OUT VOID                                             **Configuration
-  )
-{
-  LIST_ENTRY                            *List;
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-  UINTN                                 Index;
-  UINTN                                 Number;
-  VOID                                  *Buffer;
-
-  Buffer = NULL;
-  Number = 0;
-
-  PCIE_DEBUG("In GetProposedResources\n");
-  //
-  // Get the Host Bridge Instance from the resource allocation protocol
-  //
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  //
-  // Enumerate the root bridges in this host bridge
-  //
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    if (RootBridgeHandle == RootBridgeInstance->Handle) {
-      for (Index = 0; Index < TypeBus; Index ++) {
-        if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
-          Number ++;
-        }
-      }
-
-      Buffer = AllocateZeroPool (Number * sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR));
-      if (Buffer == NULL) {
-        return EFI_OUT_OF_RESOURCES;
-      }
-
-      (VOID)SetResource(RootBridgeInstance,Buffer);
-
-      *Configuration = Buffer;
-
-      return EFI_SUCCESS;
-    }
-
-    List = List->ForwardLink;
-  }
-
-  return EFI_INVALID_PARAMETER;
-}
-
-/**
-   Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various
-   stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual
-   PCI controllers before enumeration.
-
-   This function is called during the PCI enumeration process. No specific action is expected from this
-   member function. It allows the host bridge driver to preinitialize individual PCI controllers before
-   enumeration.
-
-   @param This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
-   @param RootBridgeHandle  The associated PCI root bridge handle. Type EFI_HANDLE is defined in
-                            InstallProtocolInterface() in the UEFI 2.0 Specification.
-   @param PciAddress        The address of the PCI device on the PCI bus. This address can be passed to the
-                            EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to access the PCI
-                            configuration space of the device. See Table 12-1 in the UEFI 2.0 Specification for
-                            the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
-   @param Phase             The phase of the PCI device enumeration.
-
-   @retval EFI_SUCCESS              The requested parameters were returned.
-   @retval EFI_INVALID_PARAMETER    RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_INVALID_PARAMETER    Phase is not a valid phase that is defined in
-                                    EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
-   @retval EFI_DEVICE_ERROR         Programming failed due to a hardware error. The PCI enumerator should
-                                    not enumerate this device, including its child devices if it is a PCI-to-PCI
-                                    bridge.
-
-**/
-EFI_STATUS
-EFIAPI
-PreprocessController (
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL          *This,
-  IN  EFI_HANDLE                                                RootBridgeHandle,
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS               PciAddress,
-  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE              Phase
-  )
-{
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-  LIST_ENTRY                            *List;
-
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  //
-  // Enumerate the root bridges in this host bridge
-  //
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    if (RootBridgeHandle == RootBridgeInstance->Handle) {
-      break;
-    }
-    List = List->ForwardLink;
-  }
-  if (List == &HostBridgeInstance->Head) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if ((UINT32)Phase > EfiPciBeforeResourceCollection) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  return EFI_SUCCESS;
-}
diff --git a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c b/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
deleted file mode 100644
index 3c265ea43378..000000000000
--- a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
+++ /dev/null
@@ -1,2220 +0,0 @@
-/**
- * Copyright (c) 2014, AppliedMicro Corp. All rights reserved.
- * Copyright (c) 2016, Hisilicon Limited. All rights reserved.
- * Copyright (c) 2016, Linaro Limited. All rights reserved.
- *
- * This program and the accompanying materials
- * are licensed and made available under the terms and conditions of the BSD License
- * which accompanies this distribution.  The full text of the license may be found at
- * http://opensource.org/licenses/bsd-license.php
- *
- * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
- *
- **/
-
-#include "PciHostBridge.h"
-#include <IndustryStandard/PciExpress30.h>
-#include <Library/DevicePathLib.h>
-#include <Library/DmaLib.h>
-#include <Library/PciExpressLib.h>
-#include <Regs/HisiPcieV1RegOffset.h>
-
-
-typedef struct {
-  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     SpaceDesp[TypeMax];
-  EFI_ACPI_END_TAG_DESCRIPTOR           EndDesp;
-} RESOURCE_CONFIGURATION;
-
-RESOURCE_CONFIGURATION Configuration = {
-  {{0x8A, 0x2B, 1, 0, 0, 0, 0, 0, 0, 0},
-  {0x8A, 0x2B, 0, 0, 0, 32, 0, 0, 0, 0},
-  {0x8A, 0x2B, 0, 0, 6, 32, 0, 0, 0, 0},
-  {0x8A, 0x2B, 0, 0, 0, 64, 0, 0, 0, 0},
-  {0x8A, 0x2B, 0, 0, 6, 64, 0, 0, 0, 0},
-  {0x8A, 0x2B, 2, 0, 0, 0, 0, 0, 0, 0}},
-  {0x79, 0}
-};
-
-//
-// Protocol Member Function Prototypes
-//
-
-/**
-   Polls an address in memory mapped I/O space until an exit condition is met, or
-   a timeout occurs.
-
-   This function provides a standard way to poll a PCI memory location. A PCI memory read
-   operation is performed at the PCI memory address specified by Address for the width specified
-   by Width. The result of this PCI memory read operation is stored in Result. This PCI memory
-   read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &
-   Mask) is equal to Value.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operations.
-   @param[in]   Address   The base address of the memory operations. The caller is
-                          responsible for aligning Address if required.
-   @param[in]   Mask      Mask used for the polling criteria. Bytes above Width in Mask
-                          are ignored. The bits in the bytes below Width which are zero in
-                          Mask are ignored when polling the memory address.
-   @param[in]   Value     The comparison value used for the polling exit criteria.
-   @param[in]   Delay     The number of 100 ns units to poll. Note that timer available may
-                          be of poorer granularity.
-   @param[out]  Result    Pointer to the last value read from the memory location.
-
-   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
-   @retval EFI_INVALID_PARAMETER  Width is invalid.
-   @retval EFI_INVALID_PARAMETER  Result is NULL.
-   @retval EFI_TIMEOUT            Delay expired before a match occurred.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPollMem (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN  UINT64                                 Address,
-  IN  UINT64                                 Mask,
-  IN  UINT64                                 Value,
-  IN  UINT64                                 Delay,
-  OUT UINT64                                 *Result
-  );
-
-/**
-   Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is
-   satisfied or after a defined duration.
-
-   This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is
-   performed at the PCI I/O address specified by Address for the width specified by Width.
-   The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is
-   repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal
-   to Value.
-
-   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in] Width     Signifies the width of the I/O operations.
-   @param[in] Address   The base address of the I/O operations. The caller is responsible
-                        for aligning Address if required.
-   @param[in] Mask      Mask used for the polling criteria. Bytes above Width in Mask
-                        are ignored. The bits in the bytes below Width which are zero in
-                        Mask are ignored when polling the I/O address.
-   @param[in] Value     The comparison value used for the polling exit criteria.
-   @param[in] Delay     The number of 100 ns units to poll. Note that timer available may
-                        be of poorer granularity.
-   @param[out] Result   Pointer to the last value read from the memory location.
-
-   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
-   @retval EFI_INVALID_PARAMETER  Width is invalid.
-   @retval EFI_INVALID_PARAMETER  Result is NULL.
-   @retval EFI_TIMEOUT            Delay expired before a match occurred.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPollIo (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN  UINT64                                 Address,
-  IN  UINT64                                 Mask,
-  IN  UINT64                                 Value,
-  IN  UINT64                                 Delay,
-  OUT UINT64                                 *Result
-  );
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
-
-   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
-   registers in the PCI root bridge memory space.
-   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
-   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operation.
-   @param[in]   Address   The base address of the memory operation. The caller is
-                          responsible for aligning the Address if required.
-   @param[in]   Count     The number of memory operations to perform. Bytes moved is
-                          Width size * Count, starting at Address.
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoMemRead (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  OUT    VOID                                   *Buffer
-  );
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
-
-   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
-   registers in the PCI root bridge memory space.
-   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
-   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operation.
-   @param[in]   Address   The base address of the memory operation. The caller is
-                          responsible for aligning the Address if required.
-   @param[in]   Count     The number of memory operations to perform. Bytes moved is
-                          Width size * Count, starting at Address.
-   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoMemWrite (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  IN     VOID                                   *Buffer
-  );
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
-
-   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width       Signifies the width of the memory operations.
-   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for
-                            aligning the Address if required.
-   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
-                            size * Count, starting at Address.
-   @param[out]  UserBuffer  For read operations, the destination buffer to store the results. For
-                            write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoIoRead (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 UserAddress,
-  IN     UINTN                                  Count,
-  OUT    VOID                                   *UserBuffer
-  );
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
-
-   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width       Signifies the width of the memory operations.
-   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for
-                            aligning the Address if required.
-   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
-                            size * Count, starting at Address.
-   @param[in]   UserBuffer  For read operations, the destination buffer to store the results. For
-                            write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoIoWrite (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 UserAddress,
-  IN     UINTN                                  Count,
-  IN     VOID                                   *UserBuffer
-  );
-
-/**
-   Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI
-   root bridge memory space.
-
-   The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory
-   space to another region of PCI root bridge memory space. This is especially useful for video scroll
-   operation on a memory mapped video buffer.
-   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
-   any alignment and memory width restrictions that a PCI root bridge on a platform might require.
-
-   @param[in] This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
-   @param[in] Width       Signifies the width of the memory operations.
-   @param[in] DestAddress The destination address of the memory operation. The caller is
-                          responsible for aligning the DestAddress if required.
-   @param[in] SrcAddress  The source address of the memory operation. The caller is
-                          responsible for aligning the SrcAddress if required.
-   @param[in] Count       The number of memory operations to perform. Bytes moved is
-                          Width size * Count, starting at DestAddress and SrcAddress.
-
-   @retval  EFI_SUCCESS             The data was copied from one memory region to another memory region.
-   @retval  EFI_INVALID_PARAMETER   Width is invalid for this PCI root bridge.
-   @retval  EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoCopyMem (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 DestAddress,
-  IN     UINT64                                 SrcAddress,
-  IN     UINTN                                  Count
-  );
-
-/**
-   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
-
-   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
-   registers for a PCI controller.
-   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
-   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
-   require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operations.
-   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
-   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
-                          moved is Width size * Count, starting at Address.
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPciRead (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  OUT    VOID                                   *Buffer
-  );
-
-/**
-   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
-
-   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
-   registers for a PCI controller.
-   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
-   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
-   require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operations.
-   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
-   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
-                          moved is Width size * Count, starting at Address.
-   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPciWrite (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  IN     VOID                                   *Buffer
-  );
-
-/**
-   Provides the PCI controller-specific addresses required to access system memory from a
-   DMA bus master.
-
-   The Map() function provides the PCI controller specific addresses needed to access system
-   memory. This function is used to map system memory for PCI bus master DMA accesses.
-
-   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]       Operation       Indicates if the bus master is going to read or write to system memory.
-   @param[in]       HostAddress     The system memory address to map to the PCI controller.
-   @param[in, out]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.
-   @param[out]      DeviceAddress   The resulting map address for the bus master PCI controller to use
-                                    to access the system memory's HostAddress.
-   @param[out]      Mapping         The value to pass to Unmap() when the bus master DMA operation is complete.
-
-   @retval EFI_SUCCESS            The range was mapped for the returned NumberOfBytes.
-   @retval EFI_INVALID_PARAMETER  Operation is invalid.
-   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
-   @retval EFI_INVALID_PARAMETER  NumberOfBytes is NULL.
-   @retval EFI_INVALID_PARAMETER  DeviceAddress is NULL.
-   @retval EFI_INVALID_PARAMETER  Mapping is NULL.
-   @retval EFI_UNSUPPORTED        The HostAddress cannot be mapped as a common buffer.
-   @retval EFI_DEVICE_ERROR       The system hardware could not map the requested address.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoMap (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL            *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,
-  IN     VOID                                       *HostAddress,
-  IN OUT UINTN                                      *NumberOfBytes,
-  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,
-  OUT    VOID                                       **Mapping
-  );
-
-/**
-   Completes the Map() operation and releases any corresponding resources.
-
-   The Unmap() function completes the Map() operation and releases any corresponding resources.
-   If the operation was an EfiPciOperationBusMasterWrite or
-   EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.
-   Any resources used for the mapping are freed.
-
-   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in] Mapping   The mapping value returned from Map().
-
-   @retval EFI_SUCCESS            The range was unmapped.
-   @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by Map().
-   @retval EFI_DEVICE_ERROR       The data was not committed to the target system memory.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoUnmap (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN  VOID                             *Mapping
-  );
-
-/**
-   Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or
-   EfiPciOperationBusMasterCommonBuffer64 mapping.
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param Type        This parameter is not used and must be ignored.
-   @param MemoryType  The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.
-   @param Pages       The number of pages to allocate.
-   @param HostAddress A pointer to store the base system memory address of the allocated range.
-   @param Attributes  The requested bit mask of attributes for the allocated range. Only
-                      the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED,
-                      and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.
-
-   @retval EFI_SUCCESS            The requested memory pages were allocated.
-   @retval EFI_INVALID_PARAMETER  MemoryType is invalid.
-   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
-   @retval EFI_UNSUPPORTED        Attributes is unsupported. The only legal attribute bits are
-                                  MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
-   @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoAllocateBuffer (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN  EFI_ALLOCATE_TYPE                Type,
-  IN  EFI_MEMORY_TYPE                  MemoryType,
-  IN  UINTN                            Pages,
-  OUT VOID                             **HostAddress,
-  IN  UINT64                           Attributes
-  );
-
-/**
-   Frees memory that was allocated with AllocateBuffer().
-
-   The FreeBuffer() function frees memory that was allocated with AllocateBuffer().
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param Pages       The number of pages to free.
-   @param HostAddress The base system memory address of the allocated range.
-
-   @retval EFI_SUCCESS            The requested memory pages were freed.
-   @retval EFI_INVALID_PARAMETER  The memory range specified by HostAddress and Pages
-                                  was not allocated with AllocateBuffer().
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoFreeBuffer (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN  UINTN                            Pages,
-  OUT VOID                             *HostAddress
-  );
-
-/**
-   Flushes all PCI posted write transactions from a PCI host bridge to system memory.
-
-   The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system
-   memory. Posted write transactions are generated by PCI bus masters when they perform write
-   transactions to target addresses in system memory.
-   This function does not flush posted write transactions from any PCI bridges. A PCI controller
-   specific action must be taken to guarantee that the posted write transactions have been flushed from
-   the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with
-   a PCI read transaction from the PCI controller prior to calling Flush().
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-
-   @retval EFI_SUCCESS        The PCI posted write transactions were flushed from the PCI host
-                              bridge to system memory.
-   @retval EFI_DEVICE_ERROR   The PCI posted write transactions were not flushed from the PCI
-                              host bridge due to a hardware error.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoFlush (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This
-  );
-
-/**
-   Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the
-   attributes that a PCI root bridge is currently using.
-
-   The GetAttributes() function returns the mask of attributes that this PCI root bridge supports
-   and the mask of attributes that the PCI root bridge is currently using.
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param Supported   A pointer to the mask of attributes that this PCI root bridge
-                      supports setting with SetAttributes().
-   @param Attributes  A pointer to the mask of attributes that this PCI root bridge is
-                      currently using.
-
-   @retval  EFI_SUCCESS           If Supports is not NULL, then the attributes that the PCI root
-                                  bridge supports is returned in Supports. If Attributes is
-                                  not NULL, then the attributes that the PCI root bridge is currently
-                                  using is returned in Attributes.
-   @retval  EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoGetAttributes (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  OUT UINT64                           *Supported,
-  OUT UINT64                           *Attributes
-  );
-
-/**
-   Sets attributes for a resource range on a PCI root bridge.
-
-   The SetAttributes() function sets the attributes specified in Attributes for the PCI root
-   bridge on the resource range specified by ResourceBase and ResourceLength. Since the
-   granularity of setting these attributes may vary from resource type to resource type, and from
-   platform to platform, the actual resource range and the one passed in by the caller may differ. As a
-   result, this function may set the attributes specified by Attributes on a larger resource range
-   than the caller requested. The actual range is returned in ResourceBase and
-   ResourceLength. The caller is responsible for verifying that the actual range for which the
-   attributes were set is acceptable.
-
-   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]       Attributes      The mask of attributes to set. If the attribute bit
-                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, or
-                                    MEMORY_DISABLE is set, then the resource range is specified by
-                                    ResourceBase and ResourceLength. If
-                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
-                                    MEMORY_DISABLE are not set, then ResourceBase and
-                                    ResourceLength are ignored, and may be NULL.
-   @param[in, out]  ResourceBase    A pointer to the base address of the resource range to be modified
-                                    by the attributes specified by Attributes.
-   @param[in, out]  ResourceLength  A pointer to the length of the resource range to be modified by the
-                                    attributes specified by Attributes.
-
-   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
-   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
-   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoSetAttributes (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN     UINT64                           Attributes,
-  IN OUT UINT64                           *ResourceBase,
-  IN OUT UINT64                           *ResourceLength
-  );
-
-/**
-   Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0
-   resource descriptors.
-
-   There are only two resource descriptor types from the ACPI Specification that may be used to
-   describe the current resources allocated to a PCI root bridge. These are the QWORD Address
-   Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The
-   QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic
-   or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD
-   Address Space Descriptors followed by an End Tag.
-
-   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[out]  Resources   A pointer to the ACPI 2.0 resource descriptors that describe the
-                            current configuration of this PCI root bridge. The storage for the
-                            ACPI 2.0 resource descriptors is allocated by this function. The
-                            caller must treat the return buffer as read-only data, and the buffer
-                            must not be freed by the caller.
-
-   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
-   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
-   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoConfiguration (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  OUT    VOID                             **Resources
-  );
-
-//
-// Memory Controller Pci Root Bridge Io Module Variables
-//
-EFI_METRONOME_ARCH_PROTOCOL *mMetronome;
-
-//
-// Lookup table for increment values based on transfer widths
-//
-UINT8 mInStride[] = {
-  1, // EfiPciWidthUint8
-  2, // EfiPciWidthUint16
-  4, // EfiPciWidthUint32
-  8, // EfiPciWidthUint64
-  0, // EfiPciWidthFifoUint8
-  0, // EfiPciWidthFifoUint16
-  0, // EfiPciWidthFifoUint32
-  0, // EfiPciWidthFifoUint64
-  1, // EfiPciWidthFillUint8
-  2, // EfiPciWidthFillUint16
-  4, // EfiPciWidthFillUint32
-  8  // EfiPciWidthFillUint64
-};
-
-//
-// Lookup table for increment values based on transfer widths
-//
-UINT8 mOutStride[] = {
-  1, // EfiPciWidthUint8
-  2, // EfiPciWidthUint16
-  4, // EfiPciWidthUint32
-  8, // EfiPciWidthUint64
-  1, // EfiPciWidthFifoUint8
-  2, // EfiPciWidthFifoUint16
-  4, // EfiPciWidthFifoUint32
-  8, // EfiPciWidthFifoUint64
-  0, // EfiPciWidthFillUint8
-  0, // EfiPciWidthFillUint16
-  0, // EfiPciWidthFillUint32
-  0  // EfiPciWidthFillUint64
-};
-
-
-UINT64 GetPcieCfgAddress (
-    UINT64 Ecam,
-    UINTN Bus,
-    UINTN Device,
-    UINTN Function,
-    UINTN Reg
-    )
-{
-  return Ecam + PCI_EXPRESS_LIB_ADDRESS (Bus, Device, Function, Reg);
-}
-
-
-BOOLEAN PcieIsLinkUp (UINT32 SocType, UINTN RbPciBar, UINTN Port)
-{
-    UINT32                     Value = 0;
-
-    if (0x1610 == SocType)
-    {
-        Value = MmioRead32(RbPciBar + 0x131C);
-        if ((Value & 0x3F) == 0x11)
-        {
-            return TRUE;
-        }
-        return FALSE;
-    }
-    else
-    {
-        Value = MmioRead32 (0xb0000000 + 0x6818 + 0x100 * Port);
-        if ((Value & 0x3F) == 0x11)
-        {
-            return TRUE;
-        }
-        return FALSE;
-    }
-}
-
-/**
-
-  Construct the Pci Root Bridge Io protocol
-
-  @param Protocol         Point to protocol instance
-  @param HostBridgeHandle Handle of host bridge
-  @param Attri            Attribute of host bridge
-  @param ResAppeture      ResourceAppeture for host bridge
-
-  @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.
-
-**/
-EFI_STATUS
-RootBridgeConstructor (
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *Protocol,
-  IN EFI_HANDLE                         HostBridgeHandle,
-  IN UINT64                             Attri,
-  IN PCI_ROOT_BRIDGE_RESOURCE_APPETURE  *ResAppeture,
-  IN UINT32                             Seg
-  )
-{
-  EFI_STATUS                        Status;
-  PCI_ROOT_BRIDGE_INSTANCE          *PrivateData;
-  PCI_RESOURCE_TYPE                 Index;
-
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol);
-
-  //
-  // The host to pci bridge, the host memory and io addresses are
-  // direct mapped to pci addresses, so no need translate, set bases to 0.
-  //
-  PrivateData->MemBase = ResAppeture->MemBase;
-  PrivateData->IoBase  = ResAppeture->IoBase;
-  PrivateData->RbPciBar = ResAppeture->RbPciBar;
-  PrivateData->MemLimit = ResAppeture->MemLimit;
-  PrivateData->IoLimit  = ResAppeture->IoLimit;
-  PrivateData->Ecam = ResAppeture->Ecam;
-  PrivateData->CpuMemRegionBase = ResAppeture->CpuMemRegionBase;
-  PrivateData->CpuIoRegionBase = ResAppeture->CpuIoRegionBase;
-  PrivateData->PciRegionBase = ResAppeture->PciRegionBase;
-  PrivateData->PciRegionLimit = ResAppeture->PciRegionLimit;
-
-  //
-  // Bus Appeture for this Root Bridge (Possible Range)
-  //
-  PrivateData->BusBase  = ResAppeture->BusBase;
-  PrivateData->BusLimit = ResAppeture->BusLimit;
-
-  //
-  // Specific for this chipset
-  //
-  for (Index = TypeIo; Index < TypeMax; Index++) {
-    PrivateData->ResAllocNode[Index].Type      = Index;
-    PrivateData->ResAllocNode[Index].Base      = 0;
-    PrivateData->ResAllocNode[Index].Length    = 0;
-    PrivateData->ResAllocNode[Index].Status    = ResNone;
-  }
-
-  PrivateData->RootBridgeAttrib = Attri;
-
-  PrivateData->Supports    = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | \
-                             EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \
-                             EFI_PCI_ATTRIBUTE_VGA_MEMORY | \
-                             EFI_PCI_ATTRIBUTE_VGA_IO_16  | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16 | \
-                             EFI_PCI_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER;
-  PrivateData->Attributes  = PrivateData->Supports;
-
-  Protocol->ParentHandle   = HostBridgeHandle;
-
-  Protocol->PollMem        = RootBridgeIoPollMem;
-  Protocol->PollIo         = RootBridgeIoPollIo;
-
-  Protocol->Mem.Read       = RootBridgeIoMemRead;
-  Protocol->Mem.Write      = RootBridgeIoMemWrite;
-
-  Protocol->Io.Read        = RootBridgeIoIoRead;
-  Protocol->Io.Write       = RootBridgeIoIoWrite;
-
-  Protocol->CopyMem        = RootBridgeIoCopyMem;
-
-  Protocol->Pci.Read       = RootBridgeIoPciRead;
-  Protocol->Pci.Write      = RootBridgeIoPciWrite;
-
-  Protocol->Map            = RootBridgeIoMap;
-  Protocol->Unmap          = RootBridgeIoUnmap;
-
-  Protocol->AllocateBuffer = RootBridgeIoAllocateBuffer;
-  Protocol->FreeBuffer     = RootBridgeIoFreeBuffer;
-
-  Protocol->Flush          = RootBridgeIoFlush;
-
-  Protocol->GetAttributes  = RootBridgeIoGetAttributes;
-  Protocol->SetAttributes  = RootBridgeIoSetAttributes;
-
-  Protocol->Configuration  = RootBridgeIoConfiguration;
-
-  Protocol->SegmentNumber  = Seg;
-
-
-  Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)&mMetronome);
-  if (EFI_ERROR(Status))
-  {
-      DEBUG((EFI_D_ERROR,"LocateProtocol MetronomeArchProtocol Error\n"));
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge IO.
-
-  The I/O operations are carried out exactly as requested. The caller is responsible
-  for satisfying any alignment and I/O width restrictions that a PI System on a
-  platform might require. For example on some platforms, width requests of
-  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
-  be handled by the driver.
-
-  @param[in] This           A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-  @param[in] OperationType  I/O operation type: IO/MMIO/PCI.
-  @param[in] Width          Signifies the width of the I/O or Memory operation.
-  @param[in] Address        The base address of the I/O operation.
-  @param[in] Count          The number of I/O operations to perform. The number of
-                            bytes moved is Width size * Count, starting at Address.
-  @param[in] Buffer         For read operations, the destination buffer to store the results.
-                            For write operations, the source buffer from which to write data.
-
-  @retval EFI_SUCCESS            The parameters for this request pass the checks.
-  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
-  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
-  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
-                                 and Count is not valid for this PI system.
-
-**/
-EFI_STATUS
-RootBridgeIoCheckParameter (
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN OPERATION_TYPE                         OperationType,
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN UINT64                                 Address,
-  IN UINTN                                  Count,
-  IN VOID                                   *Buffer
-  )
-{
-  PCI_ROOT_BRIDGE_INSTANCE                     *PrivateData;
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  *PciRbAddr;
-  UINT64                                       MaxCount;
-  UINT64                                       Base;
-  UINT64                                       Limit;
-
-  //
-  // Check to see if Buffer is NULL
-  //
-  if (Buffer == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Check to see if Width is in the valid range
-  //
-  if ((UINT32)Width >= EfiPciWidthMaximum) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // For FIFO type, the target address won't increase during the access,
-  // so treat Count as 1
-  //
-  if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
-    Count = 1;
-  }
-
-  //
-  // Check to see if Width is in the valid range for I/O Port operations
-  //
-  Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
-  if ((OperationType != MemOperation) && (Width == EfiPciWidthUint64)) {
-    ASSERT (FALSE);
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Check to see if Address is aligned
-  //
-  if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {
-    return EFI_UNSUPPORTED;
-  }
-
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
-
-  //
-  // Check to see if any address associated with this transfer exceeds the maximum
-  // allowed address.  The maximum address implied by the parameters passed in is
-  // Address + Size * Count.  If the following condition is met, then the transfer
-  // is not supported.
-  //
-  //    Address + Size * Count > Limit + 1
-  //
-  // Since Limit can be the maximum integer value supported by the CPU and Count
-  // can also be the maximum integer value supported by the CPU, this range
-  // check must be adjusted to avoid all oveflow conditions.
-  //
-  // The following form of the range check is equivalent but assumes that
-  // Limit is of the form (2^n - 1).
-  //
-  if (OperationType == IoOperation) {
-    Base = PrivateData->IoBase;
-    Limit = PrivateData->IoLimit;
-  } else if (OperationType == MemOperation) {
-    Base = PrivateData->MemBase;
-    Limit = PrivateData->MemLimit;
-  } else {
-    PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;
-    if (PciRbAddr->Bus < PrivateData->BusBase || PciRbAddr->Bus > PrivateData->BusLimit) {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    /* The root complex has only one device / function */
-    if (PciRbAddr->Bus == PrivateData->BusBase && PciRbAddr->Device != 0) {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    /* The other side of the RC has only one device as well */
-    if (PciRbAddr->Bus == (PrivateData->BusBase + 1 ) && PciRbAddr->Device != 0) {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    if (PciRbAddr->Device > MAX_PCI_DEVICE_NUMBER || PciRbAddr->Function > MAX_PCI_FUNCTION_NUMBER) {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    if (PciRbAddr->ExtendedRegister != 0) {
-      Address = PciRbAddr->ExtendedRegister;
-    } else {
-      Address = PciRbAddr->Register;
-    }
-    Base = 0;
-    Limit = MAX_PCI_REG_ADDRESS;
-  }
-
-  if (Address < Base) {
-      return EFI_INVALID_PARAMETER;
-  }
-
-  if (Count == 0) {
-    if (Address > Limit) {
-      return EFI_UNSUPPORTED;
-    }
-  } else {
-    MaxCount = RShiftU64 (Limit, Width);
-    if (MaxCount < (Count - 1)) {
-      return EFI_UNSUPPORTED;
-    }
-    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
-      return EFI_UNSUPPORTED;
-    }
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-   Internal help function for read and write memory space.
-
-   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Write         Switch value for Read or Write.
-   @param[in]   Width         Signifies the width of the memory operations.
-   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.
-   @param[in]   Count         The number of PCI configuration operations to perform. Bytes
-                              moved is Width size * Count, starting at Address.
-   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
-                              write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-RootBridgeIoMemRW (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     BOOLEAN                                Write,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  IN OUT VOID                                   *Buffer
-  )
-{
-  EFI_STATUS                             Status;
-  UINT8                                  InStride;
-  UINT8                                  OutStride;
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  OperationWidth;
-  UINT8                                  *Uint8Buffer;
-  PCI_ROOT_BRIDGE_INSTANCE              *PrivateData;
-
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
-  /* Address is bus resource */
-  Address -= PrivateData->PciRegionBase;
-  Address += PrivateData->CpuMemRegionBase;
-
-  PCIE_DEBUG("RootBridgeIoMemRW Address:0x%llx\n", Address);
-  PCIE_DEBUG("RootBridgeIoMemRW Count:0x%llx\n", Count);
-  PCIE_DEBUG("RootBridgeIoMemRW Write:0x%llx\n", Write);
-  PCIE_DEBUG("RootBridgeIoMemRW Width:0x%llx\n", Width);
-
-  Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, Count, Buffer);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  InStride = mInStride[Width];
-  OutStride = mOutStride[Width];
-  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
-  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
-    if (Write) {
-      switch (OperationWidth) {
-        case EfiPciWidthUint8:
-          MmioWrite8 ((UINTN)Address, *Uint8Buffer);
-          break;
-        case EfiPciWidthUint16:
-          MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
-          break;
-        case EfiPciWidthUint32:
-          MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
-          break;
-        case EfiPciWidthUint64:
-          MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
-          break;
-        default:
-          //
-          // The RootBridgeIoCheckParameter call above will ensure that this
-          // path is not taken.
-          //
-          ASSERT (FALSE);
-          break;
-      }
-    } else {
-      switch (OperationWidth) {
-        case EfiPciWidthUint8:
-          *Uint8Buffer = MmioRead8 ((UINTN)Address);
-          break;
-        case EfiPciWidthUint16:
-          *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
-          break;
-        case EfiPciWidthUint32:
-          *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
-          break;
-        case EfiPciWidthUint64:
-          *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
-          break;
-        default:
-          //
-          // The RootBridgeIoCheckParameter call above will ensure that this
-          // path is not taken.
-          //
-          ASSERT (FALSE);
-          break;
-      }
-    }
-  }
-  return EFI_SUCCESS;
-}
-
-/**
-   Internal help function for read and write IO space.
-
-   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Write         Switch value for Read or Write.
-   @param[in]   Width         Signifies the width of the memory operations.
-   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.
-   @param[in]   Count         The number of PCI configuration operations to perform. Bytes
-                              moved is Width size * Count, starting at Address.
-   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
-                              write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-RootBridgeIoIoRW (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     BOOLEAN                                Write,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  IN OUT VOID                                   *Buffer
-  )
-{
-  EFI_STATUS                             Status;
-  UINT8                                  InStride;
-  UINT8                                  OutStride;
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  OperationWidth;
-  UINT8                                  *Uint8Buffer;
-  PCI_ROOT_BRIDGE_INSTANCE              *PrivateData;
-
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
-  /* Address is bus resource */
-  Address -= PrivateData->IoBase;
-  Address += PrivateData->CpuIoRegionBase;
-
-  Status = RootBridgeIoCheckParameter (This, IoOperation, Width, Address, Count, Buffer);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  InStride = mInStride[Width];
-  OutStride = mOutStride[Width];
-  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
-
-  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
-    if (Write) {
-      switch (OperationWidth) {
-        case EfiPciWidthUint8:
-          MmioWrite8 ((UINTN)Address, *Uint8Buffer);
-          break;
-        case EfiPciWidthUint16:
-          MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
-          break;
-        case EfiPciWidthUint32:
-          MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
-          break;
-        case EfiPciWidthUint64:
-          MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
-          break;
-        default:
-          //
-          // The RootBridgeIoCheckParameter call above will ensure that this
-          // path is not taken.
-          //
-          ASSERT (FALSE);
-          break;
-      }
-    } else {
-      switch (OperationWidth) {
-        case EfiPciWidthUint8:
-          *Uint8Buffer = MmioRead8 ((UINTN)Address);
-          break;
-        case EfiPciWidthUint16:
-          *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
-          break;
-        case EfiPciWidthUint32:
-          *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
-          break;
-        case EfiPciWidthUint64:
-          *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
-          break;
-        default:
-          //
-          // The RootBridgeIoCheckParameter call above will ensure that this
-          // path is not taken.
-          //
-          ASSERT (FALSE);
-          break;
-      }
-    }
-  }
-  return EFI_SUCCESS;
-}
-
-
-/**
-   Polls an address in memory mapped I/O space until an exit condition is met, or
-   a timeout occurs.
-
-   This function provides a standard way to poll a PCI memory location. A PCI memory read
-   operation is performed at the PCI memory address specified by Address for the width specified
-   by Width. The result of this PCI memory read operation is stored in Result. This PCI memory
-   read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &
-   Mask) is equal to Value.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operations.
-   @param[in]   Address   The base address of the memory operations. The caller is
-                          responsible for aligning Address if required.
-   @param[in]   Mask      Mask used for the polling criteria. Bytes above Width in Mask
-                          are ignored. The bits in the bytes below Width which are zero in
-                          Mask are ignored when polling the memory address.
-   @param[in]   Value     The comparison value used for the polling exit criteria.
-   @param[in]   Delay     The number of 100 ns units to poll. Note that timer available may
-                          be of poorer granularity.
-   @param[out]  Result    Pointer to the last value read from the memory location.
-
-   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
-   @retval EFI_INVALID_PARAMETER  Width is invalid.
-   @retval EFI_INVALID_PARAMETER  Result is NULL.
-   @retval EFI_TIMEOUT            Delay expired before a match occurred.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPollMem (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN  UINT64                                 Address,
-  IN  UINT64                                 Mask,
-  IN  UINT64                                 Value,
-  IN  UINT64                                 Delay,
-  OUT UINT64                                 *Result
-  )
-{
-  EFI_STATUS  Status;
-  UINT64      NumberOfTicks;
-  UINT32      Remainder;
-
-  if (Result == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // No matter what, always do a single poll.
-  //
-  Status = This->Mem.Read (This, Width, Address, 1, Result);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-  if ((*Result & Mask) == Value) {
-    return EFI_SUCCESS;
-  }
-
-  if (Delay == 0) {
-    return EFI_TIMEOUT;
-
-  } else {
-
-    //
-    // Determine the proper # of metronome ticks to wait for polling the
-    // location.  The nuber of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
-    // The "+1" to account for the possibility of the first tick being short
-    // because we started in the middle of a tick.
-    //
-    // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome
-    // protocol definition is updated.
-    //
-    NumberOfTicks = DivU64x32Remainder (Delay, (UINT32) mMetronome->TickPeriod, &Remainder);
-    if (Remainder != 0) {
-      NumberOfTicks += 1;
-    }
-    NumberOfTicks += 1;
-
-    while (NumberOfTicks != 0) {
-
-      mMetronome->WaitForTick (mMetronome, 1);
-
-      Status = This->Mem.Read (This, Width, Address, 1, Result);
-      if (EFI_ERROR (Status)) {
-        return Status;
-      }
-
-      if ((*Result & Mask) == Value) {
-        return EFI_SUCCESS;
-      }
-
-      NumberOfTicks -= 1;
-    }
-  }
-  return EFI_TIMEOUT;
-}
-
-/**
-   Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is
-   satisfied or after a defined duration.
-
-   This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is
-   performed at the PCI I/O address specified by Address for the width specified by Width.
-   The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is
-   repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal
-   to Value.
-
-   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in] Width     Signifies the width of the I/O operations.
-   @param[in] Address   The base address of the I/O operations. The caller is responsible
-                        for aligning Address if required.
-   @param[in] Mask      Mask used for the polling criteria. Bytes above Width in Mask
-                        are ignored. The bits in the bytes below Width which are zero in
-                        Mask are ignored when polling the I/O address.
-   @param[in] Value     The comparison value used for the polling exit criteria.
-   @param[in] Delay     The number of 100 ns units to poll. Note that timer available may
-                        be of poorer granularity.
-   @param[out] Result   Pointer to the last value read from the memory location.
-
-   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
-   @retval EFI_INVALID_PARAMETER  Width is invalid.
-   @retval EFI_INVALID_PARAMETER  Result is NULL.
-   @retval EFI_TIMEOUT            Delay expired before a match occurred.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPollIo (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN  UINT64                                 Address,
-  IN  UINT64                                 Mask,
-  IN  UINT64                                 Value,
-  IN  UINT64                                 Delay,
-  OUT UINT64                                 *Result
-  )
-{
-  EFI_STATUS  Status;
-  UINT64      NumberOfTicks;
-  UINT32      Remainder;
-
-  //
-  // No matter what, always do a single poll.
-  //
-
-  if (Result == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Status = This->Io.Read (This, Width, Address, 1, Result);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-  if ((*Result & Mask) == Value) {
-    return EFI_SUCCESS;
-  }
-
-  if (Delay == 0) {
-    return EFI_SUCCESS;
-
-  } else {
-
-    //
-    // Determine the proper # of metronome ticks to wait for polling the
-    // location.  The number of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
-    // The "+1" to account for the possibility of the first tick being short
-    // because we started in the middle of a tick.
-    //
-    NumberOfTicks = DivU64x32Remainder (Delay, (UINT32)mMetronome->TickPeriod, &Remainder);
-    if (Remainder != 0) {
-      NumberOfTicks += 1;
-    }
-    NumberOfTicks += 1;
-
-    while (NumberOfTicks != 0) {
-
-      mMetronome->WaitForTick (mMetronome, 1);
-
-      Status = This->Io.Read (This, Width, Address, 1, Result);
-      if (EFI_ERROR (Status)) {
-        return Status;
-      }
-
-      if ((*Result & Mask) == Value) {
-        return EFI_SUCCESS;
-      }
-
-      NumberOfTicks -= 1;
-    }
-  }
-  return EFI_TIMEOUT;
-}
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
-
-   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
-   registers in the PCI root bridge memory space.
-   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
-   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operation.
-   @param[in]   Address   The base address of the memory operation. The caller is
-                          responsible for aligning the Address if required.
-   @param[in]   Count     The number of memory operations to perform. Bytes moved is
-                          Width size * Count, starting at Address.
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoMemRead (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  OUT    VOID                                   *Buffer
-  )
-{
-  return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer);
-}
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
-
-   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
-   registers in the PCI root bridge memory space.
-   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
-   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operation.
-   @param[in]   Address   The base address of the memory operation. The caller is
-                          responsible for aligning the Address if required.
-   @param[in]   Count     The number of memory operations to perform. Bytes moved is
-                          Width size * Count, starting at Address.
-   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoMemWrite (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  IN     VOID                                   *Buffer
-  )
-{
-  return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer);
-}
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
-
-   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width       Signifies the width of the memory operations.
-   @param[in]   Address     The base address of the I/O operation. The caller is responsible for
-                            aligning the Address if required.
-   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
-                            size * Count, starting at Address.
-   @param[out]  Buffer      For read operations, the destination buffer to store the results. For
-                            write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoIoRead (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  OUT    VOID                                   *Buffer
-  )
-{
-  return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer);
-}
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
-
-   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width       Signifies the width of the memory operations.
-   @param[in]   Address     The base address of the I/O operation. The caller is responsible for
-                            aligning the Address if required.
-   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
-                            size * Count, starting at Address.
-   @param[in]   Buffer       For read operations, the destination buffer to store the results. For
-                            write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoIoWrite (
-  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         *This,
-  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH   Width,
-  IN       UINT64                                  Address,
-  IN       UINTN                                   Count,
-  IN       VOID                                    *Buffer
-  )
-{
-  return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer);
-}
-
-/**
-   Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI
-   root bridge memory space.
-
-   The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory
-   space to another region of PCI root bridge memory space. This is especially useful for video scroll
-   operation on a memory mapped video buffer.
-   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
-   any alignment and memory width restrictions that a PCI root bridge on a platform might require.
-
-   @param[in] This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
-   @param[in] Width       Signifies the width of the memory operations.
-   @param[in] DestAddress The destination address of the memory operation. The caller is
-                          responsible for aligning the DestAddress if required.
-   @param[in] SrcAddress  The source address of the memory operation. The caller is
-                          responsible for aligning the SrcAddress if required.
-   @param[in] Count       The number of memory operations to perform. Bytes moved is
-                          Width size * Count, starting at DestAddress and SrcAddress.
-
-   @retval  EFI_SUCCESS             The data was copied from one memory region to another memory region.
-   @retval  EFI_INVALID_PARAMETER   Width is invalid for this PCI root bridge.
-   @retval  EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoCopyMem (
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH        Width,
-  IN UINT64                                       DestAddress,
-  IN UINT64                                       SrcAddress,
-  IN UINTN                                        Count
-  )
-{
-  EFI_STATUS  Status;
-  BOOLEAN     Direction;
-  UINTN       Stride;
-  UINTN       Index;
-  UINT64      Result;
-
-  if ((UINT32)Width > EfiPciWidthUint64) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (DestAddress == SrcAddress) {
-    return EFI_SUCCESS;
-  }
-
-  Stride = (UINTN)((UINTN)1 << Width);
-
-  Direction = TRUE;
-  if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * Stride))) {
-    Direction   = FALSE;
-    SrcAddress  = SrcAddress  + (Count-1) * Stride;
-    DestAddress = DestAddress + (Count-1) * Stride;
-  }
-
-  for (Index = 0;Index < Count;Index++) {
-    Status = RootBridgeIoMemRead (
-               This,
-               Width,
-               SrcAddress,
-               1,
-               &Result
-               );
-    if (EFI_ERROR (Status)) {
-      return Status;
-    }
-    Status = RootBridgeIoMemWrite (
-               This,
-               Width,
-               DestAddress,
-               1,
-               &Result
-               );
-    if (EFI_ERROR (Status)) {
-      return Status;
-    }
-    if (Direction) {
-      SrcAddress  += Stride;
-      DestAddress += Stride;
-    } else {
-      SrcAddress  -= Stride;
-      DestAddress -= Stride;
-    }
-  }
-  return EFI_SUCCESS;
-}
-
-/**
-  Reads memory-mapped registers.
-  @param[in]  Width    Signifies the width of the I/O or Memory operation.
-  @param[in]  Address  The base address of the I/O operation.
-  @param[in]  Count    The number of I/O operations to perform. The number of
-                       bytes moved is Width size * Count, starting at Address.
-  @param[out] Buffer   For read operations, the destination buffer to store the results.
-                       For write operations, the source buffer from which to write data.
-
-  @retval EFI_SUCCESS            The data was read from or written to the PI system.
-  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
-  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
-  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
-                                 and Count is not valid for this PI system.
-
-**/
-EFI_STATUS
-CpuMemoryServiceRead (
-  IN  EFI_CPU_IO_PROTOCOL_WIDTH  Width,
-  IN  UINT64                     Address,
-  IN  UINTN                      Count,
-  OUT VOID                       *Buffer
-  )
-{
-
-  UINT8                      InStride;
-  UINT8                      OutStride;
-  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
-  UINT8                      *Uint8Buffer;
-  UINT32                     Uint32Buffer = 0;
-
-  //
-  // Select loop based on the width of the transfer
-  //
-  InStride = mInStride[Width];
-  OutStride = mOutStride[Width];
-  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
-  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
-    if (OperationWidth == EfiCpuIoWidthUint8) {
-      Uint32Buffer = MmioRead32((UINTN)(Address & (~0x3)));
-      Uint32Buffer &= (0xFF << ((Address & 0x3) * 8));
-      *((UINT8*)Uint8Buffer) = (UINT8)(Uint32Buffer >> (((Address & 0x3) * 8)));
-    } else if (OperationWidth == EfiCpuIoWidthUint16) {
-      if (((Address & 0x3) == 1) || ((Address & 0x3) == 3)) {
-        return EFI_INVALID_PARAMETER;
-      }
-      Uint32Buffer = MmioRead32((UINTN)(Address & (~0x3)));
-      Uint32Buffer &= (0xFFFF << ((Address & 0x3) * 8));
-      *(UINT16 *)Uint8Buffer = (UINT16)(Uint32Buffer >> (((Address & 0x3) * 8)));
-    } else if (OperationWidth == EfiCpuIoWidthUint32) {
-      *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
-    } else if (OperationWidth == EfiCpuIoWidthUint64) {
-      *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
-    }
-  }
-  return EFI_SUCCESS;
-}
-
-/**
-   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
-
-   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
-   registers for a PCI controller.
-   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
-   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
-   require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operations.
-   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
-   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
-                          moved is Width size * Count, starting at Address.
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPciRead (
-  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN       UINT64                                 EfiAddress,
-  IN       UINTN                                  Count,
-  OUT      VOID                                   *Buffer
-  )
-{
-  UINT32                      Offset;
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *EfiPciAddress;
-  UINT64                      Address;
-  PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
-
-  EfiPciAddress  = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&EfiAddress;
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
-
-  if (Buffer == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (Width >= EfiPciWidthMaximum) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (EfiPciAddress->ExtendedRegister) {
-    Offset = EfiPciAddress->ExtendedRegister;
-  } else {
-    Offset = EfiPciAddress->Register;
-  }
-
-  PCIE_DEBUG ("[%a:%d] - bus %x dev %x func %x Off %x\n", __FUNCTION__, __LINE__,
-         EfiPciAddress->Bus,
-         EfiPciAddress->Device,
-         EfiPciAddress->Function,
-         Offset
-        );
-  if (EfiPciAddress->Bus < PrivateData->BusBase || EfiPciAddress->Bus > PrivateData->BusLimit) {
-    PCIE_DEBUG ("[%a:%d] - Bus number out of range %d\n", __FUNCTION__, __LINE__, EfiPciAddress->Bus);
-    SetMem (Buffer, mOutStride[Width] * Count, 0xFF);
-    return EFI_INVALID_PARAMETER;
-  }
-
-  // The UEFI PCI enumerator scans for devices at all possible addresses,
-  // and ignores some PCI rules - this results in some hardware being
-  // detected multiple times. We work around this by faking absent
-  // devices
-  if(EfiPciAddress->Bus == PrivateData->BusBase)
-  {
-    if((EfiPciAddress->Device != 0x0) || (EfiPciAddress->Function != 0)) {
-      SetMem (Buffer, mOutStride[Width] * Count, 0xFF);
-      return EFI_UNSUPPORTED;
-    }
-  }
-
-  if (EfiPciAddress->Bus == PrivateData->BusBase){
-    Address = PrivateData->RbPciBar + Offset;
-  }
-  else if(EfiPciAddress->Bus == PrivateData->BusBase + 1)
-  {
-    if (!PcieIsLinkUp(PrivateData->SocType,PrivateData->RbPciBar, PrivateData->Port))
-    {
-      SetMem (Buffer, mOutStride[Width] * Count, 0xFF);
-      return EFI_NOT_READY;
-    }
-    Address = GetPcieCfgAddress (
-        PrivateData->Ecam,
-        EfiPciAddress->Bus,
-        EfiPciAddress->Device,
-        EfiPciAddress->Function,
-        Offset
-        );
-  }
-  else
-  {
-    Address = GetPcieCfgAddress (
-         PrivateData->Ecam,
-         EfiPciAddress->Bus,
-         EfiPciAddress->Device,
-         EfiPciAddress->Function,
-         Offset
-         );
-  }
-
-  (VOID)CpuMemoryServiceRead((EFI_CPU_IO_PROTOCOL_WIDTH)Width, Address, Count, Buffer);
-  PCIE_DEBUG ("[%a:%d] - %x\n", __FUNCTION__, __LINE__, *(UINT32 *)Buffer);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Writes memory-mapped registers.
-  @param[in]  Width    Signifies the width of the I/O or Memory operation.
-  @param[in]  Address  The base address of the I/O operation.
-  @param[in]  Count    The number of I/O operations to perform. The number of
-                       bytes moved is Width size * Count, starting at Address.
-  @param[in]  Buffer   For read operations, the destination buffer to store the results.
-                       For write operations, the source buffer from which to write data.
-
-  @retval EFI_SUCCESS            The data was read from or written to the PI system.
-  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
-  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
-  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
-                                 and Count is not valid for this PI system.
-
-**/
-EFI_STATUS
-CpuMemoryServiceWrite (
-  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
-  IN UINT64                     Address,
-  IN UINTN                      Count,
-  IN VOID                       *Buffer
-  )
-{
-  UINT8                      InStride;
-  UINT8                      OutStride;
-  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
-  UINT8                      *Uint8Buffer;
-  UINT32                     Uint32Buffer;
-
-  //
-  // Select loop based on the width of the transfer
-  //
-  InStride = mInStride[Width];
-  OutStride = mOutStride[Width];
-  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
-  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
-    if (OperationWidth == EfiCpuIoWidthUint8) {
-      Uint32Buffer = MmioRead32 ((UINTN)(Address & (~0x03)));
-      Uint32Buffer &= ~(UINT32)(0xFF << ((Address & 0x3) * 8));
-      Uint32Buffer |= (UINT32)(*(UINT8 *)Uint8Buffer) << ((Address & 0x3) * 8);
-      MmioWrite32 ((UINTN)(Address & (~0x03)), Uint32Buffer);
-    } else if (OperationWidth == EfiCpuIoWidthUint16) {
-      if (((Address & 0x3) == 1) || ((Address & 0x3) == 3)) {
-        return EFI_INVALID_PARAMETER;
-      }
-      Uint32Buffer = MmioRead32 ((UINTN)(Address & (~0x03)));
-      Uint32Buffer &= ~(UINT32)(0xFFFF << ((Address & 0x3) * 8));
-      Uint32Buffer |= (UINT32)(*(UINT16 *)Uint8Buffer) << ((Address & 0x3) * 8);
-      MmioWrite32 ((UINTN)(Address & (~0x03)), Uint32Buffer);
-    } else if (OperationWidth == EfiCpuIoWidthUint32) {
-      MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
-    } else if (OperationWidth == EfiCpuIoWidthUint64) {
-      MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
-    }
-  }
-  return EFI_SUCCESS;
-}
-
-/**
-   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
-
-   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
-   registers for a PCI controller.
-   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
-   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
-   require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operations.
-   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
-   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
-                          moved is Width size * Count, starting at Address.
-   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPciWrite (
-  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN       UINT64                                 EfiAddress,
-  IN       UINTN                                  Count,
-  IN       VOID                                   *Buffer
-  )
-{
-  UINT32                      Offset;
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *EfiPciAddress;
-  UINT64                      Address;
-  PCI_ROOT_BRIDGE_INSTANCE    *PrivateData;
-
-  EfiPciAddress  = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&EfiAddress;
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
-
-  if (Buffer == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (Width >= EfiPciWidthMaximum) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (EfiPciAddress->ExtendedRegister)
-    Offset = EfiPciAddress->ExtendedRegister;
-  else
-    Offset = EfiPciAddress->Register;
-
-  PCIE_DEBUG ("[%a:%d] - bus %x dev %x func %x Off %x\n", __FUNCTION__, __LINE__,
-         EfiPciAddress->Bus,
-         EfiPciAddress->Device,
-         EfiPciAddress->Function,
-         Offset
-        );
-  if (((EfiPciAddress->Bus == PrivateData->BusBase) && (EfiPciAddress->Device == 0x00) && (EfiPciAddress->Function == 0))){
-    Address = PrivateData->RbPciBar + Offset;
-    if ((Offset == 0x14) || (Offset == 0x10)) {
-      return EFI_SUCCESS;
-    }
-  }
-  else if (EfiPciAddress->Bus == PrivateData->BusBase + 1)
-  {
-     if (!PcieIsLinkUp(PrivateData->SocType,PrivateData->RbPciBar, PrivateData->Port)) {
-      return EFI_NOT_READY;
-    }
-    Address = GetPcieCfgAddress (
-        PrivateData->Ecam,
-        EfiPciAddress->Bus,
-        EfiPciAddress->Device,
-        EfiPciAddress->Function,
-        Offset
-    );
-  }
-  else
-  {
-    Address = GetPcieCfgAddress (
-       PrivateData->Ecam,
-       EfiPciAddress->Bus,
-       EfiPciAddress->Device,
-       EfiPciAddress->Function,
-       Offset
-       );
-  }
-
-  (VOID)CpuMemoryServiceWrite ((EFI_CPU_IO_PROTOCOL_WIDTH)Width, Address, Count, Buffer);
-  PCIE_DEBUG ("[%a:%d] - 0x%08x\n", __FUNCTION__, __LINE__, *(UINT32 *)Buffer);
-  return EFI_SUCCESS;
-}
-
-/**
-   Provides the PCI controller-specific addresses required to access system memory from a
-   DMA bus master.
-
-   The Map() function provides the PCI controller specific addresses needed to access system
-   memory. This function is used to map system memory for PCI bus master DMA accesses.
-
-   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]       Operation       Indicates if the bus master is going to read or write to system memory.
-   @param[in]       HostAddress     The system memory address to map to the PCI controller.
-   @param[in, out]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.
-   @param[out]      DeviceAddress   The resulting map address for the bus master PCI controller to use
-                                    to access the system memory's HostAddress.
-   @param[out]      Mapping         The value to pass to Unmap() when the bus master DMA operation is complete.
-
-   @retval EFI_SUCCESS            The range was mapped for the returned NumberOfBytes.
-   @retval EFI_INVALID_PARAMETER  Operation is invalid.
-   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
-   @retval EFI_INVALID_PARAMETER  NumberOfBytes is NULL.
-   @retval EFI_INVALID_PARAMETER  DeviceAddress is NULL.
-   @retval EFI_INVALID_PARAMETER  Mapping is NULL.
-   @retval EFI_UNSUPPORTED        The HostAddress cannot be mapped as a common buffer.
-   @retval EFI_DEVICE_ERROR       The system hardware could not map the requested address.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoMap (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL            *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,
-  IN     VOID                                       *HostAddress,
-  IN OUT UINTN                                      *NumberOfBytes,
-  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,
-  OUT    VOID                                       **Mapping
-  )
-{
-  DMA_MAP_OPERATION   DmaOperation;
-
-  if (Operation == EfiPciOperationBusMasterRead) {
-    DmaOperation = MapOperationBusMasterRead;
-  } else if (Operation == EfiPciOperationBusMasterWrite) {
-    DmaOperation = MapOperationBusMasterWrite;
-  } else if (Operation == EfiPciOperationBusMasterCommonBuffer) {
-    DmaOperation = MapOperationBusMasterCommonBuffer;
-  } else if (Operation == EfiPciOperationBusMasterRead64) {
-    DmaOperation = MapOperationBusMasterRead;
-  } else if (Operation == EfiPciOperationBusMasterWrite64) {
-     DmaOperation = MapOperationBusMasterWrite;
-  } else if (Operation == EfiPciOperationBusMasterCommonBuffer64) {
-    DmaOperation = MapOperationBusMasterCommonBuffer;
-  } else {
-    return EFI_INVALID_PARAMETER;
-  }
-  (VOID)DmaMap (DmaOperation, HostAddress, NumberOfBytes, DeviceAddress, Mapping);
-  return EFI_SUCCESS;
-}
-
-/**
-   Completes the Map() operation and releases any corresponding resources.
-
-   The Unmap() function completes the Map() operation and releases any corresponding resources.
-   If the operation was an EfiPciOperationBusMasterWrite or
-   EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.
-   Any resources used for the mapping are freed.
-
-   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in] Mapping   The mapping value returned from Map().
-
-   @retval EFI_SUCCESS            The range was unmapped.
-   @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by Map().
-   @retval EFI_DEVICE_ERROR       The data was not committed to the target system memory.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoUnmap (
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN VOID                             *Mapping
-  )
-{
-  return DmaUnmap (Mapping);
-}
-
-/**
-   Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or
-   EfiPciOperationBusMasterCommonBuffer64 mapping.
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param Type        This parameter is not used and must be ignored.
-   @param MemoryType  The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.
-   @param Pages       The number of pages to allocate.
-   @param HostAddress A pointer to store the base system memory address of the allocated range.
-   @param Attributes  The requested bit mask of attributes for the allocated range. Only
-                      the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED,
-                      and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.
-
-   @retval EFI_SUCCESS            The requested memory pages were allocated.
-   @retval EFI_INVALID_PARAMETER  MemoryType is invalid.
-   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
-   @retval EFI_UNSUPPORTED        Attributes is unsupported. The only legal attribute bits are
-                                  MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
-   @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoAllocateBuffer (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN  EFI_ALLOCATE_TYPE                Type,
-  IN  EFI_MEMORY_TYPE                  MemoryType,
-  IN  UINTN                            Pages,
-  OUT VOID                             **HostAddress,
-  IN  UINT64                           Attributes
-  )
-{
-  if (Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) {
-    return EFI_UNSUPPORTED;
-  }
-
-  return DmaAllocateBuffer (MemoryType, Pages, HostAddress);
-
-}
-
-/**
-   Frees memory that was allocated with AllocateBuffer().
-
-   The FreeBuffer() function frees memory that was allocated with AllocateBuffer().
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param Pages       The number of pages to free.
-   @param HostAddress The base system memory address of the allocated range.
-
-   @retval EFI_SUCCESS            The requested memory pages were freed.
-   @retval EFI_INVALID_PARAMETER  The memory range specified by HostAddress and Pages
-                                  was not allocated with AllocateBuffer().
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoFreeBuffer (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN  UINTN                            Pages,
-  OUT VOID                             *HostAddress
-  )
-{
-  return DmaFreeBuffer (Pages, HostAddress);
-}
-
-/**
-   Flushes all PCI posted write transactions from a PCI host bridge to system memory.
-
-   The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system
-   memory. Posted write transactions are generated by PCI bus masters when they perform write
-   transactions to target addresses in system memory.
-   This function does not flush posted write transactions from any PCI bridges. A PCI controller
-   specific action must be taken to guarantee that the posted write transactions have been flushed from
-   the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with
-   a PCI read transaction from the PCI controller prior to calling Flush().
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-
-   @retval EFI_SUCCESS        The PCI posted write transactions were flushed from the PCI host
-                              bridge to system memory.
-   @retval EFI_DEVICE_ERROR   The PCI posted write transactions were not flushed from the PCI
-                              host bridge due to a hardware error.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoFlush (
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This
-  )
-{
-  //
-  // not supported yet
-  //
-  return EFI_SUCCESS;
-}
-
-/**
-   Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the
-   attributes that a PCI root bridge is currently using.
-
-   The GetAttributes() function returns the mask of attributes that this PCI root bridge supports
-   and the mask of attributes that the PCI root bridge is currently using.
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param Supported   A pointer to the mask of attributes that this PCI root bridge
-                      supports setting with SetAttributes().
-   @param Attributes  A pointer to the mask of attributes that this PCI root bridge is
-                      currently using.
-
-   @retval  EFI_SUCCESS           If Supports is not NULL, then the attributes that the PCI root
-                                  bridge supports is returned in Supports. If Attributes is
-                                  not NULL, then the attributes that the PCI root bridge is currently
-                                  using is returned in Attributes.
-   @retval  EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoGetAttributes (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  OUT UINT64                           *Supported,
-  OUT UINT64                           *Attributes
-  )
-{
-  PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
-
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
-
-  if (Attributes == NULL && Supported == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Set the return value for Supported and Attributes
-  //
-  if (Supported != NULL) {
-    *Supported  = PrivateData->Supports;
-  }
-
-  if (Attributes != NULL) {
-    *Attributes = PrivateData->Attributes;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-   Sets attributes for a resource range on a PCI root bridge.
-
-   The SetAttributes() function sets the attributes specified in Attributes for the PCI root
-   bridge on the resource range specified by ResourceBase and ResourceLength. Since the
-   granularity of setting these attributes may vary from resource type to resource type, and from
-   platform to platform, the actual resource range and the one passed in by the caller may differ. As a
-   result, this function may set the attributes specified by Attributes on a larger resource range
-   than the caller requested. The actual range is returned in ResourceBase and
-   ResourceLength. The caller is responsible for verifying that the actual range for which the
-   attributes were set is acceptable.
-
-   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]       Attributes      The mask of attributes to set. If the attribute bit
-                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, or
-                                    MEMORY_DISABLE is set, then the resource range is specified by
-                                    ResourceBase and ResourceLength. If
-                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
-                                    MEMORY_DISABLE are not set, then ResourceBase and
-                                    ResourceLength are ignored, and may be NULL.
-   @param[in, out]  ResourceBase    A pointer to the base address of the resource range to be modified
-                                    by the attributes specified by Attributes.
-   @param[in, out]  ResourceLength  A pointer to the length of the resource range to be modified by the
-                                    attributes specified by Attributes.
-
-   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
-   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
-   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoSetAttributes (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN     UINT64                           Attributes,
-  IN OUT UINT64                           *ResourceBase,
-  IN OUT UINT64                           *ResourceLength
-  )
-{
-  PCI_ROOT_BRIDGE_INSTANCE            *PrivateData;
-
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
-
-  if (Attributes != 0) {
-    if ((Attributes & (~(PrivateData->Supports))) != 0) {
-      return EFI_UNSUPPORTED;
-    }
-  }
-
-  //
-  // This is a generic driver for a PC-AT class system.  It does not have any
-  // chipset specific knowlegde, so none of the attributes can be set or
-  // cleared.  Any attempt to set attribute that are already set will succeed,
-  // and any attempt to set an attribute that is not supported will fail.
-  //
-  if (Attributes & (~PrivateData->Attributes)) {
-    /* FIXME: */
-    return EFI_UNSUPPORTED;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-   Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0
-   resource descriptors.
-
-   There are only two resource descriptor types from the ACPI Specification that may be used to
-   describe the current resources allocated to a PCI root bridge. These are the QWORD Address
-   Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The
-   QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic
-   or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD
-   Address Space Descriptors followed by an End Tag.
-
-   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[out]  Resources   A pointer to the ACPI 2.0 resource descriptors that describe the
-                            current configuration of this PCI root bridge. The storage for the
-                            ACPI 2.0 resource descriptors is allocated by this function. The
-                            caller must treat the return buffer as read-only data, and the buffer
-                            must not be freed by the caller.
-
-   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
-   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
-   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoConfiguration (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL     *This,
-  OUT VOID                                **Resources
-  )
-{
-  PCI_ROOT_BRIDGE_INSTANCE              *PrivateData;
-  UINTN                                 Index;
-
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
-  for (Index = 0; Index < TypeMax; Index++) {
-    if (PrivateData->ResAllocNode[Index].Status == ResAllocated) {
-      switch (Index) {
-      case TypeIo:
-        Configuration.SpaceDesp[Index].AddrRangeMin = PrivateData->IoBase;
-        break;
-      case TypeBus:
-        Configuration.SpaceDesp[Index].AddrRangeMin = PrivateData->ResAllocNode[Index].Base;
-        break;
-      default:
-      /* PCIE Device bar address should be base on PciRegionBase */
-      Configuration.SpaceDesp[Index].AddrRangeMin = PrivateData->ResAllocNode[Index].Base - PrivateData->MemBase +
-                                                    PrivateData->PciRegionBase;
-      }
-      Configuration.SpaceDesp[Index].AddrRangeMax = Configuration.SpaceDesp[Index].AddrRangeMin + PrivateData->ResAllocNode[Index].Length - 1;
-      Configuration.SpaceDesp[Index].AddrLen      = PrivateData->ResAllocNode[Index].Length;
-      Configuration.SpaceDesp[Index].AddrTranslationOffset = PrivateData->MemBase - PrivateData->PciRegionBase;
-    }
-  }
-
-  *Resources = &Configuration;
-  return EFI_SUCCESS;
-}
-
-- 
2.7.4



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

* [PATCH edk2-platforms 12/12] Hisilicon/PlatformPciLib: clear redundant felds in RESOURCE_APPETURE
  2018-03-21  1:03 [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Heyi Guo
                   ` (10 preceding siblings ...)
  2018-03-21  1:03 ` [PATCH edk2-platforms 11/12] Hisilicon: remove platform specific PciHostBridge Heyi Guo
@ 2018-03-21  1:03 ` Heyi Guo
  2018-03-28  1:05 ` [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Guo Heyi
  12 siblings, 0 replies; 33+ messages in thread
From: Heyi Guo @ 2018-03-21  1:03 UTC (permalink / raw)
  To: edk2-devel
  Cc: Heyi Guo, Yi Li, Ard Biesheuvel, Leif Lindholm, Michael D Kinney

In structure PCI_ROOT_BRIDGE_RESOURCE_APPETURE, MemBase is redundant
with CpuMemRegionBase, and MemLimit can be calculated by
CpuMemRegionBase + PciRegionLimit - PciRegionBase so it is also
redundant.

Remove these two fields to make things simple and clear.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Signed-off-by: Yi Li <phoenix.liyi@huawei.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/Hisilicon/Include/Library/PlatformPciLib.h             |  2 --
 Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.c | 16 ----------
 Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c | 32 --------------------
 3 files changed, 50 deletions(-)

diff --git a/Silicon/Hisilicon/Include/Library/PlatformPciLib.h b/Silicon/Hisilicon/Include/Library/PlatformPciLib.h
index 6725a547d54f..5fdc3d3e0afe 100644
--- a/Silicon/Hisilicon/Include/Library/PlatformPciLib.h
+++ b/Silicon/Hisilicon/Include/Library/PlatformPciLib.h
@@ -194,8 +194,6 @@ typedef struct {
   UINT64          Ecam;
   UINT64          BusBase;
   UINT64          BusLimit;
-  UINT64          MemBase;
-  UINT64          MemLimit;
   UINT64          IoBase;
   UINT64          IoLimit;
   UINT64          CpuMemRegionBase;
diff --git a/Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.c b/Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.c
index 3a770d17bb3d..59c468ac4b73 100644
--- a/Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.c
+++ b/Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.c
@@ -32,8 +32,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB0RB0_ECAM_BASE, //ecam
       0,  //BusBase
       31, //BusLimit
-      PCI_HB0RB0_PCIREGION_BASE, //Membase
-      PCI_HB0RB0_PCIREGION_BASE + PCI_HB0RB0_PCIREGION_SIZE - 1, //Memlimit
       PCI_HB0RB0_IO_BASE,  //IoBase
       (PCI_HB0RB0_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
       PCI_HB0RB0_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -49,8 +47,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB0RB1_ECAM_BASE,//ecam
       224,  //BusBase
       254, //BusLimit
-      PCI_HB0RB1_PCIREGION_BASE, //Membase
-      PCI_HB0RB1_PCIREGION_BASE + PCI_HB0RB1_PCIREGION_SIZE - 1, //MemLimit
       (PCI_HB0RB1_IO_BASE),  //IoBase
       (PCI_HB0RB1_CPUIOREGIONBASE + PCI_HB0RB1_IO_SIZE - 1), //IoLimit
       PCI_HB0RB1_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -65,8 +61,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB0RB2_ECAM_BASE,
       128,  //BusBase
       159, //BusLimit
-      PCI_HB0RB2_PCIREGION_BASE ,//MemBase
-      PCI_HB0RB2_PCIREGION_BASE + PCI_HB0RB2_PCIREGION_SIZE - 1, //MemLimit
       (PCI_HB0RB2_IO_BASE),  //IOBase
       (PCI_HB0RB2_CPUIOREGIONBASE + PCI_HB0RB2_IO_SIZE - 1), //IoLimit
       PCI_HB0RB2_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -82,8 +76,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB0RB3_ECAM_BASE,
       96,  //BusBase
       127, //BusLimit
-      (PCI_HB0RB3_ECAM_BASE),  //MemBase
-      (PCI_HB0RB3_ECAM_BASE + PCI_HB0RB3_ECAM_SIZE - 1), //MemLimit
       (0), //IoBase
       (0),  //IoLimit
       0,
@@ -100,8 +92,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB0_ECAM_BASE,
       128,  //BusBase
       159, //BusLimit
-      (PCI_HB1RB0_ECAM_BASE),  //MemBase
-      (PCI_HB1RB0_ECAM_BASE + PCI_HB1RB0_ECAM_SIZE - 1), //MemLimit
       (0), //IoBase
       (0),  //IoLimit
       0,
@@ -116,8 +106,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB1_ECAM_BASE,
       160,  //BusBase
       191, //BusLimit
-      (PCI_HB1RB1_ECAM_BASE),  //MemBase
-      (PCI_HB1RB1_ECAM_BASE + PCI_HB1RB1_ECAM_SIZE - 1), //MemLimit
       (0), //IoBase
       (0),  //IoLimit
       0,
@@ -132,8 +120,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB2_ECAM_BASE,
       192,  //BusBase
       223, //BusLimit
-      (PCI_HB1RB2_ECAM_BASE),  //MemBase
-      (PCI_HB1RB2_ECAM_BASE + PCI_HB1RB2_ECAM_SIZE - 1), //MemLimit
       (0), //IoBase
       (0),  //IoLimit
       0,
@@ -149,8 +135,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB3_ECAM_BASE,
       224,  //BusBase
       255, //BusLimit
-      (PCI_HB1RB3_ECAM_BASE),  //MemBase
-      (PCI_HB1RB3_ECAM_BASE + PCI_HB1RB3_ECAM_SIZE - 1), //MemLimit
       (0), //IoBase
       (0),  //IoLimit
       0,
diff --git a/Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c b/Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c
index c511a0ecbb52..ef82892dd7bf 100644
--- a/Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c
+++ b/Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c
@@ -33,8 +33,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB0RB0_ECAM_BASE, //ecam
       0x80,  //BusBase
       0x87, //BusLimit
-      PCI_HB0RB0_PCIREGION_BASE, //Membase
-      PCI_HB0RB0_CPUMEMREGIONBASE + PCI_HB0RB0_PCIREGION_SIZE - 1, //Memlimit
       PCI_HB0RB0_IO_BASE,  //IoBase
       (PCI_HB0RB0_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
       PCI_HB0RB0_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -49,8 +47,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB0RB1_ECAM_BASE,//ecam
       0x90,  //BusBase
       0x97, //BusLimit
-      PCI_HB0RB1_PCIREGION_BASE, //Membase
-      PCI_HB0RB1_CPUMEMREGIONBASE + PCI_HB0RB1_PCIREGION_SIZE - 1, //MemLimit
       (PCI_HB0RB1_IO_BASE),  //IoBase
       (PCI_HB0RB1_CPUIOREGIONBASE + PCI_HB0RB1_IO_SIZE - 1), //IoLimit
       PCI_HB0RB1_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -65,8 +61,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB0RB2_ECAM_BASE,
       0x80,  //BusBase
       0x87, //BusLimit
-      PCI_HB0RB2_CPUMEMREGIONBASE ,//MemBase
-      PCI_HB0RB2_CPUMEMREGIONBASE + PCI_HB0RB2_PCIREGION_SIZE - 1, //MemLimit
       (PCI_HB0RB2_IO_BASE),  //IOBase
       (PCI_HB0RB2_CPUIOREGIONBASE + PCI_HB0RB2_IO_SIZE - 1), //IoLimit
       PCI_HB0RB2_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -82,8 +76,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB0RB3_ECAM_BASE,
       0xb0,  //BusBase
       0xb7, //BusLimit
-      (PCI_HB0RB3_ECAM_BASE),  //MemBase
-      (PCI_HB0RB3_CPUMEMREGIONBASE + PCI_HB0RB3_PCIREGION_SIZE - 1), //MemLimit
       (PCI_HB0RB3_IO_BASE), //IoBase
       (PCI_HB0RB3_CPUIOREGIONBASE + PCI_HB0RB3_IO_SIZE - 1),  //IoLimit
       PCI_HB0RB3_CPUMEMREGIONBASE,
@@ -98,8 +90,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB0RB4_ECAM_BASE, //ecam
       0x88,  //BusBase
       0x8f, //BusLimit
-      PCI_HB0RB4_CPUMEMREGIONBASE, //Membase
-      PCI_HB0RB4_CPUMEMREGIONBASE + PCI_HB0RB4_PCIREGION_SIZE - 1, //Memlimit
       PCI_HB0RB4_IO_BASE,  //IoBase
       (PCI_HB0RB4_CPUIOREGIONBASE + PCI_HB0RB4_IO_SIZE - 1), //IoLimit
       PCI_HB0RB4_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -114,8 +104,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB0RB5_ECAM_BASE,//ecam
       0x0,  //BusBase
       0x7, //BusLimit
-      PCI_HB0RB5_CPUMEMREGIONBASE, //Membase
-      PCI_HB0RB5_CPUMEMREGIONBASE + PCI_HB0RB5_PCIREGION_SIZE - 1, //MemLimit
       (PCI_HB0RB5_IO_BASE),  //IoBase
       (PCI_HB0RB5_CPUIOREGIONBASE + PCI_HB0RB5_IO_SIZE - 1), //IoLimit
       PCI_HB0RB5_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -130,8 +118,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB0RB6_ECAM_BASE,
       0xC0,  //BusBase
       0xC7, //BusLimit
-      PCI_HB0RB6_PCIREGION_BASE ,//MemBase
-      PCI_HB0RB6_CPUMEMREGIONBASE + PCI_HB0RB6_PCIREGION_SIZE - 1, //MemLimit
       (PCI_HB0RB6_IO_BASE),  //IOBase
       (PCI_HB0RB6_CPUIOREGIONBASE + PCI_HB0RB6_IO_SIZE - 1), //IoLimit
       PCI_HB0RB6_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -147,8 +133,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB0RB7_ECAM_BASE,
       0x90,  //BusBase
       0x97, //BusLimit
-      PCI_HB0RB7_CPUMEMREGIONBASE,  //MemBase
-      PCI_HB0RB7_CPUMEMREGIONBASE + PCI_HB0RB7_PCIREGION_SIZE - 1, //MemLimit
       (PCI_HB0RB7_IO_BASE), //IoBase
       (PCI_HB0RB7_CPUIOREGIONBASE + PCI_HB0RB7_IO_SIZE - 1),  //IoLimit
       PCI_HB0RB7_CPUMEMREGIONBASE,
@@ -165,8 +149,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB0_ECAM_BASE,
       0x80,  //BusBase
       0x87, //BusLimit
-      (PCI_HB1RB0_ECAM_BASE),  //MemBase
-      (PCI_HB1RB0_CPUMEMREGIONBASE + PCI_HB1RB0_PCIREGION_SIZE - 1), //MemLimit
       PCI_HB1RB0_IO_BASE, //IoBase
       (PCI_HB1RB0_CPUIOREGIONBASE + PCI_HB1RB0_IO_SIZE - 1), //IoLimit
       PCI_HB1RB0_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -181,8 +163,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB1_ECAM_BASE,
       0x90,  //BusBase
       0x97, //BusLimit
-      (PCI_HB1RB1_ECAM_BASE),  //MemBase
-      (PCI_HB1RB1_CPUMEMREGIONBASE + PCI_HB1RB1_PCIREGION_SIZE - 1), //MemLimit
       PCI_HB1RB1_IO_BASE, //IoBase
       (PCI_HB1RB1_CPUIOREGIONBASE + PCI_HB1RB1_IO_SIZE - 1), //IoLimit
       PCI_HB1RB1_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -197,8 +177,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB2_ECAM_BASE,
       0x10,  //BusBase
       0x1f, //BusLimit
-      PCI_HB1RB2_CPUMEMREGIONBASE,  //MemBase
-      PCI_HB1RB2_CPUMEMREGIONBASE + PCI_HB1RB2_PCIREGION_SIZE - 1, //MemLimit
       PCI_HB1RB2_IO_BASE, //IoBase
       (PCI_HB1RB2_CPUIOREGIONBASE + PCI_HB1RB2_IO_SIZE - 1), //IoLimit
       PCI_HB1RB2_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -214,8 +192,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB3_ECAM_BASE,
       0xb0,  //BusBase
       0xb7, //BusLimit
-      (PCI_HB1RB3_ECAM_BASE),  //MemBase
-      (PCI_HB1RB3_CPUMEMREGIONBASE + PCI_HB1RB3_PCIREGION_SIZE - 1), //MemLimit
       PCI_HB1RB3_IO_BASE, //IoBase
       (PCI_HB1RB3_CPUIOREGIONBASE + PCI_HB1RB3_IO_SIZE - 1), //IoLimit
       PCI_HB1RB3_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -230,8 +206,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB4_ECAM_BASE,
       0x20,  //BusBase
       0x2f, //BusLimit
-      PCI_HB1RB4_CPUMEMREGIONBASE,  //MemBase
-      PCI_HB1RB4_CPUMEMREGIONBASE + PCI_HB1RB4_PCIREGION_SIZE - 1, //MemLimit
       PCI_HB1RB4_IO_BASE, //IoBase
       (PCI_HB1RB4_CPUIOREGIONBASE + PCI_HB1RB4_IO_SIZE - 1), //IoLimit
       PCI_HB1RB4_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -246,8 +220,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB5_ECAM_BASE,
       0x30,  //BusBase
       0x3f, //BusLimit
-      PCI_HB1RB5_CPUMEMREGIONBASE,  //MemBase
-      PCI_HB1RB5_CPUMEMREGIONBASE + PCI_HB1RB5_PCIREGION_SIZE - 1, //MemLimit
       PCI_HB1RB5_IO_BASE, //IoBase
       (PCI_HB1RB5_CPUIOREGIONBASE + PCI_HB1RB5_IO_SIZE - 1), //IoLimit
       PCI_HB1RB5_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -262,8 +234,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB6_ECAM_BASE,
       0xa8,  //BusBase
       0xaf, //BusLimit
-      (PCI_HB1RB6_ECAM_BASE),  //MemBase
-      PCI_HB1RB6_CPUMEMREGIONBASE + PCI_HB1RB6_PCIREGION_SIZE - 1, //MemLimit
       PCI_HB1RB6_IO_BASE, //IoBase
       (PCI_HB1RB6_CPUIOREGIONBASE + PCI_HB1RB6_IO_SIZE - 1), //IoLimit
       PCI_HB1RB6_CPUMEMREGIONBASE, //CpuMemRegionBase
@@ -279,8 +249,6 @@ PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_RO
       PCI_HB1RB7_ECAM_BASE,
       0xb8,  //BusBase
       0xbf, //BusLimit
-      (PCI_HB1RB7_ECAM_BASE),  //MemBase
-      PCI_HB1RB7_CPUMEMREGIONBASE + PCI_HB1RB7_PCIREGION_SIZE - 1, //MemLimit
       PCI_HB1RB7_IO_BASE, //IoBase
       (PCI_HB1RB7_CPUIOREGIONBASE + PCI_HB1RB7_IO_SIZE - 1), //IoLimit
       PCI_HB1RB7_CPUMEMREGIONBASE, //CpuMemRegionBase
-- 
2.7.4



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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-03-21  1:03 [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Heyi Guo
                   ` (11 preceding siblings ...)
  2018-03-21  1:03 ` [PATCH edk2-platforms 12/12] Hisilicon/PlatformPciLib: clear redundant felds in RESOURCE_APPETURE Heyi Guo
@ 2018-03-28  1:05 ` Guo Heyi
  2018-03-28  9:43   ` Ard Biesheuvel
  12 siblings, 1 reply; 33+ messages in thread
From: Guo Heyi @ 2018-03-28  1:05 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: edk2-devel, Ard Biesheuvel, Leif Lindholm, Michael D Kinney,
	Haojian Zhuang

Hi Leif, Ard,

Any comments for this series of patches?

Thanks,
Heyi

On Wed, Mar 21, 2018 at 09:03:06AM +0800, Heyi Guo wrote:
> For BAR address translation support was added to edk2 generic PciHostBridge by
> commit 74d0a33, now we can also use it for D03/D05 platforms.
> This series of patches include 3 parts of change:
> - Preparation for the switch, moving platform specific code out of PciHostBridge
>   driver.
> - Add depending libraries and protocol implementations, like PciHostBridgeLib,
>   PciSegmentLib and CpuIo2 Protocol.
> - Other enhancement and refinement.
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Leif Lindholm <leif.lindholm@linaro.org>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Haojian Zhuang <haojian.zhuang@linaro.org>
> 
> Heyi Guo (12):
>   Hisilicon: Enable WARN and INFO debug message
>   Hisilicon/D05/PlatformPciLib: fix misuse of macro
>   Hisilicon/Pci: move ATU configuration to PcieInitDxe
>   Hisilicon/Pci: Merge PciPlatform into PcieInit Driver
>   Hisilicon/Pci: Move EnlargeAtuConfig0() to PcieInitDxe
>   Hisilicon/PlatformPciLib: add segment for each root bridge
>   Hisilicon: add PciHostBridgeLib
>   Hisilicon: add PciCpuIo2Dxe
>   Hisilicon: add PciSegmentLib for Hi161x
>   Hisilicon/D0x: Switch to generic PciHostBridge driver
>   Hisilicon: remove platform specific PciHostBridge
>   Hisilicon/PlatformPciLib: clear redundant felds in RESOURCE_APPETURE
> 
>  Silicon/Hisilicon/Hisilicon.dsc.inc                                                                         |    8 +-
>  Platform/Hisilicon/D03/D03.dsc                                                                              |    7 +-
>  Platform/Hisilicon/D05/D05.dsc                                                                              |    7 +-
>  Platform/Hisilicon/D03/D03.fdf                                                                              |    4 +-
>  Platform/Hisilicon/D05/D05.fdf                                                                              |    4 +-
>  Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf                                                  |   53 -
>  Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf                                            |   51 +
>  Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf                                               |   48 +
>  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf                                             |   74 -
>  Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf                                               |    9 +-
>  Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/Hi161xPciSegmentLib.inf                                |   36 +
>  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h                                                  |  528 -----
>  {Platform/Hisilicon/D03/Drivers/PciPlatform => Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610}/PciPlatform.h |    0
>  Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h                                                 |   13 +
>  Silicon/Hisilicon/Include/Library/PlatformPciLib.h                                                          |    3 +-
>  Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.c                                              |   24 +-
>  Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c                                              |   66 +-
>  Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.c                                              |  304 +++
>  Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.c                                                 |  557 +++++
>  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c                                                  | 1659 --------------
>  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c                                                | 2404 --------------------
>  {Platform/Hisilicon/D03/Drivers/PciPlatform => Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610}/PciPlatform.c |   12 +
>  Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c                                                    |    7 +-
>  Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c                                                 |  309 +++
>  Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/PciSegmentLib.c                                        | 1503 ++++++++++++
>  25 files changed, 2897 insertions(+), 4793 deletions(-)
>  delete mode 100644 Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf
>  create mode 100644 Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf
>  create mode 100644 Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
>  delete mode 100644 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
>  create mode 100644 Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/Hi161xPciSegmentLib.inf
>  delete mode 100644 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h
>  rename {Platform/Hisilicon/D03/Drivers/PciPlatform => Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610}/PciPlatform.h (100%)
>  create mode 100644 Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.c
>  create mode 100644 Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.c
>  delete mode 100644 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c
>  delete mode 100644 Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
>  rename {Platform/Hisilicon/D03/Drivers/PciPlatform => Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610}/PciPlatform.c (93%)
>  create mode 100644 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
>  create mode 100644 Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/PciSegmentLib.c
> 
> -- 
> 2.7.4
> 


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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-03-28  1:05 ` [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Guo Heyi
@ 2018-03-28  9:43   ` Ard Biesheuvel
  2018-03-29  0:20     ` Guo Heyi
  0 siblings, 1 reply; 33+ messages in thread
From: Ard Biesheuvel @ 2018-03-28  9:43 UTC (permalink / raw)
  To: Guo Heyi
  Cc: Leif Lindholm, edk2-devel@lists.01.org, Michael D Kinney,
	Haojian Zhuang

On 28 March 2018 at 02:05, Guo Heyi <heyi.guo@linaro.org> wrote:
> Hi Leif, Ard,
>
> Any comments for this series of patches?
>

Hello Heyi,

Thanks for sending these patches. Leif is at the plugfest, but I will
look at these before the end of the week.


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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-03-28  9:43   ` Ard Biesheuvel
@ 2018-03-29  0:20     ` Guo Heyi
  2018-03-30 15:40       ` Ard Biesheuvel
  0 siblings, 1 reply; 33+ messages in thread
From: Guo Heyi @ 2018-03-29  0:20 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Guo Heyi, Leif Lindholm, edk2-devel@lists.01.org,
	Michael D Kinney, Haojian Zhuang

On Wed, Mar 28, 2018 at 10:43:41AM +0100, Ard Biesheuvel wrote:
> On 28 March 2018 at 02:05, Guo Heyi <heyi.guo@linaro.org> wrote:
> > Hi Leif, Ard,
> >
> > Any comments for this series of patches?
> >
> 
> Hello Heyi,
> 
> Thanks for sending these patches. Leif is at the plugfest, but I will
> look at these before the end of the week.

Forgot the plugfest as I am not attending :)


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

* Re: [PATCH edk2-platforms 03/12] Hisilicon/Pci: move ATU configuration to PcieInitDxe
  2018-03-21  1:03 ` [PATCH edk2-platforms 03/12] Hisilicon/Pci: move ATU configuration to PcieInitDxe Heyi Guo
@ 2018-03-30 15:19   ` Ard Biesheuvel
  0 siblings, 0 replies; 33+ messages in thread
From: Ard Biesheuvel @ 2018-03-30 15:19 UTC (permalink / raw)
  To: Heyi Guo; +Cc: edk2-devel@lists.01.org, Leif Lindholm, Michael D Kinney

On 21 March 2018 at 01:03, Heyi Guo <heyi.guo@linaro.org> wrote:
> This is to prepare for switching to generic PciHostBridge driver, so
> we move all platform specific code to platform specific drivers, not
> in PciHostBridge driver.
>
> This patch moves ATU initialization to PcieInitDxe driver.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Leif Lindholm <leif.lindholm@linaro.org>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> ---
>  Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf |   1 +
>  Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h   |   2 +
>  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c  | 106 ---------------
>  Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c      |   3 +
>  Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c   | 141 ++++++++++++++++++++
>  5 files changed, 147 insertions(+), 106 deletions(-)
>
> diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
> index 61b091f659b3..cb0a63f9a84e 100644
> --- a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
> +++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
> @@ -25,6 +25,7 @@ [Defines]
>  [Sources]
>    PcieInit.c
>    PcieInitLib.c
> +  PcieInitAtu.c
>
>  [Packages]
>    MdePkg/MdePkg.dec
> diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h
> index e96c53c4fe4e..87700ae8b9aa 100644
> --- a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h
> +++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.h
> @@ -246,4 +246,6 @@ EFI_STATUS PcieWaitLinkUp(UINT32 Port);
>
>  EFI_STATUS PcieSetDBICS2Enable(UINT32 HostBridgeNum, UINT32 Port, UINT32 Enable);
>
> +VOID InitAtu (PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private);

APPETURE is not a word. This should be APERTURE.

I know this occurs in existing code, and so I won't block this series
for it, but could you please post a followup patch that replaces all
occurrences of 'appeture' with 'aperture'? Thanks.

> +
>  #endif
> diff --git a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c b/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
> index 55b80aa4e49a..273a322ee48f 100644
> --- a/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
> +++ b/Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
> @@ -633,111 +633,6 @@ UINT64 GetPcieCfgAddress (
>  }
>
>
> -void SetAtuConfig0RW (
> -    PCI_ROOT_BRIDGE_INSTANCE *Private,
> -    UINT32 Index
> -    )
> -{
> -    UINTN RbPciBase = Private->RbPciBar;
> -    UINT64 MemLimit = GetPcieCfgAddress (Private->Ecam, Private->BusBase + 1, 1, 0, 0) - 1;
> -
> -
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(Private->Ecam));
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(Private->Ecam) >> 32));
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, 0);
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, 0);
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_CONFIG0);
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_SHIIF_MODE);
> -
> -    {
> -      UINTN i;
> -      for (i=0; i<0x20; i+=4) {
> -        DEBUG ((EFI_D_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
> -      }
> -    }
> -}
> -
> -void SetAtuConfig1RW (
> -    PCI_ROOT_BRIDGE_INSTANCE *Private,
> -    UINT32 Index
> -    )
> -{
> -    UINTN RbPciBase = Private->RbPciBar;
> -    UINT64 MemLimit = GetPcieCfgAddress (Private->Ecam, Private->BusLimit + 1, 0, 0, 0) - 1;
> -
> -
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_CONFIG1);
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(Private->Ecam));
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(Private->Ecam) >> 32));
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, 0);
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, 0);
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_SHIIF_MODE);
> -
> -    {
> -      UINTN i;
> -      for (i=0; i<0x20; i+=4) {
> -        DEBUG ((EFI_D_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
> -      }
> -    }
> -}
> -
> -void SetAtuIoRW(UINT64 RbPciBase,UINT64 IoBase,UINT64 CpuIoRegionLimit, UINT64 CpuIoRegionBase, UINT32 Index)
> -{
> -
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_IO);
> -
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(CpuIoRegionBase));
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)CpuIoRegionBase >> 32));
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32)(CpuIoRegionLimit));
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, (UINT32)(IoBase));
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, (UINT32)((UINT64)(IoBase) >> 32));
> -
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_NORMAL_MODE);
> -
> -    {
> -      UINTN i;
> -      for (i=0; i<0x20; i+=4) {
> -        DEBUG ((EFI_D_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
> -      }
> -    }
> -}
> -
> -void SetAtuMemRW(UINT64 RbPciBase,UINT64 MemBase,UINT64 CpuMemRegionLimit, UINT64 CpuMemRegionBase, UINT32 Index)
> -{
> -
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_MEM);
> -
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(CpuMemRegionBase));
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(CpuMemRegionBase) >> 32));
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32)(CpuMemRegionLimit));
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, (UINT32)(MemBase));
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, (UINT32)((UINT64)(MemBase) >> 32));
> -
> -    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_NORMAL_MODE);
> -
> -    {
> -      UINTN i;
> -      for (i=0; i<0x20; i+=4) {
> -        DEBUG ((EFI_D_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
> -      }
> -    }
> -}
> -
> -VOID InitAtu (PCI_ROOT_BRIDGE_INSTANCE *Private)
> -{
> -  SetAtuMemRW (Private->RbPciBar, Private->PciRegionBase, Private->PciRegionLimit, Private->CpuMemRegionBase, 0);
> -  SetAtuConfig0RW (Private, 1);
> -  SetAtuConfig1RW (Private, 2);
> -  SetAtuIoRW (Private->RbPciBar, Private->IoBase, Private->IoLimit, Private->CpuIoRegionBase, 3);
> -}
> -
> -
>  BOOLEAN PcieIsLinkUp (UINT32 SocType, UINTN RbPciBar, UINTN Port)
>  {
>      UINT32                     Value = 0;
> @@ -860,7 +755,6 @@ RootBridgeConstructor (
>
>    Protocol->SegmentNumber  = Seg;
>
> -  InitAtu (PrivateData);
>
>    Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)&mMetronome);
>    if (EFI_ERROR(Status))
> diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c
> index 5fc0ead5c1d5..de297e67e2e1 100644
> --- a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c
> +++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInit.c
> @@ -17,6 +17,7 @@
>  #include <Library/UefiBootServicesTableLib.h>
>  #include <Library/PcdLib.h>
>  #include <Library/OemMiscLib.h>
> +#include <Library/PciExpressLib.h>
>  #include <Library/PlatformPciLib.h>
>
>
> @@ -154,6 +155,8 @@ PcieInitEntry (
>                  DEBUG((EFI_D_ERROR, "HostBridge %d, Pcie Port %d Init Failed! \n", HostBridgeNum, Port));
>              }
>
> +            InitAtu (&mResAppeture[HostBridgeNum][Port]);
> +
>          }
>      }
>
> diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
> new file mode 100644
> index 000000000000..9eb3451f7402
> --- /dev/null
> +++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
> @@ -0,0 +1,141 @@
> +/** @file
> +*
> +*  Copyright (c) 2018, Hisilicon Limited. All rights reserved.
> +*  Copyright (c) 2018, Linaro Limited. All rights reserved.
> +*
> +*  This program and the accompanying materials
> +*  are licensed and made available under the terms and conditions of the BSD License
> +*  which accompanies this distribution.  The full text of the license may be found at
> +*  http://opensource.org/licenses/bsd-license.php
> +*
> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +*
> +**/
> +
> +#include <Library/OemMiscLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciExpressLib.h>
> +#include <Library/PlatformPciLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include "PcieInit.h"
> +
> +STATIC
> +UINT64
> +GetPcieCfgAddress (
> +    UINT64 Ecam,
> +    UINTN Bus,
> +    UINTN Device,
> +    UINTN Function,
> +    UINTN Reg
> +    )
> +{
> +  return Ecam + PCI_EXPRESS_LIB_ADDRESS (Bus, Device, Function, Reg);
> +}
> +
> +STATIC
> +VOID
> +SetAtuConfig0RW (
> +    PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private,
> +    UINT32 Index
> +    )
> +{
> +  UINTN RbPciBase = Private->RbPciBar;
> +  UINT64 MemLimit = GetPcieCfgAddress (Private->Ecam, Private->BusBase + 1, 1, 0, 0) - 1;
> +
> +
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(Private->Ecam));
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(Private->Ecam) >> 32));
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, 0);
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, 0);
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_CONFIG0);
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_SHIIF_MODE);
> +
> +  {
> +    UINTN i;
> +    for (i=0; i<0x20; i+=4) {
> +      DEBUG ((DEBUG_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
> +    }
> +  }
> +}
> +
> +void SetAtuConfig1RW (
> +    PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private,
> +    UINT32 Index
> +    )
> +{
> +  UINTN RbPciBase = Private->RbPciBar;
> +  UINT64 MemLimit = GetPcieCfgAddress (Private->Ecam, Private->BusLimit + 1, 0, 0, 0) - 1;
> +
> +
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_CONFIG1);
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(Private->Ecam));
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(Private->Ecam) >> 32));
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, 0);
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, 0);
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_SHIIF_MODE);
> +
> +  {
> +    UINTN i;
> +    for (i=0; i<0x20; i+=4) {
> +      DEBUG ((DEBUG_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
> +    }
> +  }
> +}
> +
> +void SetAtuIoRW(UINT64 RbPciBase,UINT64 IoBase,UINT64 CpuIoRegionLimit, UINT64 CpuIoRegionBase, UINT32 Index)
> +{
> +
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_IO);
> +
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(CpuIoRegionBase));
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)CpuIoRegionBase >> 32));
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32)(CpuIoRegionLimit));
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, (UINT32)(IoBase));
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, (UINT32)((UINT64)(IoBase) >> 32));
> +
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_NORMAL_MODE);
> +
> +    {
> +      UINTN i;
> +      for (i=0; i<0x20; i+=4) {
> +        DEBUG ((DEBUG_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
> +      }
> +    }
> +}
> +
> +void SetAtuMemRW(UINT64 RbPciBase,UINT64 MemBase,UINT64 CpuMemRegionLimit, UINT64 CpuMemRegionBase, UINT32 Index)
> +{
> +
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_MEM);
> +
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(CpuMemRegionBase));
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(CpuMemRegionBase) >> 32));
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32)(CpuMemRegionLimit));
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, (UINT32)(MemBase));
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, (UINT32)((UINT64)(MemBase) >> 32));
> +
> +    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_NORMAL_MODE);
> +
> +    {
> +      UINTN i;
> +      for (i=0; i<0x20; i+=4) {
> +        DEBUG ((DEBUG_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
> +      }
> +    }
> +}
> +
> +VOID InitAtu (PCI_ROOT_BRIDGE_RESOURCE_APPETURE *Private)
> +{
> +  SetAtuMemRW (Private->RbPciBar, Private->PciRegionBase, Private->PciRegionLimit, Private->CpuMemRegionBase, 0);
> +  SetAtuConfig0RW (Private, 1);
> +  SetAtuConfig1RW (Private, 2);
> +  SetAtuIoRW (Private->RbPciBar, Private->IoBase, Private->IoLimit, Private->CpuIoRegionBase, 3);
> +}
> +
> --
> 2.7.4
>


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

* Re: [PATCH edk2-platforms 07/12] Hisilicon: add PciHostBridgeLib
  2018-03-21  1:03 ` [PATCH edk2-platforms 07/12] Hisilicon: add PciHostBridgeLib Heyi Guo
@ 2018-03-30 15:28   ` Ard Biesheuvel
  0 siblings, 0 replies; 33+ messages in thread
From: Ard Biesheuvel @ 2018-03-30 15:28 UTC (permalink / raw)
  To: Heyi Guo; +Cc: edk2-devel@lists.01.org, Leif Lindholm, Michael D Kinney

On 21 March 2018 at 01:03, Heyi Guo <heyi.guo@linaro.org> wrote:
> This is to prepare for switching to generic PciHostBridge, and
> PciHostBridgeLib is needed by PciHostBridge driver.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Leif Lindholm <leif.lindholm@linaro.org>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> ---
>  Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf |  51 ++++
>  Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.c   | 304 ++++++++++++++++++++
>  2 files changed, 355 insertions(+)
>
> diff --git a/Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> new file mode 100644
> index 000000000000..dd451cff332c
> --- /dev/null
> +++ b/Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> @@ -0,0 +1,51 @@
> +## @file
> +#  PCI Host Bridge Library instance for Hisilicon D0x
> +#
> +#  Copyright (c) 2018, Hisilicon Limited. All rights reserved.<BR>
> +#  Copyright (c) 2017 - 2018, Linaro Ltd. All rights reserved.<BR>
> +#
> +#  This program and the accompanying materials are licensed and made available
> +#  under the terms and conditions of the BSD License which accompanies this
> +#  distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
> +#  IMPLIED.
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001000A
> +  BASE_NAME                      = PciHostBridgeLib
> +  FILE_GUID                      = e5c91e8a-0b2b-11e8-9533-286ed489ee9b
> +  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 ARM
> +#
> +
> +[Sources]
> +  PciHostBridgeLib.c
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Hisilicon/HisiPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  DevicePathLib
> +  MemoryAllocationLib
> +  OemMiscLib
> +
> +[Pcd]
> +  gHisiTokenSpaceGuid.PcdPcieRootBridgeMask
> +  gHisiTokenSpaceGuid.PcdPcieRootBridgeMask2P
> diff --git a/Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.c
> new file mode 100644
> index 000000000000..6aff5cdd3d76
> --- /dev/null
> +++ b/Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.c
> @@ -0,0 +1,304 @@
> +/** @file
> +  PCI Host Bridge Library instance for Hisilicon D0x
> +
> +  Copyright (c) 2018, Hisilicon Limited. All rights reserved.<BR>
> +  Copyright (c) 2017 - 2018, Linaro Ltd. All rights reserved.<BR>
> +
> +  This program and the accompanying materials are licensed and made available
> +  under the terms and conditions of the BSD License which accompanies this
> +  distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php.
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
> +  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +#include <PiDxe.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/OemMiscLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Library/PlatformPciLib.h>
> +
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +
> +
> +#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 = {
> +  {
> +    {
> +      ACPI_DEVICE_PATH,
> +      ACPI_DP,
> +      {
> +        (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
> +        (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    EISA_PNP_ID(0x0A03), // PCI
> +    0
> +  }, {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      END_DEVICE_PATH_LENGTH,
> +      0
> +    }
> +  }
> +};
> +
> +STATIC PCI_ROOT_BRIDGE mRootBridgeTemplate = {
> +  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
> +    0,
> +    0
> +  }, {
> +    // Io
> +    0,
> +    0,
> +    0
> +  }, {
> +    // Mem
> +    MAX_UINT64,
> +    0,
> +    0
> +  }, {
> +    // MemAbove4G
> +    MAX_UINT64,
> +    0,
> +    0
> +  }, {
> +    // PMem
> +    MAX_UINT64,
> +    0,
> +    0
> +  }, {
> +    // PMemAbove4G
> +    MAX_UINT64,
> +    0,
> +    0
> +  },
> +  (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath
> +};
> +
> +STATIC
> +EFI_STATUS
> +ConstructRootBridge (
> +    PCI_ROOT_BRIDGE                     *Bridge,
> +    PCI_ROOT_BRIDGE_RESOURCE_APPETURE   *Appeture
> +    )
> +{
> +  EFI_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;
> +  CopyMem (Bridge, &mRootBridgeTemplate, sizeof *Bridge);
> +  Bridge->Segment = Appeture->Segment;
> +  Bridge->Bus.Base = Appeture->BusBase;
> +  Bridge->Bus.Limit = Appeture->BusLimit;
> +  Bridge->Io.Base = Appeture->IoBase;
> +  // According to UEFI 2.7, device address = host address + translation
> +  Bridge->Io.Translation = Appeture->IoBase - Appeture->CpuIoRegionBase;
> +  // IoLimit is actually an address in CPU view
> +  // TODO: improve the definition of PCI_ROOT_BRIDGE_RESOURCE_APPETURE
> +  Bridge->Io.Limit = Appeture->IoLimit + Bridge->Io.Translation;

Does this mean we incorporate the type translation into the I/O
address translation? In other words, are the CPU memory addresses
equal to the CPU I/O addresses when using this translation?

If so, I think that is incorrect. The translated I/O windows should
make up a coherent I/O space in the CPU view, and the fact that we
access I/O regions via a CPU MMIO window that involves type
translation is an implementation detail.


> +  if (Appeture->PciRegionBase > MAX_UINT32) {
> +    Bridge->MemAbove4G.Base = Appeture->PciRegionBase;
> +    Bridge->MemAbove4G.Limit = Appeture->PciRegionLimit;
> +    Bridge->MemAbove4G.Translation = Appeture->PciRegionBase - Appeture->CpuMemRegionBase;
> +  } else {
> +    Bridge->Mem.Base = Appeture->PciRegionBase;
> +    Bridge->Mem.Limit = Appeture->PciRegionLimit;
> +    Bridge->Mem.Translation = Appeture->PciRegionBase - Appeture->CpuMemRegionBase;
> +  }
> +
> +  DevicePath = AllocateCopyPool(sizeof mEfiPciRootBridgeDevicePath, &mEfiPciRootBridgeDevicePath);
> +  if (DevicePath == NULL) {
> +    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] AllocatePool failed!\n", __FUNCTION__, __LINE__));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  DevicePath->AcpiDevicePath.UID = Bridge->Segment;
> +  Bridge->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  UINTN                       Loop1;
> +  UINTN                       Loop2;
> +  UINT32                      PcieRootBridgeMask;
> +  UINTN                       RootBridgeCount = 0;
> +  PCI_ROOT_BRIDGE             *Bridges;
> +
> +  // Set default value to 0 in case we got any error.
> +  *Count = 0;
> +
> +
> +  if (!OemIsMpBoot())
> +  {
> +    PcieRootBridgeMask = PcdGet32(PcdPcieRootBridgeMask);
> +  }
> +  else
> +  {
> +    PcieRootBridgeMask = PcdGet32(PcdPcieRootBridgeMask2P);
> +  }
> +
> +  for (Loop1 = 0; Loop1 < PCIE_MAX_HOSTBRIDGE; Loop1++) {
> +    if (((PcieRootBridgeMask >> (PCIE_MAX_ROOTBRIDGE * Loop1)) & 0xFF ) == 0) {
> +      continue;
> +    }
> +
> +    for (Loop2 = 0; Loop2 < PCIE_MAX_ROOTBRIDGE; Loop2++) {
> +      if (!(((PcieRootBridgeMask >> (PCIE_MAX_ROOTBRIDGE * Loop1)) >> Loop2 ) & 0x01)) {
> +        continue;
> +      }
> +      RootBridgeCount++;
> +    }
> +  }
> +
> +  Bridges = AllocatePool (RootBridgeCount * sizeof *Bridges);
> +  if (Bridges == NULL) {
> +    DEBUG ((DEBUG_ERROR, "[%a:%d] - AllocatePool failed!\n", __FUNCTION__, __LINE__));
> +    return NULL;
> +  }
> +
> +  for (Loop1 = 0; Loop1 < PCIE_MAX_HOSTBRIDGE; Loop1++) {
> +    if (((PcieRootBridgeMask >> (PCIE_MAX_ROOTBRIDGE * Loop1)) & 0xFF ) == 0) {
> +      continue;
> +    }
> +
> +    for (Loop2 = 0; Loop2 < PCIE_MAX_ROOTBRIDGE; Loop2++) {
> +      if (!(((PcieRootBridgeMask >> (PCIE_MAX_ROOTBRIDGE * Loop1)) >> Loop2 ) & 0x01)) {
> +        continue;
> +      }
> +      Status = ConstructRootBridge (&Bridges[*Count], &mResAppeture[Loop1][Loop2]);
> +      if (EFI_ERROR (Status)) {
> +        continue;
> +      }
> +      (*Count)++;
> +    }
> +  }
> +
> +  if (*Count == 0) {
> +    FreePool (Bridges);
> +    return NULL;
> +  }
> +  return Bridges;
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  UINTN Index;
> +
> +  for (Index = 0; Index < Count; Index++) {
> +    FreePool (Bridges[Index].DevicePath);
> +  }
> +
> +  if (Bridges != NULL) {
> +    FreePool (Bridges);
> +  }
> +}
> +
> +
> +#ifndef MDEPKG_NDEBUG
> +STATIC CONST CHAR16 mPciHostBridgeLibAcpiAddressSpaceTypeStr[][4] = {
> +  L"Mem", L"I/O", L"Bus"
> +};
> +#endif
> +
> +/**
> +  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
> +                   );
> +  }
> +}
> --
> 2.7.4
>


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

* Re: [PATCH edk2-platforms 08/12] Hisilicon: add PciCpuIo2Dxe
  2018-03-21  1:03 ` [PATCH edk2-platforms 08/12] Hisilicon: add PciCpuIo2Dxe Heyi Guo
@ 2018-03-30 15:30   ` Ard Biesheuvel
  0 siblings, 0 replies; 33+ messages in thread
From: Ard Biesheuvel @ 2018-03-30 15:30 UTC (permalink / raw)
  To: Heyi Guo; +Cc: edk2-devel@lists.01.org, Leif Lindholm, Michael D Kinney

On 21 March 2018 at 01:03, Heyi Guo <heyi.guo@linaro.org> wrote:
> This is to prepare for switching to generic PciHostBridge, and
> CpuIo2Dxe is needed by generic PciHostBridge driver.
>
> The driver is copied from ArmPkg/Drivers/ArmPciCpuIo2Dxe and changed
> for D0x.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Leif Lindholm <leif.lindholm@linaro.org>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> ---
>  Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf |  48 ++
>  Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.c   | 557 ++++++++++++++++++++
>  2 files changed, 605 insertions(+)
>
> diff --git a/Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf b/Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
> new file mode 100644
> index 000000000000..fbb28319ca87
> --- /dev/null
> +++ b/Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
> @@ -0,0 +1,48 @@
> +## @file
> +#  Produces the CPU I/O 2 Protocol by using the services of the I/O Library.
> +#
> +# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2016 - 2018, Linaro Ltd. All rights reserved.<BR>
> +# Copyright (c) 2018, Hisilicon Ltd. All rights reserved.<BR>
> +#
> +# This program and the accompanying materials
> +# are licensed and made available under the terms and conditions of the BSD License
> +# which accompanies this distribution.  The full text of the license may be found at
> +# http://opensource.org/licenses/bsd-license.php
> +#
> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001A
> +  BASE_NAME                      = ArmPciCpuIo2Dxe
> +  FILE_GUID                      = 94577c7e-0bce-11e8-b4e8-286ed489ee9b
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = ArmPciCpuIo2Initialize
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = ARM AARCH64
> +#
> +
> +[Sources]
> +  ArmPciCpuIo2Dxe.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  BaseLib
> +  DebugLib
> +  IoLib
> +
> +[Protocols]
> +  gEfiCpuIo2ProtocolGuid                         ## PRODUCES
> +
> +[Depex]
> +  TRUE
> diff --git a/Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.c b/Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.c
> new file mode 100644
> index 000000000000..8426c5935c8a
> --- /dev/null
> +++ b/Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.c
> @@ -0,0 +1,557 @@
> +/** @file
> +  Produces the CPU I/O 2 Protocol.
> +
> +Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2016 - 2018, Linaro Ltd. All rights reserved.<BR>
> +Copyright (c) 2018, Hisilicon Ltd. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD License
> +which accompanies this distribution.  The full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include <PiDxe.h>
> +
> +#include <Protocol/CpuIo2.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +// The translated IO PORT address is already a MMIO address, so we make it the
> +// same as memory address for range check.
> +#define MAX_IO_PORT_ADDRESS   MAX_ADDRESS
> +
> +//
> +// Lookup table for increment values based on transfer widths
> +//
> +STATIC CONST UINT8 mInStride[] = {
> +  1, // EfiCpuIoWidthUint8
> +  2, // EfiCpuIoWidthUint16
> +  4, // EfiCpuIoWidthUint32
> +  8, // EfiCpuIoWidthUint64
> +  0, // EfiCpuIoWidthFifoUint8
> +  0, // EfiCpuIoWidthFifoUint16
> +  0, // EfiCpuIoWidthFifoUint32
> +  0, // EfiCpuIoWidthFifoUint64
> +  1, // EfiCpuIoWidthFillUint8
> +  2, // EfiCpuIoWidthFillUint16
> +  4, // EfiCpuIoWidthFillUint32
> +  8  // EfiCpuIoWidthFillUint64
> +};
> +
> +//
> +// Lookup table for increment values based on transfer widths
> +//
> +STATIC CONST UINT8 mOutStride[] = {
> +  1, // EfiCpuIoWidthUint8
> +  2, // EfiCpuIoWidthUint16
> +  4, // EfiCpuIoWidthUint32
> +  8, // EfiCpuIoWidthUint64
> +  1, // EfiCpuIoWidthFifoUint8
> +  2, // EfiCpuIoWidthFifoUint16
> +  4, // EfiCpuIoWidthFifoUint32
> +  8, // EfiCpuIoWidthFifoUint64
> +  0, // EfiCpuIoWidthFillUint8
> +  0, // EfiCpuIoWidthFillUint16
> +  0, // EfiCpuIoWidthFillUint32
> +  0  // EfiCpuIoWidthFillUint64
> +};
> +
> +/**
> +  Check parameters to a CPU I/O 2 Protocol service request.
> +
> +  The I/O operations are carried out exactly as requested. The caller is responsible
> +  for satisfying any alignment and I/O width restrictions that a PI System on a
> +  platform might require. For example on some platforms, width requests of
> +  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
> +  be handled by the driver.
> +
> +  @param[in] MmioOperation  TRUE for an MMIO operation, FALSE for I/O Port operation.
> +  @param[in] Width          Signifies the width of the I/O or Memory operation.
> +  @param[in] Address        The base address of the I/O operation.
> +  @param[in] Count          The number of I/O operations to perform. The number of
> +                            bytes moved is Width size * Count, starting at Address.
> +  @param[in] Buffer         For read operations, the destination buffer to store the results.
> +                            For write operations, the source buffer from which to write data.
> +
> +  @retval EFI_SUCCESS            The parameters for this request pass the checks.
> +  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
> +  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
> +                                 and Count is not valid for this PI system.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +CpuIoCheckParameter (
> +  IN BOOLEAN                    MmioOperation,
> +  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
> +  IN UINT64                     Address,
> +  IN UINTN                      Count,
> +  IN VOID                       *Buffer
> +  )
> +{
> +  UINT64  MaxCount;
> +  UINT64  Limit;
> +
> +  //
> +  // Check to see if Buffer is NULL
> +  //
> +  if (Buffer == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Check to see if Width is in the valid range
> +  //
> +  if ((UINT32)Width >= EfiCpuIoWidthMaximum) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // For FIFO type, the target address won't increase during the access,
> +  // so treat Count as 1
> +  //
> +  if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
> +    Count = 1;
> +  }
> +
> +  //
> +  // Check to see if Width is in the valid range for I/O Port operations
> +  //
> +  Width = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
> +  if (!MmioOperation && (Width == EfiCpuIoWidthUint64)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Check to see if Address is aligned
> +  //
> +  if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Check to see if any address associated with this transfer exceeds the maximum
> +  // allowed address.  The maximum address implied by the parameters passed in is
> +  // Address + Size * Count.  If the following condition is met, then the transfer
> +  // is not supported.
> +  //
> +  //    Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
> +  //
> +  // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count
> +  // can also be the maximum integer value supported by the CPU, this range
> +  // check must be adjusted to avoid all oveflow conditions.
> +  //
> +  // The following form of the range check is equivalent but assumes that
> +  // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
> +  //
> +  Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);
> +  if (Count == 0) {
> +    if (Address > Limit) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  } else {
> +    MaxCount = RShiftU64 (Limit, Width);
> +    if (MaxCount < (Count - 1)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  //
> +  // Check to see if Buffer is aligned
> +  //
> +  if (((UINTN)Buffer & ((MIN (sizeof (UINTN), mInStride[Width])  - 1))) != 0) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Reads memory-mapped registers.
> +
> +  The I/O operations are carried out exactly as requested. The caller is responsible
> +  for satisfying any alignment and I/O width restrictions that a PI System on a
> +  platform might require. For example on some platforms, width requests of
> +  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
> +  be handled by the driver.
> +
> +  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
> +  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
> +  each of the Count operations that is performed.
> +
> +  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
> +  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
> +  incremented for each of the Count operations that is performed. The read or
> +  write operation is performed Count times on the same Address.
> +
> +  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
> +  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
> +  incremented for each of the Count operations that is performed. The read or
> +  write operation is performed Count times from the first element of Buffer.
> +
> +  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
> +  @param[in]  Width    Signifies the width of the I/O or Memory operation.
> +  @param[in]  Address  The base address of the I/O operation.
> +  @param[in]  Count    The number of I/O operations to perform. The number of
> +                       bytes moved is Width size * Count, starting at Address.
> +  @param[out] Buffer   For read operations, the destination buffer to store the results.
> +                       For write operations, the source buffer from which to write data.
> +
> +  @retval EFI_SUCCESS            The data was read from or written to the PI system.
> +  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
> +  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
> +                                 and Count is not valid for this PI system.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +CpuMemoryServiceRead (
> +  IN  EFI_CPU_IO2_PROTOCOL       *This,
> +  IN  EFI_CPU_IO_PROTOCOL_WIDTH  Width,
> +  IN  UINT64                     Address,
> +  IN  UINTN                      Count,
> +  OUT VOID                       *Buffer
> +  )
> +{
> +  EFI_STATUS                 Status;
> +  UINT8                      InStride;
> +  UINT8                      OutStride;
> +  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
> +  UINT8                      *Uint8Buffer;
> +
> +  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Select loop based on the width of the transfer
> +  //
> +  InStride = mInStride[Width];
> +  OutStride = mOutStride[Width];
> +  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
> +  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
> +    if (OperationWidth == EfiCpuIoWidthUint8) {
> +      *Uint8Buffer = MmioRead8 ((UINTN)Address);
> +    } else if (OperationWidth == EfiCpuIoWidthUint16) {
> +      *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
> +    } else if (OperationWidth == EfiCpuIoWidthUint32) {
> +      *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
> +    } else if (OperationWidth == EfiCpuIoWidthUint64) {
> +      *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Writes memory-mapped registers.
> +
> +  The I/O operations are carried out exactly as requested. The caller is responsible
> +  for satisfying any alignment and I/O width restrictions that a PI System on a
> +  platform might require. For example on some platforms, width requests of
> +  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
> +  be handled by the driver.
> +
> +  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
> +  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
> +  each of the Count operations that is performed.
> +
> +  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
> +  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
> +  incremented for each of the Count operations that is performed. The read or
> +  write operation is performed Count times on the same Address.
> +
> +  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
> +  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
> +  incremented for each of the Count operations that is performed. The read or
> +  write operation is performed Count times from the first element of Buffer.
> +
> +  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
> +  @param[in]  Width    Signifies the width of the I/O or Memory operation.
> +  @param[in]  Address  The base address of the I/O operation.
> +  @param[in]  Count    The number of I/O operations to perform. The number of
> +                       bytes moved is Width size * Count, starting at Address.
> +  @param[in]  Buffer   For read operations, the destination buffer to store the results.
> +                       For write operations, the source buffer from which to write data.
> +
> +  @retval EFI_SUCCESS            The data was read from or written to the PI system.
> +  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
> +  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
> +                                 and Count is not valid for this PI system.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +CpuMemoryServiceWrite (
> +  IN EFI_CPU_IO2_PROTOCOL       *This,
> +  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
> +  IN UINT64                     Address,
> +  IN UINTN                      Count,
> +  IN VOID                       *Buffer
> +  )
> +{
> +  EFI_STATUS                 Status;
> +  UINT8                      InStride;
> +  UINT8                      OutStride;
> +  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
> +  UINT8                      *Uint8Buffer;
> +
> +  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Select loop based on the width of the transfer
> +  //
> +  InStride = mInStride[Width];
> +  OutStride = mOutStride[Width];
> +  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
> +  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
> +    if (OperationWidth == EfiCpuIoWidthUint8) {
> +      MmioWrite8 ((UINTN)Address, *Uint8Buffer);
> +    } else if (OperationWidth == EfiCpuIoWidthUint16) {
> +      MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
> +    } else if (OperationWidth == EfiCpuIoWidthUint32) {
> +      MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
> +    } else if (OperationWidth == EfiCpuIoWidthUint64) {
> +      MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Reads I/O registers.
> +
> +  The I/O operations are carried out exactly as requested. The caller is responsible
> +  for satisfying any alignment and I/O width restrictions that a PI System on a
> +  platform might require. For example on some platforms, width requests of
> +  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
> +  be handled by the driver.
> +
> +  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
> +  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
> +  each of the Count operations that is performed.
> +
> +  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
> +  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
> +  incremented for each of the Count operations that is performed. The read or
> +  write operation is performed Count times on the same Address.
> +
> +  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
> +  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
> +  incremented for each of the Count operations that is performed. The read or
> +  write operation is performed Count times from the first element of Buffer.
> +
> +  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
> +  @param[in]  Width    Signifies the width of the I/O or Memory operation.
> +  @param[in]  Address  The base address of the I/O operation.
> +  @param[in]  Count    The number of I/O operations to perform. The number of
> +                       bytes moved is Width size * Count, starting at Address.
> +  @param[out] Buffer   For read operations, the destination buffer to store the results.
> +                       For write operations, the source buffer from which to write data.
> +
> +  @retval EFI_SUCCESS            The data was read from or written to the PI system.
> +  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
> +  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
> +                                 and Count is not valid for this PI system.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +CpuIoServiceRead (
> +  IN  EFI_CPU_IO2_PROTOCOL       *This,
> +  IN  EFI_CPU_IO_PROTOCOL_WIDTH  Width,
> +  IN  UINT64                     Address,
> +  IN  UINTN                      Count,
> +  OUT VOID                       *Buffer
> +  )
> +{
> +  EFI_STATUS                 Status;
> +  UINT8                      InStride;
> +  UINT8                      OutStride;
> +  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
> +  UINT8                      *Uint8Buffer;
> +
> +  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Select loop based on the width of the transfer
> +  //
> +  InStride = mInStride[Width];
> +  OutStride = mOutStride[Width];
> +  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
> +
> +  // Assuming address has already been translated into MMIO address by PCI host
> +  // bridge driver, so we call MmioRead/Write directly.

As noted in the previous patch, this is not correct.

This is where the type translation should occur, from I/O address in
the CPU view to an address covered by the I/O host bridge window that
translates to I/O TLPs on the PCI side.


> +  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
> +    if (OperationWidth == EfiCpuIoWidthUint8) {
> +      *Uint8Buffer = MmioRead8 ((UINTN)Address);
> +    } else if (OperationWidth == EfiCpuIoWidthUint16) {
> +      *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
> +    } else if (OperationWidth == EfiCpuIoWidthUint32) {
> +      *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Write I/O registers.
> +
> +  The I/O operations are carried out exactly as requested. The caller is responsible
> +  for satisfying any alignment and I/O width restrictions that a PI System on a
> +  platform might require. For example on some platforms, width requests of
> +  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
> +  be handled by the driver.
> +
> +  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
> +  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
> +  each of the Count operations that is performed.
> +
> +  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
> +  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
> +  incremented for each of the Count operations that is performed. The read or
> +  write operation is performed Count times on the same Address.
> +
> +  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
> +  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
> +  incremented for each of the Count operations that is performed. The read or
> +  write operation is performed Count times from the first element of Buffer.
> +
> +  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
> +  @param[in]  Width    Signifies the width of the I/O or Memory operation.
> +  @param[in]  Address  The base address of the I/O operation.
> +  @param[in]  Count    The number of I/O operations to perform. The number of
> +                       bytes moved is Width size * Count, starting at Address.
> +  @param[in]  Buffer   For read operations, the destination buffer to store the results.
> +                       For write operations, the source buffer from which to write data.
> +
> +  @retval EFI_SUCCESS            The data was read from or written to the PI system.
> +  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
> +  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
> +                                 and Count is not valid for this PI system.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +CpuIoServiceWrite (
> +  IN EFI_CPU_IO2_PROTOCOL       *This,
> +  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
> +  IN UINT64                     Address,
> +  IN UINTN                      Count,
> +  IN VOID                       *Buffer
> +  )
> +{
> +  EFI_STATUS                 Status;
> +  UINT8                      InStride;
> +  UINT8                      OutStride;
> +  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
> +  UINT8                      *Uint8Buffer;
> +
> +  //
> +  // Make sure the parameters are valid
> +  //
> +  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Select loop based on the width of the transfer
> +  //
> +  InStride = mInStride[Width];
> +  OutStride = mOutStride[Width];
> +  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
> +
> +  // Assuming address has already been translated into MMIO address by PCI host
> +  // bridge driver, so we call MmioRead/Write directly.
> +  for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
> +    if (OperationWidth == EfiCpuIoWidthUint8) {
> +      MmioWrite8 ((UINTN)Address, *Uint8Buffer);
> +    } else if (OperationWidth == EfiCpuIoWidthUint16) {
> +      MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
> +    } else if (OperationWidth == EfiCpuIoWidthUint32) {
> +      MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +//
> +// CPU I/O 2 Protocol instance
> +//
> +STATIC EFI_CPU_IO2_PROTOCOL mCpuIo2 = {
> +  {
> +    CpuMemoryServiceRead,
> +    CpuMemoryServiceWrite
> +  },
> +  {
> +    CpuIoServiceRead,
> +    CpuIoServiceWrite
> +  }
> +};
> +
> +
> +/**
> +  The user Entry Point for module CpuIo2Dxe. The user code starts with this function.
> +
> +  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
> +  @param[in] SystemTable    A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS       The entry point is executed successfully.
> +  @retval other             Some error occurs when executing this entry point.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +ArmPciCpuIo2Initialize (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid);
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &ImageHandle,
> +                  &gEfiCpuIo2ProtocolGuid, &mCpuIo2,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> --
> 2.7.4
>


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

* Re: [PATCH edk2-platforms 10/12] Hisilicon/D0x: Switch to generic PciHostBridge driver
  2018-03-21  1:03 ` [PATCH edk2-platforms 10/12] Hisilicon/D0x: Switch to generic PciHostBridge driver Heyi Guo
@ 2018-03-30 15:34   ` Ard Biesheuvel
  0 siblings, 0 replies; 33+ messages in thread
From: Ard Biesheuvel @ 2018-03-30 15:34 UTC (permalink / raw)
  To: Heyi Guo
  Cc: edk2-devel@lists.01.org, Leif Lindholm, Michael D Kinney,
	Haojian Zhuang

On 21 March 2018 at 01:03, Heyi Guo <heyi.guo@linaro.org> wrote:
> Address translation support is added to generic PciHostBridge driver
> in edk2 by commit 74d0a33, so we can switch to it for Hisilicon D03
> and D05 which are using address translation between device address and
> host address for resource BAR.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Leif Lindholm <leif.lindholm@linaro.org>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  Silicon/Hisilicon/Hisilicon.dsc.inc | 6 +++++-
>  Platform/Hisilicon/D03/D03.dsc      | 6 ++++--
>  Platform/Hisilicon/D05/D05.dsc      | 6 ++++--
>  Platform/Hisilicon/D03/D03.fdf      | 3 ++-
>  Platform/Hisilicon/D05/D05.fdf      | 3 ++-
>  5 files changed, 17 insertions(+), 7 deletions(-)
>
> diff --git a/Silicon/Hisilicon/Hisilicon.dsc.inc b/Silicon/Hisilicon/Hisilicon.dsc.inc
> index 77585933179e..8ee74a830e74 100644
> --- a/Silicon/Hisilicon/Hisilicon.dsc.inc
> +++ b/Silicon/Hisilicon/Hisilicon.dsc.inc
> @@ -253,7 +253,11 @@ [PcdsFeatureFlag.common]
>
>  [PcdsFixedAtBuild.common]
>    gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|44
> -  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0
> +  #
> +  # IO is mapped to memory space, so we use the same size of
> +  # PcdPrePiCpuMemorySize
> +  #
> +  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|44

As noted in reply to the previous patches, I think we should avoid 1:1
mapping the I/O space like this.

20 bits of I/O space should be plenty, i.e., up to 16 segments using
64 KB of I/O space each.

>    gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
>    gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
>    gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
> diff --git a/Platform/Hisilicon/D03/D03.dsc b/Platform/Hisilicon/D03/D03.dsc
> index 0b2bd29cdf83..26081a33a00a 100644
> --- a/Platform/Hisilicon/D03/D03.dsc
> +++ b/Platform/Hisilicon/D03/D03.dsc
> @@ -82,6 +82,8 @@ [LibraryClasses.common]
>
>    LpcLib|Silicon/Hisilicon/Hi1610/Library/LpcLib/LpcLib.inf
>    SerialPortLib|Silicon/Hisilicon/Hi1610/Library/Uart/LpcSerialPortLib/LpcSerialPortLib.inf
> +  PciHostBridgeLib|Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> +  PciSegmentLib|Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/Hi161xPciSegmentLib.inf
>
>  ## GIC on D02/D03 is not fully ARM GIC compatible: IRQ cannot be cancelled when
>  ## input signal is de-asserted, except for virtual timer interrupt IRQ #27.
> @@ -336,6 +338,7 @@ [Components.common]
>    ArmPkg/Drivers/CpuDxe/CpuDxe.inf
>    MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
>
> +  Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
>    Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.inf
>
>    Platform/Hisilicon/D03/Drivers/SFC/SfcDxeDriver.inf
> @@ -457,9 +460,8 @@ [Components.common]
>      <LibraryClasses>
>        NULL|Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.inf
>    }
> -  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf {
> +  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
>      <LibraryClasses>
> -      DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf
>        NULL|Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.inf
>    }
>
> diff --git a/Platform/Hisilicon/D05/D05.dsc b/Platform/Hisilicon/D05/D05.dsc
> index 2150a6f4c0e9..d6febf471630 100644
> --- a/Platform/Hisilicon/D05/D05.dsc
> +++ b/Platform/Hisilicon/D05/D05.dsc
> @@ -97,6 +97,8 @@ [LibraryClasses.common]
>
>    LpcLib|Silicon/Hisilicon/Hi1610/Library/LpcLib/LpcLib.inf
>    SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
> +  PciHostBridgeLib|Platform/Hisilicon/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> +  PciSegmentLib|Silicon/Hisilicon/Hi1610/Library/Hi161xPciSegmentLib/Hi161xPciSegmentLib.inf
>
>  [LibraryClasses.common.SEC]
>    ArmPlatformLib|Silicon/Hisilicon/Library/ArmPlatformLibHisilicon/ArmPlatformLibSec.inf
> @@ -472,6 +474,7 @@ [Components.common]
>    ArmPkg/Drivers/CpuDxe/CpuDxe.inf
>    MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
>
> +  Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
>    Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.inf
>
>    Platform/Hisilicon/D05/Drivers/SFC/SfcDxeDriver.inf
> @@ -611,9 +614,8 @@ [Components.common]
>      <LibraryClasses>
>        NULL|Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.inf
>    }
> -  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf {
> +  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
>      <LibraryClasses>
> -      DmaLib|EmbeddedPkg/Library/CoherentDmaLib/CoherentDmaLib.inf
>        NULL|Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.inf
>    }
>
> diff --git a/Platform/Hisilicon/D03/D03.fdf b/Platform/Hisilicon/D03/D03.fdf
> index e430d5c08982..0c843a3ce671 100644
> --- a/Platform/Hisilicon/D03/D03.fdf
> +++ b/Platform/Hisilicon/D03/D03.fdf
> @@ -157,6 +157,7 @@ [FV.FvMain]
>    INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
>
>    INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
> +  INF Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
>    INF Platform/Hisilicon/D03/Drivers/SFC/SfcDxeDriver.inf
>
>    INF Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.inf
> @@ -263,7 +264,7 @@ [FV.FvMain]
>    # PCI Support
>    #
>    INF Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
> -  INF Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
> +  INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
>    INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
>
>    INF Platform/Hisilicon/D03/Drivers/ReportPciePlugDidVidToBmc/ReportPciePlugDidVidToBmc.inf
> diff --git a/Platform/Hisilicon/D05/D05.fdf b/Platform/Hisilicon/D05/D05.fdf
> index 13a60837a607..b530e8e785a4 100644
> --- a/Platform/Hisilicon/D05/D05.fdf
> +++ b/Platform/Hisilicon/D05/D05.fdf
> @@ -161,6 +161,7 @@ [FV.FvMain]
>    INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
>
>    INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
> +  INF Silicon/Hisilicon/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
>    INF Platform/Hisilicon/D05/Drivers/SFC/SfcDxeDriver.inf
>
>    INF Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.inf
> @@ -285,7 +286,7 @@ [FV.FvMain]
>    # PCI Support
>    #
>    INF Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
> -  INF Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
> +  INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
>    INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
>
>    INF Platform/Hisilicon/D05/Drivers/ReportPciePlugDidVidToBmc/ReportPciePlugDidVidToBmc.inf
> --
> 2.7.4
>


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

* Re: [PATCH edk2-platforms 11/12] Hisilicon: remove platform specific PciHostBridge
  2018-03-21  1:03 ` [PATCH edk2-platforms 11/12] Hisilicon: remove platform specific PciHostBridge Heyi Guo
@ 2018-03-30 15:37   ` Ard Biesheuvel
  0 siblings, 0 replies; 33+ messages in thread
From: Ard Biesheuvel @ 2018-03-30 15:37 UTC (permalink / raw)
  To: Heyi Guo; +Cc: edk2-devel@lists.01.org, Yi Li, Leif Lindholm, Michael D Kinney

On 21 March 2018 at 01:03, Heyi Guo <heyi.guo@linaro.org> wrote:
> PciHostBridge in Silicon/Hisilicon is specific for D03/D05. After we
> switch to generic PciHostBridge in MdeModulePkg, this driver is
> useless and can be removed.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
> Signed-off-by: Yi Li <phoenix.liyi@huawei.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Leif Lindholm <leif.lindholm@linaro.org>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> ---
>  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf |   74 -
>  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h      |  520 -----
>  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c      | 1658 ---------------
>  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c    | 2220 --------------------
>  4 files changed, 4472 deletions(-)
>

Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

This is the patch I like the most in this series :-)


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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-03-29  0:20     ` Guo Heyi
@ 2018-03-30 15:40       ` Ard Biesheuvel
  2018-03-31  1:37         ` Guo Heyi
  0 siblings, 1 reply; 33+ messages in thread
From: Ard Biesheuvel @ 2018-03-30 15:40 UTC (permalink / raw)
  To: Guo Heyi
  Cc: Leif Lindholm, edk2-devel@lists.01.org, Michael D Kinney,
	Haojian Zhuang

On 29 March 2018 at 02:20, Guo Heyi <heyi.guo@linaro.org> wrote:
> On Wed, Mar 28, 2018 at 10:43:41AM +0100, Ard Biesheuvel wrote:
>> On 28 March 2018 at 02:05, Guo Heyi <heyi.guo@linaro.org> wrote:
>> > Hi Leif, Ard,
>> >
>> > Any comments for this series of patches?
>> >
>>
>> Hello Heyi,
>>
>> Thanks for sending these patches. Leif is at the plugfest, but I will
>> look at these before the end of the week.
>
> Forgot the plugfest as I am not attending :)

Hello Heyi,

I think the series looks mostly fine in general, but there are two
things that I'd like you to change (as noted in my replies):
- please split the PCI to CPU I/O translation from the CPU I/O to CPU
MMIO translation
- please fix the APPETURE spelling (in whichever way is most
convenient for you: separate patch at the beginning, at the end, etc
etc)


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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-03-30 15:40       ` Ard Biesheuvel
@ 2018-03-31  1:37         ` Guo Heyi
  2018-04-13  2:05           ` Guo Heyi
  0 siblings, 1 reply; 33+ messages in thread
From: Guo Heyi @ 2018-03-31  1:37 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Guo Heyi, Leif Lindholm, edk2-devel@lists.01.org,
	Michael D Kinney, Haojian Zhuang

Hi Ard,

Thanks for your time of reviewing the patches.
Please see my opinions below.

On Fri, Mar 30, 2018 at 05:40:20PM +0200, Ard Biesheuvel wrote:
> On 29 March 2018 at 02:20, Guo Heyi <heyi.guo@linaro.org> wrote:
> > On Wed, Mar 28, 2018 at 10:43:41AM +0100, Ard Biesheuvel wrote:
> >> On 28 March 2018 at 02:05, Guo Heyi <heyi.guo@linaro.org> wrote:
> >> > Hi Leif, Ard,
> >> >
> >> > Any comments for this series of patches?
> >> >
> >>
> >> Hello Heyi,
> >>
> >> Thanks for sending these patches. Leif is at the plugfest, but I will
> >> look at these before the end of the week.
> >
> > Forgot the plugfest as I am not attending :)
> 
> Hello Heyi,
> 
> I think the series looks mostly fine in general, but there are two
> things that I'd like you to change (as noted in my replies):
> - please split the PCI to CPU I/O translation from the CPU I/O to CPU
> MMIO translation

I heard that OS did the same as you indicated, but the reasons of why I
translated IO address into memory address in PCI host bridge are like below:

1. If we add an intermediate level of "CPU IO address space", it makes things a
little more complicated but I don't see any real benefit. If we just make a
simple policy that on ARM/AARCH64 CPU IO address is equal to CPU memory address,
we can even use a unified CPU IO driver for all ARM/AARCH64 platforms, while the
translation is covered by PCI host bridge driver.

2. From hardware perspective, the translation is done by PCIe ATU; for IO bar
access, the address from CPU to ATU is a CPU memory address, not an intermediate
CPU IO address; the intermediate CPU IO address is a totally logical concept,
and it also splits ATU function into separate drivers (CPU IO protocol driver
also sees part of ATU function).

Please let me know if my understanding is not right.

> - please fix the APPETURE spelling (in whichever way is most
> convenient for you: separate patch at the beginning, at the end, etc
> etc)

Nice catch :) will fix that.

Thanks,

Heyi


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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-03-31  1:37         ` Guo Heyi
@ 2018-04-13  2:05           ` Guo Heyi
  2018-04-13  7:19             ` Ard Biesheuvel
  0 siblings, 1 reply; 33+ messages in thread
From: Guo Heyi @ 2018-04-13  2:05 UTC (permalink / raw)
  To: Guo Heyi
  Cc: Ard Biesheuvel, Leif Lindholm, edk2-devel@lists.01.org,
	Michael D Kinney, Haojian Zhuang

Hi Ard,

Any comments?

Anyway we can modify the code if you insist on using an intermediate CPU IO
address space.

Thanks,

Heyi

On Sat, Mar 31, 2018 at 09:37:47AM +0800, Guo Heyi wrote:
> Hi Ard,
> 
> Thanks for your time of reviewing the patches.
> Please see my opinions below.
> 
> On Fri, Mar 30, 2018 at 05:40:20PM +0200, Ard Biesheuvel wrote:
> > On 29 March 2018 at 02:20, Guo Heyi <heyi.guo@linaro.org> wrote:
> > > On Wed, Mar 28, 2018 at 10:43:41AM +0100, Ard Biesheuvel wrote:
> > >> On 28 March 2018 at 02:05, Guo Heyi <heyi.guo@linaro.org> wrote:
> > >> > Hi Leif, Ard,
> > >> >
> > >> > Any comments for this series of patches?
> > >> >
> > >>
> > >> Hello Heyi,
> > >>
> > >> Thanks for sending these patches. Leif is at the plugfest, but I will
> > >> look at these before the end of the week.
> > >
> > > Forgot the plugfest as I am not attending :)
> > 
> > Hello Heyi,
> > 
> > I think the series looks mostly fine in general, but there are two
> > things that I'd like you to change (as noted in my replies):
> > - please split the PCI to CPU I/O translation from the CPU I/O to CPU
> > MMIO translation
> 
> I heard that OS did the same as you indicated, but the reasons of why I
> translated IO address into memory address in PCI host bridge are like below:
> 
> 1. If we add an intermediate level of "CPU IO address space", it makes things a
> little more complicated but I don't see any real benefit. If we just make a
> simple policy that on ARM/AARCH64 CPU IO address is equal to CPU memory address,
> we can even use a unified CPU IO driver for all ARM/AARCH64 platforms, while the
> translation is covered by PCI host bridge driver.
> 
> 2. From hardware perspective, the translation is done by PCIe ATU; for IO bar
> access, the address from CPU to ATU is a CPU memory address, not an intermediate
> CPU IO address; the intermediate CPU IO address is a totally logical concept,
> and it also splits ATU function into separate drivers (CPU IO protocol driver
> also sees part of ATU function).
> 
> Please let me know if my understanding is not right.
> 
> > - please fix the APPETURE spelling (in whichever way is most
> > convenient for you: separate patch at the beginning, at the end, etc
> > etc)
> 
> Nice catch :) will fix that.
> 
> Thanks,
> 
> Heyi


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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-04-13  2:05           ` Guo Heyi
@ 2018-04-13  7:19             ` Ard Biesheuvel
  2018-04-16 13:57               ` Guo Heyi
  0 siblings, 1 reply; 33+ messages in thread
From: Ard Biesheuvel @ 2018-04-13  7:19 UTC (permalink / raw)
  To: Guo Heyi
  Cc: Leif Lindholm, edk2-devel@lists.01.org, Michael D Kinney,
	Haojian Zhuang

On 13 April 2018 at 04:05, Guo Heyi <heyi.guo@linaro.org> wrote:
> Hi Ard,
>
> Any comments?
>

Apologies for the delay. I have been travelling and am behind on email.

> Anyway we can modify the code if you insist on using an intermediate CPU IO
> address space.
>

I have not made up my mind yet, to be honest. I agree there is a
certain elegance to merging both translations, but I am concerned that
existing EDK2 code may deal poorly with I/O addresses that require
more than 32 bits to express.

Did you try the mm command in the shell for instance? As you know, I
recently removed an artificial address range limit there, but I wonder
if it uses 64-bit variables for I/O ports.


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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-04-13  7:19             ` Ard Biesheuvel
@ 2018-04-16 13:57               ` Guo Heyi
  2018-04-17  1:20                 ` Guo Heyi
  0 siblings, 1 reply; 33+ messages in thread
From: Guo Heyi @ 2018-04-16 13:57 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Guo Heyi, Leif Lindholm, edk2-devel@lists.01.org,
	Michael D Kinney, Haojian Zhuang

Thanks, I will test mm command and let you know the result.

Regards,

Heyi

On Fri, Apr 13, 2018 at 09:19:53AM +0200, Ard Biesheuvel wrote:
> On 13 April 2018 at 04:05, Guo Heyi <heyi.guo@linaro.org> wrote:
> > Hi Ard,
> >
> > Any comments?
> >
> 
> Apologies for the delay. I have been travelling and am behind on email.
> 
> > Anyway we can modify the code if you insist on using an intermediate CPU IO
> > address space.
> >
> 
> I have not made up my mind yet, to be honest. I agree there is a
> certain elegance to merging both translations, but I am concerned that
> existing EDK2 code may deal poorly with I/O addresses that require
> more than 32 bits to express.
> 
> Did you try the mm command in the shell for instance? As you know, I
> recently removed an artificial address range limit there, but I wonder
> if it uses 64-bit variables for I/O ports.


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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-04-16 13:57               ` Guo Heyi
@ 2018-04-17  1:20                 ` Guo Heyi
  2018-04-17  1:44                   ` Guo Heyi
  2018-06-07 11:11                   ` Ard Biesheuvel
  0 siblings, 2 replies; 33+ messages in thread
From: Guo Heyi @ 2018-04-17  1:20 UTC (permalink / raw)
  To: Guo Heyi
  Cc: Ard Biesheuvel, Leif Lindholm, edk2-devel@lists.01.org,
	Michael D Kinney, Haojian Zhuang

Hi Ard,

I tested mm -io on D05, for root bridge 4 with CPU IO address starting from
0x8_abff0000, and it worked; both mm -io 0x8abff0000 and mm 0x8abff0000 provided
the same output. It seems there is no other limit for 64bit IO address after you
fixed the issue in EFI shell mm command.

Thanks and regards,

Heyi

On Mon, Apr 16, 2018 at 09:57:09PM +0800, Guo Heyi wrote:
> Thanks, I will test mm command and let you know the result.
> 
> Regards,
> 
> Heyi
> 
> On Fri, Apr 13, 2018 at 09:19:53AM +0200, Ard Biesheuvel wrote:
> > On 13 April 2018 at 04:05, Guo Heyi <heyi.guo@linaro.org> wrote:
> > > Hi Ard,
> > >
> > > Any comments?
> > >
> > 
> > Apologies for the delay. I have been travelling and am behind on email.
> > 
> > > Anyway we can modify the code if you insist on using an intermediate CPU IO
> > > address space.
> > >
> > 
> > I have not made up my mind yet, to be honest. I agree there is a
> > certain elegance to merging both translations, but I am concerned that
> > existing EDK2 code may deal poorly with I/O addresses that require
> > more than 32 bits to express.
> > 
> > Did you try the mm command in the shell for instance? As you know, I
> > recently removed an artificial address range limit there, but I wonder
> > if it uses 64-bit variables for I/O ports.


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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-04-17  1:20                 ` Guo Heyi
@ 2018-04-17  1:44                   ` Guo Heyi
  2018-05-31  1:02                     ` heyi.guo
  2018-06-07 11:11                   ` Ard Biesheuvel
  1 sibling, 1 reply; 33+ messages in thread
From: Guo Heyi @ 2018-04-17  1:44 UTC (permalink / raw)
  To: Guo Heyi
  Cc: Ard Biesheuvel, Leif Lindholm, edk2-devel@lists.01.org,
	Michael D Kinney, Haojian Zhuang

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

BTW, there is actually a bug with ATU configuration which will cause IO access
failure, and we need to apply an additional patch (this patch is generated after
PCI host bridge patch series) as attached to fix this.

Regards,
Heyi

On Tue, Apr 17, 2018 at 09:20:44AM +0800, Guo Heyi wrote:
> Hi Ard,
> 
> I tested mm -io on D05, for root bridge 4 with CPU IO address starting from
> 0x8_abff0000, and it worked; both mm -io 0x8abff0000 and mm 0x8abff0000 provided
> the same output. It seems there is no other limit for 64bit IO address after you
> fixed the issue in EFI shell mm command.
> 
> Thanks and regards,
> 
> Heyi
> 
> On Mon, Apr 16, 2018 at 09:57:09PM +0800, Guo Heyi wrote:
> > Thanks, I will test mm command and let you know the result.
> > 
> > Regards,
> > 
> > Heyi
> > 
> > On Fri, Apr 13, 2018 at 09:19:53AM +0200, Ard Biesheuvel wrote:
> > > On 13 April 2018 at 04:05, Guo Heyi <heyi.guo@linaro.org> wrote:
> > > > Hi Ard,
> > > >
> > > > Any comments?
> > > >
> > > 
> > > Apologies for the delay. I have been travelling and am behind on email.
> > > 
> > > > Anyway we can modify the code if you insist on using an intermediate CPU IO
> > > > address space.
> > > >
> > > 
> > > I have not made up my mind yet, to be honest. I agree there is a
> > > certain elegance to merging both translations, but I am concerned that
> > > existing EDK2 code may deal poorly with I/O addresses that require
> > > more than 32 bits to express.
> > > 
> > > Did you try the mm command in the shell for instance? As you know, I
> > > recently removed an artificial address range limit there, but I wonder
> > > if it uses 64-bit variables for I/O ports.

[-- Attachment #2: fix-address-overrlap.patch --]
[-- Type: text/x-diff, Size: 6091 bytes --]

>From guoheyi@huawei.com Tue Apr 17 09:40:07 2018
Delivered-To: heyi.guo@linaro.org
Received: by 10.103.107.2 with SMTP id g2csp1147351vsc;
        Mon, 16 Apr 2018 18:40:07 -0700 (PDT)
X-Google-Smtp-Source: AIpwx49xa2EjXi3IIuqoYaJ9ZR+KlZePkYWmAvMpJl534IXT0zWt/Jd5UHxMjyCgas2Aluws+S26
X-Received: by 10.101.97.165 with SMTP id i5mr102113pgv.449.1523929207660;
        Mon, 16 Apr 2018 18:40:07 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1523929207; cv=none;
        d=google.com; s=arc-20160816;
        b=JVhwQqc2tHJH/nbb9J4Q5EAe7efNCva8XlNdyeM1AjecnvMtalXxRiIcVSIp2CTTUb
         RCfB400z6ay0s7SW96MDtN0D8jezfXLZXyuMQTqYAvpXu7rxEmXGJtKblXaJ303GTvgS
         kavhZQ7QawTzXzWTjokcARGeyR+mFb9aXT8JKm3jdHVM+Ibsjl0HFYSFrMNFoeyC7EqG
         EPMbjEvcWolADxpywSCM0s0e4EhIVpGrhi1LgdVeATsyrb6GN8sEscVfb+t0b0gMj6XI
         Nqg7mMHnKZGJ4vmkJBRV5Gx+nnQbOWKsOCp8YZcVLFs8hyqWFokYsup3wsY1YtktovxU
         GQUg==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=mime-version:message-id:date:subject:cc:to:from
         :arc-authentication-results;
        bh=MzafS17Rdgthy05RGe4B87hGASmPkGgjBWmjX1ExxLo=;
        b=fj+XbZcdH1vGFsHllnQeTc3zRavri5L0Use7rHdCRemtfNojWbY1QJKD6tMVi213fj
         J9IaKL5/Q3Uh0KLfAR848Whbuj4IiFMw1vRsT8BUvu0QjkCsdJo66ypGdQTqkysdtk2X
         fdNfNTE+Dfa1du8Yx9RiFCetXrtgCjDXljVzd/JufSlKtC41HjgWjnqC2Jka4N0MOT1W
         oiBtsqOCjRuVRyb5Rlf7RVstwZ7wz6jXbxj7GYkr85bUFe7LNG8HOKxJYIv1bLyOWw6q
         KvttRU9MKaVex3HApPoMIIgg+sXj3QD1islzlobdLA/OaRKWXCH0fnXH/NuWnKZ7J1jO
         Hl7A==
ARC-Authentication-Results: i=1; mx.google.com;
       spf=pass (google.com: domain of guoheyi@huawei.com designates 45.249.212.32 as permitted sender) smtp.mailfrom=guoheyi@huawei.com
Return-Path: <guoheyi@huawei.com>
Received: from huawei.com ([45.249.212.32])
        by mx.google.com with ESMTPS id t3si10564595pgt.547.2018.04.16.18.40.07
        for <heyi.guo@linaro.org>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Mon, 16 Apr 2018 18:40:07 -0700 (PDT)
Received-SPF: pass (google.com: domain of guoheyi@huawei.com designates 45.249.212.32 as permitted sender) client-ip=45.249.212.32;
Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of guoheyi@huawei.com designates 45.249.212.32 as permitted sender) smtp.mailfrom=guoheyi@huawei.com
Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.58])
	by Forcepoint Email with ESMTP id 2B03711A12683
	for <heyi.guo@linaro.org>; Tue, 17 Apr 2018 09:40:04 +0800 (CST)
Received: from HGH1000039998.huawei.com (10.184.68.188) by
 DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id
 14.3.361.1; Tue, 17 Apr 2018 09:39:59 +0800
From: Heyi Guo <guoheyi@huawei.com>
To: <heyi.guo@linaro.org>
CC: <phoenix.liyi@huawei.com>, <mengfanrong@huawei.com>,
	<zhangjinsong2@huawei.com>
Subject: [PATCH] Hisilicon/Hi161x/PcieInit: fix address overlap
Date: Tue, 17 Apr 2018 09:35:22 +0800
Message-ID: <1523928922-9573-1-git-send-email-guoheyi@huawei.com>
X-Mailer: git-send-email 2.8.1
MIME-Version: 1.0
Content-Type: text/plain
X-Originating-IP: [10.184.68.188]
X-CFilter-Loop: Reflected
Content-Length: 2888
Lines: 55

From: Heyi Guo <heyi.guo@linaro.org>

PCIe IO address ranges are overlapped by configuration address spaces
when we set CFG0/CFG1 address range starting from ECAM. It causes
access to IO space is routed to configuration space and returned with
wrong results.

So we limit address space for configuration type 0
starting from BusBase and type 1 from (BusBase + 2), to eliminate the
address range overlapping.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
---
 Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
index f2365b5..9a92fea 100644
--- a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
+++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
@@ -96,11 +96,12 @@ SetAtuConfig0RW (
 {
   UINTN RbPciBase = Private->RbPciBar;
   UINT64 MemLimit = GetPcieCfgAddress (Private->Ecam, Private->BusBase + 1, 1, 0, 0) - 1;
+  UINT64 MemBase = GetPcieCfgAddress (Private->Ecam, Private->BusBase, 0, 0, 0);
 
 
   MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
-  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(Private->Ecam));
-  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(Private->Ecam) >> 32));
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)MemBase);
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)(MemBase >> 32));
   MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
   MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, 0);
   MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, 0);
@@ -124,12 +125,13 @@ SetAtuConfig1RW (
 {
   UINTN RbPciBase = Private->RbPciBar;
   UINT64 MemLimit = GetPcieCfgAddress (Private->Ecam, Private->BusLimit + 1, 0, 0, 0) - 1;
+  UINT64 MemBase = GetPcieCfgAddress (Private->Ecam, Private->BusBase + 2, 0, 0, 0);
 
 
   MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
   MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_CONFIG1);
-  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(Private->Ecam));
-  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(Private->Ecam) >> 32));
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)MemBase);
+  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)(MemBase >> 32));
   MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
   MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, 0);
   MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, 0);
-- 
2.8.1



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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-04-17  1:44                   ` Guo Heyi
@ 2018-05-31  1:02                     ` heyi.guo
  0 siblings, 0 replies; 33+ messages in thread
From: heyi.guo @ 2018-05-31  1:02 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Ard Biesheuvel, Leif Lindholm, edk2-devel@lists.01.org,
	Michael D Kinney, Haojian Zhuang

Hi Ard,

Have you returned from vocation? If so, could you help to continue reviewing
this patch series?

Thanks,

Heyi

On Tue, Apr 17, 2018 at 09:44:46AM +0800, Guo Heyi wrote:
> BTW, there is actually a bug with ATU configuration which will cause IO access
> failure, and we need to apply an additional patch (this patch is generated after
> PCI host bridge patch series) as attached to fix this.
> 
> Regards,
> Heyi
> 
> On Tue, Apr 17, 2018 at 09:20:44AM +0800, Guo Heyi wrote:
> > Hi Ard,
> > 
> > I tested mm -io on D05, for root bridge 4 with CPU IO address starting from
> > 0x8_abff0000, and it worked; both mm -io 0x8abff0000 and mm 0x8abff0000 provided
> > the same output. It seems there is no other limit for 64bit IO address after you
> > fixed the issue in EFI shell mm command.
> > 
> > Thanks and regards,
> > 
> > Heyi
> > 
> > On Mon, Apr 16, 2018 at 09:57:09PM +0800, Guo Heyi wrote:
> > > Thanks, I will test mm command and let you know the result.
> > > 
> > > Regards,
> > > 
> > > Heyi
> > > 
> > > On Fri, Apr 13, 2018 at 09:19:53AM +0200, Ard Biesheuvel wrote:
> > > > On 13 April 2018 at 04:05, Guo Heyi <heyi.guo@linaro.org> wrote:
> > > > > Hi Ard,
> > > > >
> > > > > Any comments?
> > > > >
> > > > 
> > > > Apologies for the delay. I have been travelling and am behind on email.
> > > > 
> > > > > Anyway we can modify the code if you insist on using an intermediate CPU IO
> > > > > address space.
> > > > >
> > > > 
> > > > I have not made up my mind yet, to be honest. I agree there is a
> > > > certain elegance to merging both translations, but I am concerned that
> > > > existing EDK2 code may deal poorly with I/O addresses that require
> > > > more than 32 bits to express.
> > > > 
> > > > Did you try the mm command in the shell for instance? As you know, I
> > > > recently removed an artificial address range limit there, but I wonder
> > > > if it uses 64-bit variables for I/O ports.

> From guoheyi@huawei.com Tue Apr 17 09:40:07 2018
> Delivered-To: heyi.guo@linaro.org
> Received: by 10.103.107.2 with SMTP id g2csp1147351vsc;
>         Mon, 16 Apr 2018 18:40:07 -0700 (PDT)
> X-Google-Smtp-Source: AIpwx49xa2EjXi3IIuqoYaJ9ZR+KlZePkYWmAvMpJl534IXT0zWt/Jd5UHxMjyCgas2Aluws+S26
> X-Received: by 10.101.97.165 with SMTP id i5mr102113pgv.449.1523929207660;
>         Mon, 16 Apr 2018 18:40:07 -0700 (PDT)
> ARC-Seal: i=1; a=rsa-sha256; t=1523929207; cv=none;
>         d=google.com; s=arc-20160816;
>         b=JVhwQqc2tHJH/nbb9J4Q5EAe7efNCva8XlNdyeM1AjecnvMtalXxRiIcVSIp2CTTUb
>          RCfB400z6ay0s7SW96MDtN0D8jezfXLZXyuMQTqYAvpXu7rxEmXGJtKblXaJ303GTvgS
>          kavhZQ7QawTzXzWTjokcARGeyR+mFb9aXT8JKm3jdHVM+Ibsjl0HFYSFrMNFoeyC7EqG
>          EPMbjEvcWolADxpywSCM0s0e4EhIVpGrhi1LgdVeATsyrb6GN8sEscVfb+t0b0gMj6XI
>          Nqg7mMHnKZGJ4vmkJBRV5Gx+nnQbOWKsOCp8YZcVLFs8hyqWFokYsup3wsY1YtktovxU
>          GQUg==
> ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
>         h=mime-version:message-id:date:subject:cc:to:from
>          :arc-authentication-results;
>         bh=MzafS17Rdgthy05RGe4B87hGASmPkGgjBWmjX1ExxLo=;
>         b=fj+XbZcdH1vGFsHllnQeTc3zRavri5L0Use7rHdCRemtfNojWbY1QJKD6tMVi213fj
>          J9IaKL5/Q3Uh0KLfAR848Whbuj4IiFMw1vRsT8BUvu0QjkCsdJo66ypGdQTqkysdtk2X
>          fdNfNTE+Dfa1du8Yx9RiFCetXrtgCjDXljVzd/JufSlKtC41HjgWjnqC2Jka4N0MOT1W
>          oiBtsqOCjRuVRyb5Rlf7RVstwZ7wz6jXbxj7GYkr85bUFe7LNG8HOKxJYIv1bLyOWw6q
>          KvttRU9MKaVex3HApPoMIIgg+sXj3QD1islzlobdLA/OaRKWXCH0fnXH/NuWnKZ7J1jO
>          Hl7A==
> ARC-Authentication-Results: i=1; mx.google.com;
>        spf=pass (google.com: domain of guoheyi@huawei.com designates 45.249.212.32 as permitted sender) smtp.mailfrom=guoheyi@huawei.com
> Return-Path: <guoheyi@huawei.com>
> Received: from huawei.com ([45.249.212.32])
>         by mx.google.com with ESMTPS id t3si10564595pgt.547.2018.04.16.18.40.07
>         for <heyi.guo@linaro.org>
>         (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
>         Mon, 16 Apr 2018 18:40:07 -0700 (PDT)
> Received-SPF: pass (google.com: domain of guoheyi@huawei.com designates 45.249.212.32 as permitted sender) client-ip=45.249.212.32;
> Authentication-Results: mx.google.com;
>        spf=pass (google.com: domain of guoheyi@huawei.com designates 45.249.212.32 as permitted sender) smtp.mailfrom=guoheyi@huawei.com
> Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.58])
> 	by Forcepoint Email with ESMTP id 2B03711A12683
> 	for <heyi.guo@linaro.org>; Tue, 17 Apr 2018 09:40:04 +0800 (CST)
> Received: from HGH1000039998.huawei.com (10.184.68.188) by
>  DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id
>  14.3.361.1; Tue, 17 Apr 2018 09:39:59 +0800
> From: Heyi Guo <guoheyi@huawei.com>
> To: <heyi.guo@linaro.org>
> CC: <phoenix.liyi@huawei.com>, <mengfanrong@huawei.com>,
> 	<zhangjinsong2@huawei.com>
> Subject: [PATCH] Hisilicon/Hi161x/PcieInit: fix address overlap
> Date: Tue, 17 Apr 2018 09:35:22 +0800
> Message-ID: <1523928922-9573-1-git-send-email-guoheyi@huawei.com>
> X-Mailer: git-send-email 2.8.1
> MIME-Version: 1.0
> Content-Type: text/plain
> X-Originating-IP: [10.184.68.188]
> X-CFilter-Loop: Reflected
> Content-Length: 2888
> Lines: 55
> 
> From: Heyi Guo <heyi.guo@linaro.org>
> 
> PCIe IO address ranges are overlapped by configuration address spaces
> when we set CFG0/CFG1 address range starting from ECAM. It causes
> access to IO space is routed to configuration space and returned with
> wrong results.
> 
> So we limit address space for configuration type 0
> starting from BusBase and type 1 from (BusBase + 2), to eliminate the
> address range overlapping.
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
> ---
>  Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
> index f2365b5..9a92fea 100644
> --- a/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
> +++ b/Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitAtu.c
> @@ -96,11 +96,12 @@ SetAtuConfig0RW (
>  {
>    UINTN RbPciBase = Private->RbPciBar;
>    UINT64 MemLimit = GetPcieCfgAddress (Private->Ecam, Private->BusBase + 1, 1, 0, 0) - 1;
> +  UINT64 MemBase = GetPcieCfgAddress (Private->Ecam, Private->BusBase, 0, 0, 0);
>  
>  
>    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
> -  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(Private->Ecam));
> -  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(Private->Ecam) >> 32));
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)MemBase);
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)(MemBase >> 32));
>    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
>    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, 0);
>    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, 0);
> @@ -124,12 +125,13 @@ SetAtuConfig1RW (
>  {
>    UINTN RbPciBase = Private->RbPciBar;
>    UINT64 MemLimit = GetPcieCfgAddress (Private->Ecam, Private->BusLimit + 1, 0, 0, 0) - 1;
> +  UINT64 MemBase = GetPcieCfgAddress (Private->Ecam, Private->BusBase + 2, 0, 0, 0);
>  
>  
>    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
>    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_CONFIG1);
> -  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(Private->Ecam));
> -  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(Private->Ecam) >> 32));
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)MemBase);
> +  MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)(MemBase >> 32));
>    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
>    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, 0);
>    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, 0);
> -- 
> 2.8.1
> 
> 



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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-04-17  1:20                 ` Guo Heyi
  2018-04-17  1:44                   ` Guo Heyi
@ 2018-06-07 11:11                   ` Ard Biesheuvel
  2018-06-22 12:58                     ` gary guo
  1 sibling, 1 reply; 33+ messages in thread
From: Ard Biesheuvel @ 2018-06-07 11:11 UTC (permalink / raw)
  To: Guo Heyi
  Cc: Leif Lindholm, edk2-devel@lists.01.org, Michael D Kinney,
	Haojian Zhuang

On 17 April 2018 at 03:20, Guo Heyi <heyi.guo@linaro.org> wrote:
> Hi Ard,
>
> I tested mm -io on D05, for root bridge 4 with CPU IO address starting from
> 0x8_abff0000, and it worked; both mm -io 0x8abff0000 and mm 0x8abff0000 provided
> the same output. It seems there is no other limit for 64bit IO address after you
> fixed the issue in EFI shell mm command.
>

OK, so I think this is fine after all, even if my uneasy feeling
hasn't gone away :-)

Could you please resend the latest rebased version of the patches?
(and include the ATU fix as well)


> On Mon, Apr 16, 2018 at 09:57:09PM +0800, Guo Heyi wrote:
>> Thanks, I will test mm command and let you know the result.
>>
>> Regards,
>>
>> Heyi
>>
>> On Fri, Apr 13, 2018 at 09:19:53AM +0200, Ard Biesheuvel wrote:
>> > On 13 April 2018 at 04:05, Guo Heyi <heyi.guo@linaro.org> wrote:
>> > > Hi Ard,
>> > >
>> > > Any comments?
>> > >
>> >
>> > Apologies for the delay. I have been travelling and am behind on email.
>> >
>> > > Anyway we can modify the code if you insist on using an intermediate CPU IO
>> > > address space.
>> > >
>> >
>> > I have not made up my mind yet, to be honest. I agree there is a
>> > certain elegance to merging both translations, but I am concerned that
>> > existing EDK2 code may deal poorly with I/O addresses that require
>> > more than 32 bits to express.
>> >
>> > Did you try the mm command in the shell for instance? As you know, I
>> > recently removed an artificial address range limit there, but I wonder
>> > if it uses 64-bit variables for I/O ports.


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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-06-07 11:11                   ` Ard Biesheuvel
@ 2018-06-22 12:58                     ` gary guo
  2018-06-22 14:08                       ` Ard Biesheuvel
  0 siblings, 1 reply; 33+ messages in thread
From: gary guo @ 2018-06-22 12:58 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Guo Heyi, Leif Lindholm, edk2-devel@lists.01.org,
	Michael D Kinney, Haojian Zhuang

Sure. A little busy these days; I'll do that ASAP.

Thanks,

Heyi

On Thu, Jun 07, 2018 at 01:11:59PM +0200, Ard Biesheuvel wrote:
> On 17 April 2018 at 03:20, Guo Heyi <heyi.guo@linaro.org> wrote:
> > Hi Ard,
> >
> > I tested mm -io on D05, for root bridge 4 with CPU IO address starting from
> > 0x8_abff0000, and it worked; both mm -io 0x8abff0000 and mm 0x8abff0000 provided
> > the same output. It seems there is no other limit for 64bit IO address after you
> > fixed the issue in EFI shell mm command.
> >
> 
> OK, so I think this is fine after all, even if my uneasy feeling
> hasn't gone away :-)
> 
> Could you please resend the latest rebased version of the patches?
> (and include the ATU fix as well)
> 
> 
> > On Mon, Apr 16, 2018 at 09:57:09PM +0800, Guo Heyi wrote:
> >> Thanks, I will test mm command and let you know the result.
> >>
> >> Regards,
> >>
> >> Heyi
> >>
> >> On Fri, Apr 13, 2018 at 09:19:53AM +0200, Ard Biesheuvel wrote:
> >> > On 13 April 2018 at 04:05, Guo Heyi <heyi.guo@linaro.org> wrote:
> >> > > Hi Ard,
> >> > >
> >> > > Any comments?
> >> > >
> >> >
> >> > Apologies for the delay. I have been travelling and am behind on email.
> >> >
> >> > > Anyway we can modify the code if you insist on using an intermediate CPU IO
> >> > > address space.
> >> > >
> >> >
> >> > I have not made up my mind yet, to be honest. I agree there is a
> >> > certain elegance to merging both translations, but I am concerned that
> >> > existing EDK2 code may deal poorly with I/O addresses that require
> >> > more than 32 bits to express.
> >> >
> >> > Did you try the mm command in the shell for instance? As you know, I
> >> > recently removed an artificial address range limit there, but I wonder
> >> > if it uses 64-bit variables for I/O ports.


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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-06-22 12:58                     ` gary guo
@ 2018-06-22 14:08                       ` Ard Biesheuvel
  2018-06-24 11:22                         ` Ard Biesheuvel
  0 siblings, 1 reply; 33+ messages in thread
From: Ard Biesheuvel @ 2018-06-22 14:08 UTC (permalink / raw)
  To: gary guo
  Cc: Leif Lindholm, edk2-devel@lists.01.org, Michael D Kinney,
	Haojian Zhuang

On 22 June 2018 at 14:58, gary guo <heyi.guo@linaro.org> wrote:
> Sure. A little busy these days; I'll do that ASAP.
>

No worries.

BTW I noticed that we still have a problem with option ROMs when using
the new MMIO translation code. Did you look into that at all?


> On Thu, Jun 07, 2018 at 01:11:59PM +0200, Ard Biesheuvel wrote:
>> On 17 April 2018 at 03:20, Guo Heyi <heyi.guo@linaro.org> wrote:
>> > Hi Ard,
>> >
>> > I tested mm -io on D05, for root bridge 4 with CPU IO address starting from
>> > 0x8_abff0000, and it worked; both mm -io 0x8abff0000 and mm 0x8abff0000 provided
>> > the same output. It seems there is no other limit for 64bit IO address after you
>> > fixed the issue in EFI shell mm command.
>> >
>>
>> OK, so I think this is fine after all, even if my uneasy feeling
>> hasn't gone away :-)
>>
>> Could you please resend the latest rebased version of the patches?
>> (and include the ATU fix as well)
>>
>>
>> > On Mon, Apr 16, 2018 at 09:57:09PM +0800, Guo Heyi wrote:
>> >> Thanks, I will test mm command and let you know the result.
>> >>
>> >> Regards,
>> >>
>> >> Heyi
>> >>
>> >> On Fri, Apr 13, 2018 at 09:19:53AM +0200, Ard Biesheuvel wrote:
>> >> > On 13 April 2018 at 04:05, Guo Heyi <heyi.guo@linaro.org> wrote:
>> >> > > Hi Ard,
>> >> > >
>> >> > > Any comments?
>> >> > >
>> >> >
>> >> > Apologies for the delay. I have been travelling and am behind on email.
>> >> >
>> >> > > Anyway we can modify the code if you insist on using an intermediate CPU IO
>> >> > > address space.
>> >> > >
>> >> >
>> >> > I have not made up my mind yet, to be honest. I agree there is a
>> >> > certain elegance to merging both translations, but I am concerned that
>> >> > existing EDK2 code may deal poorly with I/O addresses that require
>> >> > more than 32 bits to express.
>> >> >
>> >> > Did you try the mm command in the shell for instance? As you know, I
>> >> > recently removed an artificial address range limit there, but I wonder
>> >> > if it uses 64-bit variables for I/O ports.


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

* Re: [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge
  2018-06-22 14:08                       ` Ard Biesheuvel
@ 2018-06-24 11:22                         ` Ard Biesheuvel
  0 siblings, 0 replies; 33+ messages in thread
From: Ard Biesheuvel @ 2018-06-24 11:22 UTC (permalink / raw)
  To: gary guo
  Cc: Leif Lindholm, edk2-devel@lists.01.org, Michael D Kinney,
	Haojian Zhuang

On 22 June 2018 at 16:08, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> On 22 June 2018 at 14:58, gary guo <heyi.guo@linaro.org> wrote:
>> Sure. A little busy these days; I'll do that ASAP.
>>
>
> No worries.
>
> BTW I noticed that we still have a problem with option ROMs when using
> the new MMIO translation code. Did you look into that at all?
>

The option ROM code is fine as long as the PCI address of the MMIO32
region is > 0x0.
Not sure what is going on here, but probably not worth the effort of
digging into.

>
>> On Thu, Jun 07, 2018 at 01:11:59PM +0200, Ard Biesheuvel wrote:
>>> On 17 April 2018 at 03:20, Guo Heyi <heyi.guo@linaro.org> wrote:
>>> > Hi Ard,
>>> >
>>> > I tested mm -io on D05, for root bridge 4 with CPU IO address starting from
>>> > 0x8_abff0000, and it worked; both mm -io 0x8abff0000 and mm 0x8abff0000 provided
>>> > the same output. It seems there is no other limit for 64bit IO address after you
>>> > fixed the issue in EFI shell mm command.
>>> >
>>>
>>> OK, so I think this is fine after all, even if my uneasy feeling
>>> hasn't gone away :-)
>>>
>>> Could you please resend the latest rebased version of the patches?
>>> (and include the ATU fix as well)
>>>
>>>
>>> > On Mon, Apr 16, 2018 at 09:57:09PM +0800, Guo Heyi wrote:
>>> >> Thanks, I will test mm command and let you know the result.
>>> >>
>>> >> Regards,
>>> >>
>>> >> Heyi
>>> >>
>>> >> On Fri, Apr 13, 2018 at 09:19:53AM +0200, Ard Biesheuvel wrote:
>>> >> > On 13 April 2018 at 04:05, Guo Heyi <heyi.guo@linaro.org> wrote:
>>> >> > > Hi Ard,
>>> >> > >
>>> >> > > Any comments?
>>> >> > >
>>> >> >
>>> >> > Apologies for the delay. I have been travelling and am behind on email.
>>> >> >
>>> >> > > Anyway we can modify the code if you insist on using an intermediate CPU IO
>>> >> > > address space.
>>> >> > >
>>> >> >
>>> >> > I have not made up my mind yet, to be honest. I agree there is a
>>> >> > certain elegance to merging both translations, but I am concerned that
>>> >> > existing EDK2 code may deal poorly with I/O addresses that require
>>> >> > more than 32 bits to express.
>>> >> >
>>> >> > Did you try the mm command in the shell for instance? As you know, I
>>> >> > recently removed an artificial address range limit there, but I wonder
>>> >> > if it uses 64-bit variables for I/O ports.


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

end of thread, other threads:[~2018-06-24 11:22 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-03-21  1:03 [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Heyi Guo
2018-03-21  1:03 ` [PATCH edk2-platforms 01/12] Hisilicon: Enable WARN and INFO debug message Heyi Guo
2018-03-21  1:03 ` [PATCH edk2-platforms 02/12] Hisilicon/D05/PlatformPciLib: fix misuse of macro Heyi Guo
2018-03-21  1:03 ` [PATCH edk2-platforms 03/12] Hisilicon/Pci: move ATU configuration to PcieInitDxe Heyi Guo
2018-03-30 15:19   ` Ard Biesheuvel
2018-03-21  1:03 ` [PATCH edk2-platforms 04/12] Hisilicon/Pci: Merge PciPlatform into PcieInit Driver Heyi Guo
2018-03-21  1:03 ` [PATCH edk2-platforms 05/12] Hisilicon/Pci: Move EnlargeAtuConfig0() to PcieInitDxe Heyi Guo
2018-03-21  1:03 ` [PATCH edk2-platforms 06/12] Hisilicon/PlatformPciLib: add segment for each root bridge Heyi Guo
2018-03-21  1:03 ` [PATCH edk2-platforms 07/12] Hisilicon: add PciHostBridgeLib Heyi Guo
2018-03-30 15:28   ` Ard Biesheuvel
2018-03-21  1:03 ` [PATCH edk2-platforms 08/12] Hisilicon: add PciCpuIo2Dxe Heyi Guo
2018-03-30 15:30   ` Ard Biesheuvel
2018-03-21  1:03 ` [PATCH edk2-platforms 09/12] Hisilicon: add PciSegmentLib for Hi161x Heyi Guo
2018-03-21  1:03 ` [PATCH edk2-platforms 10/12] Hisilicon/D0x: Switch to generic PciHostBridge driver Heyi Guo
2018-03-30 15:34   ` Ard Biesheuvel
2018-03-21  1:03 ` [PATCH edk2-platforms 11/12] Hisilicon: remove platform specific PciHostBridge Heyi Guo
2018-03-30 15:37   ` Ard Biesheuvel
2018-03-21  1:03 ` [PATCH edk2-platforms 12/12] Hisilicon/PlatformPciLib: clear redundant felds in RESOURCE_APPETURE Heyi Guo
2018-03-28  1:05 ` [PATCH edk2-platforms 00/12] Hisilicon/D0x: Switch to generic PciHostBridge Guo Heyi
2018-03-28  9:43   ` Ard Biesheuvel
2018-03-29  0:20     ` Guo Heyi
2018-03-30 15:40       ` Ard Biesheuvel
2018-03-31  1:37         ` Guo Heyi
2018-04-13  2:05           ` Guo Heyi
2018-04-13  7:19             ` Ard Biesheuvel
2018-04-16 13:57               ` Guo Heyi
2018-04-17  1:20                 ` Guo Heyi
2018-04-17  1:44                   ` Guo Heyi
2018-05-31  1:02                     ` heyi.guo
2018-06-07 11:11                   ` Ard Biesheuvel
2018-06-22 12:58                     ` gary guo
2018-06-22 14:08                       ` Ard Biesheuvel
2018-06-24 11:22                         ` Ard Biesheuvel

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