Skip to content

Commit

Permalink
x86: Move base tables to a writer function
Browse files Browse the repository at this point in the history
Use the new ACPI writer to write the base tables at the start of the area,
moving this code from the x86 implementation.

Signed-off-by: Simon Glass <sjg@chromium.org>
  • Loading branch information
sjg20 committed Jan 25, 2022
1 parent 31c27eb commit 94ba15a
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 96 deletions.
2 changes: 0 additions & 2 deletions arch/x86/lib/acpi_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,8 +521,6 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx,
int ret;
int i;

acpi_setup_base_tables(ctx);

debug("ACPI: * FACS\n");
facs = ctx->current;
acpi_inc_align(ctx, sizeof(struct acpi_facs));
Expand Down
10 changes: 0 additions & 10 deletions include/acpi/acpi_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -678,16 +678,6 @@ void acpi_inc_align(struct acpi_ctx *ctx, uint amount);
*/
int acpi_add_table(struct acpi_ctx *ctx, void *table);

/**
* acpi_setup_base_tables() - Set up base tables - RSDP, RSDT and XSDT
*
* Writes the basic tables to the given context, which must first be set up with
* acpi_setup_ctx().
*
* @ctx: Context to write base tables to
*/
void acpi_setup_base_tables(struct acpi_ctx *ctx);

/**
* acpi_write_rsdp() - Write out an RSDP indicating where the ACPI tables are
*
Expand Down
23 changes: 21 additions & 2 deletions include/dm/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,11 @@ struct acpi_ctx {

/**
* enum acpi_writer_flags_t - flags to use for the ACPI writers
*
* ACPIWF_ALIGN64 - align to 64 bytes after writing this one (default is 16)
*/
enum acpi_writer_flags_t {
ACPIWF_ALIGN64_,
ACPIWF_ALIGN64 = 1 << 0,
};

struct acpi_writer;
Expand Down Expand Up @@ -103,7 +105,7 @@ struct acpi_writer {
int flags;
};

/* Declare a new ACPI table writer */
/* Declare a new ACPI-table writer */
#define ACPI_WRITER(_name, _table, _write, _flags) \
ll_entry_declare(struct acpi_writer, _name, acpi_writer) = { \
.name = #_name, \
Expand All @@ -112,6 +114,10 @@ struct acpi_writer {
.flags = _flags, \
}

/* Get a pointer to a given ACPI-table writer */
#define ACPI_WRITER_GET(_name) \
ll_entry_get(struct acpi_writer, _name, acpi_writer)

/**
* struct acpi_ops - ACPI operations supported by driver model
*/
Expand Down Expand Up @@ -309,6 +315,19 @@ int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry);
*/
void acpi_setup_ctx(struct acpi_ctx *ctx, ulong start);

/**
* acpi_write_one() - Call a single ACPI writer entry
*
* This handles aligning the context afterwards, if the entry flags indicate
* that.
*
* @ctx: ACPI context to use
* @entry: Entry to call
* @return 0 if OK, -ENOENT if this writer produced an empty entry, other -ve
* value on error
*/
int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry);

#endif /* __ACPI__ */

#endif
5 changes: 5 additions & 0 deletions lib/acpi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_device.o
obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_dp.o
obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_table.o
obj-y += acpi_writer.o

# With QEMU the ACPI tables come from there, not from U-Boot
ifndef CONFIG_QEMU
obj-y += base.o
endif
75 changes: 0 additions & 75 deletions lib/acpi/acpi_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,81 +201,6 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table)
return 0;
}

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)
{
/* 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));
ctx->xsdt = ctx->current;
acpi_inc_align(ctx, sizeof(struct acpi_xsdt));

/* clear all table memory */
memset(ctx->base, '\0', ctx->current - ctx->base);

acpi_write_rsdp(ctx->rsdp, ctx->rsdt, ctx->xsdt);
acpi_write_rsdt(ctx->rsdt);
acpi_write_xsdt(ctx->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);
}

