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> Reviewed-on: https://review.coreboot.org/23820 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Youness Alaoui <snifikino@gmail.com> Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
parent
e85e0f57ac
commit
81a6f109ba
|
@ -39,6 +39,12 @@
|
||||||
|
|
||||||
#define HPET_BASE_ADDRESS 0xfed00000
|
#define HPET_BASE_ADDRESS 0xfed00000
|
||||||
|
|
||||||
|
#define GFXVT_BASE_ADDRESS 0xfed90000ULL
|
||||||
|
#define GFXVT_BASE_SIZE 0x1000
|
||||||
|
|
||||||
|
#define VTVC0_BASE_ADDRESS 0xfed91000ULL
|
||||||
|
#define VTVC0_BASE_SIZE 0x1000
|
||||||
|
|
||||||
#define ACPI_BASE_ADDRESS 0x1000
|
#define ACPI_BASE_ADDRESS 0x1000
|
||||||
#define ACPI_BASE_SIZE 0x100
|
#define ACPI_BASE_SIZE 0x100
|
||||||
|
|
||||||
|
|
|
@ -86,4 +86,7 @@
|
||||||
#define PMIR_CF9LOCK (1 << 31)
|
#define PMIR_CF9LOCK (1 << 31)
|
||||||
#define PMIR_CF9GR (1 << 20)
|
#define PMIR_CF9GR (1 << 20)
|
||||||
|
|
||||||
|
#define LPC_IBDF 0x6C /* I/O APIC bus/dev/fn */
|
||||||
|
#define LPC_HnBDF(n) (0x70 + n * 2) /* HPET n bus/dev/fn */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -112,4 +112,9 @@
|
||||||
#define PCH_DEV_SATA2 _PCH_DEV(LPC, 5)
|
#define PCH_DEV_SATA2 _PCH_DEV(LPC, 5)
|
||||||
#define PCH_DEV_THERMAL _PCH_DEV(LPC, 6)
|
#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
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -74,6 +74,11 @@
|
||||||
#define D_LCK (1 << 4)
|
#define D_LCK (1 << 4)
|
||||||
#define G_SMRAME (1 << 3)
|
#define G_SMRAME (1 << 3)
|
||||||
#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
|
#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
|
||||||
|
#define CAPID0_A 0xe4
|
||||||
|
#define VTD_DISABLE (1 << 23)
|
||||||
|
#define ARCHDIS 0xff0 /* DMA Remap Engine Policy Control */
|
||||||
|
#define DMAR_LCKDN (1 << 31)
|
||||||
|
#define PRSCAPDIS (1 << 2)
|
||||||
|
|
||||||
#define MESEG_BASE 0x70 /* Management Engine Base. */
|
#define MESEG_BASE 0x70 /* Management Engine Base. */
|
||||||
#define MESEG_LIMIT 0x78 /* Management Engine Limit. */
|
#define MESEG_LIMIT 0x78 /* Management Engine Limit. */
|
||||||
|
@ -95,7 +100,9 @@
|
||||||
|
|
||||||
#define MCHBAR_PEI_VERSION 0x5034
|
#define MCHBAR_PEI_VERSION 0x5034
|
||||||
#define BIOS_RESET_CPL 0x5da8
|
#define BIOS_RESET_CPL 0x5da8
|
||||||
|
#define GFXVTBAR 0x5400
|
||||||
#define EDRAMBAR 0x5408
|
#define EDRAMBAR 0x5408
|
||||||
|
#define VTVC0BAR 0x5410
|
||||||
#define MCH_PAIR 0x5418
|
#define MCH_PAIR 0x5418
|
||||||
#define GDXCBAR 0x5420
|
#define GDXCBAR 0x5420
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,10 @@ static void pch_enable_ioapic(struct device *dev)
|
||||||
{
|
{
|
||||||
u32 reg32;
|
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);
|
set_ioapic_id(VIO_APIC_VADDR, 0x02);
|
||||||
|
|
||||||
/* affirm full set of redirection table entries ("write once") */
|
/* affirm full set of redirection table entries ("write once") */
|
||||||
|
@ -67,6 +71,16 @@ static void pch_enable_ioapic(struct device *dev)
|
||||||
io_apic_write(VIO_APIC_VADDR, 0x03, 0x01);
|
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
|
/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
|
||||||
* 0x00 - 0000 = Reserved
|
* 0x00 - 0000 = Reserved
|
||||||
* 0x01 - 0001 = Reserved
|
* 0x01 - 0001 = Reserved
|
||||||
|
@ -436,6 +450,7 @@ static void lpc_init(struct device *dev)
|
||||||
pch_pirq_init(dev);
|
pch_pirq_init(dev);
|
||||||
setup_i8259();
|
setup_i8259();
|
||||||
i8259_configure_irq_trigger(9, 1);
|
i8259_configure_irq_trigger(9, 1);
|
||||||
|
enable_hpet(dev);
|
||||||
|
|
||||||
/* Initialize power management */
|
/* Initialize power management */
|
||||||
pch_power_options(dev);
|
pch_power_options(dev);
|
||||||
|
|
|
@ -47,5 +47,26 @@ static const struct reg_script systemagent_early_init_script[] = {
|
||||||
|
|
||||||
void systemagent_early_init(void)
|
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);
|
reg_script_run_on_dev(SA_DEV_ROOT, systemagent_early_init_script);
|
||||||
|
|
||||||
|
if (vtd_capable) {
|
||||||
|
/* setup BARs: zeroize top 32 bits; set enable bit */
|
||||||
|
MCHBAR32(GFXVTBAR + 4) = GFXVT_BASE_ADDRESS >> 32;
|
||||||
|
MCHBAR32(GFXVTBAR) = GFXVT_BASE_ADDRESS | 1;
|
||||||
|
MCHBAR32(VTVC0BAR + 4) = VTVC0_BASE_ADDRESS >> 32;
|
||||||
|
MCHBAR32(VTVC0BAR) = VTVC0_BASE_ADDRESS | 1;
|
||||||
|
|
||||||
|
/* set PRSCAPDIS, lock GFXVTBAR policy cfg registers */
|
||||||
|
u32 reg32;
|
||||||
|
reg32 = read32((void *)(GFXVT_BASE_ADDRESS + ARCHDIS));
|
||||||
|
write32((void *)(GFXVT_BASE_ADDRESS + ARCHDIS),
|
||||||
|
reg32 | DMAR_LCKDN | PRSCAPDIS);
|
||||||
|
/* lock VTVC0BAR policy cfg registers */
|
||||||
|
reg32 = read32((void *)(VTVC0_BASE_ADDRESS + ARCHDIS));
|
||||||
|
write32((void *)(VTVC0_BASE_ADDRESS + ARCHDIS),
|
||||||
|
reg32 | DMAR_LCKDN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,7 +271,7 @@ static void mc_report_map_entries(device_t dev, uint64_t *values)
|
||||||
printk(BIOS_DEBUG, "MC MAP: GGC: 0x%x\n", pci_read_config16(dev, GGC));
|
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 base_k, size_k;
|
||||||
unsigned long touud_k;
|
unsigned long touud_k;
|
||||||
|
@ -327,7 +327,7 @@ static void mc_add_dram_resources(device_t dev)
|
||||||
* The resource index starts low and should not meet or exceed
|
* The resource index starts low and should not meet or exceed
|
||||||
* PCI_BASE_ADDRESS_0.
|
* PCI_BASE_ADDRESS_0.
|
||||||
*/
|
*/
|
||||||
index = 0;
|
index = *resource_cnt;
|
||||||
|
|
||||||
/* 0 - > 0xa0000 */
|
/* 0 - > 0xa0000 */
|
||||||
base_k = 0;
|
base_k = 0;
|
||||||
|
@ -373,18 +373,32 @@ static void mc_add_dram_resources(device_t dev)
|
||||||
(0x100000 - 0xc0000) >> 10);
|
(0x100000 - 0xc0000) >> 10);
|
||||||
|
|
||||||
chromeos_reserve_ram_oops(dev, index++);
|
chromeos_reserve_ram_oops(dev, index++);
|
||||||
|
|
||||||
|
*resource_cnt = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void systemagent_read_resources(device_t dev)
|
static void systemagent_read_resources(device_t dev)
|
||||||
{
|
{
|
||||||
|
int index = 0;
|
||||||
|
const bool vtd_capable =
|
||||||
|
!(pci_read_config32(dev, CAPID0_A) & VTD_DISABLE);
|
||||||
|
|
||||||
/* Read standard PCI resources. */
|
/* Read standard PCI resources. */
|
||||||
pci_dev_read_resources(dev);
|
pci_dev_read_resources(dev);
|
||||||
|
|
||||||
/* Add all fixed MMIO resources. */
|
/* Add all fixed MMIO resources. */
|
||||||
mc_add_fixed_mmio_resources(dev);
|
mc_add_fixed_mmio_resources(dev);
|
||||||
|
|
||||||
|
/* Add VT-d MMIO resources if capable */
|
||||||
|
if (vtd_capable) {
|
||||||
|
mmio_resource(dev, index++, GFXVT_BASE_ADDRESS / KiB,
|
||||||
|
GFXVT_BASE_SIZE / KiB);
|
||||||
|
mmio_resource(dev, index++, VTVC0_BASE_ADDRESS / KiB,
|
||||||
|
VTVC0_BASE_SIZE / KiB);
|
||||||
|
}
|
||||||
|
|
||||||
/* Calculate and add DRAM resources. */
|
/* Calculate and add DRAM resources. */
|
||||||
mc_add_dram_resources(dev);
|
mc_add_dram_resources(dev, &index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void systemagent_init(struct device *dev)
|
static void systemagent_init(struct device *dev)
|
||||||
|
|
Loading…
Reference in New Issue