diff options
author | Simon Glass <sjg@chromium.org> | 2020-04-26 09:19:51 -0600 |
---|---|---|
committer | Bin Meng <bmeng.cn@gmail.com> | 2020-04-30 17:16:12 +0800 |
commit | 7e586f69070db02171dca77f41adbcccd6394b33 (patch) | |
tree | e3215822437a057ffbd20f8eefb6790ac22adb84 /lib/acpi | |
parent | 29b351122ed23124f70473a411c65074d5a61146 (diff) |
acpi: Put table-setup code in its own function
We always write three basic tables to ACPI at the start. Move this into
its own function, along with acpi_fill_header(), so we can write a test
for this code.
Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'lib/acpi')
-rw-r--r-- | lib/acpi/acpi_table.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c index 4e354d313f..59980bc0e1 100644 --- a/lib/acpi/acpi_table.c +++ b/lib/acpi/acpi_table.c @@ -181,3 +181,85 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table) return 0; } + +static void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, + struct acpi_xsdt *xsdt) +{ + memset(rsdp, 0, sizeof(struct acpi_rsdp)); + + memcpy(rsdp->signature, RSDP_SIG, 8); + memcpy(rsdp->oem_id, OEM_ID, 6); + + rsdp->length = sizeof(struct acpi_rsdp); + rsdp->rsdt_address = map_to_sysmem(rsdt); + + rsdp->xsdt_address = map_to_sysmem(xsdt); + rsdp->revision = ACPI_RSDP_REV_ACPI_2_0; + + /* Calculate checksums */ + rsdp->checksum = table_compute_checksum(rsdp, 20); + rsdp->ext_checksum = table_compute_checksum(rsdp, + sizeof(struct acpi_rsdp)); +} + +static void acpi_write_rsdt(struct acpi_rsdt *rsdt) +{ + struct acpi_table_header *header = &rsdt->header; + + /* Fill out header fields */ + acpi_fill_header(header, "RSDT"); + header->length = sizeof(struct acpi_rsdt); + header->revision = 1; + + /* Entries are filled in later, we come with an empty set */ + + /* Fix checksum */ + header->checksum = table_compute_checksum(rsdt, + sizeof(struct acpi_rsdt)); +} + +static void acpi_write_xsdt(struct acpi_xsdt *xsdt) +{ + struct acpi_table_header *header = &xsdt->header; + + /* Fill out header fields */ + acpi_fill_header(header, "XSDT"); + header->length = sizeof(struct acpi_xsdt); + header->revision = 1; + + /* Entries are filled in later, we come with an empty set */ + + /* Fix checksum */ + header->checksum = table_compute_checksum(xsdt, + sizeof(struct acpi_xsdt)); +} + +void acpi_setup_base_tables(struct acpi_ctx *ctx, void *start) +{ + struct acpi_xsdt *xsdt; + + ctx->current = start; + + /* Align ACPI tables to 16 byte */ + acpi_align(ctx); + + /* We need at least an RSDP and an RSDT Table */ + ctx->rsdp = ctx->current; + acpi_inc_align(ctx, sizeof(struct acpi_rsdp)); + ctx->rsdt = ctx->current; + acpi_inc_align(ctx, sizeof(struct acpi_rsdt)); + xsdt = ctx->current; + acpi_inc_align(ctx, sizeof(struct acpi_xsdt)); + + /* clear all table memory */ + memset((void *)start, '\0', ctx->current - start); + + acpi_write_rsdp(ctx->rsdp, ctx->rsdt, xsdt); + acpi_write_rsdt(ctx->rsdt); + acpi_write_xsdt(xsdt); + /* + * Per ACPI spec, the FACS table address must be aligned to a 64 byte + * boundary (Windows checks this, but Linux does not). + */ + acpi_align64(ctx); +} |