diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c index e03c7f4913..78d5f07045 100644 --- a/src/acpi/acpi.c +++ b/src/acpi/acpi.c @@ -1582,6 +1582,13 @@ void preload_acpi_dsdt(void) cbfs_preload(file); } +static uintptr_t coreboot_rsdp; + +uintptr_t get_coreboot_rsdp(void) +{ + return coreboot_rsdp; +} + unsigned long write_acpi_tables(unsigned long start) { unsigned long current; @@ -1689,6 +1696,7 @@ unsigned long write_acpi_tables(unsigned long start) /* We need at least an RSDP and an RSDT Table */ rsdp = (acpi_rsdp_t *) current; + coreboot_rsdp = (uintptr_t)rsdp; current += sizeof(acpi_rsdp_t); current = acpi_align_current(current); rsdt = (acpi_rsdt_t *) current; diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h index 91da8e01fa..01b12f3a48 100644 --- a/src/commonlib/include/commonlib/coreboot_tables.h +++ b/src/commonlib/include/commonlib/coreboot_tables.h @@ -85,6 +85,7 @@ enum { LB_TAG_BOARD_CONFIG = 0x0040, LB_TAG_ACPI_CNVS = 0x0041, LB_TAG_TYPE_C_INFO = 0x0042, + LB_TAG_ACPI_RSDP = 0x0043, /* The following options are CMOS-related */ LB_TAG_CMOS_OPTION_TABLE = 0x00c8, LB_TAG_OPTION = 0x00c9, @@ -574,4 +575,15 @@ struct lb_tpm_physical_presence { uint8_t tpm_version; /* 1: TPM1.2, 2: TPM2.0 */ uint8_t ppi_version; /* BCD encoded */ } __packed; + + +/* + * Handoff the ACPI RSDP + */ +struct lb_acpi_rsdp { + uint32_t tag; + uint32_t size; + struct lb_uint64 rsdp_pointer; /* Address of the ACPI RSDP */ +}; + #endif diff --git a/src/include/acpi/acpi.h b/src/include/acpi/acpi.h index 05267a142f..dbd5c38f8b 100644 --- a/src/include/acpi/acpi.h +++ b/src/include/acpi/acpi.h @@ -1220,6 +1220,7 @@ typedef struct acpi_einj { } __packed acpi_einj_t; +uintptr_t get_coreboot_rsdp(void); void acpi_create_einj(acpi_einj_t *einj, uintptr_t addr, u8 actions); unsigned long fw_cfg_acpi_tables(unsigned long start); diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c index d0cba80dcc..3ceab3746f 100644 --- a/src/lib/coreboot_table.c +++ b/src/lib/coreboot_table.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include @@ -420,6 +421,16 @@ static unsigned long lb_table_fini(struct lb_header *head) return (unsigned long)rec + rec->size; } +static void lb_add_acpi_rsdp(struct lb_header *head) +{ + struct lb_acpi_rsdp *acpi_rsdp; + struct lb_record *rec = lb_new_record(head); + acpi_rsdp = (struct lb_acpi_rsdp *)rec; + acpi_rsdp->tag = LB_TAG_ACPI_RSDP; + acpi_rsdp->size = sizeof(*acpi_rsdp); + acpi_rsdp->rsdp_pointer = pack_lb64(get_coreboot_rsdp()); +} + size_t write_coreboot_forwarding_table(uintptr_t entry, uintptr_t target) { struct lb_header *head; @@ -523,6 +534,9 @@ static uintptr_t write_coreboot_table(uintptr_t rom_table_end) /* Add all cbmem entries into the coreboot tables. */ cbmem_add_records_to_cbtable(head); + if (CONFIG(HAVE_ACPI_TABLES)) + lb_add_acpi_rsdp(head); + /* Remember where my valid memory ranges are */ return lb_table_fini(head); } diff --git a/tests/lib/coreboot_table-test.c b/tests/lib/coreboot_table-test.c index f9d963de2d..a50dd15d08 100644 --- a/tests/lib/coreboot_table-test.c +++ b/tests/lib/coreboot_table-test.c @@ -210,6 +210,12 @@ void arch_write_tables(uintptr_t coreboot_table) { } +static const uintptr_t ebda_base = 0xf0000; +uintptr_t get_coreboot_rsdp(void) +{ + return ebda_base; +} + struct resource mock_bootmem_ranges[] = { {.base = 0x1000, .size = 0x2000, .flags = LB_MEM_RAM}, {.base = 0x0000, .size = 0x4000, .flags = LB_MEM_RAM}, @@ -476,6 +482,12 @@ static void test_write_tables(void **state) assert_int_equal(ram_code(), board_config->ram_code); assert_int_equal(sku_id(), board_config->sku_id); break; + case LB_TAG_ACPI_RSDP: + assert_int_equal(sizeof(struct lb_acpi_rsdp), record->size); + + const struct lb_acpi_rsdp *acpi_rsdp = (struct lb_acpi_rsdp *)record; + assert_int_equal(ebda_base, unpack_lb64(acpi_rsdp->rsdp_pointer)); + break; default: fail_msg("Unexpected tag found in record. Tag ID: 0x%x", record->tag); }