Matt DeVillier has uploaded this change for review. ( https://review.coreboot.org/23820
Change subject: soc/intel/broadwell: Enable VT-d and X2APIC ......................................................................
soc/intel/broadwell: Enable VT-d and X2APIC
We use the usual static addresses 0xfed90000/0xfed91000 for the GFX IOMMU and the general IOMMU respectively. These addresses have to be configured in MCHBAR registers and reserved from the OS.
Change-Id: I7afcce0da028a160174db2cf6b4b6735bcd59165 Signed-off-by: Matt DeVillier matt.devillier@gmail.com --- M src/soc/intel/broadwell/include/soc/iomap.h M src/soc/intel/broadwell/include/soc/pci_devs.h M src/soc/intel/broadwell/include/soc/systemagent.h M src/soc/intel/broadwell/lpc.c M src/soc/intel/broadwell/romstage/systemagent.c M src/soc/intel/broadwell/systemagent.c 6 files changed, 105 insertions(+), 3 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/23820/1
diff --git a/src/soc/intel/broadwell/include/soc/iomap.h b/src/soc/intel/broadwell/include/soc/iomap.h index fe8e78b..3afd653 100644 --- a/src/soc/intel/broadwell/include/soc/iomap.h +++ b/src/soc/intel/broadwell/include/soc/iomap.h @@ -39,6 +39,12 @@
#define HPET_BASE_ADDRESS 0xfed00000
+#define GFXVT_BASE_ADDRESS 0xfed90000 +#define GFXVT_BASE_SIZE 0x1000 + +#define VTVC0_BASE_ADDRESS 0xfed91000 +#define VTVC0_BASE_SIZE 0x1000 + #define ACPI_BASE_ADDRESS 0x1000 #define ACPI_BASE_SIZE 0x100
diff --git a/src/soc/intel/broadwell/include/soc/pci_devs.h b/src/soc/intel/broadwell/include/soc/pci_devs.h index 59c64ce..6fb1562 100644 --- a/src/soc/intel/broadwell/include/soc/pci_devs.h +++ b/src/soc/intel/broadwell/include/soc/pci_devs.h @@ -112,4 +112,12 @@ #define PCH_DEV_SATA2 _PCH_DEV(LPC, 5) #define PCH_DEV_THERMAL _PCH_DEV(LPC, 6)
+#define PCH_IOAPIC_PCI_BUS 250 +#define PCH_IOAPIC_PCI_SLOT 31 +#define PCH_HPET_PCI_BUS 250 +#define PCH_HPET_PCI_SLOT 15 + +#define LPC_IBDF 0x6C /* I/O APIC bus/dev/fn */ +#define LPC_HnBDF(n) (0x70 + n * 2) /* HPET n bus/dev/fn */ + #endif diff --git a/src/soc/intel/broadwell/include/soc/systemagent.h b/src/soc/intel/broadwell/include/soc/systemagent.h index 125ba47..cf8c998 100644 --- a/src/soc/intel/broadwell/include/soc/systemagent.h +++ b/src/soc/intel/broadwell/include/soc/systemagent.h @@ -74,6 +74,8 @@ #define D_LCK (1 << 4) #define G_SMRAME (1 << 3) #define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0)) +#define CAPID0_A 0xe4 +#define VTD_DISABLE (1 << 23)
#define MESEG_BASE 0x70 /* Management Engine Base. */ #define MESEG_LIMIT 0x78 /* Management Engine Limit. */ @@ -95,7 +97,9 @@
#define MCHBAR_PEI_VERSION 0x5034 #define BIOS_RESET_CPL 0x5da8 +#define GFXVTBAR 0x5400 #define EDRAMBAR 0x5408 +#define VTVC0BAR 0x5410 #define MCH_PAIR 0x5418 #define GDXCBAR 0x5420
@@ -130,4 +134,25 @@ /* System Agent identification */ u8 systemagent_revision(void);
+/* + * Fixed MMIO range + * INDEX = Either PCI configuration space registers or MMIO offsets + * mapped from REG. + * BASE = 32 bit Address. + * SIZE = base length + * DESCRIPTION = Name of the register/offset. + */ +struct sa_mmio_descriptor { + unsigned int index; + uintptr_t base; + size_t size; + const char *description; +}; + +#ifndef __BOOTBLOCK__ +static const struct sa_mmio_descriptor soc_vtd_resources[] = { + { GFXVTBAR, GFXVT_BASE_ADDRESS, GFXVT_BASE_SIZE, "GFXVTBAR" }, + { VTVC0BAR, VTVC0_BASE_ADDRESS, VTVC0_BASE_SIZE, "VTVC0BAR" }, +}; +#endif #endif diff --git a/src/soc/intel/broadwell/lpc.c b/src/soc/intel/broadwell/lpc.c index d1c4242..8e7f4de 100644 --- a/src/soc/intel/broadwell/lpc.c +++ b/src/soc/intel/broadwell/lpc.c @@ -49,6 +49,10 @@ { u32 reg32;
+ /* Assign unique bus/dev/fn for I/O APIC */ + pci_write_config16(dev, LPC_IBDF, + PCH_IOAPIC_PCI_BUS << 8 | PCH_IOAPIC_PCI_SLOT << 3); + set_ioapic_id(VIO_APIC_VADDR, 0x02);
/* affirm full set of redirection table entries ("write once") */ @@ -67,6 +71,16 @@ io_apic_write(VIO_APIC_VADDR, 0x03, 0x01); }
+static void enable_hpet(struct device *dev) +{ + size_t i; + + /* Assign unique bus/dev/fn for each HPET */ + for (i = 0; i < 8; ++i) + pci_write_config16(dev, LPC_HnBDF(i), + PCH_HPET_PCI_BUS << 8 | PCH_HPET_PCI_SLOT << 3 | i); +} + /* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control * 0x00 - 0000 = Reserved * 0x01 - 0001 = Reserved @@ -436,6 +450,7 @@ pch_pirq_init(dev); setup_i8259(); i8259_configure_irq_trigger(9, 1); + enable_hpet(dev);
/* Initialize power management */ pch_power_options(dev); diff --git a/src/soc/intel/broadwell/romstage/systemagent.c b/src/soc/intel/broadwell/romstage/systemagent.c index e7dbbc8..e83d65b 100644 --- a/src/soc/intel/broadwell/romstage/systemagent.c +++ b/src/soc/intel/broadwell/romstage/systemagent.c @@ -47,5 +47,21 @@
void systemagent_early_init(void) { + const bool vtd_capable = + !(pci_read_config32(SA_DEV_ROOT, CAPID0_A) & VTD_DISABLE); + reg_script_run_on_dev(SA_DEV_ROOT, systemagent_early_init_script); + + if (vtd_capable) { + int i; + size_t count = ARRAY_SIZE(soc_vtd_resources); + for (i = 0; i < count; i++) { + uintptr_t base; + unsigned int index; + + base = soc_vtd_resources[i].base; + index = soc_vtd_resources[i].index; + write32((void *)(MCH_BASE_ADDRESS + index), base | 1); + } + } } diff --git a/src/soc/intel/broadwell/systemagent.c b/src/soc/intel/broadwell/systemagent.c index f46f5ea..47addeb 100644 --- a/src/soc/intel/broadwell/systemagent.c +++ b/src/soc/intel/broadwell/systemagent.c @@ -127,6 +127,29 @@ * Add all known fixed MMIO ranges that hang off the host bridge/memory * controller device. */ +static void sa_add_fixed_mmio_resources(struct device *dev, int *resource_cnt, + const struct sa_mmio_descriptor *sa_fixed_resources, size_t count) +{ + int i; + int index = *resource_cnt; + + for (i = 0; i < count; i++) { + uintptr_t base; + size_t size; + + size = sa_fixed_resources[i].size; + base = sa_fixed_resources[i].base; + + mmio_resource(dev, index++, base / KiB, size / KiB); + } + + *resource_cnt = index; +} + +/* + * Add all known fixed MMIO ranges that hang off the host bridge/memory + * controller device. + */ static void mc_add_fixed_mmio_resources(device_t dev) { int i; @@ -271,7 +294,7 @@ printk(BIOS_DEBUG, "MC MAP: GGC: 0x%x\n", pci_read_config16(dev, GGC)); }
-static void mc_add_dram_resources(device_t dev) +static void mc_add_dram_resources(device_t dev, int *resource_cnt) { unsigned long base_k, size_k; unsigned long touud_k; @@ -327,7 +350,7 @@ * The resource index starts low and should not meet or exceed * PCI_BASE_ADDRESS_0. */ - index = 0; + index = *resource_cnt;
/* 0 - > 0xa0000 */ base_k = 0; @@ -377,14 +400,23 @@
static void systemagent_read_resources(device_t dev) { + struct device *const root_dev = SA_DEV_ROOT; + bool soc_is_vtd_capable = root_dev && + !(pci_read_config32(root_dev, CAPID0_A) & VTD_DISABLE); + int index = 0; + /* Read standard PCI resources. */ pci_dev_read_resources(dev);
/* Add all fixed MMIO resources. */ mc_add_fixed_mmio_resources(dev);
+ if (soc_is_vtd_capable) + sa_add_fixed_mmio_resources(dev, &index, soc_vtd_resources, + ARRAY_SIZE(soc_vtd_resources)); + /* Calculate and add DRAM resources. */ - mc_add_dram_resources(dev); + mc_add_dram_resources(dev, &index); }
static void systemagent_init(struct device *dev)