diff options
author | Tom Rini <trini@konsulko.com> | 2023-04-03 16:45:41 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-04-03 16:45:41 -0400 |
commit | 288fe30a2367b8d0e3f416493150a38ebaa88459 (patch) | |
tree | 1f841eb95d9ceeda4aa3255fb1132a0342f9b19a /test | |
parent | fd4ed6b7e83ec3aea9a2ce21baea8ca9676f40dd (diff) | |
parent | 9876c8c147144db2c120fcc9ffa6de27f6894441 (diff) | |
download | u-boot-288fe30a2367b8d0e3f416493150a38ebaa88459.tar.gz |
Merge branch 'next'
Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'test')
32 files changed, 1276 insertions, 127 deletions
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c index e1eb8ccd9a..4fe9fd7220 100644 --- a/test/boot/bootdev.c +++ b/test/boot/bootdev.c @@ -289,7 +289,7 @@ static int bootdev_test_prio(struct unit_test_state *uts) /* try again but enable hunting, which brings in SCSI */ bootflow_iter_uninit(&iter); - ut_assertok(bootflow_scan_first(NULL, NULL, &iter, BOOTFLOWF_HUNT, + ut_assertok(bootflow_scan_first(NULL, NULL, &iter, BOOTFLOWIF_HUNT, &bflow)); ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow)); ut_asserteq(7, iter.num_devs); @@ -427,8 +427,8 @@ static int bootdev_test_hunt_scan(struct unit_test_state *uts) ut_assertok(bootstd_test_drop_bootdev_order(uts)); ut_assertok(bootflow_scan_first(NULL, NULL, &iter, - BOOTFLOWF_SHOW | BOOTFLOWF_HUNT | - BOOTFLOWF_SKIP_GLOBAL, &bflow)); + BOOTFLOWIF_SHOW | BOOTFLOWIF_HUNT | + BOOTFLOWIF_SKIP_GLOBAL, &bflow)); ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used); return 0; @@ -649,7 +649,7 @@ static int bootdev_test_next_prio(struct unit_test_state *uts) iter.part = 0; uclass_first_device(UCLASS_BOOTMETH, &bflow.method); iter.cur_prio = 0; - iter.flags = BOOTFLOWF_SHOW; + iter.flags = BOOTFLOWIF_SHOW; dev = NULL; console_record_reset_enable(); @@ -662,7 +662,7 @@ static int bootdev_test_next_prio(struct unit_test_state *uts) ut_assert_console_end(); /* now try again with hunting enabled */ - iter.flags = BOOTFLOWF_SHOW | BOOTFLOWF_HUNT; + iter.flags = BOOTFLOWIF_SHOW | BOOTFLOWIF_HUNT; iter.cur_prio = 0; iter.part = 0; diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index b9284fc464..fd0e1d6243 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -277,7 +277,7 @@ static int bootflow_iter(struct unit_test_state *uts) /* The first device is mmc2.bootdev which has no media */ ut_asserteq(-EPROTONOSUPPORT, bootflow_scan_first(NULL, NULL, &iter, - BOOTFLOWF_ALL | BOOTFLOWF_SKIP_GLOBAL, &bflow)); + BOOTFLOWIF_ALL | BOOTFLOWIF_SKIP_GLOBAL, &bflow)); ut_asserteq(2, iter.num_methods); ut_asserteq(0, iter.cur_method); ut_asserteq(0, iter.part); diff --git a/test/cmd/Makefile b/test/cmd/Makefile index 2ffde8703a..055adc65a2 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -14,10 +14,14 @@ obj-$(CONFIG_CMD_FDT) += fdt.o obj-$(CONFIG_CONSOLE_TRUETYPE) += font.o obj-$(CONFIG_CMD_LOADM) += loadm.o obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o +ifdef CONFIG_CMD_PCI +obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o +endif obj-$(CONFIG_CMD_PINMUX) += pinmux.o obj-$(CONFIG_CMD_PWM) += pwm.o obj-$(CONFIG_CMD_SEAMA) += seama.o ifdef CONFIG_SANDBOX +obj-$(CONFIG_CMD_READ) += rw.o obj-$(CONFIG_CMD_SETEXPR) += setexpr.o endif obj-$(CONFIG_CMD_TEMPERATURE) += temperature.o diff --git a/test/cmd/exit.c b/test/cmd/exit.c index ca34abef89..7e160f7e4b 100644 --- a/test/cmd/exit.c +++ b/test/cmd/exit.c @@ -60,20 +60,20 @@ static int cmd_exit_test(struct unit_test_state *uts) /* Validate that 'exit' behaves the same way as 'exit 0' */ ut_assertok(console_record_reset_enable()); - ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo ; echo $?", i)); + ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo ; echo $?")); ut_assert_nextline("bar"); ut_assert_nextline("0"); ut_assertok(ut_check_console_end(uts)); ut_assertok(console_record_reset_enable()); - ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo && echo quux ; echo $?", i)); + ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo && echo quux ; echo $?")); ut_assert_nextline("bar"); ut_assert_nextline("quux"); ut_assert_nextline("0"); ut_assertok(ut_check_console_end(uts)); ut_assertok(console_record_reset_enable()); - ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo || echo quux ; echo $?", i)); + ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo || echo quux ; echo $?")); ut_assert_nextline("bar"); /* Either 'exit' returns 0, or 'echo quux' returns 0 */ ut_assert_nextline("0"); @@ -81,39 +81,39 @@ static int cmd_exit_test(struct unit_test_state *uts) /* Validate that return value still propagates from 'run' command */ ut_assertok(console_record_reset_enable()); - ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo ; echo $?", i)); + ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo ; echo $?")); ut_assert_nextline("bar"); ut_assert_nextline("0"); ut_assertok(ut_check_console_end(uts)); ut_assertok(console_record_reset_enable()); - ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo && echo quux ; echo $?", i)); + ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo && echo quux ; echo $?")); ut_assert_nextline("bar"); ut_assert_nextline("quux"); ut_assert_nextline("0"); ut_assertok(ut_check_console_end(uts)); ut_assertok(console_record_reset_enable()); - ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo || echo quux ; echo $?", i)); + ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo || echo quux ; echo $?")); ut_assert_nextline("bar"); /* The 'true' returns 0 */ ut_assert_nextline("0"); ut_assertok(ut_check_console_end(uts)); ut_assertok(console_record_reset_enable()); - ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo ; echo $?", i)); + ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo ; echo $?")); ut_assert_nextline("bar"); ut_assert_nextline("1"); ut_assertok(ut_check_console_end(uts)); ut_assertok(console_record_reset_enable()); - ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo && echo quux ; echo $?", i)); + ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo && echo quux ; echo $?")); ut_assert_nextline("bar"); ut_assert_nextline("1"); ut_assertok(ut_check_console_end(uts)); ut_assertok(console_record_reset_enable()); - ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo || echo quux ; echo $?", i)); + ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo || echo quux ; echo $?")); ut_assert_nextline("bar"); ut_assert_nextline("quux"); /* The 'echo quux' returns 0 */ diff --git a/test/cmd/fdt.c b/test/cmd/fdt.c index cdbaf8c425..7835da232d 100644 --- a/test/cmd/fdt.c +++ b/test/cmd/fdt.c @@ -15,6 +15,13 @@ #include <test/ut.h> DECLARE_GLOBAL_DATA_PTR; +/* + * Missing tests: + * fdt boardsetup - Do board-specific set up + * fdt checksign [<addr>] - check FIT signature + * <addr> - address of key blob + * default gd->fdt_blob + */ /* Declare a new fdt test */ #define FDT_TEST(_name, _flags) UNIT_TEST(_name, _flags, fdt_test) @@ -168,7 +175,7 @@ static int fdt_test_addr(struct unit_test_state *uts) /* Set the working FDT */ set_working_fdt_addr(0); ut_assert_nextline("Working FDT set to 0"); - ut_assertok(run_commandf("fdt addr %08x", addr)); + ut_assertok(run_commandf("fdt addr %08lx", addr)); ut_assert_nextline("Working FDT set to %lx", addr); ut_asserteq(addr, map_to_sysmem(working_fdt)); ut_assertok(ut_check_console_end(uts)); @@ -178,7 +185,7 @@ static int fdt_test_addr(struct unit_test_state *uts) /* Set the control FDT */ fdt_blob = gd->fdt_blob; gd->fdt_blob = NULL; - ret = run_commandf("fdt addr -c %08x", addr); + ret = run_commandf("fdt addr -c %08lx", addr); new_fdt = gd->fdt_blob; gd->fdt_blob = fdt_blob; ut_assertok(ret); @@ -187,7 +194,7 @@ static int fdt_test_addr(struct unit_test_state *uts) /* Test setting an invalid FDT */ fdt[0] = 123; - ut_asserteq(1, run_commandf("fdt addr %08x", addr)); + ut_asserteq(1, run_commandf("fdt addr %08lx", addr)); ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC"); ut_assertok(ut_check_console_end(uts)); @@ -216,20 +223,19 @@ static int fdt_test_addr_resize(struct unit_test_state *uts) /* Test setting and resizing the working FDT to a larger size */ ut_assertok(console_record_reset_enable()); - ut_assertok(run_commandf("fdt addr %08x %x", addr, newsize)); + ut_assertok(run_commandf("fdt addr %08lx %x", addr, newsize)); ut_assert_nextline("Working FDT set to %lx", addr); ut_assertok(ut_check_console_end(uts)); /* Try shrinking it */ - ut_assertok(run_commandf("fdt addr %08x %x", addr, sizeof(fdt) / 4)); + ut_assertok(run_commandf("fdt addr %08lx %zx", addr, sizeof(fdt) / 4)); ut_assert_nextline("Working FDT set to %lx", addr); ut_assert_nextline("New length %d < existing length %d, ignoring", (int)sizeof(fdt) / 4, newsize); ut_assertok(ut_check_console_end(uts)); /* ...quietly */ - ut_assertok(run_commandf("fdt addr -q %08x %x", addr, sizeof(fdt) / 4)); - ut_assert_nextline("Working FDT set to %lx", addr); + ut_assertok(run_commandf("fdt addr -q %08lx %zx", addr, sizeof(fdt) / 4)); ut_assertok(ut_check_console_end(uts)); /* We cannot easily provoke errors in fdt_open_into(), so ignore that */ @@ -258,13 +264,13 @@ static int fdt_test_move(struct unit_test_state *uts) /* Test moving the working FDT to a new location */ ut_assertok(console_record_reset_enable()); - ut_assertok(run_commandf("fdt move %08x %08x %x", addr, newaddr, ts)); + ut_assertok(run_commandf("fdt move %08lx %08lx %x", addr, newaddr, ts)); ut_assert_nextline("Working FDT set to %lx", newaddr); ut_assertok(ut_check_console_end(uts)); /* Compare the source and destination DTs */ ut_assertok(console_record_reset_enable()); - ut_assertok(run_commandf("cmp.b %08x %08x %x", addr, newaddr, ts)); + ut_assertok(run_commandf("cmp.b %08lx %08lx %x", addr, newaddr, ts)); ut_assert_nextline("Total of %d byte(s) were the same", ts); ut_assertok(ut_check_console_end(uts)); @@ -296,6 +302,149 @@ static int fdt_test_resize(struct unit_test_state *uts) } FDT_TEST(fdt_test_resize, UT_TESTF_CONSOLE_REC); +static int fdt_test_print_list_common(struct unit_test_state *uts, + const char *opc, const char *node) +{ + /* + * Test printing/listing the working FDT + * subnode $node/subnode + */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt %s %s/subnode", opc, node)); + ut_assert_nextline("subnode {"); + ut_assert_nextline("\t#address-cells = <0x00000000>;"); + ut_assert_nextline("\t#size-cells = <0x00000000>;"); + ut_assert_nextline("\tcompatible = \"u-boot,fdt-subnode-test-device\";"); + ut_assert_nextline("};"); + ut_assertok(ut_check_console_end(uts)); + + /* + * Test printing/listing the working FDT + * path / string property model + */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt %s / model", opc)); + ut_assert_nextline("model = \"U-Boot FDT test\""); + ut_assertok(ut_check_console_end(uts)); + + /* + * Test printing/listing the working FDT + * path $node string property compatible + */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt %s %s compatible", opc, node)); + ut_assert_nextline("compatible = \"u-boot,fdt-test-device1\""); + ut_assertok(ut_check_console_end(uts)); + + /* + * Test printing/listing the working FDT + * path $node stringlist property clock-names + */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt %s %s clock-names", opc, node)); + ut_assert_nextline("clock-names = \"fixed\", \"i2c\", \"spi\", \"uart2\", \"uart1\""); + ut_assertok(ut_check_console_end(uts)); + + /* + * Test printing/listing the working FDT + * path $node u32 property clock-frequency + */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt %s %s clock-frequency", opc, node)); + ut_assert_nextline("clock-frequency = <0x00fde800>"); + ut_assertok(ut_check_console_end(uts)); + + /* + * Test printing/listing the working FDT + * path $node empty property u-boot,empty-property + */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt %s %s u-boot,empty-property", opc, node)); + /* + * This is the only 'fdt print' / 'fdt list' incantation which + * prefixes the property with node path. This has been in U-Boot + * since the beginning of the command 'fdt', keep it. + */ + ut_assert_nextline("%s u-boot,empty-property", node); + ut_assertok(ut_check_console_end(uts)); + + /* + * Test printing/listing the working FDT + * path $node prop-encoded array property regs + */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt %s %s regs", opc, node)); + ut_assert_nextline("regs = <0x00001234 0x00001000>"); + ut_assertok(ut_check_console_end(uts)); + + return 0; +} + +static int fdt_test_print_list(struct unit_test_state *uts, bool print) +{ + const char *opc = print ? "print" : "list"; + char fdt[4096]; + ulong addr; + int ret; + + /* Original source DT */ + ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt))); + addr = map_to_sysmem(fdt); + set_working_fdt_addr(addr); + + /* Test printing/listing the working FDT -- node / */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt %s", opc)); + ut_assert_nextline("/ {"); + ut_assert_nextline("\t#address-cells = <0x00000001>;"); + ut_assert_nextline("\t#size-cells = <0x00000001>;"); + ut_assert_nextline("\tcompatible = \"u-boot,fdt-test\";"); + ut_assert_nextline("\tmodel = \"U-Boot FDT test\";"); + ut_assert_nextline("\taliases {"); + if (print) { + ut_assert_nextline("\t\tbadalias = \"/bad/alias\";"); + ut_assert_nextline("\t\tsubnodealias = \"/test-node@1234/subnode\";"); + ut_assert_nextline("\t\ttestnodealias = \"/test-node@1234\";"); + } + ut_assert_nextline("\t};"); + ut_assert_nextline("\ttest-node@1234 {"); + if (print) { + ut_assert_nextline("\t\t#address-cells = <0x00000000>;"); + ut_assert_nextline("\t\t#size-cells = <0x00000000>;"); + ut_assert_nextline("\t\tcompatible = \"u-boot,fdt-test-device1\";"); + ut_assert_nextline("\t\tclock-names = \"fixed\", \"i2c\", \"spi\", \"uart2\", \"uart1\";"); + ut_assert_nextline("\t\tu-boot,empty-property;"); + ut_assert_nextline("\t\tclock-frequency = <0x00fde800>;"); + ut_assert_nextline("\t\tregs = <0x00001234 0x00001000>;"); + ut_assert_nextline("\t\tsubnode {"); + ut_assert_nextline("\t\t\t#address-cells = <0x00000000>;"); + ut_assert_nextline("\t\t\t#size-cells = <0x00000000>;"); + ut_assert_nextline("\t\t\tcompatible = \"u-boot,fdt-subnode-test-device\";"); + ut_assert_nextline("\t\t};"); + } + ut_assert_nextline("\t};"); + ut_assert_nextline("};"); + ut_assertok(ut_check_console_end(uts)); + + ret = fdt_test_print_list_common(uts, opc, "/test-node@1234"); + if (!ret) + ret = fdt_test_print_list_common(uts, opc, "testnodealias"); + + return 0; +} + +static int fdt_test_print(struct unit_test_state *uts) +{ + return fdt_test_print_list(uts, true); +} +FDT_TEST(fdt_test_print, UT_TESTF_CONSOLE_REC); + +static int fdt_test_list(struct unit_test_state *uts) +{ + return fdt_test_print_list(uts, false); +} +FDT_TEST(fdt_test_list, UT_TESTF_CONSOLE_REC); + /* Test 'fdt get value' reading an fdt */ static int fdt_test_get_value_string(struct unit_test_state *uts, const char *node, const char *prop, @@ -646,23 +795,21 @@ static int fdt_test_set_single(struct unit_test_state *uts, * => fdt set /path property */ ut_assertok(console_record_reset_enable()); - if (sval) { + if (sval) ut_assertok(run_commandf("fdt set %s %s %s", path, prop, sval)); - } else if (integer) { + else if (integer) ut_assertok(run_commandf("fdt set %s %s <%d>", path, prop, ival)); - } else { + else ut_assertok(run_commandf("fdt set %s %s", path, prop)); - } /* Validate the property is present and has correct value. */ ut_assertok(run_commandf("fdt get value svar %s %s", path, prop)); - if (sval) { + if (sval) ut_asserteq_str(sval, env_get("svar")); - } else if (integer) { + else if (integer) ut_asserteq(ival, env_get_hex("svar", 0x1234)); - } else { + else ut_assertnull(env_get("svar")); - } ut_assertok(ut_check_console_end(uts)); return 0; @@ -964,6 +1111,411 @@ static int fdt_test_bootcpu(struct unit_test_state *uts) } FDT_TEST(fdt_test_bootcpu, UT_TESTF_CONSOLE_REC); +static int fdt_test_header_get(struct unit_test_state *uts, + const char *field, const unsigned long val) +{ + /* Test getting valid header entry */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt header get fvar %s", field)); + ut_asserteq(val, env_get_hex("fvar", 0x1234)); + ut_assertok(ut_check_console_end(uts)); + + /* Test getting malformed header entry */ + ut_assertok(console_record_reset_enable()); + ut_asserteq(1, run_commandf("fdt header get fvar typo%stypo", field)); + ut_assertok(ut_check_console_end(uts)); + + return 0; +} + +static int fdt_test_header(struct unit_test_state *uts) +{ + char fdt[256]; + ulong addr; + + ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt))); + addr = map_to_sysmem(fdt); + set_working_fdt_addr(addr); + + /* Test header print */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt header")); + ut_assert_nextline("magic:\t\t\t0x%x", fdt_magic(fdt)); + ut_assert_nextline("totalsize:\t\t0x%x (%d)", fdt_totalsize(fdt), fdt_totalsize(fdt)); + ut_assert_nextline("off_dt_struct:\t\t0x%x", fdt_off_dt_struct(fdt)); + ut_assert_nextline("off_dt_strings:\t\t0x%x", fdt_off_dt_strings(fdt)); + ut_assert_nextline("off_mem_rsvmap:\t\t0x%x", fdt_off_mem_rsvmap(fdt)); + ut_assert_nextline("version:\t\t%d", fdt_version(fdt)); + ut_assert_nextline("last_comp_version:\t%d", fdt_last_comp_version(fdt)); + ut_assert_nextline("boot_cpuid_phys:\t0x%x", fdt_boot_cpuid_phys(fdt)); + ut_assert_nextline("size_dt_strings:\t0x%x", fdt_size_dt_strings(fdt)); + ut_assert_nextline("size_dt_struct:\t\t0x%x", fdt_size_dt_struct(fdt)); + ut_assert_nextline("number mem_rsv:\t\t0x%x", fdt_num_mem_rsv(fdt)); + ut_assert_nextline_empty(); + ut_assertok(ut_check_console_end(uts)); + + /* Test header get */ + fdt_test_header_get(uts, "magic", fdt_magic(fdt)); + fdt_test_header_get(uts, "totalsize", fdt_totalsize(fdt)); + fdt_test_header_get(uts, "off_dt_struct", fdt_off_dt_struct(fdt)); + fdt_test_header_get(uts, "off_dt_strings", fdt_off_dt_strings(fdt)); + fdt_test_header_get(uts, "off_mem_rsvmap", fdt_off_mem_rsvmap(fdt)); + fdt_test_header_get(uts, "version", fdt_version(fdt)); + fdt_test_header_get(uts, "last_comp_version", fdt_last_comp_version(fdt)); + fdt_test_header_get(uts, "boot_cpuid_phys", fdt_boot_cpuid_phys(fdt)); + fdt_test_header_get(uts, "size_dt_strings", fdt_size_dt_strings(fdt)); + fdt_test_header_get(uts, "size_dt_struct", fdt_size_dt_struct(fdt)); + + return 0; +} +FDT_TEST(fdt_test_header, UT_TESTF_CONSOLE_REC); + +static int fdt_test_memory_cells(struct unit_test_state *uts, + const unsigned int cells) +{ + unsigned char *pada, *pads; + unsigned char *seta, *sets; + char fdt[8192]; + const int size = sizeof(fdt); + fdt32_t *regs; + ulong addr; + char *spc; + int i; + + /* Create DT with node /memory { regs = <0x100 0x200>; } and #*cells */ + ut_assertnonnull(regs = calloc(2 * cells, sizeof(*regs))); + ut_assertnonnull(pada = calloc(12, cells)); + ut_assertnonnull(pads = calloc(12, cells)); + ut_assertnonnull(seta = calloc(12, cells)); + ut_assertnonnull(sets = calloc(12, cells)); + for (i = cells; i >= 1; i--) { + regs[cells - 1] = cpu_to_fdt32(i * 0x10000); + regs[(cells * 2) - 1] = cpu_to_fdt32(~i); + snprintf(seta + (8 * (cells - i)), 9, "%08x", i * 0x10000); + snprintf(sets + (8 * (cells - i)), 9, "%08x", ~i); + spc = (i != 1) ? " " : ""; + snprintf(pada + (11 * (cells - i)), 12, "0x%08x%s", i * 0x10000, spc); + snprintf(pads + (11 * (cells - i)), 12, "0x%08x%s", ~i, spc); + } + + ut_assertok(fdt_create(fdt, size)); + ut_assertok(fdt_finish_reservemap(fdt)); + ut_assert(fdt_begin_node(fdt, "") >= 0); + ut_assertok(fdt_property_u32(fdt, "#address-cells", cells)); + ut_assertok(fdt_property_u32(fdt, "#size-cells", cells)); + ut_assert(fdt_begin_node(fdt, "memory") >= 0); + ut_assertok(fdt_property_string(fdt, "device_type", "memory")); + ut_assertok(fdt_property(fdt, "reg", ®s, cells * 2)); + ut_assertok(fdt_end_node(fdt)); + ut_assertok(fdt_end_node(fdt)); + ut_assertok(fdt_finish(fdt)); + fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */ + addr = map_to_sysmem(fdt); + set_working_fdt_addr(addr); + + /* Test updating the memory node */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt memory 0x%s 0x%s", seta, sets)); + ut_assertok(run_commandf("fdt print /memory")); + ut_assert_nextline("memory {"); + ut_assert_nextline("\tdevice_type = \"memory\";"); + ut_assert_nextline("\treg = <%s %s>;", pada, pads); + ut_assert_nextline("};"); + ut_assertok(ut_check_console_end(uts)); + + free(sets); + free(seta); + free(pads); + free(pada); + free(regs); + + return 0; +} + +static int fdt_test_memory(struct unit_test_state *uts) +{ + /* + * Test memory fixup for 32 and 64 bit systems, anything bigger is + * so far unsupported and fails because of simple_stroull() being + * 64bit tops in the 'fdt memory' command implementation. + */ + fdt_test_memory_cells(uts, 1); + fdt_test_memory_cells(uts, 2); + + /* + * The 'fdt memory' command is limited to /memory node, it does + * not support any other valid DT memory node format, which is + * either one or multiple /memory@adresss nodes. Therefore, this + * DT variant is not tested here. + */ + + return 0; +} +FDT_TEST(fdt_test_memory, UT_TESTF_CONSOLE_REC); + +static int fdt_test_rsvmem(struct unit_test_state *uts) +{ + char fdt[8192]; + ulong addr; + + ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt))); + fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */ + fdt_add_mem_rsv(fdt, 0x42, 0x1701); + fdt_add_mem_rsv(fdt, 0x74656, 0x9); + addr = map_to_sysmem(fdt); + set_working_fdt_addr(addr); + + /* Test default reserved memory node presence */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt rsvmem print")); + ut_assert_nextline("index\t\t start\t\t size"); + ut_assert_nextline("------------------------------------------------"); + ut_assert_nextline(" %x\t%016x\t%016x", 0, 0x42, 0x1701); + ut_assert_nextline(" %x\t%016x\t%016x", 1, 0x74656, 0x9); + ut_assertok(ut_check_console_end(uts)); + + /* Test add new reserved memory node */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt rsvmem add 0x1234 0x5678")); + ut_assertok(run_commandf("fdt rsvmem print")); + ut_assert_nextline("index\t\t start\t\t size"); + ut_assert_nextline("------------------------------------------------"); + ut_assert_nextline(" %x\t%016x\t%016x", 0, 0x42, 0x1701); + ut_assert_nextline(" %x\t%016x\t%016x", 1, 0x74656, 0x9); + ut_assert_nextline(" %x\t%016x\t%016x", 2, 0x1234, 0x5678); + ut_assertok(ut_check_console_end(uts)); + + /* Test delete reserved memory node */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt rsvmem delete 0")); + ut_assertok(run_commandf("fdt rsvmem print")); + ut_assert_nextline("index\t\t start\t\t size"); + ut_assert_nextline("------------------------------------------------"); + ut_assert_nextline(" %x\t%016x\t%016x", 0, 0x74656, 0x9); + ut_assert_nextline(" %x\t%016x\t%016x", 1, 0x1234, 0x5678); + ut_assertok(ut_check_console_end(uts)); + + /* Test re-add new reserved memory node */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt rsvmem add 0x42 0x1701")); + ut_assertok(run_commandf("fdt rsvmem print")); + ut_assert_nextline("index\t\t start\t\t size"); + ut_assert_nextline("------------------------------------------------"); + ut_assert_nextline(" %x\t%016x\t%016x", 0, 0x74656, 0x9); + ut_assert_nextline(" %x\t%016x\t%016x", 1, 0x1234, 0x5678); + ut_assert_nextline(" %x\t%016x\t%016x", 2, 0x42, 0x1701); + ut_assertok(ut_check_console_end(uts)); + + /* Test delete nonexistent reserved memory node */ + ut_assertok(console_record_reset_enable()); + ut_asserteq(1, run_commandf("fdt rsvmem delete 10")); + ut_assert_nextline("libfdt fdt_del_mem_rsv(): FDT_ERR_NOTFOUND"); + ut_assertok(ut_check_console_end(uts)); + + return 0; +} +FDT_TEST(fdt_test_rsvmem, UT_TESTF_CONSOLE_REC); + +static int fdt_test_chosen(struct unit_test_state *uts) +{ + const char *env_bootargs = env_get("bootargs"); + char fdt[8192]; + ulong addr; + + ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt))); + fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */ + addr = map_to_sysmem(fdt); + set_working_fdt_addr(addr); + + /* Test default chosen node presence, fail as there is no /chosen node */ + ut_assertok(console_record_reset_enable()); + ut_asserteq(1, run_commandf("fdt print /chosen")); + ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND"); + ut_assertok(ut_check_console_end(uts)); + + /* Test add new chosen node without initrd */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt chosen")); + ut_assertok(run_commandf("fdt print /chosen")); + ut_assert_nextline("chosen {"); + ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */ + if (env_bootargs) + ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs); + ut_assert_nextline("};"); + ut_assertok(ut_check_console_end(uts)); + + /* Test add new chosen node with initrd */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt chosen 0x1234 0x5678")); + ut_assertok(run_commandf("fdt print /chosen")); + ut_assert_nextline("chosen {"); + ut_assert_nextline("\tlinux,initrd-end = <0x%08x 0x%08x>;", + upper_32_bits(0x1234 + 0x5678 - 1), + lower_32_bits(0x1234 + 0x5678 - 1)); + ut_assert_nextline("\tlinux,initrd-start = <0x%08x 0x%08x>;", + upper_32_bits(0x1234), lower_32_bits(0x1234)); + ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */ + if (env_bootargs) + ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs); + ut_assert_nextline("};"); + ut_assertok(ut_check_console_end(uts)); + + return 0; +} +FDT_TEST(fdt_test_chosen, UT_TESTF_CONSOLE_REC); + +static int fdt_test_apply(struct unit_test_state *uts) +{ + char fdt[8192], fdto[8192]; + ulong addr, addro; + + /* Create base DT with __symbols__ node */ + ut_assertok(fdt_create(fdt, sizeof(fdt))); + ut_assertok(fdt_finish_reservemap(fdt)); + ut_assert(fdt_begin_node(fdt, "") >= 0); + ut_assert(fdt_begin_node(fdt, "__symbols__") >= 0); + ut_assertok(fdt_end_node(fdt)); + ut_assertok(fdt_end_node(fdt)); + ut_assertok(fdt_finish(fdt)); + fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */ + addr = map_to_sysmem(fdt); + set_working_fdt_addr(addr); + + /* Create DTO which adds single property to root node / */ + ut_assertok(fdt_create(fdto, sizeof(fdto))); + ut_assertok(fdt_finish_reservemap(fdto)); + ut_assert(fdt_begin_node(fdto, "") >= 0); + ut_assert(fdt_begin_node(fdto, "fragment") >= 0); + ut_assertok(fdt_property_string(fdto, "target-path", "/")); + ut_assert(fdt_begin_node(fdto, "__overlay__") >= 0); + ut_assertok(fdt_property_string(fdto, "newstring", "newvalue")); + ut_assertok(fdt_end_node(fdto)); + ut_assertok(fdt_end_node(fdto)); + ut_assertok(fdt_finish(fdto)); + addro = map_to_sysmem(fdto); + + /* Test default DT print */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt print /")); + ut_assert_nextline("/ {"); + ut_assert_nextline("\t__symbols__ {"); + ut_assert_nextline("\t};"); + ut_assert_nextline("};"); + ut_assertok(ut_check_console_end(uts)); + + /* Test simple DTO application */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt apply 0x%08lx", addro)); + ut_assertok(run_commandf("fdt print /")); + ut_assert_nextline("/ {"); + ut_assert_nextline("\tnewstring = \"newvalue\";"); + ut_assert_nextline("\t__symbols__ {"); + ut_assert_nextline("\t};"); + ut_assert_nextline("};"); + ut_assertok(ut_check_console_end(uts)); + + /* + * Create complex DTO which: + * - modifies newstring property in root node / + * - adds new properties to root node / + * - adds new subnode with properties to root node / + * - adds phandle to the subnode and therefore __symbols__ node + */ + ut_assertok(fdt_create(fdto, sizeof(fdto))); + ut_assertok(fdt_finish_reservemap(fdto)); + ut_assert(fdt_begin_node(fdto, "") >= 0); + ut_assertok(fdt_property_cell(fdto, "#address-cells", 1)); + ut_assertok(fdt_property_cell(fdto, "#size-cells", 0)); + + ut_assert(fdt_begin_node(fdto, "fragment@0") >= 0); + ut_assertok(fdt_property_string(fdto, "target-path", "/")); + ut_assert(fdt_begin_node(fdto, "__overlay__") >= 0); + ut_assertok(fdt_property_string(fdto, "newstring", "newervalue")); + ut_assertok(fdt_property_u32(fdto, "newu32", 0x12345678)); + ut_assertok(fdt_property(fdto, "empty-property", NULL, 0)); + ut_assert(fdt_begin_node(fdto, "subnode") >= 0); + ut_assertok(fdt_property_string(fdto, "subnewstring", "newervalue")); + ut_assertok(fdt_property_u32(fdto, "subnewu32", 0x12345678)); + ut_assertok(fdt_property(fdto, "subempty-property", NULL, 0)); + ut_assertok(fdt_property_u32(fdto, "phandle", 0x01)); + ut_assertok(fdt_end_node(fdto)); + ut_assertok(fdt_end_node(fdto)); + ut_assertok(fdt_end_node(fdto)); + + ut_assert(fdt_begin_node(fdto, "__symbols__") >= 0); + ut_assertok(fdt_property_string(fdto, "subnodephandle", "/fragment@0/__overlay__/subnode")); + ut_assertok(fdt_end_node(fdto)); + ut_assertok(fdt_finish(fdto)); + addro = map_to_sysmem(fdto); + + /* Test complex DTO application */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt apply 0x%08lx", addro)); + ut_assertok(run_commandf("fdt print /")); + ut_assert_nextline("/ {"); + ut_assert_nextline("\tempty-property;"); + ut_assert_nextline("\tnewu32 = <0x12345678>;"); + ut_assert_nextline("\tnewstring = \"newervalue\";"); + ut_assert_nextline("\tsubnode {"); + ut_assert_nextline("\t\tphandle = <0x00000001>;"); + ut_assert_nextline("\t\tsubempty-property;"); + ut_assert_nextline("\t\tsubnewu32 = <0x12345678>;"); + ut_assert_nextline("\t\tsubnewstring = \"newervalue\";"); + ut_assert_nextline("\t};"); + ut_assert_nextline("\t__symbols__ {"); + ut_assert_nextline("\t\tsubnodephandle = \"/subnode\";"); + ut_assert_nextline("\t};"); + ut_assert_nextline("};"); + ut_assertok(ut_check_console_end(uts)); + + /* + * Create complex DTO which: + * - modifies subnewu32 property in subnode via phandle and uses __fixups__ node + */ + ut_assertok(fdt_create(fdto, sizeof(fdto))); + ut_assertok(fdt_finish_reservemap(fdto)); + ut_assert(fdt_begin_node(fdto, "") >= 0); + ut_assertok(fdt_property_cell(fdto, "#address-cells", 1)); + ut_assertok(fdt_property_cell(fdto, "#size-cells", 0)); + + ut_assert(fdt_begin_node(fdto, "fragment@0") >= 0); + ut_assertok(fdt_property_u32(fdto, "target", 0xffffffff)); + ut_assert(fdt_begin_node(fdto, "__overlay__") >= 0); + ut_assertok(fdt_property_u32(fdto, "subnewu32", 0xabcdef01)); + ut_assertok(fdt_end_node(fdto)); + ut_assertok(fdt_end_node(fdto)); + + ut_assert(fdt_begin_node(fdto, "__fixups__") >= 0); + ut_assertok(fdt_property_string(fdto, "subnodephandle", "/fragment@0:target:0")); + ut_assertok(fdt_end_node(fdto)); + ut_assertok(fdt_end_node(fdto)); + ut_assertok(fdt_finish(fdto)); + addro = map_to_sysmem(fdto); + + /* Test complex DTO application */ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_commandf("fdt apply 0x%08lx", addro)); + ut_assertok(run_commandf("fdt print /")); + ut_assert_nextline("/ {"); + ut_assert_nextline("\tempty-property;"); + ut_assert_nextline("\tnewu32 = <0x12345678>;"); + ut_assert_nextline("\tnewstring = \"newervalue\";"); + ut_assert_nextline("\tsubnode {"); + ut_assert_nextline("\t\tphandle = <0x00000001>;"); + ut_assert_nextline("\t\tsubempty-property;"); + ut_assert_nextline("\t\tsubnewu32 = <0xabcdef01>;"); + ut_assert_nextline("\t\tsubnewstring = \"newervalue\";"); + ut_assert_nextline("\t};"); + ut_assert_nextline("\t__symbols__ {"); + ut_assert_nextline("\t\tsubnodephandle = \"/subnode\";"); + ut_assert_nextline("\t};"); + ut_assert_nextline("};"); + ut_assertok(ut_check_console_end(uts)); + + return 0; +} +FDT_TEST(fdt_test_apply, UT_TESTF_CONSOLE_REC); + int do_ut_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { struct unit_test *tests = UNIT_TEST_SUITE_START(fdt_test); diff --git a/test/cmd/font.c b/test/cmd/font.c index adb353965a..40682e5ce4 100644 --- a/test/cmd/font.c +++ b/test/cmd/font.c @@ -19,6 +19,7 @@ static int font_test_base(struct unit_test_state *uts) { struct udevice *dev; + const char *name; int max_metrics; uint size; int ret; @@ -32,8 +33,8 @@ static int font_test_base(struct unit_test_state *uts) ut_assert_nextline("cantoraone_regular"); ut_assertok(ut_check_console_end(uts)); - ut_asserteq_str("nimbus_sans_l_regular", - vidconsole_get_font_size(dev, &size)); + ut_assertok(vidconsole_get_font_size(dev, &name, &size)); + ut_asserteq_str("nimbus_sans_l_regular", name); ut_asserteq(18, size); max_metrics = 1; @@ -52,15 +53,15 @@ static int font_test_base(struct unit_test_state *uts) ut_assertok(ret); ut_assertok(ut_check_console_end(uts)); - ut_asserteq_str("cantoraone_regular", - vidconsole_get_font_size(dev, &size)); + ut_assertok(vidconsole_get_font_size(dev, &name, &size)); + ut_asserteq_str("cantoraone_regular", name); ut_asserteq(40, size); ut_assertok(run_command("font size 30", 0)); ut_assertok(ut_check_console_end(uts)); - ut_asserteq_str("cantoraone_regular", - vidconsole_get_font_size(dev, &size)); + ut_assertok(vidconsole_get_font_size(dev, &name, &size)); + ut_asserteq_str("cantoraone_regular", name); ut_asserteq(30, size); return 0; diff --git a/test/cmd/pci_mps.c b/test/cmd/pci_mps.c new file mode 100644 index 0000000000..fd96f4fba6 --- /dev/null +++ b/test/cmd/pci_mps.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Tests that the PCI Maximum Payload Size (MPS) command can set the sandbox + * PCI Express device to safe mode and determine the correct payload size. + * + * Copyright 2023 Microsoft + * Written by Stephen Carlson <stcarlso@linux.microsoft.com> + */ + +#include <common.h> +#include <console.h> +#include <test/suites.h> +#include <test/ut.h> + +#define PCI_MPS_TEST(_name, _flags) UNIT_TEST(_name, _flags, pci_mps_test) + +/* Test "pci_mps" command in safe "s" mode */ +static int test_pci_mps_safe(struct unit_test_state *uts) +{ + /* Enumerate PCI Express first */ + ut_assertok(run_command("pci e", 0)); + ut_assert_console_end(); + + /* Test pci_mps s */ + ut_assertok(run_command("pci_mps s", 0)); + ut_assert_nextline("Setting MPS of all devices to 256B"); + ut_assert_console_end(); + + return 0; +} + +PCI_MPS_TEST(test_pci_mps_safe, UT_TESTF_CONSOLE_REC); + +int do_ut_pci_mps(struct cmd_tbl *cmdtp, int flag, int argc, + char * const argv[]) +{ + struct unit_test *tests = UNIT_TEST_SUITE_START(pci_mps_test); + const int n = UNIT_TEST_SUITE_COUNT(pci_mps_test); + + return cmd_ut_category("cmd_pci_mps", "pci_mps_test_", tests, n, + argc, argv); +} diff --git a/test/cmd/pwm.c b/test/cmd/pwm.c index 2fc0b5e407..cf7ee0e0e6 100644 --- a/test/cmd/pwm.c +++ b/test/cmd/pwm.c @@ -27,11 +27,11 @@ static int dm_test_pwm_cmd(struct unit_test_state *uts) /* pwm <invert> <pwm_dev_num> <channel> <polarity> */ /* cros-ec-pwm doesn't support invert */ ut_asserteq(1, run_command("pwm invert 0 0 1", 0)); - ut_assert_nextline("error(-38)") + ut_assert_nextline("error(-38)"); ut_assert_console_end(); ut_asserteq(1, run_command("pwm invert 0 0 0", 0)); - ut_assert_nextline("error(-38)") + ut_assert_nextline("error(-38)"); ut_assert_console_end(); /* pwm <config> <pwm_dev_num> <channel> <period_ns> <duty_ns> */ diff --git a/test/cmd/rw.c b/test/cmd/rw.c new file mode 100644 index 0000000000..98302bf047 --- /dev/null +++ b/test/cmd/rw.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Tests for read and write commands + */ + +#include <common.h> +#include <dm/test.h> +#include <mapmem.h> +#include <part.h> +#include <test/test.h> +#include <test/ut.h> + +static int setup_partitions(struct unit_test_state *uts, struct blk_desc **mmc_dev_desc) +{ + char str_disk_guid[UUID_STR_LEN + 1]; + struct disk_partition parts[2] = { + { + .start = 48, /* GPT data takes up the first 34 blocks or so */ + .size = 4, + .name = "data", + }, + { + .start = 52, + .size = 10, + .name = "log", + }, + }; + + ut_asserteq(2, blk_get_device_by_str("mmc", "2", mmc_dev_desc)); + if (CONFIG_IS_ENABLED(RANDOM_UUID)) { + gen_rand_uuid_str(parts[0].uuid, UUID_STR_FORMAT_STD); + gen_rand_uuid_str(parts[1].uuid, UUID_STR_FORMAT_STD); + gen_rand_uuid_str(str_disk_guid, UUID_STR_FORMAT_STD); + } + ut_assertok(gpt_restore(*mmc_dev_desc, str_disk_guid, parts, + ARRAY_SIZE(parts))); + return 0; +} + +/* Fill the write buffer with pseudo-random data, clear the read buffer. */ +static void init_buffers(char *rb, char *wb, size_t size, unsigned seed) +{ + memset(rb, 0, size); + while (size--) { + *wb++ = seed; + seed *= 43; + seed += 17 + size/4; + } +} + +static int dm_test_read_write(struct unit_test_state *uts) +{ + struct blk_desc *dev_desc; + char wbuf[1024], rbuf[1024]; + ulong wa, ra; + +#define INIT_BUFFERS() init_buffers(rbuf, wbuf, sizeof(rbuf), __LINE__) + + ut_assertok(setup_partitions(uts, &dev_desc)); + + wa = map_to_sysmem(wbuf); + ra = map_to_sysmem(rbuf); + + /* Simple test, write to/read from same partition. */ + INIT_BUFFERS(); + ut_assertok(run_commandf("write mmc 2:1 0x%lx 0 2", wa)); + ut_assertok(run_commandf("read mmc 2:1 0x%lx 0 2", ra)); + ut_assertok(memcmp(wbuf, rbuf, sizeof(wbuf))); + ut_assertok(run_commandf("read mmc 2:1 0x%lx 1 1", ra)); + ut_assertok(memcmp(&wbuf[512], rbuf, 512)); + + /* Use name for write, number for read. */ + INIT_BUFFERS(); + ut_assertok(run_commandf("write mmc 2#log 0x%lx 0 2", wa)); + ut_assertok(run_commandf("read mmc 2:2 0x%lx 0 2", ra)); + ut_assertok(memcmp(wbuf, rbuf, sizeof(wbuf))); + + /* Use full device for write, name for read. */ + INIT_BUFFERS(); + ut_assertok(run_commandf("write mmc 2:0 0x%lx 0x30 2", wa)); + ut_assertok(run_commandf("read mmc 2#data 0x%lx 0 2", ra)); + ut_assertok(memcmp(wbuf, rbuf, sizeof(wbuf))); + + /* Use name for write, full device for read */ + INIT_BUFFERS(); + ut_assertok(run_commandf("write mmc 2#log 0x%lx 1 2", wa)); + ut_assertok(run_commandf("read mmc 2:0 0x%lx 0x35 2", ra)); + ut_assertok(memcmp(wbuf, rbuf, sizeof(wbuf))); + + /* Read/write outside partition bounds should be rejected upfront. */ + console_record_reset_enable(); + ut_asserteq(1, run_commandf("read mmc 2#data 0x%lx 3 2", ra)); + ut_assert_nextlinen("read out of range"); + ut_assert_console_end(); + + console_record_reset_enable(); + ut_asserteq(1, run_commandf("write mmc 2#log 0x%lx 9 2", wa)); + ut_assert_nextlinen("write out of range"); + ut_assert_console_end(); + + return 0; +} + +DM_TEST(dm_test_read_write, UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC); diff --git a/test/cmd_ut.c b/test/cmd_ut.c index 409c22bfd2..d440da833a 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -110,6 +110,9 @@ static struct cmd_tbl cmd_ut_sub[] = { #ifdef CONFIG_CMD_LOADM U_BOOT_CMD_MKENT(loadm, CONFIG_SYS_MAXARGS, 1, do_ut_loadm, "", ""), #endif +#ifdef CONFIG_CMD_PCI_MPS + U_BOOT_CMD_MKENT(pci_mps, CONFIG_SYS_MAXARGS, 1, do_ut_pci_mps, "", ""), +#endif #ifdef CONFIG_CMD_SEAMA U_BOOT_CMD_MKENT(seama, CONFIG_SYS_MAXARGS, 1, do_ut_seama, "", ""), #endif @@ -210,6 +213,9 @@ static char ut_help_text[] = #ifdef CONFIG_UT_OVERLAY "\noverlay - device tree overlays" #endif +#ifdef CONFIG_CMD_PCI_MPS + "\npci_mps - PCI Express Maximum Payload Size" +#endif "\nprint - printing things to the console" "\nsetexpr - setexpr command" #ifdef CONFIG_SANDBOX diff --git a/test/command_ut.c b/test/command_ut.c index 9837d10eb5..a74bd109e1 100644 --- a/test/command_ut.c +++ b/test/command_ut.c @@ -9,6 +9,8 @@ #include <command.h> #include <env.h> #include <log.h> +#include <string.h> +#include <linux/errno.h> static const char test_cmd[] = "setenv list 1\n setenv list ${list}2; " "setenv list ${list}3\0" @@ -17,6 +19,8 @@ static const char test_cmd[] = "setenv list 1\n setenv list ${list}2; " static int do_ut_cmd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + char long_str[CONFIG_SYS_CBSIZE + 42]; + printf("%s: Testing commands\n", __func__); run_command("env default -f -a", 0); @@ -60,6 +64,36 @@ static int do_ut_cmd(struct cmd_tbl *cmdtp, int flag, int argc, assert(run_command("'", 0) == 1); + /* Variadic function test-cases */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-zero-length" + assert(run_commandf("") == 0); +#pragma GCC diagnostic pop + assert(run_commandf(" ") == 0); + assert(run_commandf("'") == 1); + + assert(run_commandf("env %s %s", "delete -f", "list") == 0); + /* Expected: "Error: "list" not defined" */ + assert(run_commandf("printenv list") == 1); + + memset(long_str, 'x', sizeof(long_str)); + assert(run_commandf("Truncation case: %s", long_str) == -ENOSPC); + + if (IS_ENABLED(CONFIG_HUSH_PARSER)) { + assert(run_commandf("env %s %s %s %s", "delete -f", "adder", + "black", "foo") == 0); + assert(run_commandf("setenv foo 'setenv %s 1\nsetenv %s 2'", + "black", "adder") == 0); + run_command("run foo", 0); + assert(env_get("black")); + assert(!strcmp("1", env_get("black"))); + assert(env_get("adder")); + assert(!strcmp("2", env_get("adder"))); + } + + /* Clean up before exit */ + run_command("env default -f -a", 0); + printf("%s: Everything went swimmingly\n", __func__); return 0; } diff --git a/test/dm/acpigen.c b/test/dm/acpigen.c index 3ec2743af9..15b2b6f64a 100644 --- a/test/dm/acpigen.c +++ b/test/dm/acpigen.c @@ -1083,7 +1083,7 @@ static int dm_test_acpi_write_name(struct unit_test_state *uts) ut_asserteq(NAME_OP, *ptr++); ptr += 10; ut_asserteq(STRING_PREFIX, *ptr++); - ut_asserteq_str("baldrick", (char *)ptr) + ut_asserteq_str("baldrick", (char *)ptr); ptr += 9; ut_asserteq(NAME_OP, *ptr++); diff --git a/test/dm/misc.c b/test/dm/misc.c index 1506fdefe3..8bdd8c64bc 100644 --- a/test/dm/misc.c +++ b/test/dm/misc.c @@ -51,13 +51,13 @@ static int dm_test_misc(struct unit_test_state *uts) /* Read back last issued ioctl */ ut_assertok(misc_call(dev, 2, NULL, 0, &last_ioctl, sizeof(last_ioctl))); - ut_asserteq(6, last_ioctl) + ut_asserteq(6, last_ioctl); ut_assertok(misc_ioctl(dev, 23, NULL)); /* Read back last issued ioctl */ ut_assertok(misc_call(dev, 2, NULL, 0, &last_ioctl, sizeof(last_ioctl))); - ut_asserteq(23, last_ioctl) + ut_asserteq(23, last_ioctl); /* Enable / disable tests */ diff --git a/test/dm/phy.c b/test/dm/phy.c index df4c73fc70..4d4a083dd0 100644 --- a/test/dm/phy.c +++ b/test/dm/phy.c @@ -28,22 +28,22 @@ static int dm_test_phy_base(struct unit_test_state *uts) /* * Get the same phy port in 2 different ways and compare. */ - ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method1)) - ut_assertok(generic_phy_get_by_index(parent, 0, &phy1_method2)) + ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method1)); + ut_assertok(generic_phy_get_by_index(parent, 0, &phy1_method2)); ut_asserteq(phy1_method1.id, phy1_method2.id); /* * Get the second phy port. Check that the same phy provider (device) * provides this 2nd phy port, but that the IDs are different */ - ut_assertok(generic_phy_get_by_name(parent, "phy2", &phy2)) + ut_assertok(generic_phy_get_by_name(parent, "phy2", &phy2)); ut_asserteq_ptr(phy1_method2.dev, phy2.dev); ut_assert(phy1_method1.id != phy2.id); /* * Get the third phy port. Check that the phy provider is different */ - ut_assertok(generic_phy_get_by_name(parent, "phy3", &phy3)) + ut_assertok(generic_phy_get_by_name(parent, "phy3", &phy3)); ut_assert(phy2.dev != phy3.dev); /* Try to get a non-existing phy */ diff --git a/test/dm/scmi.c b/test/dm/scmi.c index 93c7d08f43..d87e2731ce 100644 --- a/test/dm/scmi.c +++ b/test/dm/scmi.c @@ -187,10 +187,10 @@ static int dm_test_scmi_resets(struct unit_test_state *uts) ut_assertnonnull(agent); /* Test SCMI resect controller manipulation */ - ut_assert(!agent->reset[0].asserted) + ut_assert(!agent->reset[0].asserted); ut_assertok(reset_assert(&scmi_devices->reset[0])); - ut_assert(agent->reset[0].asserted) + ut_assert(agent->reset[0].asserted); ut_assertok(reset_deassert(&scmi_devices->reset[0])); ut_assert(!agent->reset[0].asserted); diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 1d2af94f56..8e6e42e46b 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -215,7 +215,7 @@ static int dm_test_fdt_pre_reloc(struct unit_test_state *uts) /* * These are 2 pre-reloc devices: - * one with "u-boot,dm-pre-reloc" property (a-test node), and the other + * one with "bootph-all" property (a-test node), and the other * one whose driver marked with DM_FLAG_PRE_RELOC flag (h-test node). */ ut_asserteq(2, list_count_items(&uc->dev_head)); diff --git a/test/dm/tpm.c b/test/dm/tpm.c index 0b46f79959..3defb3c3da 100644 --- a/test/dm/tpm.c +++ b/test/dm/tpm.c @@ -11,24 +11,116 @@ #include <test/test.h> #include <test/ut.h> -/* Basic test of the TPM uclass */ +/* + * get_tpm_version() - Get a TPM of the given version + * + * @version: Version to get + * @devp: Returns the TPM device + * Returns: 0 if OK, -ENODEV if not found + */ +static int get_tpm_version(enum tpm_version version, struct udevice **devp) +{ + struct udevice *dev; + + /* + * For now we have to probe each TPM, since the version is set up in + * of_to_plat(). We could require TPMs to declare their version when + * probed, to avoid this + */ + uclass_foreach_dev_probe(UCLASS_TPM, dev) { + if (tpm_get_version(dev) == version) { + *devp = dev; + return 0; + } + } + + return -ENODEV; +} + +/* Basic test of initing a TPM */ +static int test_tpm_init(struct unit_test_state *uts, enum tpm_version version) +{ + struct udevice *dev; + + /* check probe success */ + ut_assertok(get_tpm_version(version, &dev)); + + ut_assertok(tpm_init(dev)); + + return 0; +} + static int dm_test_tpm(struct unit_test_state *uts) { + ut_assertok(test_tpm_init(uts, TPM_V1)); + ut_assertok(test_tpm_init(uts, TPM_V2)); + + return 0; +} +DM_TEST(dm_test_tpm, UT_TESTF_SCAN_FDT); + +/* Test report_state */ +static int dm_test_tpm_report_state(struct unit_test_state *uts) +{ struct udevice *dev; char buf[50]; /* check probe success */ - ut_assertok(uclass_first_device_err(UCLASS_TPM, &dev)); - ut_assert(tpm_is_v2(dev)); + ut_assertok(get_tpm_version(TPM_V2, &dev)); ut_assert(tpm_report_state(dev, buf, sizeof(buf))); ut_asserteq_str("init_done=0", buf); - ut_assertok(tpm_init(dev)); + ut_assertok(tpm_auto_start(dev)); ut_assert(tpm_report_state(dev, buf, sizeof(buf))); ut_asserteq_str("init_done=1", buf); return 0; } -DM_TEST(dm_test_tpm, UT_TESTF_SCAN_FDT); +DM_TEST(dm_test_tpm_report_state, UT_TESTF_SCAN_FDT); + +/** + * test_tpm_autostart() - check the tpm_auto_start() call + * + * @uts: Unit test state + * @version: TPM version to use + * @reinit: true to call tpm_init() first + * Returns 0 if OK, non-zero on failure + */ +static int test_tpm_autostart(struct unit_test_state *uts, + enum tpm_version version, bool reinit) +{ + struct udevice *dev; + + /* check probe success */ + ut_assertok(get_tpm_version(version, &dev)); + + if (reinit) + ut_assertok(tpm_init(dev)); + /* + * tpm_auto_start will rerun tpm_init() if reinit, but handles the + * -EBUSY return code internally. + */ + ut_assertok(tpm_auto_start(dev)); + + return 0; +} + +static int dm_test_tpm_autostart(struct unit_test_state *uts) +{ + ut_assertok(test_tpm_autostart(uts, TPM_V1, false)); + ut_assertok(test_tpm_autostart(uts, TPM_V2, false)); + + return 0; +} +DM_TEST(dm_test_tpm_autostart, UT_TESTF_SCAN_FDT); + +static int dm_test_tpm_autostart_reinit(struct unit_test_state *uts) +{ + ut_assertok(test_tpm_autostart(uts, TPM_V1, true)); + ut_assertok(test_tpm_autostart(uts, TPM_V2, true)); + + return 0; +} +DM_TEST(dm_test_tpm_autostart_reinit, UT_TESTF_SCAN_FDT); diff --git a/test/dm/video.c b/test/dm/video.c index 17a33cc7af..30778157d9 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -151,6 +151,8 @@ static int dm_test_video_text(struct unit_test_state *uts) ut_assertok(select_vidconsole(uts, "vidconsole0")); ut_assertok(video_get_nologo(uts, &dev)); + ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); + ut_assertok(vidconsole_select_font(con, "8x16", 0)); ut_asserteq(46, compress_frame_buffer(uts, dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); @@ -175,6 +177,42 @@ static int dm_test_video_text(struct unit_test_state *uts) } DM_TEST(dm_test_video_text, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_video_text_12x22(struct unit_test_state *uts) +{ + struct udevice *dev, *con; + int i; + +#define WHITE 0xffff +#define SCROLL_LINES 100 + + ut_assertok(select_vidconsole(uts, "vidconsole0")); + ut_assertok(video_get_nologo(uts, &dev)); + ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); + ut_assertok(vidconsole_select_font(con, "12x22", 0)); + ut_asserteq(46, compress_frame_buffer(uts, dev)); + + ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); + vidconsole_putc_xy(con, 0, 0, 'a'); + ut_asserteq(89, compress_frame_buffer(uts, dev)); + + vidconsole_putc_xy(con, 0, 0, ' '); + ut_asserteq(46, compress_frame_buffer(uts, dev)); + + for (i = 0; i < 20; i++) + vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); + ut_asserteq(363, compress_frame_buffer(uts, dev)); + + vidconsole_set_row(con, 0, WHITE); + ut_asserteq(46, compress_frame_buffer(uts, dev)); + + for (i = 0; i < 20; i++) + vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); + ut_asserteq(363, compress_frame_buffer(uts, dev)); + + return 0; +} +DM_TEST(dm_test_video_text_12x22, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + /* Test handling of special characters in the console */ static int dm_test_video_chars(struct unit_test_state *uts) { @@ -184,6 +222,7 @@ static int dm_test_video_chars(struct unit_test_state *uts) ut_assertok(select_vidconsole(uts, "vidconsole0")); ut_assertok(video_get_nologo(uts, &dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); + ut_assertok(vidconsole_select_font(con, "8x16", 0)); vidconsole_put_string(con, test_string); ut_asserteq(466, compress_frame_buffer(uts, dev)); @@ -201,6 +240,7 @@ static int dm_test_video_ansi(struct unit_test_state *uts) ut_assertok(select_vidconsole(uts, "vidconsole0")); ut_assertok(video_get_nologo(uts, &dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); + ut_assertok(vidconsole_select_font(con, "8x16", 0)); /* reference clear: */ video_clear(con->parent); @@ -249,6 +289,7 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot, ut_assertok(video_get_nologo(uts, &dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); + ut_assertok(vidconsole_select_font(con, "8x16", 0)); ut_asserteq(46, compress_frame_buffer(uts, dev)); /* Check display wrap */ diff --git a/test/lib/kconfig.c b/test/lib/kconfig.c index 472d2c5728..76225ba8ff 100644 --- a/test/lib/kconfig.c +++ b/test/lib/kconfig.c @@ -15,12 +15,12 @@ static int lib_test_is_enabled(struct unit_test_state *uts) { ulong val; - ut_asserteq(1, IS_ENABLED(CONFIG_CMDLINE)) - ut_asserteq(0, IS_ENABLED(CONFIG__UNDEFINED)) + ut_asserteq(1, IS_ENABLED(CONFIG_CMDLINE)); + ut_asserteq(0, IS_ENABLED(CONFIG__UNDEFINED)); - ut_asserteq(1, CONFIG_IS_ENABLED(CMDLINE)) - ut_asserteq(0, CONFIG_IS_ENABLED(OF_PLATDATA)) - ut_asserteq(0, CONFIG_IS_ENABLED(_UNDEFINED)) + ut_asserteq(1, CONFIG_IS_ENABLED(CMDLINE)); + ut_asserteq(0, CONFIG_IS_ENABLED(OF_PLATDATA)); + ut_asserteq(0, CONFIG_IS_ENABLED(_UNDEFINED)); ut_asserteq(0xc000, IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED, CONFIG_BLOBLIST_ADDR)); diff --git a/test/lib/kconfig_spl.c b/test/lib/kconfig_spl.c index c89ceaec66..8f8a3411b1 100644 --- a/test/lib/kconfig_spl.c +++ b/test/lib/kconfig_spl.c @@ -15,9 +15,9 @@ static int lib_test_spl_is_enabled(struct unit_test_state *uts) { ulong val; - ut_asserteq(0, CONFIG_IS_ENABLED(CMDLINE)) - ut_asserteq(1, CONFIG_IS_ENABLED(OF_PLATDATA)) - ut_asserteq(0, CONFIG_IS_ENABLED(_UNDEFINED)) + ut_asserteq(0, CONFIG_IS_ENABLED(CMDLINE)); + ut_asserteq(1, CONFIG_IS_ENABLED(OF_PLATDATA)); + ut_asserteq(0, CONFIG_IS_ENABLED(_UNDEFINED)); /* * This fails if CONFIG_TEST_KCONFIG_ENABLE is not enabled, since the diff --git a/test/nokia_rx51_test.sh b/test/nokia_rx51_test.sh index a516ec2967..dca9ef3027 100755 --- a/test/nokia_rx51_test.sh +++ b/test/nokia_rx51_test.sh @@ -83,8 +83,10 @@ echo # Download qflasher and nolo images # This is proprietary qemu flasher tool with first stage images, but license allows non-commercial redistribution -wget -c http://repository.maemo.org/qemu-n900/qemu-n900.tar.gz -tar -xf qemu-n900.tar.gz +if ! test -f qflasher || ! test -f xloader-qemu.bin || ! test -f secondary-qemu.bin; then + test -f qemu-n900.tar.gz || wget -c http://repository.maemo.org/qemu-n900/qemu-n900.tar.gz + tar -xf qemu-n900.tar.gz +fi # Download Maemo script u-boot-gen-combined if ! test -f u-boot-gen-combined; then @@ -94,16 +96,22 @@ if ! test -f u-boot-gen-combined; then fi # Download Maemo fiasco kernel -wget -c http://repository.maemo.org/pool/maemo5.0/free/k/kernel/kernel_2.6.28-20103103+0m5_armel.deb -dpkg -x kernel_2.6.28-20103103+0m5_armel.deb kernel_2.6.28 +if ! test -d kernel_2.6.28; then + test -f kernel_2.6.28-20103103+0m5_armel.deb || wget -c http://repository.maemo.org/pool/maemo5.0/free/k/kernel/kernel_2.6.28-20103103+0m5_armel.deb + dpkg -x kernel_2.6.28-20103103+0m5_armel.deb kernel_2.6.28 +fi # Download Maemo libc -wget -c http://repository.maemo.org/pool/maemo5.0/free/g/glibc/libc6_2.5.1-1eglibc27+0m5_armel.deb -dpkg -x libc6_2.5.1-1eglibc27+0m5_armel.deb libc6_2.5.1 +if ! test -d libc6_2.5.1; then + test -f libc6_2.5.1-1eglibc27+0m5_armel.deb || wget -c http://repository.maemo.org/pool/maemo5.0/free/g/glibc/libc6_2.5.1-1eglibc27+0m5_armel.deb + dpkg -x libc6_2.5.1-1eglibc27+0m5_armel.deb libc6_2.5.1 +fi # Download Maemo busybox -wget -c http://repository.maemo.org/pool/maemo5.0/free/b/busybox/busybox_1.10.2.legal-1osso30+0m5_armel.deb -dpkg -x busybox_1.10.2.legal-1osso30+0m5_armel.deb busybox_1.10.2 +if ! test -d busybox_1.10.2; then + test -f busybox_1.10.2.legal-1osso30+0m5_armel.deb || wget -c http://repository.maemo.org/pool/maemo5.0/free/b/busybox/busybox_1.10.2.legal-1osso30+0m5_armel.deb + dpkg -x busybox_1.10.2.legal-1osso30+0m5_armel.deb busybox_1.10.2 +fi echo echo "=======================================" diff --git a/test/py/multiplexed_log.py b/test/py/multiplexed_log.py index 5e79075f2e..63237594bb 100644 --- a/test/py/multiplexed_log.py +++ b/test/py/multiplexed_log.py @@ -111,7 +111,7 @@ class RunAndLog(object): """Clean up any resources managed by this object.""" pass - def run(self, cmd, cwd=None, ignore_errors=False, stdin=None): + def run(self, cmd, cwd=None, ignore_errors=False, stdin=None, env=None): """Run a command as a sub-process, and log the results. The output is available at self.output which can be useful if there is @@ -126,6 +126,7 @@ class RunAndLog(object): or exits with an error code, otherwise an exception will be raised if such problems occur. stdin: Input string to pass to the command as stdin (or None) + env: Environment to use, or None to use the current one Returns: The output as a string. @@ -139,7 +140,7 @@ class RunAndLog(object): try: p = subprocess.Popen(cmd, cwd=cwd, stdin=subprocess.PIPE if stdin else None, - stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env) (stdout, stderr) = p.communicate(input=stdin) if stdout is not None: stdout = stdout.decode('utf-8') diff --git a/test/py/requirements.txt b/test/py/requirements.txt index fae8b59caf..e241780f92 100644 --- a/test/py/requirements.txt +++ b/test/py/requirements.txt @@ -1,5 +1,6 @@ atomicwrites==1.4.1 attrs==19.3.0 +concurrencytest==0.1.2 coverage==4.5.4 extras==1.0.0 filelock==3.0.12 diff --git a/test/py/tests/test_fs/test_ext.py b/test/py/tests/test_fs/test_ext.py index dba874fc59..05fefa53a0 100644 --- a/test/py/tests/test_fs/test_ext.py +++ b/test/py/tests/test_fs/test_ext.py @@ -8,11 +8,24 @@ This test verifies extended write operation on file system. """ +import os.path import pytest import re +from subprocess import check_output from fstest_defs import * from fstest_helpers import assert_fs_integrity +PLAIN_FILE='abcdefgh.txt' +MANGLE_FILE='abcdefghi.txt' + +def str2fat(long_filename): + splitext = os.path.splitext(long_filename.upper()) + name = splitext[0] + ext = splitext[1][1:] + if len(name) > 8: + name = '%s~1' % name[:6] + return '%-8s %s' % (name, ext) + @pytest.mark.boardspec('sandbox') @pytest.mark.slow class TestFsExt(object): @@ -317,3 +330,26 @@ class TestFsExt(object): assert('FILE0123456789_79' in output) assert_fs_integrity(fs_type, fs_img) + + def test_fs_ext12(self, u_boot_console, fs_obj_ext): + """ + Test Case 12 - write plain and mangle file + """ + fs_type,fs_img,md5val = fs_obj_ext + with u_boot_console.log.section('Test Case 12 - write plain and mangle file'): + # Test Case 12a - Check if command successfully returned + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % fs_img, + '%swrite host 0:0 %x /%s 0' + % (fs_type, ADDR, PLAIN_FILE), + '%swrite host 0:0 %x /%s 0' + % (fs_type, ADDR, MANGLE_FILE)]) + assert('0 bytes written' in ''.join(output)) + # Test Case 12b - Read file system content + output = check_output('mdir -i %s' % fs_img, shell=True).decode() + # Test Case 12c - Check if short filename is not mangled + assert(str2fat(PLAIN_FILE) in ''.join(output)) + # Test Case 12d - Check if long filename is mangled + assert(str2fat(MANGLE_FILE) in ''.join(output)) + + assert_fs_integrity(fs_type, fs_img) diff --git a/test/py/tests/test_of_migrate.py b/test/py/tests/test_of_migrate.py new file mode 100644 index 0000000000..910f7c0551 --- /dev/null +++ b/test/py/tests/test_of_migrate.py @@ -0,0 +1,108 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright 2023 Google LLC +# Written by Simon Glass <sjg@chromium.org> + +"""Test handling of unmigrated u-boot,dm- tags""" + +import os +import pytest + +import u_boot_utils as util + +# This is needed for Azure, since the default '..' directory is not writeable +TMPDIR1 = '/tmp/test_no_migrate' +TMPDIR2 = '/tmp/test_no_migrate_spl' +TMPDIR3 = '/tmp/test_migrate' + +def build_for_migrate(cons, replace_pair, board, tmpdir, disable_migrate=True): + """Build an updated U-Boot with a slightly modified device tree + + Args: + cons (ConsoleBase): U-Boot console + replace_pair (tuple): + String to find + String to replace it with + board (str): Board to build + tmpdir (str): Temporary directory to use + disable_migrate (bool): True to disable CONFIG_OF_TAG_MIGRATE in build + """ + srcdir = cons.config.source_dir + build_dir = cons.config.build_dir + + # Get the source for the existing dts + dt_dir = os.path.join(build_dir, 'arch', 'sandbox', 'dts') + orig_fname = os.path.join(dt_dir, 'sandbox.dtb') + out_dts = os.path.join(dt_dir, 'sandbox_out.dts') + util.run_and_log(cons, ['dtc', orig_fname, '-I', 'dtb', '-O', 'dts', + '-o', out_dts]) + + # Update it to use an old tag + with open(out_dts) as inf: + data = inf.read() + data = data.replace(*replace_pair) + + dts_fname = os.path.join(dt_dir, 'sandbox_oldtag.dts') + with open(dts_fname, 'w') as outf: + print(data, file=outf) + dtb_fname = os.path.join(dt_dir, 'sandbox_oldtag.dtb') + util.run_and_log(cons, ['dtc', dts_fname, '-o', dtb_fname]) + + migrate = ['-a', '~CONFIG_OF_TAG_MIGRATE'] if disable_migrate else [] + + # Build sandbox with this new dtb, turning off OF_TAG_MIGRATE + env = dict(os.environ) + env['EXT_DTB'] = dtb_fname + env['DEVICE_TREE'] = 'sandbox_new' + env['NO_LTO'] = '1' # Speed up build + out = util.run_and_log( + cons, ['./tools/buildman/buildman', '-m', '--board', board, + *migrate, '-w', '-o', tmpdir], ignore_errors=True, env=env) + return out + +@pytest.mark.slow +@pytest.mark.boardspec('sandbox') +def test_of_no_migrate(u_boot_console): + """Test sandbox with old boot phase tags like u-boot,dm-pre-proper""" + cons = u_boot_console + + build_for_migrate(cons, ['bootph-some-ram', 'u-boot,dm-pre-proper'], + 'sandbox', TMPDIR1) + + # It should fail to run, since the lcd device will not be bound before + # relocation. so won't get its frame-buffer memory + out = util.run_and_log( + cons, [os.path.join(TMPDIR1, 'u-boot'), '-D', '-c', 'help'], + ignore_errors=True) + assert "Video device 'lcd' cannot allocate frame buffer memory" in out + + +@pytest.mark.slow +@pytest.mark.boardspec('sandbox_spl') +@pytest.mark.boardspec('spl_of_platdata_inst') +@pytest.mark.boardspec('!sandbox_tpl') +def test_of_no_migrate_spl(u_boot_console): + """Test sandbox with old boot phase tags like u-boot,dm-spl""" + cons = u_boot_console + + out = build_for_migrate(cons, ['bootph-pre-ram', 'u-boot,dm-spl'], + 'sandbox_spl', TMPDIR2) + + # It should fail to build, since the SPL DT will not include 'spl-test' + # node, among others + assert "undefined type ‘struct dtd_sandbox_spl_test’" in out + + +@pytest.mark.slow +@pytest.mark.boardspec('sandbox') +def test_of_migrate(u_boot_console): + """Test sandbox shows a message when tags were migrated""" + cons = u_boot_console + + build_for_migrate(cons, ['bootph-some-ram', 'u-boot,dm-pre-proper'], + 'sandbox', TMPDIR3, disable_migrate=False) + + # It should show a migration message + out = util.run_and_log( + cons, [os.path.join(TMPDIR3, 'u-boot'), '-D', '-c', 'help'], + ignore_errors=True) + assert "Warning: Device tree includes old 'u-boot,dm-' tags" in out diff --git a/test/py/tests/test_ofplatdata.py b/test/py/tests/test_ofplatdata.py index e9cce4daf4..51a188454f 100644 --- a/test/py/tests/test_ofplatdata.py +++ b/test/py/tests/test_ofplatdata.py @@ -13,10 +13,10 @@ def test_spl_devicetree(u_boot_console): fdtgrep = cons.config.build_dir + '/tools/fdtgrep' output = util.run_and_log(cons, [fdtgrep, '-l', dtb]) - assert "u-boot,dm-pre-reloc" not in output - assert "u-boot,dm-pre-proper" not in output - assert "u-boot,dm-spl" not in output - assert "u-boot,dm-tpl" not in output + assert "bootph-all" not in output + assert "bootph-some-ram" not in output + assert "bootph-pre-ram" not in output + assert "bootph-pre-sram" not in output assert "spl-test5" not in output assert "spl-test6" not in output diff --git a/test/py/tests/test_vbe_vpl.py b/test/py/tests/test_vbe_vpl.py index d1c9d0548a..ed12d3a461 100644 --- a/test/py/tests/test_vbe_vpl.py +++ b/test/py/tests/test_vbe_vpl.py @@ -15,6 +15,7 @@ def test_vbe_vpl(u_boot_console): #cmd = [cons.config.build_dir + fname, '-v'] ram = os.path.join(cons.config.build_dir, 'ram.bin') fdt = os.path.join(cons.config.build_dir, 'arch/sandbox/dts/test.dtb') + image_fname = os.path.join(cons.config.build_dir, 'image.bin') # Enable firmware1 and the mmc that it uses. These are needed for the full # VBE flow. @@ -24,12 +25,13 @@ def test_vbe_vpl(u_boot_console): cons, f'fdtput -t s {fdt} /bootstd/firmware1 status okay') u_boot_utils.run_and_log( cons, f'fdtput -t s {fdt} /mmc3 status okay') + u_boot_utils.run_and_log( + cons, f'fdtput -t s {fdt} /mmc3 filename {image_fname}') # Remove any existing RAM file, so we don't have old data present if os.path.exists(ram): os.remove(ram) - flags = ['-p', os.path.join(cons.config.build_dir, 'image.bin'), '-w', - '-s', 'state.dtb'] + flags = ['-p', image_fname, '-w', '-s', 'state.dtb'] cons.restart_uboot_with_flags(flags) # Make sure that VBE was used in both VPL (to load SPL) and SPL (to load diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py index e3e7ca4b21..04fa59f98b 100644 --- a/test/py/tests/test_vboot.py +++ b/test/py/tests/test_vboot.py @@ -30,6 +30,12 @@ For pre-load header verification: - Check that image verification fails Tests run with both SHA1 and SHA256 hashing. + +This also tests fdt_add_pubkey utility in the simple way: +- Create DTB and FIT files +- Add keys with fdt_add_pubkey to DTB +- Sign FIT image +- Check with fit_check_sign that keys properly added to DTB file """ import os @@ -40,6 +46,41 @@ import u_boot_utils as util import vboot_forge import vboot_evil +# Common helper functions +def dtc(dts, cons, dtc_args, datadir, tmpdir, dtb): + """Run the device tree compiler to compile a .dts file + + The output file will be the same as the input file but with a .dtb + extension. + + Args: + dts: Device tree file to compile. + cons: U-Boot console. + dtc_args: DTC arguments. + datadir: Path to data directory. + tmpdir: Path to temp directory. + dtb: Resulting DTB file. + """ + dtb = dts.replace('.dts', '.dtb') + util.run_and_log(cons, 'dtc %s %s%s -O dtb ' + '-o %s%s' % (dtc_args, datadir, dts, tmpdir, dtb)) + +def make_fit(its, cons, mkimage, dtc_args, datadir, fit): + """Make a new FIT from the .its source file. + + This runs 'mkimage -f' to create a new FIT. + + Args: + its: Filename containing .its source. + cons: U-Boot console. + mkimage: Path to mkimage utility. + dtc_args: DTC arguments. + datadir: Path to data directory. + fit: Resulting FIT file. + """ + util.run_and_log(cons, [mkimage, '-D', dtc_args, '-f', + '%s%s' % (datadir, its), fit]) + # Only run the full suite on a few combinations, since it doesn't add any more # test coverage. TESTDATA_IN = [ @@ -82,19 +123,6 @@ def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required, The SHA1 and SHA256 tests are combined into a single test since the key-generation process is quite slow and we want to avoid doing it twice. """ - def dtc(dts): - """Run the device tree compiler to compile a .dts file - - The output file will be the same as the input file but with a .dtb - extension. - - Args: - dts: Device tree file to compile. - """ - dtb = dts.replace('.dts', '.dtb') - util.run_and_log(cons, 'dtc %s %s%s -O dtb ' - '-o %s%s' % (dtc_args, datadir, dts, tmpdir, dtb)) - def dtc_options(dts, options): """Run the device tree compiler to compile a .dts file @@ -152,17 +180,6 @@ def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required, assert('sandbox: continuing, as we cannot run' not in ''.join(output)) - def make_fit(its): - """Make a new FIT from the .its source file. - - This runs 'mkimage -f' to create a new FIT. - - Args: - its: Filename containing .its source. - """ - util.run_and_log(cons, [mkimage, '-D', dtc_args, '-f', - '%s%s' % (datadir, its), fit]) - def sign_fit(sha_algo, options): """Sign the FIT @@ -286,12 +303,12 @@ def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required, # Compile our device tree files for kernel and U-Boot. These are # regenerated here since mkimage will modify them (by adding a # public key) below. - dtc('sandbox-kernel.dts') - dtc('sandbox-u-boot.dts') + dtc('sandbox-kernel.dts', cons, dtc_args, datadir, tmpdir, dtb) + dtc('sandbox-u-boot.dts', cons, dtc_args, datadir, tmpdir, dtb) # Build the FIT, but don't sign anything yet cons.log.action('%s: Test FIT with signed images' % sha_algo) - make_fit('sign-images-%s%s.its' % (sha_algo, padding)) + make_fit('sign-images-%s%s.its' % (sha_algo, padding), cons, mkimage, dtc_args, datadir, fit) run_bootm(sha_algo, 'unsigned images', ' - OK' if algo_arg else 'dev-', True) # Sign images with our dev keys @@ -299,10 +316,10 @@ def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required, run_bootm(sha_algo, 'signed images', 'dev+', True) # Create a fresh .dtb without the public keys - dtc('sandbox-u-boot.dts') + dtc('sandbox-u-boot.dts', cons, dtc_args, datadir, tmpdir, dtb) cons.log.action('%s: Test FIT with signed configuration' % sha_algo) - make_fit('sign-configs-%s%s.its' % (sha_algo, padding)) + make_fit('sign-configs-%s%s.its' % (sha_algo, padding), cons, mkimage, dtc_args, datadir, fit) run_bootm(sha_algo, 'unsigned config', '%s+ OK' % ('sha256' if algo_arg else sha_algo), True) # Sign images with our dev keys @@ -352,7 +369,7 @@ def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required, run_bootm(sha_algo, 'evil kernel@', msg, False, efit) # Create a new properly signed fit and replace header bytes - make_fit('sign-configs-%s%s.its' % (sha_algo, padding)) + make_fit('sign-configs-%s%s.its' % (sha_algo, padding), cons, mkimage, dtc_args, datadir, fit) sign_fit(sha_algo, sign_options) bcfg = u_boot_console.config.buildconfig max_size = int(bcfg.get('config_fit_signature_max_size', 0x10000000), 0) @@ -399,19 +416,19 @@ def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required, # Compile our device tree files for kernel and U-Boot. These are # regenerated here since mkimage will modify them (by adding a # public key) below. - dtc('sandbox-kernel.dts') - dtc('sandbox-u-boot.dts') + dtc('sandbox-kernel.dts', cons, dtc_args, datadir, tmpdir, dtb) + dtc('sandbox-u-boot.dts', cons, dtc_args, datadir, tmpdir, dtb) cons.log.action('%s: Test FIT with configs images' % sha_algo) # Build the FIT with prod key (keys required) and sign it. This puts the # signature into sandbox-u-boot.dtb, marked 'required' - make_fit('sign-configs-%s%s-prod.its' % (sha_algo, padding)) + make_fit('sign-configs-%s%s-prod.its' % (sha_algo, padding), cons, mkimage, dtc_args, datadir, fit) sign_fit(sha_algo, sign_options) # Build the FIT with dev key (keys NOT required). This adds the # signature into sandbox-u-boot.dtb, NOT marked 'required'. - make_fit('sign-configs-%s%s.its' % (sha_algo, padding)) + make_fit('sign-configs-%s%s.its' % (sha_algo, padding), cons, mkimage, dtc_args, datadir, fit) sign_fit_norequire(sha_algo, sign_options) # So now sandbox-u-boot.dtb two signatures, for the prod and dev keys. @@ -423,7 +440,7 @@ def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required, # Build the FIT with dev key (keys required) and sign it. This puts the # signature into sandbox-u-boot.dtb, marked 'required'. - make_fit('sign-configs-%s%s.its' % (sha_algo, padding)) + make_fit('sign-configs-%s%s.its' % (sha_algo, padding), cons, mkimage, dtc_args, datadir, fit) sign_fit(sha_algo, sign_options) # Set the required-mode policy to "any". @@ -461,17 +478,17 @@ def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required, # Compile our device tree files for kernel and U-Boot. These are # regenerated here since mkimage will modify them (by adding a # public key) below. - dtc('sandbox-kernel.dts') + dtc('sandbox-kernel.dts', cons, dtc_args, datadir, tmpdir, dtb) dtc_options('sandbox-u-boot-global%s.dts' % padding, '-p 1024') # Build the FIT with dev key (keys NOT required). This adds the # signature into sandbox-u-boot.dtb, NOT marked 'required'. - make_fit('simple-images.its') + make_fit('simple-images.its', cons, mkimage, dtc_args, datadir, fit) sign_fit_dtb(sha_algo, '', dtb) # Build the dtb for binman that define the pre-load header # with the global sigature. - dtc('sandbox-binman%s.dts' % padding) + dtc('sandbox-binman%s.dts' % padding, cons, dtc_args, datadir, tmpdir, dtb) # Run binman to create the final image with the not signed fit # and the pre-load header that contains the global signature. @@ -531,3 +548,96 @@ def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required, # Go back to the original U-Boot with the correct dtb. cons.config.dtb = old_dtb cons.restart_uboot() + + +TESTDATA_IN = [ + ['sha1-basic', 'sha1', '', None, False], + ['sha1-pad', 'sha1', '', '-E -p 0x10000', False], + ['sha1-pss', 'sha1', '-pss', None, False], + ['sha1-pss-pad', 'sha1', '-pss', '-E -p 0x10000', False], + ['sha256-basic', 'sha256', '', None, False], + ['sha256-pad', 'sha256', '', '-E -p 0x10000', False], + ['sha256-pss', 'sha256', '-pss', None, False], + ['sha256-pss-pad', 'sha256', '-pss', '-E -p 0x10000', False], + ['sha256-pss-required', 'sha256', '-pss', None, False], + ['sha256-pss-pad-required', 'sha256', '-pss', '-E -p 0x10000', False], + ['sha384-basic', 'sha384', '', None, False], + ['sha384-pad', 'sha384', '', '-E -p 0x10000', False], + ['algo-arg', 'algo-arg', '', '-o sha256,rsa2048', True], + ['sha256-global-sign', 'sha256', '', '', False], + ['sha256-global-sign-pss', 'sha256', '-pss', '', False], +] + +# Mark all but the first test as slow, so they are not run with '-k not slow' +TESTDATA = [TESTDATA_IN[0]] +TESTDATA += [pytest.param(*v, marks=pytest.mark.slow) for v in TESTDATA_IN[1:]] + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('fit_signature') +@pytest.mark.requiredtool('dtc') +@pytest.mark.requiredtool('openssl') +@pytest.mark.parametrize("name,sha_algo,padding,sign_options,algo_arg", TESTDATA) +def test_fdt_add_pubkey(u_boot_console, name, sha_algo, padding, sign_options, algo_arg): + """Test fdt_add_pubkey utility with bunch of different algo options.""" + + def sign_fit(sha_algo, options): + """Sign the FIT + + Signs the FIT and writes the signature into it. + + Args: + sha_algo: Either 'sha1' or 'sha256', to select the algorithm to + use. + options: Options to provide to mkimage. + """ + args = [mkimage, '-F', '-k', tmpdir, fit] + if options: + args += options.split(' ') + cons.log.action('%s: Sign images' % sha_algo) + util.run_and_log(cons, args) + + def test_add_pubkey(sha_algo, padding, sign_options): + """Test fdt_add_pubkey utility with given hash algorithm and padding. + + This function tests if fdt_add_pubkey utility may add public keys into dtb. + + Args: + sha_algo: Either 'sha1' or 'sha256', to select the algorithm to use + padding: Either '' or '-pss', to select the padding to use for the + rsa signature algorithm. + sign_options: Options to mkimage when signing a fit image. + """ + + # Create a fresh .dtb without the public keys + dtc('sandbox-u-boot.dts', cons, dtc_args, datadir, tmpdir, dtb) + + cons.log.action('%s: Test fdt_add_pubkey with signed configuration' % sha_algo) + # Then add the dev key via the fdt_add_pubkey tool + util.run_and_log(cons, [fdt_add_pubkey, '-a', '%s,%s' % ('sha256' if algo_arg else sha_algo, \ + 'rsa3072' if sha_algo == 'sha384' else 'rsa2048'), + '-k', tmpdir, '-n', 'dev', '-r', 'conf', dtb]) + + make_fit('sign-configs-%s%s.its' % (sha_algo, padding), cons, mkimage, dtc_args, datadir, fit) + + # Sign images with our dev keys + sign_fit(sha_algo, sign_options) + + # Check with fit_check_sign that FIT is signed with key + util.run_and_log(cons, [fit_check_sign, '-f', fit, '-k', dtb]) + + cons = u_boot_console + tmpdir = os.path.join(cons.config.result_dir, name) + '/' + if not os.path.exists(tmpdir): + os.mkdir(tmpdir) + datadir = cons.config.source_dir + '/test/py/tests/vboot/' + fit = '%stest.fit' % tmpdir + mkimage = cons.config.build_dir + '/tools/mkimage' + binman = cons.config.source_dir + '/tools/binman/binman' + fit_check_sign = cons.config.build_dir + '/tools/fit_check_sign' + fdt_add_pubkey = cons.config.build_dir + '/tools/fdt_add_pubkey' + dtc_args = '-I dts -O dtb -i %s' % tmpdir + dtb = '%ssandbox-u-boot.dtb' % tmpdir + + # keys created in test_vboot test + + test_add_pubkey(sha_algo, padding, sign_options) diff --git a/test/py/u_boot_utils.py b/test/py/u_boot_utils.py index c4fc23aeda..9e161fbc23 100644 --- a/test/py/u_boot_utils.py +++ b/test/py/u_boot_utils.py @@ -157,7 +157,7 @@ def wait_until_file_open_fails(fn, ignore_errors): return raise Exception('File can still be opened') -def run_and_log(u_boot_console, cmd, ignore_errors=False, stdin=None): +def run_and_log(u_boot_console, cmd, ignore_errors=False, stdin=None, env=None): """Run a command and log its output. Args: @@ -170,6 +170,7 @@ def run_and_log(u_boot_console, cmd, ignore_errors=False, stdin=None): an error code, otherwise an exception will be raised if such problems occur. stdin: Input string to pass to the command as stdin (or None) + env: Environment to use, or None to use the current one Returns: The output as a string. @@ -177,7 +178,7 @@ def run_and_log(u_boot_console, cmd, ignore_errors=False, stdin=None): if isinstance(cmd, str): cmd = cmd.split() runner = u_boot_console.log.get_runner(cmd[0], sys.stdout) - output = runner.run(cmd, ignore_errors=ignore_errors, stdin=stdin) + output = runner.run(cmd, ignore_errors=ignore_errors, stdin=stdin, env=env) runner.close() return output @@ -56,6 +56,11 @@ echo "${prompt}" run_test "sandbox_noinst" ./test/py/test.py --bd sandbox_noinst --build ${para} \ -k 'test_ofplatdata or test_handoff or test_spl' +# Run tests which require sandbox_vpl +echo "${prompt}" +run_test "sandbox_vpl" ./test/py/test.py --bd sandbox_vpl --build ${para} \ + -k 'vpl or test_spl' + if [ -z "$tools_only" ]; then # Run tests for the flat-device-tree version of sandbox. This is a special # build which does not enable CONFIG_OF_LIVE for the live device tree, so we can @@ -76,6 +81,7 @@ TOOLS_DIR=build-sandbox_spl/tools run_test "binman" ./tools/binman/binman --toolpath ${TOOLS_DIR} test run_test "patman" ./tools/patman/patman test +run_test "u_boot_pylib" ./tools/u_boot_pylib/u_boot_pylib run_test "buildman" ./tools/buildman/buildman -t ${skip} run_test "fdt" ./tools/dtoc/test_fdt -t diff --git a/test/test-main.c b/test/test-main.c index ea959f4e85..b3c30d9293 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -46,14 +46,14 @@ enum fdtchk_t { */ static enum fdtchk_t fdt_action(void) { - /* Do a copy for sandbox (but only the U-Boot build, not SPL) */ - if (CONFIG_IS_ENABLED(SANDBOX)) - return FDTCHK_COPY; - /* For sandbox SPL builds, do nothing */ - if (IS_ENABLED(CONFIG_SANDBOX)) + if (IS_ENABLED(CONFIG_SANDBOX) && IS_ENABLED(CONFIG_SPL_BUILD)) return FDTCHK_NONE; + /* Do a copy for sandbox (but only the U-Boot build, not SPL) */ + if (IS_ENABLED(CONFIG_SANDBOX)) + return FDTCHK_COPY; + /* For all other boards, do a checksum */ return FDTCHK_CHECKSUM; } diff --git a/test/unicode_ut.c b/test/unicode_ut.c index 382b796516..b27d7116b9 100644 --- a/test/unicode_ut.c +++ b/test/unicode_ut.c @@ -192,7 +192,7 @@ static int unicode_test_utf8_get(struct unit_test_state *uts) if (!code) break; } - ut_asserteq_ptr(s, d2 + 9) + ut_asserteq_ptr(s, d2 + 9); /* Check characters less than 0x10000 */ s = d3; @@ -203,7 +203,7 @@ static int unicode_test_utf8_get(struct unit_test_state *uts) if (!code) break; } - ut_asserteq_ptr(s, d3 + 9) + ut_asserteq_ptr(s, d3 + 9); /* Check character greater 0xffff */ s = d4; @@ -228,7 +228,7 @@ static int unicode_test_utf8_put(struct unit_test_state *uts) /* Commercial at, translates to one character */ pos = buffer; - ut_assert(!utf8_put('@', &pos)) + ut_assert(!utf8_put('@', &pos)); ut_asserteq(1, pos - buffer); ut_asserteq('@', buffer[0]); ut_assert(!buffer[1]); |