acpi.c contains architectural specific things like IOAPIC, legacy IRQ, DMAR, HPET, ... all which require the presence of architectural headers. Instead of littering the code with #if ENV_X86 move the functions to different compilation units. Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Change-Id: I5083b26c0d4cc6764b4e3cb0ff586797cae7e3af Reviewed-on: https://review.coreboot.org/c/coreboot/+/76008 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
197 lines
5.2 KiB
C
197 lines
5.2 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
|
|
#include <acpi/acpi.h>
|
|
#include <arch/ioapic.h>
|
|
#include <cpu/cpu.h>
|
|
#include <version.h>
|
|
|
|
void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags,
|
|
unsigned long (*acpi_fill_dmar)(unsigned long))
|
|
{
|
|
acpi_header_t *header = &(dmar->header);
|
|
unsigned long current = (unsigned long)dmar + sizeof(acpi_dmar_t);
|
|
|
|
memset((void *)dmar, 0, sizeof(acpi_dmar_t));
|
|
|
|
if (!header)
|
|
return;
|
|
|
|
/* Fill out header fields. */
|
|
memcpy(header->signature, "DMAR", 4);
|
|
memcpy(header->oem_id, OEM_ID, 6);
|
|
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
|
memcpy(header->asl_compiler_id, ASLC, 4);
|
|
|
|
header->asl_compiler_revision = asl_revision;
|
|
header->length = sizeof(acpi_dmar_t);
|
|
header->revision = get_acpi_table_revision(DMAR);
|
|
|
|
dmar->host_address_width = cpu_phys_address_size() - 1;
|
|
dmar->flags = flags;
|
|
|
|
current = acpi_fill_dmar(current);
|
|
|
|
/* (Re)calculate length and checksum. */
|
|
header->length = current - (unsigned long)dmar;
|
|
header->checksum = acpi_checksum((void *)dmar, header->length);
|
|
}
|
|
|
|
unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags,
|
|
u16 segment, u64 bar)
|
|
{
|
|
dmar_entry_t *drhd = (dmar_entry_t *)current;
|
|
memset(drhd, 0, sizeof(*drhd));
|
|
drhd->type = DMAR_DRHD;
|
|
drhd->length = sizeof(*drhd); /* will be fixed up later */
|
|
drhd->flags = flags;
|
|
drhd->segment = segment;
|
|
drhd->bar = bar;
|
|
|
|
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,
|
|
u16 segment)
|
|
{
|
|
dmar_atsr_entry_t *atsr = (dmar_atsr_entry_t *)current;
|
|
memset(atsr, 0, sizeof(*atsr));
|
|
atsr->type = DMAR_ATSR;
|
|
atsr->length = sizeof(*atsr); /* will be fixed up later */
|
|
atsr->flags = flags;
|
|
atsr->segment = segment;
|
|
|
|
return atsr->length;
|
|
}
|
|
|
|
unsigned long acpi_create_dmar_rhsa(unsigned long current, u64 base_addr,
|
|
u32 proximity_domain)
|
|
{
|
|
dmar_rhsa_entry_t *rhsa = (dmar_rhsa_entry_t *)current;
|
|
memset(rhsa, 0, sizeof(*rhsa));
|
|
rhsa->type = DMAR_RHSA;
|
|
rhsa->length = sizeof(*rhsa);
|
|
rhsa->base_address = base_addr;
|
|
rhsa->proximity_domain = proximity_domain;
|
|
|
|
return rhsa->length;
|
|
}
|
|
|
|
unsigned long acpi_create_dmar_andd(unsigned long current, u8 device_number,
|
|
const char *device_name)
|
|
{
|
|
dmar_andd_entry_t *andd = (dmar_andd_entry_t *)current;
|
|
int andd_len = sizeof(dmar_andd_entry_t) + strlen(device_name) + 1;
|
|
memset(andd, 0, andd_len);
|
|
andd->type = DMAR_ANDD;
|
|
andd->length = andd_len;
|
|
andd->device_number = device_number;
|
|
memcpy(&andd->device_name, device_name, strlen(device_name));
|
|
|
|
return andd->length;
|
|
}
|
|
|
|
unsigned long acpi_create_dmar_satc(unsigned long current, u8 flags, u16 segment)
|
|
{
|
|
dmar_satc_entry_t *satc = (dmar_satc_entry_t *)current;
|
|
int satc_len = sizeof(dmar_satc_entry_t);
|
|
memset(satc, 0, satc_len);
|
|
satc->type = DMAR_SATC;
|
|
satc->length = satc_len;
|
|
satc->flags = flags;
|
|
satc->segment_number = segment;
|
|
|
|
return satc->length;
|
|
}
|
|
|
|
void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current)
|
|
{
|
|
dmar_entry_t *drhd = (dmar_entry_t *)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)
|
|
{
|
|
dmar_atsr_entry_t *atsr = (dmar_atsr_entry_t *)base;
|
|
atsr->length = current - base;
|
|
}
|
|
|
|
void acpi_dmar_satc_fixup(unsigned long base, unsigned long current)
|
|
{
|
|
dmar_satc_entry_t *satc = (dmar_satc_entry_t *)base;
|
|
satc->length = current - base;
|
|
}
|
|
|
|
static unsigned long acpi_create_dmar_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, 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_ds_pci_br(unsigned long current, u8 bus,
|
|
u8 dev, u8 fn)
|
|
{
|
|
return acpi_create_dmar_ds(current,
|
|
SCOPE_PCI_SUB, 0, bus, dev, fn);
|
|
}
|
|
|
|
unsigned long acpi_create_dmar_ds_pci(unsigned long current, u8 bus,
|
|
u8 dev, u8 fn)
|
|
{
|
|
return acpi_create_dmar_ds(current,
|
|
SCOPE_PCI_ENDPOINT, 0, bus, dev, fn);
|
|
}
|
|
|
|
unsigned long acpi_create_dmar_ds_ioapic(unsigned long current,
|
|
u8 enumeration_id, u8 bus, u8 dev, u8 fn)
|
|
{
|
|
return acpi_create_dmar_ds(current,
|
|
SCOPE_IOAPIC, enumeration_id, bus, dev, fn);
|
|
}
|
|
|
|
unsigned long acpi_create_dmar_ds_ioapic_from_hw(unsigned long current,
|
|
u32 addr, u8 bus, u8 dev, u8 fn)
|
|
{
|
|
u8 enumeration_id = get_ioapic_id((void *)(uintptr_t)addr);
|
|
return acpi_create_dmar_ds(current,
|
|
SCOPE_IOAPIC, enumeration_id, bus, dev, fn);
|
|
}
|
|
|
|
unsigned long acpi_create_dmar_ds_msi_hpet(unsigned long current,
|
|
u8 enumeration_id, u8 bus, u8 dev, u8 fn)
|
|
{
|
|
return acpi_create_dmar_ds(current,
|
|
SCOPE_MSI_HPET, enumeration_id, bus, dev, fn);
|
|
}
|