[PATCH] PCI: Exclude VTBAR range from Local MMIOL if necessary

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Intel's x58 chipset (IOH) includes a VTBAR (Base Address Register for
Intel VT-d Chipset Registers) that specifies an 8K aligned system memory
address for VT-d memory mapped registers.  If BIOS has placed the VT-d
register window within the Local MMIOL range, it will not be available
for downstream PCI devices, so remove it from the host bridge's MMIOL
range.

This patch determines if the VTBAR is enabled and modifies the IOH's
Local MMIOL range if it is programmed within such.


Reference: "Intel X58 Express Chipset Datasheet"
           http://www.intel.com/Assets/PDF/datasheet/320838.pdf


Signed-off-by: Myron Stowe <myron.stowe@xxxxxx>
---

 arch/x86/pci/intel_bus.c |   20 +++++++++++++++++++-
 1 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/arch/x86/pci/intel_bus.c b/arch/x86/pci/intel_bus.c
index b7a55dc..f58136c 100644
--- a/arch/x86/pci/intel_bus.c
+++ b/arch/x86/pci/intel_bus.c
@@ -39,13 +39,16 @@ static inline void print_ioh_resources(struct pci_root_info *info)
 #define IOH_LMMIOH_LIMITU	0x118
 #define IOH_LCFGBUS		0x11c
 
+#define IOH_VTBAR		0x180
+#define IOH_VTSIZE		0x2000	/* Fixed HW size (not programmable) */
+
 static void __devinit pci_root_bus_res(struct pci_dev *dev)
 {
 	u16 word;
 	u32 dword;
 	struct pci_root_info *info;
 	u16 io_base, io_end;
-	u32 mmiol_base, mmiol_end;
+	u32 mmiol_base, mmiol_end, vtbar;
 	u64 mmioh_base, mmioh_end;
 	int bus_base, bus_end;
 
@@ -72,6 +75,21 @@ static void __devinit pci_root_bus_res(struct pci_dev *dev)
 	pci_read_config_dword(dev, IOH_LMMIOL, &dword);
 	mmiol_base = (dword & 0xff00) << (24 - 8);
 	mmiol_end = (dword & 0xff000000) | 0xffffff;
+	pci_read_config_dword(dev, IOH_VTBAR, &dword);
+	vtbar = dword & 0xfffffffe;
+	if (dword & 0x1 &&
+		(mmiol_base < vtbar + IOH_VTSIZE - 1 && vtbar < mmiol_end)) {
+		/* remove VT-d DRDH from Local MMIOL window */
+		if (vtbar <= mmiol_base)
+			mmiol_base = vtbar + IOH_VTSIZE;
+		else if (mmiol_end <= vtbar + IOH_VTSIZE - 1)
+			mmiol_end = vtbar;
+		else {
+			update_res(info, mmiol_base, vtbar - 1,
+				   IORESOURCE_MEM, 0);
+			mmiol_base = vtbar + IOH_VTSIZE;
+		}
+	}
 	update_res(info, mmiol_base, mmiol_end, IORESOURCE_MEM, 0);
 
 	pci_read_config_dword(dev, IOH_LMMIOH, &dword);

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux