
Write MADT in common code and let the SoC fill out the body by calling acpi_fill_madt() which must be implemented at SoC level.
Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Cc: Simon Glass sjg@chromium.org Cc: Bin Meng bmeng.cn@gmail.com --- Changelog v3: - Pass ACPI context to acpi_fill_madt
--- arch/sandbox/lib/Makefile | 9 +++--- arch/sandbox/lib/acpi_table.c | 7 +++++ arch/x86/cpu/intel_common/acpi.c | 21 +++++++++----- arch/x86/cpu/tangier/acpi.c | 7 ++++- arch/x86/include/asm/acpi_table.h | 3 +- arch/x86/lib/acpi_table.c | 47 ++++++------------------------- include/acpi/acpi_table.h | 11 ++++++++ lib/acpi/acpi_table.c | 31 ++++++++++++++++++++ 8 files changed, 84 insertions(+), 52 deletions(-) create mode 100644 arch/sandbox/lib/acpi_table.c
diff --git a/arch/sandbox/lib/Makefile b/arch/sandbox/lib/Makefile index d7d15a50bb..5d7beb250c 100644 --- a/arch/sandbox/lib/Makefile +++ b/arch/sandbox/lib/Makefile @@ -5,7 +5,8 @@ # (C) Copyright 2002-2006 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-obj-y += fdt_fixup.o interrupts.o -obj-$(CONFIG_PCI) += pci_io.o -obj-$(CONFIG_CMD_BOOTM) += bootm.o -obj-$(CONFIG_CMD_BOOTZ) += bootm.o +obj-y += fdt_fixup.o interrupts.o +obj-$(CONFIG_PCI) += pci_io.o +obj-$(CONFIG_CMD_BOOTM) += bootm.o +obj-$(CONFIG_CMD_BOOTZ) += bootm.o +obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_table.o diff --git a/arch/sandbox/lib/acpi_table.c b/arch/sandbox/lib/acpi_table.c new file mode 100644 index 0000000000..e74e8f83d4 --- /dev/null +++ b/arch/sandbox/lib/acpi_table.c @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include <acpi/acpi_table.h> + +void *acpi_fill_madt(struct acpi_madt *madt, struct acpi_ctx *ctx) +{ + return ctx->current; +} diff --git a/arch/x86/cpu/intel_common/acpi.c b/arch/x86/cpu/intel_common/acpi.c index 29676b4abf..a0179db395 100644 --- a/arch/x86/cpu/intel_common/acpi.c +++ b/arch/x86/cpu/intel_common/acpi.c @@ -19,6 +19,7 @@ #include <asm/global_data.h> #include <asm/intel_acpi.h> #include <asm/ioapic.h> +#include <asm/lapic.h> #include <asm/mpspec.h> #include <asm/smm.h> #include <asm/turbo.h> @@ -80,33 +81,39 @@ static int acpi_sci_irq(void) return sci_irq; }
-static unsigned long acpi_madt_irq_overrides(unsigned long current) +static void *acpi_madt_irq_overrides(void *current) { int sci = acpi_sci_irq(); u16 flags = MP_IRQ_TRIGGER_LEVEL;
- if (sci < 0) - return log_msg_ret("sci irq", sci); + if (sci < 0) { + log_err("sci irq %d", sci); + return current; + }
/* INT_SRC_OVR */ - current += acpi_create_madt_irqoverride((void *)current, 0, 0, 2, 0); + current += acpi_create_madt_irqoverride(current, 0, 0, 2, 0);
flags |= arch_madt_sci_irq_polarity(sci);
/* SCI */ current += - acpi_create_madt_irqoverride((void *)current, 0, sci, sci, flags); + acpi_create_madt_irqoverride(current, 0, sci, sci, flags);
return current; }
-u32 acpi_fill_madt(u32 current) +void *acpi_fill_madt(struct acpi_madt *madt, struct acpi_ctx *ctx) { + void *current = ctx->current; + madt->lapic_addr = LAPIC_DEFAULT_BASE; + madt->flags = ACPI_MADT_PCAT_COMPAT; + /* Local APICs */ current += acpi_create_madt_lapics(current);
/* IOAPIC */ - current += acpi_create_madt_ioapic((void *)current, 2, IO_APIC_ADDR, 0); + current += acpi_create_madt_ioapic(current, 2, IO_APIC_ADDR, 0);
return acpi_madt_irq_overrides(current); } diff --git a/arch/x86/cpu/tangier/acpi.c b/arch/x86/cpu/tangier/acpi.c index 1c73a9dbfe..f476825ccb 100644 --- a/arch/x86/cpu/tangier/acpi.c +++ b/arch/x86/cpu/tangier/acpi.c @@ -10,6 +10,7 @@ #include <mapmem.h> #include <acpi/acpi_table.h> #include <asm/ioapic.h> +#include <asm/lapic.h> #include <asm/mpspec.h> #include <asm/tables.h> #include <asm/arch/global_nvs.h> @@ -31,8 +32,12 @@ void acpi_fill_fadt(struct acpi_fadt *fadt) fadt->minor_revision = 2; }
-u32 acpi_fill_madt(u32 current) +void *acpi_fill_madt(struct acpi_madt *madt, struct acpi_ctx *ctx) { + void *current = ctx->current; + madt->lapic_addr = LAPIC_DEFAULT_BASE; + madt->flags = ACPI_MADT_PCAT_COMPAT; + current += acpi_create_madt_lapics(current);
current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current, diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h index 3988898f66..3254bbc380 100644 --- a/arch/x86/include/asm/acpi_table.h +++ b/arch/x86/include/asm/acpi_table.h @@ -24,14 +24,13 @@ struct acpi_table_header;
/* These can be used by the target port */
-int acpi_create_madt_lapics(u32 current); +int acpi_create_madt_lapics(void *current); int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id, u32 addr, u32 gsi_base); int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride, u8 bus, u8 source, u32 gsirq, u16 flags); int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi, u8 cpu, u16 flags, u8 lint); -u32 acpi_fill_madt(u32 current); int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base, u16 seg_nr, u8 start, u8 end);
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index ff02ce80d1..02d5c0fe8f 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -40,7 +40,7 @@ static int acpi_create_madt_lapic(struct acpi_madt_lapic *lapic, return lapic->length; }
-int acpi_create_madt_lapics(u32 current) +int acpi_create_madt_lapics(void *current) { struct udevice *dev; int total_length = 0; @@ -100,23 +100,27 @@ int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi, return lapic_nmi->length; }
-static int acpi_create_madt_irq_overrides(u32 current) +static int acpi_create_madt_irq_overrides(void *current) { struct acpi_madt_irqoverride *irqovr; u16 sci_flags = MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH; int length = 0;
- irqovr = (void *)current; + irqovr = current; length += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0);
- irqovr = (void *)(current + length); + irqovr = current + length; length += acpi_create_madt_irqoverride(irqovr, 0, 9, 9, sci_flags);
return length; }
-__weak u32 acpi_fill_madt(u32 current) +__weak void *acpi_fill_madt(struct acpi_madt *madt, struct acpi_ctx *ctx) { + void *current = ctx->current; + madt->lapic_addr = LAPIC_DEFAULT_BASE; + madt->flags = ACPI_MADT_PCAT_COMPAT; + current += acpi_create_madt_lapics(current);
current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current, @@ -127,39 +131,6 @@ __weak u32 acpi_fill_madt(u32 current) return current; }
-int acpi_write_madt(struct acpi_ctx *ctx, const struct acpi_writer *entry) -{ - struct acpi_table_header *header; - struct acpi_madt *madt; - u32 current; - - madt = ctx->current; - - memset(madt, '\0', sizeof(struct acpi_madt)); - header = &madt->header; - - /* Fill out header fields */ - acpi_fill_header(header, "APIC"); - header->length = sizeof(struct acpi_madt); - header->revision = ACPI_MADT_REV_ACPI_3_0; - - madt->lapic_addr = LAPIC_DEFAULT_BASE; - madt->flags = ACPI_MADT_PCAT_COMPAT; - - current = (u32)madt + sizeof(struct acpi_madt); - current = acpi_fill_madt(current); - - /* (Re)calculate length and checksum */ - header->length = current - (u32)madt; - - header->checksum = table_compute_checksum((void *)madt, header->length); - acpi_add_table(ctx, madt); - acpi_inc(ctx, madt->header.length); - - return 0; -} -ACPI_WRITER(5x86, NULL, acpi_write_madt, 0); - /** * acpi_create_tcpa() - Create a TCPA table * diff --git a/include/acpi/acpi_table.h b/include/acpi/acpi_table.h index aa79e61084..1a49578b6e 100644 --- a/include/acpi/acpi_table.h +++ b/include/acpi/acpi_table.h @@ -963,6 +963,17 @@ int acpi_fill_csrt(struct acpi_ctx *ctx); */ void acpi_fill_fadt(struct acpi_fadt *fadt);
+/** + * acpi_fill_madt() - Fill out the body of the MADT + * + * Must be implemented in SoC specific code. + * + * @madt: The MADT to update + * @ctx: ACPI context to write MADT sub-tables to + * @return Pointer to the end of tables, where the next tables can be written + */ +void *acpi_fill_madt(struct acpi_madt *madt, struct acpi_ctx *ctx); + /** * acpi_get_rsdp_addr() - get ACPI RSDP table address * diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c index 1b25fe1b9c..d7deed2df1 100644 --- a/lib/acpi/acpi_table.c +++ b/lib/acpi/acpi_table.c @@ -244,6 +244,37 @@ int acpi_write_fadt(struct acpi_ctx *ctx, const struct acpi_writer *entry)
ACPI_WRITER(5fadt, "FADT", acpi_write_fadt, 0);
+int acpi_write_madt(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + struct acpi_table_header *header; + struct acpi_madt *madt; + void *current; + + madt = ctx->current; + + memset(madt, '\0', sizeof(struct acpi_madt)); + header = &madt->header; + + /* Fill out header fields */ + acpi_fill_header(header, "APIC"); + header->length = sizeof(struct acpi_madt); + header->revision = ACPI_MADT_REV_ACPI_3_0; + + acpi_inc(ctx, sizeof(struct acpi_madt)); + current = acpi_fill_madt(madt, ctx); + + /* (Re)calculate length and checksum */ + header->length = (uintptr_t)current - (uintptr_t)madt; + + header->checksum = table_compute_checksum((void *)madt, header->length); + acpi_add_table(ctx, madt); + ctx->current = (void *)madt + madt->header.length; + + return 0; +} + +ACPI_WRITER(5madt, "MADT", acpi_write_madt, 0); + void acpi_create_dbg2(struct acpi_dbg2_header *dbg2, int port_type, int port_subtype, struct acpi_gen_regaddr *address, u32 address_size,