Merge tag 'u-boot-rockchip-20200501' of https://gitlab.denx.de/u-boot/custodians...
[platform/kernel/u-boot.git] / test / dm / acpi.c
index 59aee1f..176d207 100644 (file)
@@ -7,7 +7,12 @@
  */
 
 #include <common.h>
+#include <console.h>
 #include <dm.h>
+#include <malloc.h>
+#include <mapmem.h>
+#include <version.h>
+#include <tables_csum.h>
 #include <version.h>
 #include <acpi/acpi_table.h>
 #include <dm/acpi.h>
@@ -21,10 +26,14 @@ static int testacpi_write_tables(const struct udevice *dev,
                                 struct acpi_ctx *ctx)
 {
        struct acpi_dmar *dmar;
+       int ret;
 
        dmar = (struct acpi_dmar *)ctx->current;
        acpi_create_dmar(dmar, DMAR_INTR_REMAP);
        ctx->current += sizeof(struct acpi_dmar);
+       ret = acpi_add_table(ctx, dmar);
+       if (ret)
+               return log_msg_ret("add", ret);
 
        return 0;
 }
@@ -133,9 +142,9 @@ static int dm_test_acpi_write_tables(struct unit_test_state *uts)
        buf = malloc(BUF_SIZE);
        ut_assertnonnull(buf);
 
-       ctx.current = buf;
+       acpi_setup_base_tables(&ctx, buf);
+       dmar = ctx.current;
        ut_assertok(acpi_write_dev_tables(&ctx));
