
From: Simon Glass <sjg@chromium.org> For QEMU we want to add new tables to the end of what QEMU provides. Add a function to find the correct place for a new table. Add a function to support this. Signed-off-by: Simon Glass <sjg@chromium.org> --- include/acpi/acpi_table.h | 10 +++++++++ lib/acpi/acpi.c | 25 +++++++++++++++++++++ test/dm/acpi.c | 46 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) diff --git a/include/acpi/acpi_table.h b/include/acpi/acpi_table.h index 6d599455bd6..7a75e3afc49 100644 --- a/include/acpi/acpi_table.h +++ b/include/acpi/acpi_table.h @@ -1288,6 +1288,16 @@ struct acpi_table_header *acpi_find_table(const char *sig); */ void acpi_update_checksum(struct acpi_table_header *header); +/** + * acpi_get_end() - Find the first place where an ACPI table can be added + * + * Searches for the last ACPI table in memory and returns the address + * immediately after it, where a new table coule added + * + * Return: Address at the end of all tables + */ +void *acpi_get_end(void); + #endif /* !__ACPI__*/ #include <asm/acpi_table.h> diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index 44ea5136de4..b13cba1a608 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -277,3 +277,28 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table) return 0; } + +void *acpi_get_end(void) +{ + const struct acpi_table_header *end; + struct acpi_rsdt *rsdt; + struct acpi_xsdt *xsdt; + int i, count; + + count = setup_search(&rsdt, &xsdt); + if (!count) + return NULL; + + end = xsdt ? &xsdt->header : &rsdt->header; + for (i = 0; i < count; i++) { + const struct acpi_table_header *hdr; + + if (xsdt) + hdr = nomap_sysmem(xsdt->entry[i], 0); + else + hdr = nomap_sysmem(rsdt->entry[i], 0); + end = max(hdr, end); + } + + return (void *)end + end->length; +} diff --git a/test/dm/acpi.c b/test/dm/acpi.c index bb37e7da88f..6c157de0e3b 100644 --- a/test/dm/acpi.c +++ b/test/dm/acpi.c @@ -853,3 +853,49 @@ static int dm_test_acpi_offsets(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_acpi_offsets, 0); + +/* Test finding the end of the ACPI tables */ +static int dm_test_acpi_get_end(struct unit_test_state *uts) +{ + struct acpi_ctx ctx; + ulong acpi_start, addr; + void *buf; + struct acpi_table_header *table1, *table2, *table3; + void *ptr; + + /* Keep reference to original ACPI tables */ + acpi_start = gd_acpi_start(); + + /* Setup new ACPI tables */ + addr = 0; + buf = map_sysmem(addr, BUF_SIZE); + ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr)); + table3 = dm_test_write_test_table(&ctx, 3); + table1 = dm_test_write_test_table(&ctx, 1); + table2 = dm_test_write_test_table(&ctx, 2); + + ptr = acpi_get_end(); + ut_asserteq(0x288 + 0x24, ptr - buf); + + run_command("acpi list", 0); + ut_assert_nextline("Name Base Size Detail"); + ut_assert_nextlinen("--"); + ut_assert_nextline("RSDP 0 24 v02 U-BOOT"); + ut_assert_nextline( + "RSDT 30 30 v01 U-BOOT U-BOOTBL 20250101 INTL 0"); + ut_assert_nextline( + "XSDT e0 3c v01 U-BOOT U-BOOTBL 20250101 INTL 0"); + ut_assert_nextline( + "TST3 240 24 v00 U-BOOT U-BOOTBL 20250101 INTL 0"); + ut_assert_nextline( + "TST1 264 24 v00 U-BOOT U-BOOTBL 20250101 INTL 0"); + ut_assert_nextline( + "TST2 288 24 v00 U-BOOT U-BOOTBL 20250101 INTL 0"); + + /* Restore previous ACPI tables */ + gd_set_acpi_start(acpi_start); + unmap_sysmem(buf); + + return 0; +} +DM_TEST(dm_test_acpi_get_end, 0); -- 2.43.0