arch/x86/acpi: Add DMAR RMRR helper functions

Add DMAR RMRR table entry and helper functions, using the existing
DRHD functions as a model. As the DRHD device scope (DS) functions
aren't DRHD-specific, genericize them to be used with RMRR tables as
well. Correct DRHD bar size to match table entry in creator function,
as noted in comments from patchset below.

Adapted from/supersedes https://review.coreboot.org/25445

Change-Id: I912b1d7244ca4dd911bb6629533d453b1b4a06be
Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-on: https://review.coreboot.org/27269
Reviewed-by: Youness Alaoui <snifikino@gmail.com>
Reviewed-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Jay Talbott <JayTalbott@sysproconsulting.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Matt DeVillier 2018-03-29 14:59:57 +02:00 committed by Nico Huber
parent a6b3b4dd8f
commit 7866d497ad
8 changed files with 71 additions and 39 deletions

View File

@ -449,7 +449,7 @@ void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags,
} }
unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags, unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags,
u16 segment, u32 bar) u16 segment, u64 bar)
{ {
dmar_entry_t *drhd = (dmar_entry_t *)current; dmar_entry_t *drhd = (dmar_entry_t *)current;
memset(drhd, 0, sizeof(*drhd)); memset(drhd, 0, sizeof(*drhd));
@ -462,6 +462,20 @@ unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags,
return drhd->length; return drhd->length;
} }
unsigned long acpi_create_dmar_rmrr(unsigned long current, u16 segment,
u64 bar, u64 limit)
{
dmar_rmrr_entry_t *rmrr = (dmar_rmrr_entry_t *)current;
memset(rmrr, 0, sizeof(*rmrr));
rmrr->type = DMAR_RMRR;
rmrr->length = sizeof(*rmrr); /* will be fixed up later */
rmrr->segment = segment;
rmrr->bar = bar;
rmrr->limit = limit;
return rmrr->length;
}
unsigned long acpi_create_dmar_atsr(unsigned long current, u8 flags, unsigned long acpi_create_dmar_atsr(unsigned long current, u8 flags,
u16 segment) u16 segment)
{ {
@ -481,13 +495,19 @@ void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current)
drhd->length = current - base; drhd->length = current - base;
} }
void acpi_dmar_rmrr_fixup(unsigned long base, unsigned long current)
{
dmar_rmrr_entry_t *rmrr = (dmar_rmrr_entry_t *)base;
rmrr->length = current - base;
}
void acpi_dmar_atsr_fixup(unsigned long base, unsigned long current) void acpi_dmar_atsr_fixup(unsigned long base, unsigned long current)
{ {
dmar_atsr_entry_t *atsr = (dmar_atsr_entry_t *)base; dmar_atsr_entry_t *atsr = (dmar_atsr_entry_t *)base;
atsr->length = current - base; atsr->length = current - base;
} }
static unsigned long acpi_create_dmar_drhd_ds(unsigned long current, static unsigned long acpi_create_dmar_ds(unsigned long current,
enum dev_scope_type type, u8 enumeration_id, u8 bus, u8 dev, u8 fn) enum dev_scope_type type, u8 enumeration_id, u8 bus, u8 dev, u8 fn)
{ {
/* we don't support longer paths yet */ /* we don't support longer paths yet */
@ -505,31 +525,31 @@ static unsigned long acpi_create_dmar_drhd_ds(unsigned long current,
return ds->length; return ds->length;
} }
unsigned long acpi_create_dmar_drhd_ds_pci_br(unsigned long current, u8 bus, unsigned long acpi_create_dmar_ds_pci_br(unsigned long current, u8 bus,
u8 dev, u8 fn) u8 dev, u8 fn)
{ {
return acpi_create_dmar_drhd_ds(current, return acpi_create_dmar_ds(current,
SCOPE_PCI_SUB, 0, bus, dev, fn); SCOPE_PCI_SUB, 0, bus, dev, fn);
} }
unsigned long acpi_create_dmar_drhd_ds_pci(unsigned long current, u8 bus, unsigned long acpi_create_dmar_ds_pci(unsigned long current, u8 bus,
u8 dev, u8 fn) u8 dev, u8 fn)
{ {
return acpi_create_dmar_drhd_ds(current, return acpi_create_dmar_ds(current,
SCOPE_PCI_ENDPOINT, 0, bus, dev, fn); SCOPE_PCI_ENDPOINT, 0, bus, dev, fn);
} }
unsigned long acpi_create_dmar_drhd_ds_ioapic(unsigned long current, unsigned long acpi_create_dmar_ds_ioapic(unsigned long current,
u8 enumeration_id, u8 bus, u8 dev, u8 fn) u8 enumeration_id, u8 bus, u8 dev, u8 fn)
{ {
return acpi_create_dmar_drhd_ds(current, return acpi_create_dmar_ds(current,
SCOPE_IOAPIC, enumeration_id, bus, dev, fn); SCOPE_IOAPIC, enumeration_id, bus, dev, fn);
} }
unsigned long acpi_create_dmar_drhd_ds_msi_hpet(unsigned long current, unsigned long acpi_create_dmar_ds_msi_hpet(unsigned long current,
u8 enumeration_id, u8 bus, u8 dev, u8 fn) u8 enumeration_id, u8 bus, u8 dev, u8 fn)
{ {
return acpi_create_dmar_drhd_ds(current, return acpi_create_dmar_ds(current,
SCOPE_MSI_HPET, enumeration_id, bus, dev, fn); SCOPE_MSI_HPET, enumeration_id, bus, dev, fn);
} }

View File

@ -331,6 +331,15 @@ typedef struct dmar_entry {
u64 bar; u64 bar;
} __packed dmar_entry_t; } __packed dmar_entry_t;
typedef struct dmar_rmrr_entry {
u16 type;
u16 length;
u16 reserved;
u16 segment;
u64 bar;
u64 limit;
} __packed dmar_rmrr_entry_t;
typedef struct dmar_atsr_entry { typedef struct dmar_atsr_entry {
u16 type; u16 type;
u16 length; u16 length;
@ -738,19 +747,22 @@ unsigned long acpi_write_dbg2_pci_uart(acpi_rsdp_t *rsdp, unsigned long current,
void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags, void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags,
unsigned long (*acpi_fill_dmar)(unsigned long)); unsigned long (*acpi_fill_dmar)(unsigned long));
unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags, unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags,
u16 segment, u32 bar); u16 segment, u64 bar);
unsigned long acpi_create_dmar_rmrr(unsigned long current, u16 segment,
u64 bar, u64 limit);
unsigned long acpi_create_dmar_atsr(unsigned long current, u8 flags, unsigned long acpi_create_dmar_atsr(unsigned long current, u8 flags,
u16 segment); u16 segment);
void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current); void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current);
void acpi_dmar_rmrr_fixup(unsigned long base, unsigned long current);
void acpi_dmar_atsr_fixup(unsigned long base, unsigned long current); void acpi_dmar_atsr_fixup(unsigned long base, unsigned long current);
unsigned long acpi_create_dmar_drhd_ds_pci_br(unsigned long current, unsigned long acpi_create_dmar_ds_pci_br(unsigned long current,
u8 bus, u8 dev, u8 fn); u8 bus, u8 dev, u8 fn);
unsigned long acpi_create_dmar_drhd_ds_pci(unsigned long current, unsigned long acpi_create_dmar_ds_pci(unsigned long current,
u8 bus, u8 dev, u8 fn); u8 bus, u8 dev, u8 fn);
unsigned long acpi_create_dmar_drhd_ds_ioapic(unsigned long current, unsigned long acpi_create_dmar_ds_ioapic(unsigned long current,
u8 enumeration_id, u8 enumeration_id,
u8 bus, u8 dev, u8 fn); u8 bus, u8 dev, u8 fn);
unsigned long acpi_create_dmar_drhd_ds_msi_hpet(unsigned long current, unsigned long acpi_create_dmar_ds_msi_hpet(unsigned long current,
u8 enumeration_id, u8 enumeration_id,
u8 bus, u8 dev, u8 fn); u8 bus, u8 dev, u8 fn);
void acpi_write_hest(acpi_hest_t *hest, void acpi_write_hest(acpi_hest_t *hest,

View File

@ -78,24 +78,24 @@ static unsigned long acpi_fill_dmar(unsigned long current)
unsigned long tmp = current; unsigned long tmp = current;
current += acpi_create_dmar_drhd(current, 0, 0, IOMMU_BASE1); current += acpi_create_dmar_drhd(current, 0, 0, IOMMU_BASE1);
current += acpi_create_dmar_drhd_ds_pci(current, 0, 0x1b, 0); current += acpi_create_dmar_ds_pci(current, 0, 0x1b, 0);
acpi_dmar_drhd_fixup(tmp, current); acpi_dmar_drhd_fixup(tmp, current);
if (stepping != STEPPING_B2) { if (stepping != STEPPING_B2) {
tmp = current; tmp = current;
current += acpi_create_dmar_drhd(current, 0, 0, IOMMU_BASE2); current += acpi_create_dmar_drhd(current, 0, 0, IOMMU_BASE2);
current += acpi_create_dmar_drhd_ds_pci(current, 0, 0x2, 0); current += acpi_create_dmar_ds_pci(current, 0, 0x2, 0);
current += acpi_create_dmar_drhd_ds_pci(current, 0, 0x2, 1); current += acpi_create_dmar_ds_pci(current, 0, 0x2, 1);
acpi_dmar_drhd_fixup(tmp, current); acpi_dmar_drhd_fixup(tmp, current);
} }
if (me_active) { if (me_active) {
tmp = current; tmp = current;
current += acpi_create_dmar_drhd(current, 0, 0, IOMMU_BASE3); current += acpi_create_dmar_drhd(current, 0, 0, IOMMU_BASE3);
current += acpi_create_dmar_drhd_ds_pci(current, 0, 0x3, 0); current += acpi_create_dmar_ds_pci(current, 0, 0x3, 0);
current += acpi_create_dmar_drhd_ds_pci(current, 0, 0x3, 1); current += acpi_create_dmar_ds_pci(current, 0, 0x3, 1);
current += acpi_create_dmar_drhd_ds_pci(current, 0, 0x3, 2); current += acpi_create_dmar_ds_pci(current, 0, 0x3, 2);
current += acpi_create_dmar_drhd_ds_pci(current, 0, 0x3, 3); current += acpi_create_dmar_ds_pci(current, 0, 0x3, 3);
acpi_dmar_drhd_fixup(tmp, current); acpi_dmar_drhd_fixup(tmp, current);
} }

View File

@ -85,7 +85,7 @@ static unsigned long acpi_fill_dmar(unsigned long current)
const unsigned long tmp = current; const unsigned long tmp = current;
current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar); current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar);
current += acpi_create_dmar_drhd_ds_pci(current, 0, 2, 0); current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
acpi_dmar_drhd_fixup(tmp, current); acpi_dmar_drhd_fixup(tmp, current);
} }
@ -95,11 +95,11 @@ static unsigned long acpi_fill_dmar(unsigned long current)
const unsigned long tmp = current; const unsigned long tmp = current;
current += acpi_create_dmar_drhd(current, current += acpi_create_dmar_drhd(current,
DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar); DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
current += acpi_create_dmar_drhd_ds_ioapic(current, current += acpi_create_dmar_ds_ioapic(current,
2, PCH_IOAPIC_PCI_BUS, PCH_IOAPIC_PCI_SLOT, 0); 2, PCH_IOAPIC_PCI_BUS, PCH_IOAPIC_PCI_SLOT, 0);
size_t i; size_t i;
for (i = 0; i < 8; ++i) for (i = 0; i < 8; ++i)
current += acpi_create_dmar_drhd_ds_msi_hpet(current, current += acpi_create_dmar_ds_msi_hpet(current,
0, PCH_HPET_PCI_BUS, 0, PCH_HPET_PCI_BUS,
PCH_HPET_PCI_SLOT, i); PCH_HPET_PCI_SLOT, i);
acpi_dmar_drhd_fixup(tmp, current); acpi_dmar_drhd_fixup(tmp, current);

View File

@ -74,19 +74,19 @@ static unsigned long acpi_fill_dmar(unsigned long current)
if (igfx && igfx->enabled) { if (igfx && igfx->enabled) {
const unsigned long tmp = current; const unsigned long tmp = current;
current += acpi_create_dmar_drhd(current, 0, 0, IOMMU_BASE1); current += acpi_create_dmar_drhd(current, 0, 0, IOMMU_BASE1);
current += acpi_create_dmar_drhd_ds_pci(current, 0, 2, 0); current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
current += acpi_create_dmar_drhd_ds_pci(current, 0, 2, 1); current += acpi_create_dmar_ds_pci(current, 0, 2, 1);
acpi_dmar_drhd_fixup(tmp, current); acpi_dmar_drhd_fixup(tmp, current);
} }
const unsigned long tmp = current; const unsigned long tmp = current;
current += acpi_create_dmar_drhd(current, current += acpi_create_dmar_drhd(current,
DRHD_INCLUDE_PCI_ALL, 0, IOMMU_BASE2); DRHD_INCLUDE_PCI_ALL, 0, IOMMU_BASE2);
current += acpi_create_dmar_drhd_ds_ioapic(current, current += acpi_create_dmar_ds_ioapic(current,
2, PCH_IOAPIC_PCI_BUS, PCH_IOAPIC_PCI_SLOT, 0); 2, PCH_IOAPIC_PCI_BUS, PCH_IOAPIC_PCI_SLOT, 0);
size_t i; size_t i;
for (i = 0; i < 8; ++i) for (i = 0; i < 8; ++i)
current += acpi_create_dmar_drhd_ds_msi_hpet(current, current += acpi_create_dmar_ds_msi_hpet(current,
0, PCH_HPET_PCI_BUS, PCH_HPET_PCI_SLOT, i); 0, PCH_HPET_PCI_BUS, PCH_HPET_PCI_SLOT, i);
acpi_dmar_drhd_fixup(tmp, current); acpi_dmar_drhd_fixup(tmp, current);

View File

@ -586,7 +586,7 @@ static unsigned long acpi_fill_dmar(unsigned long current)
const unsigned long tmp = current; const unsigned long tmp = current;
current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar); current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar);
current += acpi_create_dmar_drhd_ds_pci(current, 0, 2, 0); current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
acpi_dmar_drhd_fixup(tmp, current); acpi_dmar_drhd_fixup(tmp, current);
} }
@ -596,11 +596,11 @@ static unsigned long acpi_fill_dmar(unsigned long current)
const unsigned long tmp = current; const unsigned long tmp = current;
current += acpi_create_dmar_drhd(current, current += acpi_create_dmar_drhd(current,
DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar); DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
current += acpi_create_dmar_drhd_ds_ioapic(current, current += acpi_create_dmar_ds_ioapic(current,
2, PCH_IOAPIC_PCI_BUS, PCH_IOAPIC_PCI_SLOT, 0); 2, PCH_IOAPIC_PCI_BUS, PCH_IOAPIC_PCI_SLOT, 0);
size_t i; size_t i;
for (i = 0; i < 8; ++i) for (i = 0; i < 8; ++i)
current += acpi_create_dmar_drhd_ds_msi_hpet(current, current += acpi_create_dmar_ds_msi_hpet(current,
0, PCH_HPET_PCI_BUS, 0, PCH_HPET_PCI_BUS,
PCH_HPET_PCI_SLOT, i); PCH_HPET_PCI_SLOT, i);
acpi_dmar_drhd_fixup(tmp, current); acpi_dmar_drhd_fixup(tmp, current);

View File

@ -331,12 +331,12 @@ static unsigned long acpi_fill_dmar(unsigned long current)
current += acpi_create_dmar_drhd(current, current += acpi_create_dmar_drhd(current,
DRHD_INCLUDE_PCI_ALL, 0, vtbar); DRHD_INCLUDE_PCI_ALL, 0, vtbar);
/* The IIO I/O APIC is fixed on PCI 00:05.4 on Broadwell-DE */ /* The IIO I/O APIC is fixed on PCI 00:05.4 on Broadwell-DE */
current += acpi_create_dmar_drhd_ds_ioapic(current, current += acpi_create_dmar_ds_ioapic(current,
9, 0, 5, 4); 9, 0, 5, 4);
/* Get the PCI BDF for the PCH I/O APIC */ /* Get the PCI BDF for the PCH I/O APIC */
dev = dev_find_slot(0, LPC_DEV_FUNC); dev = dev_find_slot(0, LPC_DEV_FUNC);
bdf = pci_read_config16(dev, 0x6c); bdf = pci_read_config16(dev, 0x6c);
current += acpi_create_dmar_drhd_ds_ioapic(current, current += acpi_create_dmar_ds_ioapic(current,
8, (bdf >> 8), PCI_SLOT(bdf), PCI_FUNC(bdf)); 8, (bdf >> 8), PCI_SLOT(bdf), PCI_FUNC(bdf));
/* /*
@ -365,7 +365,7 @@ static unsigned long acpi_fill_dmar(unsigned long current)
/* Create one HPET entry in DMAR for every unique HPET PCI path. */ /* Create one HPET entry in DMAR for every unique HPET PCI path. */
for (i = 0; i < ARRAY_SIZE(hpet_bdf); i++) { for (i = 0; i < ARRAY_SIZE(hpet_bdf); i++) {
if (hpet_bdf[i]) if (hpet_bdf[i])
current += acpi_create_dmar_drhd_ds_msi_hpet(current, current += acpi_create_dmar_ds_msi_hpet(current,
0, (hpet_bdf[i] >> 8), PCI_SLOT(hpet_bdf[i]), 0, (hpet_bdf[i] >> 8), PCI_SLOT(hpet_bdf[i]),
PCI_FUNC(hpet_bdf[i])); PCI_FUNC(hpet_bdf[i]));
} }
@ -380,7 +380,7 @@ static unsigned long acpi_fill_dmar(unsigned long current)
dev = dev_find_class(PCI_CLASS_BRIDGE_PCI << 8, dev); dev = dev_find_class(PCI_CLASS_BRIDGE_PCI << 8, dev);
if (dev && dev->bus->secondary == 0 && if (dev && dev->bus->secondary == 0 &&
PCI_SLOT(dev->path.pci.devfn) <= 3) PCI_SLOT(dev->path.pci.devfn) <= 3)
current += acpi_create_dmar_drhd_ds_pci_br(current, current += acpi_create_dmar_ds_pci_br(current,
dev->bus->secondary, dev->bus->secondary,
PCI_SLOT(dev->path.pci.devfn), PCI_SLOT(dev->path.pci.devfn),
PCI_FUNC(dev->path.pci.devfn)); PCI_FUNC(dev->path.pci.devfn));

View File

@ -557,7 +557,7 @@ static unsigned long acpi_fill_dmar(unsigned long current)
const unsigned long tmp = current; const unsigned long tmp = current;
current += acpi_create_dmar_drhd(current, 0, 0, gfx_vtbar); current += acpi_create_dmar_drhd(current, 0, 0, gfx_vtbar);
current += acpi_create_dmar_drhd_ds_pci(current, 0, 2, 0); current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
acpi_dmar_drhd_fixup(tmp, current); acpi_dmar_drhd_fixup(tmp, current);
} }
@ -582,9 +582,9 @@ static unsigned long acpi_fill_dmar(unsigned long current)
current += acpi_create_dmar_drhd(current, current += acpi_create_dmar_drhd(current,
DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar); DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
current += acpi_create_dmar_drhd_ds_ioapic(current, current += acpi_create_dmar_ds_ioapic(current,
2, ibdf >> 8, PCI_SLOT(ibdf), PCI_FUNC(ibdf)); 2, ibdf >> 8, PCI_SLOT(ibdf), PCI_FUNC(ibdf));
current += acpi_create_dmar_drhd_ds_msi_hpet(current, current += acpi_create_dmar_ds_msi_hpet(current,
0, hbdf >> 8, PCI_SLOT(hbdf), PCI_FUNC(hbdf)); 0, hbdf >> 8, PCI_SLOT(hbdf), PCI_FUNC(hbdf));
acpi_dmar_drhd_fixup(tmp, current); acpi_dmar_drhd_fixup(tmp, current);