From 6c4751d5965c3c8d87b21c39efd66ccc26ff5823 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Mon, 26 Oct 2015 12:03:54 +0100 Subject: [PATCH] ACPI: Add functions for DMAR I/O-APIC and HPET entries Refactor acpi_create_dmar_drhd_ds_pci() and add similar functions for I/O-APICs and MSI capable HPETs. We violate the spec [1] here, which talks about 16-bit source-ids spread over start_bus and path entries. Intel actually uses bus/dev/fn identification for those devices too, and so do we. [1] Intel Virtualization Technology for Directed I/O Architecture Specification Document-Number: D51397 Change-Id: I0fce075961762610d44b5552b71e010511871fc2 Signed-off-by: Nico Huber Reviewed-on: http://review.coreboot.org/12192 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie Reviewed-by: Patrick Georgi --- src/arch/x86/acpi.c | 41 +++++++++++++++++++++++++------- src/arch/x86/include/arch/acpi.h | 10 ++++++-- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/arch/x86/acpi.c b/src/arch/x86/acpi.c index 1570dc8d07..55995c9542 100644 --- a/src/arch/x86/acpi.c +++ b/src/arch/x86/acpi.c @@ -436,20 +436,45 @@ void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current) drhd->length = current - base; } -unsigned long acpi_create_dmar_drhd_ds_pci(unsigned long current, u8 segment, - u8 dev, u8 fn) +static unsigned long acpi_create_dmar_drhd_ds(unsigned long current, + enum dev_scope_type type, u8 enumeration_id, u8 bus, u8 dev, u8 fn) { + /* we don't support longer paths yet */ + const size_t dev_scope_length = sizeof(dev_scope_t) + 2; + dev_scope_t *ds = (dev_scope_t *)current; - memset(ds, 0, sizeof(*ds)); - ds->type = SCOPE_PCI_ENDPOINT; - ds->length = sizeof(*ds) + 2; /* we don't support longer paths yet */ - ds->start_bus = segment; - ds->path[0].dev = dev; - ds->path[0].fn = fn; + memset(ds, 0, dev_scope_length); + ds->type = type; + ds->length = dev_scope_length; + ds->enumeration = enumeration_id; + ds->start_bus = bus; + ds->path[0].dev = dev; + ds->path[0].fn = fn; return ds->length; } +unsigned long acpi_create_dmar_drhd_ds_pci(unsigned long current, u8 bus, + u8 dev, u8 fn) +{ + return acpi_create_dmar_drhd_ds(current, + SCOPE_PCI_ENDPOINT, 0, bus, dev, fn); +} + +unsigned long acpi_create_dmar_drhd_ds_ioapic(unsigned long current, + u8 enumeration_id, u8 bus, u8 dev, u8 fn) +{ + return acpi_create_dmar_drhd_ds(current, + SCOPE_IOAPIC, enumeration_id, bus, dev, fn); +} + +unsigned long acpi_create_dmar_drhd_ds_msi_hpet(unsigned long current, + u8 enumeration_id, u8 bus, u8 dev, u8 fn) +{ + return acpi_create_dmar_drhd_ds(current, + SCOPE_MSI_HPET, enumeration_id, bus, dev, fn); +} + /* http://h21007.www2.hp.com/portal/download/files/unprot/Itanium/slit.pdf */ void acpi_create_slit(acpi_slit_t *slit, unsigned long (*acpi_fill_slit)(unsigned long current)) diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h index 2a7ea79e01..66e11006dc 100644 --- a/src/arch/x86/include/arch/acpi.h +++ b/src/arch/x86/include/arch/acpi.h @@ -553,8 +553,14 @@ void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags, unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags, u16 segment, u32 bar); void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current); -unsigned long acpi_create_dmar_drhd_ds_pci(unsigned long current, u8 segment, - u8 dev, u8 fn); +unsigned long acpi_create_dmar_drhd_ds_pci(unsigned long current, + u8 bus, u8 dev, u8 fn); +unsigned long acpi_create_dmar_drhd_ds_ioapic(unsigned long current, + u8 enumeration_id, + u8 bus, u8 dev, u8 fn); +unsigned long acpi_create_dmar_drhd_ds_msi_hpet(unsigned long current, + u8 enumeration_id, + u8 bus, u8 dev, u8 fn); void acpi_write_hest(acpi_hest_t *hest, unsigned long (*acpi_fill_hest)(acpi_hest_t *hest));