From 331048471dee5c1d9cede54382256e6cfaee2370 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:08 -0600 Subject: dm: core: Introduce support for multiple trees At present ofnode only works with a single device tree, for the most part. This is the control FDT used by U-Boot. When booting an OS we may obtain a different device tree and want to modify it. Add some initial support for this into the ofnode API. Note that we don't permit aliases in this other device tree, since the of_access implementation maintains a list of aliases collected at start-up. Also, we don't need aliases to do fixups in the other FDT. So make sure that flat tree and live tree processing are consistent in this area. Signed-off-by: Simon Glass --- test/dm/ofnode.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'test') diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 61ae1db62d7..6a252f3f504 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -469,3 +470,69 @@ static int dm_test_ofnode_get_phy(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_ofnode_get_phy, 0); + +/** + * make_ofnode_fdt() - Create an FDT for testing with ofnode + * + * The size is set to the minimum needed + * + * @uts: Test state + * @fdt: Place to write FDT + * @size: Maximum size of space for fdt + */ +static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size) +{ + ut_assertok(fdt_create(fdt, size)); + ut_assertok(fdt_finish_reservemap(fdt)); + ut_assert(fdt_begin_node(fdt, "") >= 0); + + ut_assert(fdt_begin_node(fdt, "aliases") >= 0); + ut_assertok(fdt_property_string(fdt, "mmc0", "/new-mmc")); + ut_assertok(fdt_end_node(fdt)); + + ut_assert(fdt_begin_node(fdt, "new-mmc") >= 0); + ut_assertok(fdt_end_node(fdt)); + + ut_assertok(fdt_end_node(fdt)); + ut_assertok(fdt_finish(fdt)); + + return 0; +} + +static int dm_test_ofnode_root(struct unit_test_state *uts) +{ + struct device_node *root = NULL; + char fdt[256]; + oftree tree; + ofnode node; + + /* Check that aliases work on the control FDT */ + node = ofnode_get_aliases_node("ethernet3"); + ut_assert(ofnode_valid(node)); + ut_asserteq_str("sbe5", ofnode_get_name(node)); + + ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt))); + if (of_live_active()) { + ut_assertok(unflatten_device_tree(fdt, &root)); + tree.np = root; + } else { + tree.fdt = fdt; + } + + /* Make sure they don't work on this new tree */ + node = ofnode_path_root(tree, "mmc0"); + ut_assert(!ofnode_valid(node)); + + /* It should appear in the new tree */ + node = ofnode_path_root(tree, "/new-mmc"); + ut_assert(ofnode_valid(node)); + + /* ...and not in the control FDT */ + node = ofnode_path_root(oftree_default(), "/new-mmc"); + ut_assert(!ofnode_valid(node)); + + free(root); + + return 0; +} +DM_TEST(dm_test_ofnode_root, UT_TESTF_SCAN_FDT); -- cgit v1.2.3 From 6571559449cef5fe11678c25bc4fdf57b6a4e81f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:09 -0600 Subject: dm: core: Move ofnode-writing test to ofnode This fits better in the ofnode tests, so move it. Signed-off-by: Simon Glass --- test/dm/ofnode.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/dm/test-fdt.c | 53 --------------------------------------------------- 2 files changed, 56 insertions(+), 53 deletions(-) (limited to 'test') diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 6a252f3f504..b8d8e440dbc 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -4,8 +4,12 @@ #include #include #include +#include +#include #include +#include #include +#include #include #include @@ -536,3 +540,55 @@ static int dm_test_ofnode_root(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_ofnode_root, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) +{ + struct udevice *dev; + ofnode node; + + if (!of_live_active()) { + printf("Live tree not active; ignore test\n"); + return 0; + } + + /* Test enabling devices */ + + node = ofnode_path("/usb@2"); + + ut_assert(!of_device_is_available(ofnode_to_np(node))); + ofnode_set_enabled(node, true); + ut_assert(of_device_is_available(ofnode_to_np(node))); + + device_bind_driver_to_node(dm_root(), "usb_sandbox", "usb@2", node, + &dev); + ut_assertok(uclass_find_device_by_seq(UCLASS_USB, 2, &dev)); + + /* Test string property setting */ + + ut_assert(device_is_compatible(dev, "sandbox,usb")); + ofnode_write_string(node, "compatible", "gdsys,super-usb"); + ut_assert(device_is_compatible(dev, "gdsys,super-usb")); + ofnode_write_string(node, "compatible", "sandbox,usb"); + ut_assert(device_is_compatible(dev, "sandbox,usb")); + + /* Test setting generic properties */ + + /* Non-existent in DTB */ + ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr(dev)); + /* reg = 0x42, size = 0x100 */ + ut_assertok(ofnode_write_prop(node, "reg", 8, + "\x00\x00\x00\x42\x00\x00\x01\x00")); + ut_asserteq(0x42, dev_read_addr(dev)); + + /* Test disabling devices */ + + device_remove(dev, DM_REMOVE_NORMAL); + device_unbind(dev); + + ut_assert(of_device_is_available(ofnode_to_np(node))); + ofnode_set_enabled(node, false); + ut_assert(!of_device_is_available(ofnode_to_np(node))); + + return 0; +} +DM_TEST(dm_test_ofnode_livetree_writing, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index f9e81747595..6118ad42ca8 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -735,58 +734,6 @@ static int dm_test_fdt_remap_addr_name_live(struct unit_test_state *uts) DM_TEST(dm_test_fdt_remap_addr_name_live, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); -static int dm_test_fdt_livetree_writing(struct unit_test_state *uts) -{ - struct udevice *dev; - ofnode node; - - if (!of_live_active()) { - printf("Live tree not active; ignore test\n"); - return 0; - } - - /* Test enabling devices */ - - node = ofnode_path("/usb@2"); - - ut_assert(!of_device_is_available(ofnode_to_np(node))); - ofnode_set_enabled(node, true); - ut_assert(of_device_is_available(ofnode_to_np(node))); - - device_bind_driver_to_node(dm_root(), "usb_sandbox", "usb@2", node, - &dev); - ut_assertok(uclass_find_device_by_seq(UCLASS_USB, 2, &dev)); - - /* Test string property setting */ - - ut_assert(device_is_compatible(dev, "sandbox,usb")); - ofnode_write_string(node, "compatible", "gdsys,super-usb"); - ut_assert(device_is_compatible(dev, "gdsys,super-usb")); - ofnode_write_string(node, "compatible", "sandbox,usb"); - ut_assert(device_is_compatible(dev, "sandbox,usb")); - - /* Test setting generic properties */ - - /* Non-existent in DTB */ - ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr(dev)); - /* reg = 0x42, size = 0x100 */ - ut_assertok(ofnode_write_prop(node, "reg", 8, - "\x00\x00\x00\x42\x00\x00\x01\x00")); - ut_asserteq(0x42, dev_read_addr(dev)); - - /* Test disabling devices */ - - device_remove(dev, DM_REMOVE_NORMAL); - device_unbind(dev); - - ut_assert(of_device_is_available(ofnode_to_np(node))); - ofnode_set_enabled(node, false); - ut_assert(!of_device_is_available(ofnode_to_np(node))); - - return 0; -} -DM_TEST(dm_test_fdt_livetree_writing, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); - static int dm_test_fdt_disable_enable_by_path(struct unit_test_state *uts) { ofnode node; -- cgit v1.2.3 From be0789a8ee024e685f070dbd8c58736ea3891654 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:10 -0600 Subject: dm: core: Swap parameters of ofnode_write_prop() It is normal for the length to come after the value in libfdt. Follow this same convention with ofnode. Signed-off-by: Simon Glass --- test/dm/ofnode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index b8d8e440dbc..0aeaaeb7f8c 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -576,8 +576,8 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) /* Non-existent in DTB */ ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr(dev)); /* reg = 0x42, size = 0x100 */ - ut_assertok(ofnode_write_prop(node, "reg", 8, - "\x00\x00\x00\x42\x00\x00\x01\x00")); + ut_assertok(ofnode_write_prop(node, "reg", + "\x00\x00\x00\x42\x00\x00\x01\x00", 8)); ut_asserteq(0x42, dev_read_addr(dev)); /* Test disabling devices */ -- cgit v1.2.3 From b7eaa4f5e5b78cbf8b133f13e65412be55484d07 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:11 -0600 Subject: dm: core: Tidy up ofnode-writing test Update this test to use the livetree flag so that special check can be avoided. Also drop a few blank lines. Signed-off-by: Simon Glass --- test/dm/ofnode.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'test') diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 0aeaaeb7f8c..ce96f9d1ee2 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -546,13 +546,7 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) struct udevice *dev; ofnode node; - if (!of_live_active()) { - printf("Live tree not active; ignore test\n"); - return 0; - } - /* Test enabling devices */ - node = ofnode_path("/usb@2"); ut_assert(!of_device_is_available(ofnode_to_np(node))); @@ -564,7 +558,6 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) ut_assertok(uclass_find_device_by_seq(UCLASS_USB, 2, &dev)); /* Test string property setting */ - ut_assert(device_is_compatible(dev, "sandbox,usb")); ofnode_write_string(node, "compatible", "gdsys,super-usb"); ut_assert(device_is_compatible(dev, "gdsys,super-usb")); @@ -581,7 +574,6 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) ut_asserteq(0x42, dev_read_addr(dev)); /* Test disabling devices */ - device_remove(dev, DM_REMOVE_NORMAL); device_unbind(dev); @@ -591,4 +583,5 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_ofnode_livetree_writing, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +DM_TEST(dm_test_ofnode_livetree_writing, + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_TREE); -- cgit v1.2.3 From 7b1dfc9fd7e2efed345c3fe9a2412b5300ac285e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:12 -0600 Subject: dm: core: Prepare for updating the device tree with ofnode Add some documentation and a new flag so that we can safely enabled using the ofnode interface to write to the device tree. Signed-off-by: Simon Glass --- test/test-main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/test-main.c b/test/test-main.c index ee38d1faea8..c0d0378c5d8 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -338,7 +338,8 @@ static int ut_run_test_live_flat(struct unit_test_state *uts, /* Run with the live tree if possible */ runs = 0; if (CONFIG_IS_ENABLED(OF_LIVE)) { - if (!(test->flags & UT_TESTF_FLAT_TREE)) { + if (!(test->flags & + (UT_TESTF_FLAT_TREE | UT_TESTF_LIVE_OR_FLAT))) { uts->of_live = true; ut_assertok(ut_run_test(uts, test, test->name)); runs++; -- cgit v1.2.3 From 39e42be12b9456e604ac3e228973b1cb1136864c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:13 -0600 Subject: dm: core: Allow writing to a flat tree with ofnode In generally it is not permitted to implement an ofnode function only for flat tree or live tree. Both must be supported. Also the code for live tree access should be in of_access.c rather than ofnode.c which is really just for holding the API-conversion code. Update ofnode_write_prop() accordingly and fix the test so it can work with flat tree too. Signed-off-by: Simon Glass --- test/dm/ofnode.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index ce96f9d1ee2..bd598d23e44 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -549,9 +549,9 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) /* Test enabling devices */ node = ofnode_path("/usb@2"); - ut_assert(!of_device_is_available(ofnode_to_np(node))); - ofnode_set_enabled(node, true); - ut_assert(of_device_is_available(ofnode_to_np(node))); + ut_assert(!ofnode_is_enabled(node)); + ut_assertok(ofnode_set_enabled(node, true)); + ut_asserteq(true, ofnode_is_enabled(node)); device_bind_driver_to_node(dm_root(), "usb_sandbox", "usb@2", node, &dev); @@ -577,11 +577,11 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) device_remove(dev, DM_REMOVE_NORMAL); device_unbind(dev); - ut_assert(of_device_is_available(ofnode_to_np(node))); - ofnode_set_enabled(node, false); - ut_assert(!of_device_is_available(ofnode_to_np(node))); + ut_assert(ofnode_is_enabled(node)); + ut_assertok(ofnode_set_enabled(node, false)); + ut_assert(!ofnode_is_enabled(node)); return 0; } DM_TEST(dm_test_ofnode_livetree_writing, - UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_TREE); + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT); -- cgit v1.2.3 From 55f7990bfeb92c172065d5b53c59d5306cc554ca Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:14 -0600 Subject: dm: core: Add support for writing u32 with ofnode Add a new function to write an integer to an ofnode (live tree or flat tree). Signed-off-by: Simon Glass --- test/dm/ofnode.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'test') diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index bd598d23e44..f80993f8927 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -585,3 +585,19 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_livetree_writing, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT); + +static int dm_test_ofnode_u32(struct unit_test_state *uts) +{ + ofnode node; + + node = ofnode_path("/lcd"); + ut_assert(ofnode_valid(node)); + ut_asserteq(1366, ofnode_read_u32_default(node, "xres", 123)); + ut_assertok(ofnode_write_u32(node, "xres", 1367)); + ut_asserteq(1367, ofnode_read_u32_default(node, "xres", 123)); + ut_assertok(ofnode_write_u32(node, "xres", 1366)); + + return 0; +} +DM_TEST(dm_test_ofnode_u32, + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT); -- cgit v1.2.3 From f25f575acfffc47cc65fc50424b23b54118c3ada Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:16 -0600 Subject: bootstd: Drop delays in the tests Some tests go as far as booting a distribution. In this case a menu is presented to the user, with a two-second timeout. This adds a total of 12 seconds to the test runs at present. Avoid this by inserting a response using the console-recording feature. Signed-off-by: Simon Glass --- test/boot/bootflow.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'test') diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 1ebb789e97b..a2ed8ac774f 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -16,6 +16,22 @@ #include #include "bootstd_common.h" +static int inject_response(struct unit_test_state *uts) +{ + /* + * The image being booted presents a menu of options: + * + * Fedora-Workstation-armhfp-31-1.9 Boot Options. + * 1: Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl) + * Enter choice: + * + * Provide input for this, to avoid waiting two seconds for a timeout. + */ + ut_asserteq(2, console_in_puts("1\n")); + + return 0; +} + /* Check 'bootflow scan/list' commands */ static int bootflow_cmd(struct unit_test_state *uts) { @@ -188,6 +204,7 @@ BOOTSTD_TEST(bootflow_cmd_info, UT_TESTF_DM | UT_TESTF_SCAN_FDT); static int bootflow_scan_boot(struct unit_test_state *uts) { console_record_reset_enable(); + ut_assertok(inject_response(uts)); ut_assertok(run_command("bootflow scan -b", 0)); ut_assert_nextline( "** Booting bootflow 'mmc1.bootdev.part_1' with syslinux"); @@ -351,6 +368,8 @@ static int bootflow_iter_disable(struct unit_test_state *uts) ut_assertok(bootstd_test_drop_bootdev_order(uts)); bootstd_clear_glob(); + console_record_reset_enable(); + ut_assertok(inject_response(uts)); ut_assertok(run_command("bootflow scan -lb", 0)); /* Try to boot the bootmgr flow, which will fail */ @@ -358,6 +377,7 @@ static int bootflow_iter_disable(struct unit_test_state *uts) ut_assertok(bootflow_scan_first(&iter, 0, &bflow)); ut_asserteq(3, iter.num_methods); ut_asserteq_str("sandbox", iter.method->name); + ut_assertok(inject_response(uts)); ut_asserteq(-ENOTSUPP, bootflow_run_boot(&iter, &bflow)); ut_assert_skip_to_line("Boot method 'sandbox' failed and will not be retried"); @@ -382,6 +402,8 @@ static int bootflow_cmd_boot(struct unit_test_state *uts) ut_assert_console_end(); ut_assertok(run_command("bootflow select 0", 0)); ut_assert_console_end(); + + ut_assertok(inject_response(uts)); ut_asserteq(1, run_command("bootflow boot", 0)); ut_assert_nextline( "** Booting bootflow 'mmc1.bootdev.part_1' with syslinux"); -- cgit v1.2.3 From f1c8cbd944e097f2d03563316460baf926eeae39 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:17 -0600 Subject: bootstd: Fix comment in bootmeth test Correct the comment at the top of this file. Signed-off-by: Simon Glass --- test/boot/bootmeth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/boot/bootmeth.c b/test/boot/bootmeth.c index 07776c5368d..81421f550b5 100644 --- a/test/boot/bootmeth.c +++ b/test/boot/bootmeth.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Test for bootdev functions. All start with 'bootdev' + * Test for bootdev functions. All start with 'bootmeth' * * Copyright 2021 Google LLC * Written by Simon Glass -- cgit v1.2.3 From 988cacaeedae920c13741c9ab2fc580f63a06c3a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:19 -0600 Subject: bootstd: Provide a bootmeth method to obtain state info Some bootmeths can provide information about what is available to boot. For example, VBE simple provides access to the firmware state. Add a new method for this, along with a sandbox test. Signed-off-by: Simon Glass --- test/boot/bootmeth.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'test') diff --git a/test/boot/bootmeth.c b/test/boot/bootmeth.c index 81421f550b5..5d2e87b1c95 100644 --- a/test/boot/bootmeth.c +++ b/test/boot/bootmeth.c @@ -7,7 +7,9 @@ */ #include +#include #include +#include #include #include #include "bootstd_common.h" @@ -120,3 +122,19 @@ static int bootmeth_env(struct unit_test_state *uts) return 0; } BOOTSTD_TEST(bootmeth_env, UT_TESTF_DM | UT_TESTF_SCAN_FDT); + +/* Check the get_state_desc() method */ +static int bootmeth_state(struct unit_test_state *uts) +{ + struct udevice *dev; + char buf[50]; + + ut_assertok(uclass_first_device(UCLASS_BOOTMETH, &dev)); + ut_assertnonnull(dev); + + ut_assertok(bootmeth_get_state_desc(dev, buf, sizeof(buf))); + ut_asserteq_str("OK", buf); + + return 0; +} +BOOTSTD_TEST(bootmeth_state, UT_TESTF_DM | UT_TESTF_SCAN_FDT); -- cgit v1.2.3 From 2662b54d70fc04f070f0e4a9742d4b3197c9f3ea Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:22 -0600 Subject: bootstd: Allow EFI bootmgr to support an invalid bootflow For most testing we don't want this bootmeth to actually do anything. For the one test where we do, add a test hook to obtain the correct behaviour. This will allow us to bind the device always, rather than just doing it for this test. Signed-off-by: Simon Glass --- test/boot/bootflow.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'test') diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index a2ed8ac774f..22eef40c0e3 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include #include @@ -328,6 +330,8 @@ static int bootflow_system(struct unit_test_state *uts) ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd)); ut_assertok(device_bind_driver(bootstd, "bootmeth_efi_mgr", "bootmgr", &dev)); + ut_assertok(device_probe(dev)); + sandbox_set_fake_efi_mgr_dev(dev, true); /* Add the system bootdev that it uses */ ut_assertok(device_bind_driver(bootstd, "system_bootdev", -- cgit v1.2.3 From ee8ab07e3039d945889dccd8e8ab7adfb9f8c30c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:26 -0600 Subject: dm: core: Call dm_scan_other() when setting up for tests At present this function is not called, so tests miss out on any devices created by it. Add it in so that tests can rely on these extra devices. Signed-off-by: Simon Glass --- test/test-main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/test-main.c b/test/test-main.c index c0d0378c5d8..31837e57a8f 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -228,8 +228,10 @@ static int test_pre_run(struct unit_test_state *uts, struct unit_test *test) uts->start = mallinfo(); - if (test->flags & UT_TESTF_SCAN_PDATA) + if (test->flags & UT_TESTF_SCAN_PDATA) { ut_assertok(dm_scan_plat(false)); + ut_assertok(dm_scan_other(false)); + } if (test->flags & UT_TESTF_PROBE_TEST) ut_assertok(do_autoprobe(uts)); -- cgit v1.2.3 From c627cfc14c08a803f5aa9e39d841dcf990d8d034 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:27 -0600 Subject: bootstd: Allow scanning for global bootmeths separately Typically we want to find and use global bootmeths first, since they have the best idea of how the system should boot. We then use normal bootmeths as a fallback. Add the logic for this, putting global bootmeths at the end of the ordering. We can then easily scan the global bootmeths first, then drop them from the list for subsequent bootdev-centric scans. This changes the ordering of global bootmeths, so update the bootflow_system() accordingly. Drop the comment from bootmeth_setup_iter_order() since this is an exported function and it should be in the header file. Signed-off-by: Simon Glass --- test/boot/bootflow.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 22eef40c0e3..07b0517718e 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -343,8 +343,9 @@ static int bootflow_system(struct unit_test_state *uts) bootstd_clear_glob(); console_record_reset_enable(); ut_assertok(run_command("bootflow scan -l", 0)); - ut_assert_skip_to_line(" 1 bootmgr ready bootstd 0 "); - ut_assert_nextline("No more bootdevs"); + ut_assert_skip_to_line( + " 0 bootmgr ready (none) 0 "); + ut_assert_skip_to_line("No more bootdevs"); ut_assert_skip_to_line("(2 bootflows, 2 valid)"); ut_assert_console_end(); -- cgit v1.2.3 From bd18b69de10d1a681e760f2ee65b3de29d3006fd Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:28 -0600 Subject: bootstd: Always create the EFI bootmgr bootmeth Now that we can separate this out from the normal bootmeths, update the code to create it always. We cannot rely on the device tree to create this, since the EFI project is quite opposed to having anything in the device tree that helps U-Boot with its processing. Signed-off-by: Simon Glass --- test/boot/bootflow.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'test') diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 07b0517718e..b2f77972d1f 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -324,34 +324,26 @@ BOOTSTD_TEST(bootflow_iter, UT_TESTF_DM | UT_TESTF_SCAN_FDT); /* Check using the system bootdev */ static int bootflow_system(struct unit_test_state *uts) { - struct udevice *bootstd, *dev; + struct udevice *dev; - /* Add the EFI bootmgr driver */ - ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd)); - ut_assertok(device_bind_driver(bootstd, "bootmeth_efi_mgr", "bootmgr", - &dev)); - ut_assertok(device_probe(dev)); + ut_assertok(uclass_get_device_by_name(UCLASS_BOOTMETH, "efi_mgr", + &dev)); sandbox_set_fake_efi_mgr_dev(dev, true); - /* Add the system bootdev that it uses */ - ut_assertok(device_bind_driver(bootstd, "system_bootdev", - "system-bootdev", &dev)); - - ut_assertok(bootstd_test_drop_bootdev_order(uts)); - /* We should get a single 'bootmgr' method right at the end */ bootstd_clear_glob(); console_record_reset_enable(); ut_assertok(run_command("bootflow scan -l", 0)); ut_assert_skip_to_line( - " 0 bootmgr ready (none) 0 "); + " 0 efi_mgr ready (none) 0 "); ut_assert_skip_to_line("No more bootdevs"); - ut_assert_skip_to_line("(2 bootflows, 2 valid)"); + ut_assert_skip_to_line("(6 bootflows, 6 valid)"); ut_assert_console_end(); return 0; } -BOOTSTD_TEST(bootflow_system, UT_TESTF_DM | UT_TESTF_SCAN_FDT); +BOOTSTD_TEST(bootflow_system, UT_TESTF_DM | UT_TESTF_SCAN_PDATA | + UT_TESTF_SCAN_FDT); /* Check disabling a bootmethod if it requests it */ static int bootflow_iter_disable(struct unit_test_state *uts) -- cgit v1.2.3 From 2ff5490d7dee933eaf0b73d4d50d76660e5da6ff Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:29 -0600 Subject: bootstd: Drop the system bootdev This was a work-around for the fact that global bootmeths such as EFI bootmgr and VBE don't use a particular bootdev, or at least select it themselves so that we don't need to scan all bootdevs when using that bootmeth. Drop the system bootdev entirely. Signed-off-by: Simon Glass --- test/boot/bootflow.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'test') diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index b2f77972d1f..39c2c33dead 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -337,7 +336,7 @@ static int bootflow_system(struct unit_test_state *uts) ut_assert_skip_to_line( " 0 efi_mgr ready (none) 0 "); ut_assert_skip_to_line("No more bootdevs"); - ut_assert_skip_to_line("(6 bootflows, 6 valid)"); + ut_assert_skip_to_line("(5 bootflows, 5 valid)"); ut_assert_console_end(); return 0; @@ -358,10 +357,6 @@ static int bootflow_iter_disable(struct unit_test_state *uts) ut_assertok(device_bind_driver(bootstd, "bootmeth_sandbox", "sandbox", &dev)); - /* Add the system bootdev that it uses */ - ut_assertok(device_bind_driver(bootstd, "system_bootdev", - "system-bootdev", &dev)); - ut_assertok(bootstd_test_drop_bootdev_order(uts)); bootstd_clear_glob(); -- cgit v1.2.3 From 98887ab802e4118e7c813e5e052678772fa1b3a8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:31 -0600 Subject: event: Add an event for device tree fixups At present there is a confusing array of functions that handle the device tree fix-ups needed for booting an OS. We should be able to switch to using events to clean this up. As a first step, create a new event type and call it from the standard place. Note that this event uses the ofnode interface only, since this can support live tree which is more efficient when making lots of updates. Signed-off-by: Simon Glass --- test/py/tests/test_event_dump.py | 1 + 1 file changed, 1 insertion(+) (limited to 'test') diff --git a/test/py/tests/test_event_dump.py b/test/py/tests/test_event_dump.py index b753e804ac3..17001777247 100644 --- a/test/py/tests/test_event_dump.py +++ b/test/py/tests/test_event_dump.py @@ -16,5 +16,6 @@ def test_event_dump(u_boot_console): out = util.run_and_log(cons, ['scripts/event_dump.py', sandbox]) expect = '''.*Event type Id Source location -------------------- ------------------------------ ------------------------------ +EVT_FT_FIXUP bootmeth_vbe_simple_ft_fixup boot/vbe_simple.c:.* EVT_MISC_INIT_F sandbox_misc_init_f .*arch/sandbox/cpu/start.c:''' assert re.match(expect, out, re.MULTILINE) is not None -- cgit v1.2.3 From cb47e21acbc4c404214623de1d4a306452ec466d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:33 -0600 Subject: vbe: Support VBE simple Add support for VBE simple, which permits firmware update of a single image stored in MMC or another block device. Signed-off-by: Simon Glass --- test/py/tests/test_event_dump.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/py/tests/test_event_dump.py b/test/py/tests/test_event_dump.py index 17001777247..bc54149e8f2 100644 --- a/test/py/tests/test_event_dump.py +++ b/test/py/tests/test_event_dump.py @@ -16,6 +16,6 @@ def test_event_dump(u_boot_console): out = util.run_and_log(cons, ['scripts/event_dump.py', sandbox]) expect = '''.*Event type Id Source location -------------------- ------------------------------ ------------------------------ -EVT_FT_FIXUP bootmeth_vbe_simple_ft_fixup boot/vbe_simple.c:.* +EVT_FT_FIXUP bootmeth_vbe_simple_ft_fixup .*boot/vbe_simple.c:.* EVT_MISC_INIT_F sandbox_misc_init_f .*arch/sandbox/cpu/start.c:''' assert re.match(expect, out, re.MULTILINE) is not None -- cgit v1.2.3 From 0917f77393126c4658c47609366ecf582f936103 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:34 -0600 Subject: bootstd: Add vbe bootmeth into sandbox Update sandbox to include the VBE bootmeth. Update a few existing tests to take account of this change, specifically that the new bootmeth now appears when scanning. Signed-off-by: Simon Glass --- test/boot/Makefile | 4 ++++ test/boot/bootflow.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- test/boot/bootmeth.c | 25 +++++++++++++++++++++---- 3 files changed, 68 insertions(+), 8 deletions(-) (limited to 'test') diff --git a/test/boot/Makefile b/test/boot/Makefile index 1730792b5fa..9e9d5ae21f3 100644 --- a/test/boot/Makefile +++ b/test/boot/Makefile @@ -3,3 +3,7 @@ # Copyright 2021 Google LLC obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o + +ifdef CONFIG_OF_LIVE +obj-$(CONFIG_BOOTMETH_VBE_SIMPLE) += vbe_simple.o +endif diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 39c2c33dead..d2c42e8b060 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -90,7 +91,7 @@ static int bootflow_cmd_glob(struct unit_test_state *uts) ut_assertok(bootstd_test_drop_bootdev_order(uts)); console_record_reset_enable(); - ut_assertok(run_command("bootflow scan -l", 0)); + ut_assertok(run_command("bootflow scan -lG", 0)); ut_assert_nextline("Scanning for bootflows in all bootdevs"); ut_assert_nextline("Seq Method State Uclass Part Name Filename"); ut_assert_nextlinen("---"); @@ -122,7 +123,7 @@ static int bootflow_cmd_scan_e(struct unit_test_state *uts) ut_assertok(bootstd_test_drop_bootdev_order(uts)); console_record_reset_enable(); - ut_assertok(run_command("bootflow scan -ale", 0)); + ut_assertok(run_command("bootflow scan -aleG", 0)); ut_assert_nextline("Scanning for bootflows in all bootdevs"); ut_assert_nextline("Seq Method State Uclass Part Name Filename"); ut_assert_nextlinen("---"); @@ -233,7 +234,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(&iter, BOOTFLOWF_ALL, &bflow)); + bootflow_scan_first(&iter, BOOTFLOWF_ALL | BOOTFLOWF_SKIP_GLOBAL, &bflow)); ut_asserteq(2, iter.num_methods); ut_asserteq(0, iter.cur_method); ut_asserteq(0, iter.part); @@ -242,7 +243,7 @@ static int bootflow_iter(struct unit_test_state *uts) ut_asserteq(0, bflow.err); /* - * This shows MEDIA even though there is none, since int + * This shows MEDIA even though there is none, since in * bootdev_find_in_blk() we call part_get_info() which returns * -EPROTONOSUPPORT. Ideally it would return -EEOPNOTSUPP and we would * know. @@ -384,6 +385,44 @@ static int bootflow_iter_disable(struct unit_test_state *uts) } BOOTSTD_TEST(bootflow_iter_disable, UT_TESTF_DM | UT_TESTF_SCAN_FDT); +/* Check 'bootflow scan' with a bootmeth ordering including a global bootmeth */ +static int bootflow_scan_glob_bootmeth(struct unit_test_state *uts) +{ + ut_assertok(bootstd_test_drop_bootdev_order(uts)); + + /* + * Make sure that the -G flag makes the scan fail, since this is not + * supported when an ordering is provided + */ + console_record_reset_enable(); + ut_assertok(bootmeth_set_order("efi firmware0")); + ut_assertok(run_command("bootflow scan -lG", 0)); + ut_assert_nextline("Scanning for bootflows in all bootdevs"); + ut_assert_nextline( + "Seq Method State Uclass Part Name Filename"); + ut_assert_nextlinen("---"); + ut_assert_nextlinen("---"); + ut_assert_nextline("(0 bootflows, 0 valid)"); + ut_assert_console_end(); + + ut_assertok(run_command("bootflow scan -l", 0)); + ut_assert_nextline("Scanning for bootflows in all bootdevs"); + ut_assert_nextline( + "Seq Method State Uclass Part Name Filename"); + ut_assert_nextlinen("---"); + ut_assert_nextline("Scanning global bootmeth 'firmware0':"); + ut_assert_nextline("Scanning bootdev 'mmc2.bootdev':"); + ut_assert_nextline("Scanning bootdev 'mmc1.bootdev':"); + ut_assert_nextline("Scanning bootdev 'mmc0.bootdev':"); + ut_assert_nextline("No more bootdevs"); + ut_assert_nextlinen("---"); + ut_assert_nextline("(0 bootflows, 0 valid)"); + ut_assert_console_end(); + + return 0; +} +BOOTSTD_TEST(bootflow_scan_glob_bootmeth, UT_TESTF_DM | UT_TESTF_SCAN_FDT); + /* Check 'bootflow boot' to boot a selected bootflow */ static int bootflow_cmd_boot(struct unit_test_state *uts) { diff --git a/test/boot/bootmeth.c b/test/boot/bootmeth.c index 5d2e87b1c95..ae216293d64 100644 --- a/test/boot/bootmeth.c +++ b/test/boot/bootmeth.c @@ -23,8 +23,9 @@ static int bootmeth_cmd_list(struct unit_test_state *uts) ut_assert_nextlinen("---"); ut_assert_nextline(" 0 0 syslinux Syslinux boot from a block device"); ut_assert_nextline(" 1 1 efi EFI boot from an .efi file"); + ut_assert_nextline(" glob 2 firmware0 VBE simple"); ut_assert_nextlinen("---"); - ut_assert_nextline("(2 bootmeths)"); + ut_assert_nextline("(3 bootmeths)"); ut_assert_console_end(); return 0; @@ -56,8 +57,9 @@ static int bootmeth_cmd_order(struct unit_test_state *uts) ut_assert_nextlinen("---"); ut_assert_nextline(" 0 0 syslinux Syslinux boot from a block device"); ut_assert_nextline(" - 1 efi EFI boot from an .efi file"); + ut_assert_nextline(" glob 2 firmware0 VBE simple"); ut_assert_nextlinen("---"); - ut_assert_nextline("(2 bootmeths)"); + ut_assert_nextline("(3 bootmeths)"); ut_assert_console_end(); /* Check the -a flag with the reverse order */ @@ -68,8 +70,9 @@ static int bootmeth_cmd_order(struct unit_test_state *uts) ut_assert_nextlinen("---"); ut_assert_nextline(" 1 0 syslinux Syslinux boot from a block device"); ut_assert_nextline(" 0 1 efi EFI boot from an .efi file"); + ut_assert_nextline(" glob 2 firmware0 VBE simple"); ut_assert_nextlinen("---"); - ut_assert_nextline("(2 bootmeths)"); + ut_assert_nextline("(3 bootmeths)"); ut_assert_console_end(); /* Now reset the order to empty, which should show all of them again */ @@ -77,7 +80,7 @@ static int bootmeth_cmd_order(struct unit_test_state *uts) ut_assert_console_end(); ut_assertnull(env_get("bootmeths")); ut_assertok(run_command("bootmeth list", 0)); - ut_assert_skip_to_line("(2 bootmeths)"); + ut_assert_skip_to_line("(3 bootmeths)"); /* Try reverse order */ ut_assertok(run_command("bootmeth order \"efi syslinux\"", 0)); @@ -93,6 +96,20 @@ static int bootmeth_cmd_order(struct unit_test_state *uts) ut_asserteq_str("efi syslinux", env_get("bootmeths")); ut_assert_console_end(); + /* Try with global bootmeths */ + ut_assertok(run_command("bootmeth order \"efi firmware0\"", 0)); + ut_assert_console_end(); + ut_assertok(run_command("bootmeth list", 0)); + ut_assert_nextline("Order Seq Name Description"); + ut_assert_nextlinen("---"); + ut_assert_nextline(" 0 1 efi EFI boot from an .efi file"); + ut_assert_nextline(" glob 2 firmware0 VBE simple"); + ut_assert_nextlinen("---"); + ut_assert_nextline("(2 bootmeths)"); + ut_assertnonnull(env_get("bootmeths")); + ut_asserteq_str("efi firmware0", env_get("bootmeths")); + ut_assert_console_end(); + return 0; } BOOTSTD_TEST(bootmeth_cmd_order, UT_TESTF_DM | UT_TESTF_SCAN_FDT); -- cgit v1.2.3 From 11361c596585bff7530e993e2d6c88c2766c0913 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:36 -0600 Subject: bootstd: Check building without global bootmeths Use the sandbox_flattree build to check that everything works correctly with BOOTMETH_GLOBAL disabled. Update the tests as needed. Signed-off-by: Simon Glass --- test/boot/bootflow.c | 7 +++++++ test/boot/bootmeth.c | 24 +++++++++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index d2c42e8b060..85305234e01 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -12,7 +12,9 @@ #include #include #include +#ifdef CONFIG_SANDBOX #include +#endif #include #include #include @@ -321,6 +323,7 @@ static int bootflow_iter(struct unit_test_state *uts) } BOOTSTD_TEST(bootflow_iter, UT_TESTF_DM | UT_TESTF_SCAN_FDT); +#if defined(CONFIG_SANDBOX) && defined(CONFIG_BOOTMETH_GLOBAL) /* Check using the system bootdev */ static int bootflow_system(struct unit_test_state *uts) { @@ -344,6 +347,7 @@ static int bootflow_system(struct unit_test_state *uts) } BOOTSTD_TEST(bootflow_system, UT_TESTF_DM | UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +#endif /* Check disabling a bootmethod if it requests it */ static int bootflow_iter_disable(struct unit_test_state *uts) @@ -388,6 +392,9 @@ BOOTSTD_TEST(bootflow_iter_disable, UT_TESTF_DM | UT_TESTF_SCAN_FDT); /* Check 'bootflow scan' with a bootmeth ordering including a global bootmeth */ static int bootflow_scan_glob_bootmeth(struct unit_test_state *uts) { + if (!IS_ENABLED(CONFIG_BOOTMETH_GLOBAL)) + return 0; + ut_assertok(bootstd_test_drop_bootdev_order(uts)); /* diff --git a/test/boot/bootmeth.c b/test/boot/bootmeth.c index ae216293d64..fb627313396 100644 --- a/test/boot/bootmeth.c +++ b/test/boot/bootmeth.c @@ -23,9 +23,11 @@ static int bootmeth_cmd_list(struct unit_test_state *uts) ut_assert_nextlinen("---"); ut_assert_nextline(" 0 0 syslinux Syslinux boot from a block device"); ut_assert_nextline(" 1 1 efi EFI boot from an .efi file"); - ut_assert_nextline(" glob 2 firmware0 VBE simple"); + if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL)) + ut_assert_nextline(" glob 2 firmware0 VBE simple"); ut_assert_nextlinen("---"); - ut_assert_nextline("(3 bootmeths)"); + ut_assert_nextline(IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) ? + "(3 bootmeths)" : "(2 bootmeths)"); ut_assert_console_end(); return 0; @@ -57,9 +59,11 @@ static int bootmeth_cmd_order(struct unit_test_state *uts) ut_assert_nextlinen("---"); ut_assert_nextline(" 0 0 syslinux Syslinux boot from a block device"); ut_assert_nextline(" - 1 efi EFI boot from an .efi file"); - ut_assert_nextline(" glob 2 firmware0 VBE simple"); + if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL)) + ut_assert_nextline(" glob 2 firmware0 VBE simple"); ut_assert_nextlinen("---"); - ut_assert_nextline("(3 bootmeths)"); + ut_assert_nextline(IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) ? + "(3 bootmeths)" : "(2 bootmeths)"); ut_assert_console_end(); /* Check the -a flag with the reverse order */ @@ -70,9 +74,11 @@ static int bootmeth_cmd_order(struct unit_test_state *uts) ut_assert_nextlinen("---"); ut_assert_nextline(" 1 0 syslinux Syslinux boot from a block device"); ut_assert_nextline(" 0 1 efi EFI boot from an .efi file"); - ut_assert_nextline(" glob 2 firmware0 VBE simple"); + if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL)) + ut_assert_nextline(" glob 2 firmware0 VBE simple"); ut_assert_nextlinen("---"); - ut_assert_nextline("(3 bootmeths)"); + ut_assert_nextline(IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) ? + "(3 bootmeths)" : "(2 bootmeths)"); ut_assert_console_end(); /* Now reset the order to empty, which should show all of them again */ @@ -80,7 +86,8 @@ static int bootmeth_cmd_order(struct unit_test_state *uts) ut_assert_console_end(); ut_assertnull(env_get("bootmeths")); ut_assertok(run_command("bootmeth list", 0)); - ut_assert_skip_to_line("(3 bootmeths)"); + ut_assert_skip_to_line(IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) ? + "(3 bootmeths)" : "(2 bootmeths)"); /* Try reverse order */ ut_assertok(run_command("bootmeth order \"efi syslinux\"", 0)); @@ -97,6 +104,9 @@ static int bootmeth_cmd_order(struct unit_test_state *uts) ut_assert_console_end(); /* Try with global bootmeths */ + if (!IS_ENABLED(CONFIG_BOOTMETH_GLOBAL)) + return 0; + ut_assertok(run_command("bootmeth order \"efi firmware0\"", 0)); ut_assert_console_end(); ut_assertok(run_command("bootmeth list", 0)); -- cgit v1.2.3 From 5fe76d460d857b00d582d7cd6cea9ac740ea912b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:37 -0600 Subject: vbe: Add a new vbe command Add a command to look at VBE methods and their status. Provide a test for all of this as well. Signed-off-by: Simon Glass --- test/boot/vbe_simple.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 test/boot/vbe_simple.c (limited to 'test') diff --git a/test/boot/vbe_simple.c b/test/boot/vbe_simple.c new file mode 100644 index 00000000000..2f6979cafcf --- /dev/null +++ b/test/boot/vbe_simple.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for vbe-simple bootmeth. All start with 'vbe_simple' + * + * Copyright 2023 Google LLC + * Written by Simon Glass + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bootstd_common.h" + +#define NVDATA_START_BLK ((0x400 + 0x400) / MMC_MAX_BLOCK_LEN) +#define VERSION_START_BLK ((0x400 + 0x800) / MMC_MAX_BLOCK_LEN) +#define TEST_VERSION "U-Boot v2022.04-local2" +#define TEST_VERNUM 0x00010002 + +/* Basic test of reading nvdata and updating a fwupd node in the device tree */ +static int vbe_simple_test_base(struct unit_test_state *uts) +{ + ALLOC_CACHE_ALIGN_BUFFER(u8, buf, MMC_MAX_BLOCK_LEN); + const char *version, *bl_version; + struct event_ft_fixup fixup; + struct udevice *dev, *mmc; + struct device_node *np; + struct blk_desc *desc; + char fdt_buf[0x400]; + char info[100]; + int node_ofs; + ofnode node; + u32 vernum; + + /* Set up the version string */ + ut_assertok(uclass_get_device(UCLASS_MMC, 1, &mmc)); + desc = blk_get_by_device(mmc); + ut_assertnonnull(desc); + + memset(buf, '\0', MMC_MAX_BLOCK_LEN); + strcpy(buf, TEST_VERSION); + if (blk_dwrite(desc, VERSION_START_BLK, 1, buf) != 1) + return log_msg_ret("write", -EIO); + + /* Set up the nvdata */ + memset(buf, '\0', MMC_MAX_BLOCK_LEN); + buf[1] = ilog2(0x40) << 4 | 1; + *(u32 *)(buf + 4) = TEST_VERNUM; + buf[0] = crc8(0, buf + 1, 0x3f); + if (blk_dwrite(desc, NVDATA_START_BLK, 1, buf) != 1) + return log_msg_ret("write", -EIO); + + /* Read the version back */ + ut_assertok(vbe_find_by_any("firmware0", &dev)); + ut_assertok(bootmeth_get_state_desc(dev, info, sizeof(info))); + ut_asserteq_str("Version: " TEST_VERSION "\nVernum: 1/2", info); + + ut_assertok(fdt_create_empty_tree(fdt_buf, sizeof(fdt_buf))); + node_ofs = fdt_add_subnode(fdt_buf, 0, "chosen"); + ut_assert(node_ofs > 0); + + node_ofs = fdt_add_subnode(fdt_buf, node_ofs, "fwupd"); + ut_assert(node_ofs > 0); + + node_ofs = fdt_add_subnode(fdt_buf, node_ofs, "firmware0"); + ut_assert(node_ofs > 0); + + /* + * This can only work on the live tree, since the ofnode interface for + * flat tree assumes that ofnode points to the control FDT + */ + ut_assertok(unflatten_device_tree(fdt_buf, &np)); + + /* + * It would be better to call image_setup_libfdt() here, but that + * function does not allow passing an ofnode. We can pass fdt_buf but + * when it comes to send the evenr, it creates an ofnode that uses the + * control FDT, since it has no way of accessing the live tree created + * here. + * + * Two fix this we need: + * - image_setup_libfdt() is updated to use ofnode + * - ofnode updated to support access to an FDT other than the control + * FDT. This is partially implemented with live tree, but not with + * flat tree + */ + fixup.tree.np = np; + ut_assertok(event_notify(EVT_FT_FIXUP, &fixup, sizeof(fixup))); + + node = ofnode_path_root(fixup.tree, "/chosen/fwupd/firmware0"); + + version = ofnode_read_string(node, "cur-version"); + ut_assertnonnull(version); + ut_asserteq_str(TEST_VERSION, version); + + ut_assertok(ofnode_read_u32(node, "cur-vernum", &vernum)); + ut_asserteq(TEST_VERNUM, vernum); + + bl_version = ofnode_read_string(node, "bootloader-version"); + ut_assertnonnull(bl_version); + ut_asserteq_str(version_string, bl_version); + + return 0; +} +BOOTSTD_TEST(vbe_simple_test_base, UT_TESTF_DM | UT_TESTF_SCAN_FDT | + UT_TESTF_LIVE_TREE); -- cgit v1.2.3