]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
acpi: Write pointers to tables instead of addresses
authorSimon Glass <sjg@chromium.org>
Sun, 31 Dec 2023 15:25:54 +0000 (08:25 -0700)
committerSimon Glass <sjg@chromium.org>
Sun, 7 Jan 2024 20:45:07 +0000 (13:45 -0700)
Sandbox uses an API to map between addresses and pointers. This allows
it to have (emulated) memory at zero and avoid arch-specific addressing
details. It also allows memory-mapped peripherals to work.

As an example, on many machines sandbox maps address 100 to pointer
value 10000000.

However this is not correct for ACPI, if sandbox starts another program
(e.g EFI app) and passes it the tables. That app has no knowledge of
sandbox's address mapping. So to make this work we want to store
10000000 as the value in the table.

Add two new 'nomap' functions which clearly make this exeption to how
sandbox works.

This should allow EFI apps to access ACPI tables with sandbox, e.g. for
testing purposes.

Signed-off-by: Simon Glass <sjg@chromium.org>
Suggested-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
arch/sandbox/include/asm/io.h
arch/x86/lib/acpi_table.c
cmd/acpi.c
include/mapmem.h
lib/acpi/acpi.c
lib/acpi/acpi_table.c
lib/acpi/base.c
test/dm/acpi.c

index 3c0a102697ec70ae40818f5a25946b6551b68a38..a23bd64994ab55ce6b5ab70e38ab771120911a1d 100644 (file)
@@ -231,5 +231,21 @@ static inline void unmap_sysmem(const void *vaddr)
        unmap_physmem(vaddr, MAP_WRBACK);
 }
 
+/**
+ * nomap_sysmem() - pass through an address unchanged
+ *
+ * This is used to indicate an address which should NOT be mapped, e.g. in
+ * SMBIOS tables. Using this function instead of a case shows that the sandbox
+ * conversion has been done
+ */
+static inline void *nomap_sysmem(phys_addr_t paddr, unsigned long len)
+{
+       return (void *)(uintptr_t)paddr;
+}
+
+static inline phys_addr_t nomap_to_sysmem(const void *ptr)
+{
+       return (phys_addr_t)(uintptr_t)ptr;
+}
 
 #endif
index c5b33dc65de4d6e5fca97081021232c80ad31ad4..b366e44e337703930184163d82bab0cb4981b4b5 100644 (file)
@@ -197,7 +197,7 @@ int acpi_write_tcpa(struct acpi_ctx *ctx, const struct acpi_writer *entry)
 
        tcpa->platform_class = 0;
        tcpa->laml = size;
-       tcpa->lasa = map_to_sysmem(log);
+       tcpa->lasa = nomap_to_sysmem(log);
 
        /* (Re)calculate length and checksum */
        current = (u32)tcpa + sizeof(struct acpi_tcpa);
