[PATCH v3 13/30] acpi: acpi_table: Support ACPI 2.0 platforms
Peter Robinson
pbrobinson at gmail.com
Wed Sep 11 11:45:30 CEST 2024
> On platforms that do not have usable DRAM below 4GiB, like QEMU sbsa,
> the RSDT cannot be used. Allow both RSDT and XSDT to be null and only
> fill those tables that are present in acpi_add_table().
I'm not sure what ACPI 2.0 from the subject has to do with the above,
eg ACPI only started supporting aarch64 with ACPI 5.1
> Fixes a crash on QEMU sbsa.
>
> Signed-off-by: Patrick Rudolph <patrick.rudolph at 9elements.com>
> Cc: Simon Glass <sjg at chromium.org>
> Cc: Tom Rini <trini at konsulko.com>
> ---
> lib/acpi/acpi_table.c | 95 ++++++++++++++++++++++++++-----------------
> 1 file changed, 57 insertions(+), 38 deletions(-)
>
> diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c
> index 4f5cfe522c..8aab41212a 100644
> --- a/lib/acpi/acpi_table.c
> +++ b/lib/acpi/acpi_table.c
> @@ -157,51 +157,70 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table)
> struct acpi_rsdt *rsdt;
> struct acpi_xsdt *xsdt;
>
> - /* The RSDT is mandatory while the XSDT is not */
> - rsdt = ctx->rsdt;
> -
> - /* This should always be MAX_ACPI_TABLES */
> - entries_num = ARRAY_SIZE(rsdt->entry);
> -
> - for (i = 0; i < entries_num; i++) {
> - if (rsdt->entry[i] == 0)
> - break;
> - }
> -
> - if (i >= entries_num) {
> - log_err("ACPI: Error: too many tables\n");
> - return -E2BIG;
> - }
> + /* On legacy x86 platforms the RSDT is mandatory while the XSDT is not.
> + * On other platforms there might be no memory below 4GiB, thus RSDT is NULL.
> + */
> + if (ctx->rsdt) {
> + rsdt = ctx->rsdt;
>
> - /* Add table to the RSDT */
> - rsdt->entry[i] = nomap_to_sysmem(table);
> + /* This should always be MAX_ACPI_TABLES */
> + entries_num = ARRAY_SIZE(rsdt->entry);
>
> - /* Fix RSDT length or the kernel will assume invalid entries */
> - rsdt->header.length = sizeof(struct acpi_table_header) +
> - (sizeof(u32) * (i + 1));
> + for (i = 0; i < entries_num; i++) {
> + if (rsdt->entry[i] == 0)
> + break;
> + }
>
> - /* Re-calculate checksum */
> - rsdt->header.checksum = 0;
> - rsdt->header.checksum = table_compute_checksum((u8 *)rsdt,
> - rsdt->header.length);
> + if (i >= entries_num) {
> + log_err("ACPI: Error: too many tables\n");
> + return -E2BIG;
> + }
>
> - /*
> - * And now the same thing for the XSDT. We use the same index as for
> - * now we want the XSDT and RSDT to always be in sync in U-Boot
> - */
> - xsdt = ctx->xsdt;
> + /* Add table to the RSDT */
> + rsdt->entry[i] = nomap_to_sysmem(table);
>
> - /* Add table to the XSDT */
> - xsdt->entry[i] = nomap_to_sysmem(table);
> + /* Fix RSDT length or the kernel will assume invalid entries */
> + rsdt->header.length = sizeof(struct acpi_table_header) +
> + (sizeof(u32) * (i + 1));
>
> - /* Fix XSDT length */
> - xsdt->header.length = sizeof(struct acpi_table_header) +
> - (sizeof(u64) * (i + 1));
> + /* Re-calculate checksum */
> + rsdt->header.checksum = 0;
> + rsdt->header.checksum = table_compute_checksum((u8 *)rsdt,
> + rsdt->header.length);
> + }
>
> - /* Re-calculate checksum */
> - xsdt->header.checksum = 0;
> - xsdt->header.checksum = table_compute_checksum((u8 *)xsdt,
> - xsdt->header.length);
> + if (ctx->xsdt) {
> + /*
> + * And now the same thing for the XSDT. We use the same index as for
> + * now we want the XSDT and RSDT to always be in sync in U-Boot
> + */
> + xsdt = ctx->xsdt;
> +
> + /* This should always be MAX_ACPI_TABLES */
> + entries_num = ARRAY_SIZE(xsdt->entry);
> +
> + for (i = 0; i < entries_num; i++) {
> + if (xsdt->entry[i] == 0)
> + break;
> + }
> +
> + if (i >= entries_num) {
> + log_err("ACPI: Error: too many tables\n");
> + return -E2BIG;
> + }
> +
> + /* Add table to the XSDT */
> + xsdt->entry[i] = nomap_to_sysmem(table);
> +
> + /* Fix XSDT length */
> + xsdt->header.length = sizeof(struct acpi_table_header) +
> + (sizeof(u64) * (i + 1));
> +
> + /* Re-calculate checksum */
> + xsdt->header.checksum = 0;
> + xsdt->header.checksum = table_compute_checksum((u8 *)xsdt,
> + xsdt->header.length);
> + }
>
> return 0;
> }
> --
> 2.46.0
>
More information about the U-Boot
mailing list