void acpi_create_dbg2(struct acpi_dbg2_header *dbg2,
int port_type, int port_subtype,
struct acpi_gen_regaddr *address, u32 address_size,
Expand Down
5 changes: 4 additions & 1 deletion lib/acpi/acpi_writer.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry)
if (ret)
return log_msg_ret("write", ret);

acpi_align(ctx);
if (entry->flags & ACPIWF_ALIGN64)
acpi_align64(ctx);
else
acpi_align(ctx);

return 0;
}
Expand Down
92 changes: 92 additions & 0 deletions lib/acpi/base.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Write base ACPI tables
*
* Copyright 2021 Google LLC
*/

#include <common.h>
#include <acpi/acpi_table.h>
#include <dm/acpi.h>
#include <mapmem.h>
#include <tables_csum.h>

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

static int acpi_write_base(struct acpi_ctx *ctx,
const struct acpi_writer *entry)
{
/* 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));
ctx->xsdt = ctx->current;
acpi_inc_align(ctx, sizeof(struct acpi_xsdt));

/* clear all table memory */
memset(ctx->base, '\0', ctx->current - ctx->base);

acpi_write_rsdp(ctx->rsdp, ctx->rsdt, ctx->xsdt);
acpi_write_rsdt(ctx->rsdt);
acpi_write_xsdt(ctx->xsdt);

return 0;
}
/*
* Per ACPI spec, the FACS table address must be aligned to a 64-byte boundary
* (Windows checks this, but Linux does not).
*
* Use the '0' prefix to put this one first
*/
ACPI_WRITER(0base, NULL, acpi_write_base, ACPIWF_ALIGN64);
17 changes: 11 additions & 6 deletions test/dm/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,15 @@ struct testacpi_plat {
*
* @ctx: Context to set up
*/
static int setup_ctx_and_base_tables(struct acpi_ctx *ctx, ulong start)
static int setup_ctx_and_base_tables(struct unit_test_state *uts,
struct acpi_ctx *ctx, ulong start)
{
struct acpi_writer *entry = ACPI_WRITER_GET(0base);

acpi_setup_ctx(ctx, start);
acpi_setup_base_tables(ctx);

ctx->tab_start = ctx->current;
ut_assertok(acpi_write_one(ctx, entry));

return 0;
}
Expand Down Expand Up @@ -264,7 +269,7 @@ static int dm_test_acpi_write_tables(struct unit_test_state *uts)
ut_assertnonnull(buf);
addr = map_to_sysmem(buf);

setup_ctx_and_base_tables(&ctx, addr);
ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr));
dmar = ctx.current;
ut_assertok(acpi_write_dev_tables(&ctx));

Expand Down Expand Up @@ -339,7 +344,7 @@ static int dm_test_setup_ctx_and_base_tables(struct unit_test_state *uts)
buf = memalign(64, BUF_SIZE);
ut_assertnonnull(buf);
addr = map_to_sysmem(buf);
setup_ctx_and_base_tables(&ctx, addr + 4);
ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr + 4));
ut_asserteq(map_to_sysmem(PTR_ALIGN(buf + 4, 16)), gd_acpi_start());

rsdp = buf + 16;
Expand Down Expand Up @@ -382,7 +387,7 @@ static int dm_test_acpi_cmd_list(struct unit_test_state *uts)
buf = memalign(16, BUF_SIZE);
ut_assertnonnull(buf);
addr = map_to_sysmem(buf);
setup_ctx_and_base_tables(&ctx, addr);
ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr));

ut_assertok(acpi_write_dev_tables(&ctx));

Expand Down Expand Up @@ -424,7 +429,7 @@ static int dm_test_acpi_cmd_dump(struct unit_test_state *uts)
buf = memalign(16, BUF_SIZE);
ut_assertnonnull(buf);
addr = map_to_sysmem(buf);
setup_ctx_and_base_tables(&ctx, addr);
ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr));

ut_assertok(acpi_write_dev_tables(&ctx));

Expand Down

0 comments on commit 94ba15a

Please sign in to comment.