@@ -268,7 +268,7 @@ static int acpi_write_tpm2(struct acpi_ctx *ctx,
 
        /* Fill the log area size and start address fields. */
        tpm2->laml = tpm2_log_len;
-       tpm2->lasa = map_to_sysmem(lasa);
+       tpm2->lasa = nomap_to_sysmem(lasa);
 
        /* Calculate checksum. */
        header->checksum = table_compute_checksum(tpm2, header->length);
@@ -430,7 +430,7 @@ int acpi_write_gnvs(struct acpi_ctx *ctx, const struct acpi_writer *entry)
                        u32 *gnvs = (u32 *)((u32)ctx->dsdt + i);
 
                        if (*gnvs == ACPI_GNVS_ADDR) {
-                               *gnvs = map_to_sysmem(ctx->current);
+                               *gnvs = nomap_to_sysmem(ctx->current);
                                log_debug("Fix up global NVS in DSDT to %#08x\n",
                                          *gnvs);
                                break;
index 0c144092420eae705aa1f2fc932df6418215901c..79e9335b5db8eadb041670902d8f0c69c7891de5 100644 (file)
@@ -45,7 +45,7 @@ static int dump_table_name(const char *sig)
        if (!hdr)
                return -ENOENT;
        printf("%.*s @ %16lx\n", ACPI_NAME_LEN, hdr->signature,
-              (ulong)map_to_sysmem(hdr));
+              (ulong)nomap_to_sysmem(hdr));
        print_buffer(0, hdr, 1, hdr->length, 0);
 
        return 0;
@@ -54,9 +54,9 @@ static int dump_table_name(const char *sig)
 static void list_fadt(struct acpi_fadt *fadt)
 {
        if (fadt->dsdt)
-               dump_hdr(map_sysmem(fadt->dsdt, 0));
+               dump_hdr(nomap_sysmem(fadt->dsdt, 0));
        if (fadt->firmware_ctrl)
-               dump_hdr(map_sysmem(fadt->firmware_ctrl, 0));
+               dump_hdr(nomap_sysmem(fadt->firmware_ctrl, 0));
 }
 
 static void list_rsdt(struct acpi_rsdp *rsdp)
@@ -66,11 +66,11 @@ static void list_rsdt(struct acpi_rsdp *rsdp)
        struct acpi_xsdt *xsdt;
 
        if (rsdp->rsdt_address) {
-               rsdt = map_sysmem(rsdp->rsdt_address, 0);
+               rsdt = nomap_sysmem(rsdp->rsdt_address, 0);
                dump_hdr(&rsdt->header);
        }
        if (rsdp->xsdt_address) {
-               xsdt = map_sysmem(rsdp->xsdt_address, 0);
+               xsdt = nomap_sysmem(rsdp->xsdt_address, 0);
                dump_hdr(&xsdt->header);
                len = xsdt->header.length - sizeof(xsdt->header);
                count = len / sizeof(u64);
@@ -91,7 +91,7 @@ static void list_rsdt(struct acpi_rsdp *rsdp)
                        entry = rsdt->entry[i];
                if (!entry)
                        break;
-               hdr = map_sysmem(entry, 0);
+               hdr = nomap_sysmem(entry, 0);
                dump_hdr(hdr);
                if (!memcmp(hdr->signature, "FACP", ACPI_NAME_LEN))
                        list_fadt((struct acpi_fadt *)hdr);
index bb68b4c11afdb882ee8b885c77aa3d6f7b4cc40d..f496c96d16c641a47c41ae35089bb533dc30ff7b 100644 (file)
@@ -28,6 +28,24 @@ static inline phys_addr_t map_to_sysmem(const void *ptr)
 {
        return (phys_addr_t)(uintptr_t)ptr;
 }
+
+/**
+ * nomap_sysmem() - pass through an address unchanged
+ *
+ * This is used to indicate an address which should NOT be mapped, e.g. in
+ * SMBIOS tables. Using this function instead of a case shows that the sandbox
+ * conversion has been done
+ */
+static inline void *nomap_sysmem(phys_addr_t paddr, unsigned long len)
+{
+       return (void *)(uintptr_t)paddr;
+}
+
+static inline phys_addr_t nomap_to_sysmem(const void *ptr)
+{
+       return (phys_addr_t)(uintptr_t)ptr;
+}
+
 # endif
 
 #endif /* __MAPMEM_H */
index 939a638bb5b5c34b0cd82ddddb55bb9fb89ba59e..bcafd771750afdb8a64d0d41219b9d5d2268273f 100644 (file)
@@ -22,13 +22,13 @@ struct acpi_table_header *acpi_find_table(const char *sig)
        if (!rsdp)
                return NULL;
        if (rsdp->xsdt_address) {
-               xsdt = map_sysmem(rsdp->xsdt_address, 0);
+               xsdt = nomap_sysmem(rsdp->xsdt_address, 0);
                len = xsdt->header.length - sizeof(xsdt->header);
                count = len / sizeof(u64);
        } else {
                if (!rsdp->rsdt_address)
                        return NULL;
-               rsdt = map_sysmem(rsdp->rsdt_address, 0);
+               rsdt = nomap_sysmem(rsdp->rsdt_address, 0);
                len = rsdt->header.length - sizeof(rsdt->header);
                count = len / sizeof(u32);
        }
@@ -36,19 +36,19 @@ struct acpi_table_header *acpi_find_table(const char *sig)
                struct acpi_table_header *hdr;
 
                if (rsdp->xsdt_address)
-                       hdr = map_sysmem(xsdt->entry[i], 0);
+                       hdr = nomap_sysmem(xsdt->entry[i], 0);
                else
-                       hdr = map_sysmem(rsdt->entry[i], 0);
+                       hdr = nomap_sysmem(rsdt->entry[i], 0);
                if (!memcmp(hdr->signature, sig, ACPI_NAME_LEN))
                        return hdr;
                if (!memcmp(hdr->signature, "FACP", ACPI_NAME_LEN)) {
                        struct acpi_fadt *fadt = (struct acpi_fadt *)hdr;
 
                        if (!memcmp(sig, "DSDT", ACPI_NAME_LEN) && fadt->dsdt)
-                               return map_sysmem(fadt->dsdt, 0);
+                               return nomap_sysmem(fadt->dsdt, 0);
                        if (!memcmp(sig, "FACS", ACPI_NAME_LEN) &&
                            fadt->firmware_ctrl)
-                               return map_sysmem(fadt->firmware_ctrl, 0);
+                               return nomap_sysmem(fadt->firmware_ctrl, 0);
                }
        }
 
index e74522e9972ef6592a4ee874569bdb15f2fe85ab..39dd53ec402b9fd892644c9e8c1150d735d1d0c3 100644 (file)
@@ -167,7 +167,7 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table)
        }
 
        /* Add table to the RSDT */
