summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2018-01-30 11:24:17 +0000
committerArd Biesheuvel <ard.biesheuvel@linaro.org>2018-03-15 16:04:30 +0000
commit9dd8190e49956e02dbeeda7c5d8e08e854283f9e (patch)
tree8f01101506ff5c64a3483af591e661f223814018
parentf5951dd21469610de4f2308596404a8689f38e08 (diff)
downloadedk2-platforms-9dd8190e49956e02dbeeda7c5d8e08e854283f9e.tar.xz
Silicon/SynQuacer: tweak PCI I/O windows for ACPI/Linux support
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. Now that the generic PCI host bridge driver has gained support for address translation, we can actually support this configuration seamlessly in UEFI as well, by applying an offset to the second I/O window to make it appear adjacent to the first one in the CPU view of the I/O space. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
-rw-r--r--Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi2
-rw-r--r--Silicon/Socionext/SynQuacer/Drivers/SynQuacerPciCpuIo2Dxe/SynQuacerPciCpuIo2Dxe.c21
-rw-r--r--Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h14
-rw-r--r--Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.c6
4 files changed, 27 insertions, 16 deletions
diff --git a/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi b/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi
index 29236de94d..fdaccb9844 100644
--- a/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi
+++ b/Silicon/Socionext/SynQuacer/DeviceTree/SynQuacer.dtsi
@@ -482,7 +482,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/Drivers/SynQuacerPciCpuIo2Dxe/SynQuacerPciCpuIo2Dxe.c b/Silicon/Socionext/SynQuacer/Drivers/SynQuacerPciCpuIo2Dxe/SynQuacerPciCpuIo2Dxe.c
index 6ef44b11bb..736b20cd51 100644
--- a/Silicon/Socionext/SynQuacer/Drivers/SynQuacerPciCpuIo2Dxe/SynQuacerPciCpuIo2Dxe.c
+++ b/Silicon/Socionext/SynQuacer/Drivers/SynQuacerPciCpuIo2Dxe/SynQuacerPciCpuIo2Dxe.c
@@ -25,7 +25,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
-#define MAX_IO_PORT_ADDRESS SYNQUACER_PCI_SEG1_PORTIO_MAX
+#define MAX_IO_PORT_ADDRESS (SYNQUACER_PCI_SEG1_PORTIO_MAX + \
+ SYNQUACER_PCI_SEG1_PORTIO_OFFSET)
//
// Handle for the CPU I/O 2 Protocol
@@ -414,12 +415,18 @@ CpuIoServiceRead (
return Status;
}
- if ((Address >= SYNQUACER_PCI_SEG0_PORTIO_MIN) &&
- (Address <= SYNQUACER_PCI_SEG0_PORTIO_MAX)) {
- Address += SYNQUACER_PCI_SEG0_PORTIO_MEMBASE;
- } else if ((Address >= SYNQUACER_PCI_SEG1_PORTIO_MIN) &&
- (Address <= SYNQUACER_PCI_SEG1_PORTIO_MAX)) {
- Address += SYNQUACER_PCI_SEG1_PORTIO_MEMBASE;
+ if ((Address >= (SYNQUACER_PCI_SEG0_PORTIO_MIN +
+ SYNQUACER_PCI_SEG0_PORTIO_OFFSET)) &&
+ (Address <= (SYNQUACER_PCI_SEG0_PORTIO_MAX +
+ SYNQUACER_PCI_SEG0_PORTIO_OFFSET))) {
+ Address += SYNQUACER_PCI_SEG0_PORTIO_MEMBASE -
+ SYNQUACER_PCI_SEG0_PORTIO_OFFSET;
+ } else if ((Address >= (SYNQUACER_PCI_SEG1_PORTIO_MIN +
+ SYNQUACER_PCI_SEG1_PORTIO_OFFSET)) &&
+ (Address <= (SYNQUACER_PCI_SEG1_PORTIO_MAX +
+ SYNQUACER_PCI_SEG1_PORTIO_OFFSET))) {
+ Address += SYNQUACER_PCI_SEG1_PORTIO_MEMBASE -
+ SYNQUACER_PCI_SEG1_PORTIO_OFFSET;
} else {
ASSERT (FALSE);
diff --git a/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h b/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h
index 2d3d5cd91b..950cece13e 100644
--- a/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h
+++ b/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h
@@ -23,12 +23,13 @@
#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_MEMBASE 0x67f00000
-#define SYNQUACER_PCI_SEG0_PORTIO_MEMSIZE SYNQUACER_PCI_SEG0_PORTIO_SIZE
+#define SYNQUACER_PCI_SEG0_PORTIO_MEMSIZE 0x10000
+#define SYNQUACER_PCI_SEG0_PORTIO_OFFSET 0x0
#define SYNQUACER_PCI_SEG0_MMIO32_MIN 0x68000000
#define SYNQUACER_PCI_SEG0_MMIO32_MAX 0x6fffffff
@@ -45,12 +46,13 @@
#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 0x0
+#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_PORTIO_OFFSET 0x10000
#define SYNQUACER_PCI_SEG1_MMIO32_MIN 0x78000000
#define SYNQUACER_PCI_SEG1_MMIO32_MAX 0x7fffffff
diff --git a/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.c b/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.c
index 596862baf4..341939876b 100644
--- a/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.c
+++ b/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.c
@@ -104,7 +104,8 @@ PCI_ROOT_BRIDGE mPciRootBridges[] = {
{ SYNQUACER_PCI_SEG0_BUSNUM_MIN,
SYNQUACER_PCI_SEG0_BUSNUM_MAX }, // Bus
{ SYNQUACER_PCI_SEG0_PORTIO_MIN,
- SYNQUACER_PCI_SEG0_PORTIO_MAX }, // Io
+ SYNQUACER_PCI_SEG0_PORTIO_MAX,
+ MAX_UINT64 - SYNQUACER_PCI_SEG0_PORTIO_OFFSET + 1 }, // Io
{ SYNQUACER_PCI_SEG0_MMIO32_MIN,
SYNQUACER_PCI_SEG0_MMIO32_MAX }, // Mem
{ SYNQUACER_PCI_SEG0_MMIO64_MIN,
@@ -123,7 +124,8 @@ PCI_ROOT_BRIDGE mPciRootBridges[] = {
{ SYNQUACER_PCI_SEG1_BUSNUM_MIN,
SYNQUACER_PCI_SEG1_BUSNUM_MAX }, // Bus
{ SYNQUACER_PCI_SEG1_PORTIO_MIN,
- SYNQUACER_PCI_SEG1_PORTIO_MAX }, // Io
+ SYNQUACER_PCI_SEG1_PORTIO_MAX,
+ MAX_UINT64 - SYNQUACER_PCI_SEG1_PORTIO_OFFSET + 1 }, // Io
{ SYNQUACER_PCI_SEG1_MMIO32_MIN,
SYNQUACER_PCI_SEG1_MMIO32_MAX }, // Mem
{ SYNQUACER_PCI_SEG1_MMIO64_MIN,