[PATCH 2/3] cmd: acpi: fix acpi list command
Simon Glass
sjg at chromium.org
Sun Nov 12 04:08:40 CET 2023
Hi Heinrich,
On Sat, 11 Nov 2023 at 06:42, Heinrich Schuchardt
<heinrich.schuchardt at canonical.com> wrote:
>
> ACPI tables may comprise either RSDT, XSDT, or both. The current code fails
> to check the presence of the RSDT table before accessing it. This leads to
> an exception if the RSDT table is not provided.
>
> The XSDT table takes precedence over the RSDT table.
>
> Addresses in the XSDT table are 64-bit. Adjust the output accordingly.
>
> The ACPI specification does not require that the sequence of tables are the
> same in XSDT and RSDT. Comparing entries with the same index makes no
> sense.
Does it make any sense to have different sequences? Have you seen that
in the wild?
>
> The FACS table header does not provide revision information. Correct the
> description of dump_hdr().
>
> Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
> ---
> cmd/acpi.c | 48 +++++++++++++++++++++++++++++-------------------
> 1 file changed, 29 insertions(+), 19 deletions(-)
>
> diff --git a/cmd/acpi.c b/cmd/acpi.c
> index 7e397d1a74..d02108d821 100644
> --- a/cmd/acpi.c
> +++ b/cmd/acpi.c
> @@ -17,7 +17,8 @@ DECLARE_GLOBAL_DATA_PTR;
> /**
> * dump_hdr() - Dump an ACPI header
> *
> - * If the header is for FACS then it shows the revision information as well
> + * Except for the Firmware ACPI Control Structure (FACS)
> + * additionally show the revision information.
> *
> * @hdr: ACPI header to dump
> */
> @@ -25,7 +26,7 @@ static void dump_hdr(struct acpi_table_header *hdr)
> {
> bool has_hdr = memcmp(hdr->signature, "FACS", ACPI_NAME_LEN);
>
> - printf("%.*s %08lx %5x", ACPI_NAME_LEN, hdr->signature,
> + printf("%.*s %016lx %5x", ACPI_NAME_LEN, hdr->signature,
> (ulong)map_to_sysmem(hdr), hdr->length);
> if (has_hdr) {
> printf(" v%02d %.6s %.8s %x %.4s %x\n", hdr->revision,
> @@ -43,7 +44,7 @@ static int dump_table_name(const char *sig)
> hdr = acpi_find_table(sig);
> if (!hdr)
> return -ENOENT;
> - printf("%.*s @ %08lx\n", ACPI_NAME_LEN, hdr->signature,
> + printf("%.*s @ %016lx\n", ACPI_NAME_LEN, hdr->signature,
We really don't want 16 hex digits of output. It just isn't readable.
Should we add a way of writing a hex number with an underscore between
digits 8 and 9?
12345678_3846263d
Better I think (at least for now) would be to use %10lx and live with
the column misalignment in the unlikely event that very large
addresses are used.
> (ulong)map_to_sysmem(hdr));
> print_buffer(0, hdr, 1, hdr->length, 0);
>
> @@ -62,26 +63,34 @@ static int list_rsdt(struct acpi_rsdt *rsdt, struct acpi_xsdt *xsdt)
> {
> int len, i, count;
>
> - dump_hdr(&rsdt->header);
> - if (xsdt)
> + if (rsdt)
> + dump_hdr(&rsdt->header);
> + if (xsdt) {
> dump_hdr(&xsdt->header);
> - len = rsdt->header.length - sizeof(rsdt->header);
> - count = len / sizeof(u32);
> + len = xsdt->header.length - sizeof(xsdt->header);
> + count = len / sizeof(u64);
> + } else if (rsdt) {
> + len = rsdt->header.length - sizeof(rsdt->header);
> + count = len / sizeof(u32);
> + } else {
> + return 0;
> + }
> +
> for (i = 0; i < count; i++) {
> struct acpi_table_header *hdr;
>
> - if (!rsdt->entry[i])
> - break;
> - hdr = map_sysmem(rsdt->entry[i], 0);
> + if (xsdt) {
> + if (!xsdt->entry[i])
> + break;
> + hdr = map_sysmem(xsdt->entry[i], 0);
> + } else {
> + if (!rsdt->entry[i])
> + break;
> + hdr = map_sysmem(rsdt->entry[i], 0);
> + }
> dump_hdr(hdr);
> if (!memcmp(hdr->signature, "FACP", ACPI_NAME_LEN))
> list_fadt((struct acpi_fadt *)hdr);
> - if (xsdt) {
> - if (xsdt->entry[i] != rsdt->entry[i]) {
> - printf(" (xsdt mismatch %llx)\n",
> - xsdt->entry[i]);
> - }
> - }
> }
>
> return 0;
> @@ -92,10 +101,11 @@ static int list_rsdp(struct acpi_rsdp *rsdp)
> struct acpi_rsdt *rsdt;
> struct acpi_xsdt *xsdt;
>
> - printf("RSDP %08lx %5x v%02d %.6s\n", (ulong)map_to_sysmem(rsdp),
> + printf("RSDP %016lx %5x v%02d %.6s\n", (ulong)map_to_sysmem(rsdp),
> rsdp->length, rsdp->revision, rsdp->oem_id);
> rsdt = map_sysmem(rsdp->rsdt_address, 0);
> xsdt = map_sysmem(rsdp->xsdt_address, 0);
> +
> list_rsdt(rsdt, xsdt);
>
> return 0;
> @@ -111,8 +121,8 @@ static int do_acpi_list(struct cmd_tbl *cmdtp, int flag, int argc,
> printf("No ACPI tables present\n");
> return 0;
> }
> - printf("Name Base Size Detail\n");
> - printf("---- -------- ----- ------\n");
> + printf("Name Base Size Detail\n"
> + "---- ---------------- ----- ----------------------------\n");
> list_rsdp(rsdp);
>
> return 0;
> --
> 2.40.1
>
Regards,
Simon
More information about the U-Boot
mailing list