]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
acpi: cannot have RSDT above 4 GiB
authorHeinrich Schuchardt <heinrich.schuchardt@canonical.com>
Sun, 12 Nov 2023 23:53:56 +0000 (00:53 +0100)
committerTom Rini <trini@konsulko.com>
Wed, 13 Dec 2023 23:39:05 +0000 (18:39 -0500)
The field RsdtAddress has only 32 bit. The RSDT table cannot be located
beyond 4 GiB.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
lib/acpi/base.c

index 2057bd2bef8897c50255c4cd1e39d207a0c93857..26bf0cb8d30d0073ad5a085c0eaae00cdcaff4c7 100644 (file)
@@ -12,6 +12,7 @@
 #include <dm/acpi.h>
 #include <mapmem.h>
 #include <tables_csum.h>
+#include <linux/sizes.h>
 
 void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
                     struct acpi_xsdt *xsdt)
@@ -21,10 +22,13 @@ void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
        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);
+       if (rsdt)
+               rsdp->rsdt_address = map_to_sysmem(rsdt);
+
+       if (xsdt)
+               rsdp->xsdt_address = map_to_sysmem(xsdt);
 
-       rsdp->xsdt_address = map_to_sysmem(xsdt);
+       rsdp->length = sizeof(struct acpi_rsdp);
        rsdp->revision = ACPI_RSDP_REV_ACPI_2_0;
 
        /* Calculate checksums */
@@ -68,11 +72,15 @@ static void acpi_write_xsdt(struct acpi_xsdt *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 */
+       /* We need at least an RSDP and an XSDT 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));
+       if (map_to_sysmem(ctx->current) < SZ_4G - SZ_64K) {
+               ctx->rsdt = ctx->current;
+               acpi_inc_align(ctx, sizeof(struct acpi_rsdt));
+       } else {
+               ctx->rsdt = 0;
+       }
        ctx->xsdt = ctx->current;
        acpi_inc_align(ctx, sizeof(struct acpi_xsdt));
 
@@ -80,7 +88,8 @@ static int acpi_write_base(struct acpi_ctx *ctx,
        memset(ctx->base, '\0', ctx->current - ctx->base);
 
        acpi_write_rsdp(ctx->rsdp, ctx->rsdt, ctx->xsdt);
-       acpi_write_rsdt(ctx->rsdt);
+       if (ctx->rsdt)
+               acpi_write_rsdt(ctx->rsdt);
        acpi_write_xsdt(ctx->xsdt);
 
        return 0;