-       dmar = buf;
 
        /*
         * We should have two dmar tables, one for each "denx,u-boot-acpi-test"
@@ -148,6 +157,15 @@ static int dm_test_acpi_write_tables(struct unit_test_state *uts)
        ut_asserteq(DMAR_INTR_REMAP, dmar[1].flags);
        ut_asserteq(32 - 1, dmar[1].host_address_width);
 
+       /* Check that the pointers were added correctly */
+       ut_asserteq(map_to_sysmem(dmar), ctx.rsdt->entry[0]);
+       ut_asserteq(map_to_sysmem(dmar + 1), ctx.rsdt->entry[1]);
+       ut_asserteq(0, ctx.rsdt->entry[2]);
+
+       ut_asserteq(map_to_sysmem(dmar), ctx.xsdt->entry[0]);
+       ut_asserteq(map_to_sysmem(dmar + 1), ctx.xsdt->entry[1]);
+       ut_asserteq(0, ctx.xsdt->entry[2]);
+
        return 0;
 }
 DM_TEST(dm_test_acpi_write_tables, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
@@ -179,3 +197,121 @@ static int dm_test_acpi_basic(struct unit_test_state *uts)
        return 0;
 }
 DM_TEST(dm_test_acpi_basic, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test acpi_setup_base_tables */
+static int dm_test_acpi_setup_base_tables(struct unit_test_state *uts)
+{
+       struct acpi_rsdp *rsdp;
+       struct acpi_rsdt *rsdt;
+       struct acpi_xsdt *xsdt;
+       struct acpi_ctx ctx;
+       void *buf, *end;
+
+       /*
+        * Use an unaligned address deliberately, by allocating an aligned
+        * address and then adding 4 to it
+        */
+       buf = memalign(64, BUF_SIZE);
+       ut_assertnonnull(buf);
+       acpi_setup_base_tables(&ctx, buf + 4);
+       ut_asserteq(map_to_sysmem(PTR_ALIGN(buf + 4, 16)), gd->arch.acpi_start);
+
+       rsdp = buf + 16;
+       ut_asserteq_ptr(rsdp, ctx.rsdp);
+       ut_assertok(memcmp(RSDP_SIG, rsdp->signature, sizeof(rsdp->signature)));
+       ut_asserteq(sizeof(*rsdp), rsdp->length);
+       ut_assertok(table_compute_checksum(rsdp, 20));
+       ut_assertok(table_compute_checksum(rsdp, sizeof(*rsdp)));
+
+       rsdt = PTR_ALIGN((void *)rsdp + sizeof(*rsdp), 16);
+       ut_asserteq_ptr(rsdt, ctx.rsdt);
+       ut_assertok(memcmp("RSDT", rsdt->header.signature, ACPI_NAME_LEN));
+       ut_asserteq(sizeof(*rsdt), rsdt->header.length);
+       ut_assertok(table_compute_checksum(rsdt, sizeof(*rsdt)));
+
+       xsdt = PTR_ALIGN((void *)rsdt + sizeof(*rsdt), 16);
+       ut_asserteq_ptr(xsdt, ctx.xsdt);
+       ut_assertok(memcmp("XSDT", xsdt->header.signature, ACPI_NAME_LEN));
+       ut_asserteq(sizeof(*xsdt), xsdt->header.length);
+       ut_assertok(table_compute_checksum(xsdt, sizeof(*xsdt)));
+
+       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);
+
+       return 0;
+}
+DM_TEST(dm_test_acpi_setup_base_tables,
+       DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test 'acpi list' command */
+static int dm_test_acpi_cmd_list(struct unit_test_state *uts)
+{
+       struct acpi_ctx ctx;
+       ulong addr;
+       void *buf;
+
+       buf = memalign(16, BUF_SIZE);
+       ut_assertnonnull(buf);
+       acpi_setup_base_tables(&ctx, buf);
+
+       ut_assertok(acpi_write_dev_tables(&ctx));
+
+       console_record_reset();
+       run_command("acpi list", 0);
+       addr = (ulong)map_to_sysmem(buf);
+       ut_assert_nextline("ACPI tables start at %lx", addr);
+       ut_assert_nextline("RSDP %08lx %06lx (v02 U-BOOT)", addr,
+                          sizeof(struct acpi_rsdp));
+       addr = ALIGN(addr + sizeof(struct acpi_rsdp), 16);
+       ut_assert_nextline("RSDT %08lx %06lx (v01 U-BOOT U-BOOTBL %u INTL 0)",
+                          addr, sizeof(struct acpi_table_header) +
+                          2 * sizeof(u32), U_BOOT_BUILD_DATE);
+       addr = ALIGN(addr + sizeof(struct acpi_rsdt), 16);
+       ut_assert_nextline("XSDT %08lx %06lx (v01 U-BOOT U-BOOTBL %u INTL 0)",
+                          addr, sizeof(struct acpi_table_header) +
+                          2 * sizeof(u64), U_BOOT_BUILD_DATE);
+       addr = ALIGN(addr + sizeof(struct acpi_xsdt), 64);
+       ut_assert_nextline("DMAR %08lx %06lx (v01 U-BOOT U-BOOTBL %u INTL 0)",
+                          addr, sizeof(struct acpi_dmar), U_BOOT_BUILD_DATE);
+       addr = ALIGN(addr + sizeof(struct acpi_dmar), 16);
+       ut_assert_nextline("DMAR %08lx %06lx (v01 U-BOOT U-BOOTBL %u INTL 0)",
+                          addr, sizeof(struct acpi_dmar), U_BOOT_BUILD_DATE);
+       ut_assert_console_end();
+
+       return 0;
+}
+DM_TEST(dm_test_acpi_cmd_list, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test 'acpi dump' command */
+static int dm_test_acpi_cmd_dump(struct unit_test_state *uts)
+{
+       struct acpi_ctx ctx;
+       ulong addr;
+       void *buf;
+
+       buf = memalign(16, BUF_SIZE);
+       ut_assertnonnull(buf);
+       acpi_setup_base_tables(&ctx, buf);
+
+       ut_assertok(acpi_write_dev_tables(&ctx));
+
+       /* First search for a non-existent table */
+       console_record_reset();
+       run_command("acpi dump rdst", 0);
+       ut_assert_nextline("Table 'RDST' not found");
+       ut_assert_console_end();
+
+       /* 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);
+       ut_assert_nextline("DMAR @ %08lx", addr);
+       ut_assert_nextlines_are_dump(0x30);
+       ut_assert_console_end();
+
+       return 0;
+}
+DM_TEST(dm_test_acpi_cmd_dump, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);