[edk2,edk2-platforms,v2,2/7] Silicon/SynQuacer: tweak PCI I/O windows for ACPI/Linux support

Message ID 20180228192421.17684-3-ard.biesheuvel@linaro.org
State New
Headers show
Series
  • SynQuacer ACPI support
Related show

Commit Message

Ard Biesheuvel Feb. 28, 2018, 7:24 p.m.
The ACPI/Linux code does not cope very well with I/O BAR windows that
involve type translation and address translation. In particular, the
secondary I/O window we implement on SynQuacer:

   I/O  0x10000 ... 0x1ffff -> 0x77f00000

is misinterpreted by Linux, and results in the MMIO range starting at
0x77f10000 to be mapped for I/O port access to this range.

This can be mitigated by using the same bus range for I/O port access
on both RCs., i.e., [0x0 ... 0xffff]. This configuration can be represented
using both DT and ACPI, and will work as expected in Linux.

However, there is a downside: UEFI does not cope with I/O address
translation in the generic PCI host bridge driver, and so it does
not allow two regions [0x0 ... 0xffff] to be configured.

Since we have plenty of I/O space, and given that nobody cares about
port I/O anymore in the first place, let's shrink the UEFI view of
the I/O windows until they no longer overlap. In our case, with two
such windows, this means we divide the size by 2, and we end up with
a window [0x0 ... 0x7fff] and one at [0x8000 ... 0xffff].

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

---
 Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi                                                |  2 +-
 Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h                                                  | 18 +++++++++++-------
 Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c |  4 ++--
 3 files changed, 14 insertions(+), 10 deletions(-)

-- 
2.11.0

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Patch

diff --git a/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi b/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi
index 05d1673a5c2b..6eb5fd9430cb 100644
--- a/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi
+++ b/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi
@@ -483,7 +483,7 @@ 
         bus-range = <0x0 0x7e>;
         #address-cells = <3>;
         #size-cells = <2>;
-        ranges = <0x1000000 0x00 0x00010000 0x00 0x77f00000 0x0 0x00010000>,
+        ranges = <0x1000000 0x00 0x00000000 0x00 0x77f00000 0x0 0x00010000>,
                  <0x2000000 0x00 0x78000000 0x00 0x78000000 0x0 0x08000000>,
                  <0x3000000 0x3f 0x00000000 0x3f 0x00000000 0x1 0x00000000>;
 
diff --git a/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h b/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h
index 2d3d5cd91be0..fea01c29088c 100644
--- a/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h
+++ b/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h
@@ -23,12 +23,12 @@ 
 
 #define SYNQUACER_PCI_SEG0_BUSNUM_MIN       0x0
 #define SYNQUACER_PCI_SEG0_BUSNUM_MAX       0x7e
+#define SYNQUACER_PCI_SEG0_BUSNUM_RANGE     0x7f
 
 #define SYNQUACER_PCI_SEG0_PORTIO_MIN       0x0
-#define SYNQUACER_PCI_SEG0_PORTIO_MAX       0xffff
-#define SYNQUACER_PCI_SEG0_PORTIO_SIZE      0x10000
+#define SYNQUACER_PCI_SEG0_PORTIO_MAX       0x7fff
 #define SYNQUACER_PCI_SEG0_PORTIO_MEMBASE   0x67f00000
-#define SYNQUACER_PCI_SEG0_PORTIO_MEMSIZE   SYNQUACER_PCI_SEG0_PORTIO_SIZE
+#define SYNQUACER_PCI_SEG0_PORTIO_MEMSIZE   0x10000
 
 #define SYNQUACER_PCI_SEG0_MMIO32_MIN       0x68000000
 #define SYNQUACER_PCI_SEG0_MMIO32_MAX       0x6fffffff
@@ -45,12 +45,12 @@ 
 
 #define SYNQUACER_PCI_SEG1_BUSNUM_MIN       0x0
 #define SYNQUACER_PCI_SEG1_BUSNUM_MAX       0x7e
+#define SYNQUACER_PCI_SEG1_BUSNUM_RANGE     0x7f
 
-#define SYNQUACER_PCI_SEG1_PORTIO_MIN       0x10000
-#define SYNQUACER_PCI_SEG1_PORTIO_MAX       0x1ffff
-#define SYNQUACER_PCI_SEG1_PORTIO_SIZE      0x10000
+#define SYNQUACER_PCI_SEG1_PORTIO_MIN       0x8000
+#define SYNQUACER_PCI_SEG1_PORTIO_MAX       0xffff
 #define SYNQUACER_PCI_SEG1_PORTIO_MEMBASE   0x77f00000
-#define SYNQUACER_PCI_SEG1_PORTIO_MEMSIZE   SYNQUACER_PCI_SEG1_PORTIO_SIZE
+#define SYNQUACER_PCI_SEG1_PORTIO_MEMSIZE   0x10000
 
 #define SYNQUACER_PCI_SEG1_MMIO32_MIN       0x78000000
 #define SYNQUACER_PCI_SEG1_MMIO32_MAX       0x7fffffff
@@ -65,4 +65,8 @@ 
 #define SYNQUACER_PCI_SLOT1_LOCATION        SYNQUACER_PCI_LOCATION(0, 1, 3)
 #define SYNQUACER_PCI_SLOT2_LOCATION        SYNQUACER_PCI_LOCATION(0, 1, 7)
 
+#define SYNQUACER_PCI_OS_IO_BASE            SYNQUACER_PCI_SEG0_PORTIO_MIN
+#define SYNQUACER_PCI_OS_IO_LIMIT           SYNQUACER_PCI_SEG1_PORTIO_MAX
+#define SYNQUACER_PCI_OS_IO_RANGE           SYNQUACER_PCI_SEG1_PORTIO_MEMSIZE
+
 #endif
diff --git a/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c b/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c
index e4679543cc66..6a3b32f6ca55 100644
--- a/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c
+++ b/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c
@@ -348,8 +348,8 @@  PciInitControllerPost (
   // Region 3: port I/O range
   ConfigureWindow (DbiBase, 3,
     IoMemBase,
-    RootBridge->Io.Base,
-    RootBridge->Io.Limit - RootBridge->Io.Base + 1,
+    SYNQUACER_PCI_OS_IO_BASE,
+    SYNQUACER_PCI_OS_IO_RANGE,
     IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_IO,
     0);