acpi: Provide a way to locate the end of the ACPI tables

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>
This commit is contained in:
Simon Glass
2025-07-06 16:56:30 +02:00
parent 34203312d0
commit 3354f95e7e
3 changed files with 81 additions and 0 deletions

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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);