aboutsummaryrefslogtreecommitdiff
path: root/lib/acpi
diff options
context:
space:
mode:
authorHeinrich Schuchardt <heinrich.schuchardt@canonical.com>2023-11-13 00:53:56 +0100
committerTom Rini <trini@konsulko.com>2023-12-13 18:39:05 -0500
commitc7b31a9ad5f596ff28f34d517caf316e9ead1539 (patch)
treeddd4318e436bd40d3d28849768503ccdd7d78bd0 /lib/acpi
parentdbdc9c6aefbf5f90777584ab2f914b34ddfc23e5 (diff)
downloadu-boot-c7b31a9ad5f596ff28f34d517caf316e9ead1539.zip
u-boot-c7b31a9ad5f596ff28f34d517caf316e9ead1539.tar.gz
u-boot-c7b31a9ad5f596ff28f34d517caf316e9ead1539.tar.bz2
acpi: cannot have RSDT above 4 GiB
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>
Diffstat (limited to 'lib/acpi')
-rw-r--r--lib/acpi/base.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/lib/acpi/base.c b/lib/acpi/base.c
index 2057bd2..26bf0cb 100644
--- a/lib/acpi/base.c
+++ b/lib/acpi/base.c
@@ -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;