-       rsdt->entry[i] = map_to_sysmem(table);
+       rsdt->entry[i] = nomap_to_sysmem(table);
 
        /* Fix RSDT length or the kernel will assume invalid entries */
        rsdt->header.length = sizeof(struct acpi_table_header) +
@@ -185,7 +185,7 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table)
        xsdt = ctx->xsdt;
 
        /* Add table to the XSDT */
-       xsdt->entry[i] = map_to_sysmem(table);
+       xsdt->entry[i] = nomap_to_sysmem(table);
 
        /* Fix XSDT length */
        xsdt->header.length = sizeof(struct acpi_table_header) +
index 07b53e0c5614ede9c7dcbd7b0e5cf4027cf9d590..8b6af2bc43a9a3ff8ae323c546c8e879f96dc211 100644 (file)
@@ -24,10 +24,10 @@ void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
        memcpy(rsdp->oem_id, OEM_ID, 6);
 
        if (rsdt)
-               rsdp->rsdt_address = map_to_sysmem(rsdt);
+               rsdp->rsdt_address = nomap_to_sysmem(rsdt);
 
        if (xsdt)
-               rsdp->xsdt_address = map_to_sysmem(xsdt);
+               rsdp->xsdt_address = nomap_to_sysmem(xsdt);
 
        rsdp->length = sizeof(struct acpi_rsdp);
        rsdp->revision = ACPI_RSDP_REV_ACPI_2_0;
index 1211e2f0e7f7d93643b18660de214975abd475a4..c53ebcdb1c10ce8978ecb1717deaf9b3ccffd25f 100644 (file)
@@ -291,8 +291,8 @@ static int dm_test_acpi_write_tables(struct unit_test_state *uts)
 
        /* Check that the pointers were added correctly */
        for (i = 0; i < 3; i++) {
-               ut_asserteq(map_to_sysmem(dmar + i), ctx.rsdt->entry[i]);
-               ut_asserteq(map_to_sysmem(dmar + i), ctx.xsdt->entry[i]);
+               ut_asserteq(nomap_to_sysmem(dmar + i), ctx.rsdt->entry[i]);
+               ut_asserteq(nomap_to_sysmem(dmar + i), ctx.xsdt->entry[i]);
        }
        ut_asserteq(0, ctx.rsdt->entry[3]);
        ut_asserteq(0, ctx.xsdt->entry[3]);
@@ -371,8 +371,8 @@ static int dm_test_acpi_ctx_and_base_tables(struct unit_test_state *uts)
        end = PTR_ALIGN((void *)xsdt + sizeof(*xsdt), 64);
        ut_asserteq_ptr(end, ctx.current);
 
-       ut_asserteq(map_to_sysmem(rsdt), rsdp->rsdt_address);
-       ut_asserteq(map_to_sysmem(xsdt), rsdp->xsdt_address);
+       ut_asserteq(nomap_to_sysmem(rsdt), rsdp->rsdt_address);
+       ut_asserteq(nomap_to_sysmem(xsdt), rsdp->xsdt_address);
 
        return 0;
 }
@@ -445,7 +445,7 @@ static int dm_test_acpi_cmd_dump(struct unit_test_state *uts)
        /* Now a real table */
        console_record_reset();
        run_command("acpi dump dmar", 0);
-       addr = ALIGN(map_to_sysmem(ctx.xsdt) + sizeof(struct acpi_xsdt), 64);
+       addr = ALIGN(nomap_to_sysmem(ctx.xsdt) + sizeof(struct acpi_xsdt), 64);
        ut_assert_nextline("DMAR @ %16lx", addr);
        ut_assert_nextlines_are_dump(0x30);
        ut_assert_console_end();