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:
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user