summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Makefile6
-rw-r--r--test/boot/Makefile2
-rw-r--r--test/boot/bootdev.c11
-rw-r--r--test/boot/bootflow.c2
-rw-r--r--test/cmd/Makefile3
-rw-r--r--test/cmd/command.c31
-rw-r--r--test/cmd/spawn.c32
-rw-r--r--test/common/Makefile6
-rw-r--r--test/common/print.c8
-rw-r--r--test/dm/Makefile2
-rw-r--r--test/dm/dsa.c8
-rw-r--r--test/dm/eth.c77
-rw-r--r--test/dm/power-domain.c11
-rw-r--r--test/dm/test-fdt.c20
-rw-r--r--test/dm/video.c266
-rw-r--r--test/fuzz/Makefile2
-rw-r--r--test/lib/Makefile6
-rw-r--r--test/lib/initjmp.c73
-rw-r--r--test/lib/uthread.c146
-rw-r--r--test/py/tests/test_fs/conftest.py2
-rw-r--r--test/py/tests/test_fs/test_basic.py13
-rw-r--r--test/py/tests/test_memtest.py8
-rw-r--r--test/py/tests/test_spi.py29
-rw-r--r--test/py/tests/test_trace.py8
24 files changed, 637 insertions, 135 deletions
diff --git a/test/Makefile b/test/Makefile
index 99d4797d968..f7ab9a36b2a 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -4,15 +4,15 @@
obj-y += test-main.o
-obj-$(CONFIG_$(XPL_)CMDLINE) += cmd/
-obj-$(CONFIG_$(XPL_)CMDLINE) += cmd_ut.o
+obj-$(CONFIG_$(PHASE_)CMDLINE) += cmd/
+obj-$(CONFIG_$(PHASE_)CMDLINE) += cmd_ut.o
obj-y += dm/
obj-$(CONFIG_FUZZ) += fuzz/
ifndef CONFIG_SANDBOX_VPL
obj-$(CONFIG_UNIT_TEST) += lib/
endif
ifneq ($(CONFIG_HUSH_PARSER),)
-obj-$(CONFIG_$(XPL_)CMDLINE) += hush/
+obj-$(CONFIG_$(PHASE_)CMDLINE) += hush/
endif
obj-$(CONFIG_UT_OPTEE) += optee/
obj-y += ut.o
diff --git a/test/boot/Makefile b/test/boot/Makefile
index 63487e8d29e..00223b44fe0 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_CEDIT) += cedit.o
endif
ifdef CONFIG_SANDBOX
-obj-$(CONFIG_$(XPL_)CMDLINE) += bootm.o
+obj-$(CONFIG_$(PHASE_)CMDLINE) += bootm.o
endif
obj-$(CONFIG_MEASURED_BOOT) += measurement.o
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index d5499918249..9af94786870 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -392,8 +392,7 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
ut_assert_console_end();
ut_assertok(bootdev_hunt("usb1", false));
- ut_assert_nextline(
- "Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
+ ut_assert_skip_to_line("Bus usb@1: 5 USB Device(s) found");
ut_assert_console_end();
/* USB is 7th in the list, so bit 8 */
@@ -448,8 +447,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
ut_assert_nextline("scanning bus for devices...");
ut_assert_skip_to_line("Hunting with: spi_flash");
ut_assert_nextline("Hunting with: usb");
- ut_assert_nextline(
- "Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
+ ut_assert_skip_to_line("Bus usb@1: 5 USB Device(s) found");
ut_assert_nextline("Hunting with: virtio");
ut_assert_console_end();
@@ -551,8 +549,7 @@ static int bootdev_test_hunt_prio(struct unit_test_state *uts)
ut_assertok(bootdev_hunt_prio(BOOTDEVP_5_SCAN_SLOW, true));
ut_assert_nextline("Hunting with: ide");
ut_assert_nextline("Hunting with: usb");
- ut_assert_nextline(
- "Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
+ ut_assert_skip_to_line("Bus usb@1: 5 USB Device(s) found");
ut_assert_console_end();
return 0;
@@ -604,7 +601,7 @@ static int bootdev_test_hunt_label(struct unit_test_state *uts)
ut_assertnonnull(dev);
ut_asserteq_str("usb_mass_storage.lun0.bootdev", dev->name);
ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS, mflags);
- ut_assert_nextlinen("Bus usb@1: scanning bus usb@1");
+ ut_assert_nextline("Bus usb@1: 5 USB Device(s) found");
ut_assert_console_end();
return 0;
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 5f9c037ff53..b261bd5f620 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -1290,7 +1290,7 @@ static int bootflow_efi(struct unit_test_state *uts)
ut_assertok(run_command("bootflow scan", 0));
ut_assert_skip_to_line(
- "Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
+ "Bus usb@1: 5 USB Device(s) found");
ut_assertok(run_command("bootflow list", 0));
diff --git a/test/cmd/Makefile b/test/cmd/Makefile
index d8a5e77402d..595e4cfcada 100644
--- a/test/cmd/Makefile
+++ b/test/cmd/Makefile
@@ -3,7 +3,7 @@
# Copyright (c) 2013 Google, Inc
# Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
-obj-$(CONFIG_$(XPL_)CMDLINE) += command.o
+obj-$(CONFIG_$(PHASE_)CMDLINE) += command.o
ifdef CONFIG_HUSH_PARSER
obj-$(CONFIG_CONSOLE_RECORD) += test_echo.o
endif
@@ -39,3 +39,4 @@ obj-$(CONFIG_CMD_WGET) += wget.o
endif
obj-$(CONFIG_ARM_FFA_TRANSPORT) += armffa.o
endif
+obj-$(CONFIG_CMD_SPAWN) += spawn.o
diff --git a/test/cmd/command.c b/test/cmd/command.c
index 5ec93d490ba..5b1e5a77e5d 100644
--- a/test/cmd/command.c
+++ b/test/cmd/command.c
@@ -45,31 +45,32 @@ static int command_test(struct unit_test_state *uts)
"setenv list ${list}3", strlen("setenv list 1"), 0);
ut_assert(!strcmp("1", env_get("list")));
- ut_asserteq(1, run_command("false", 0));
ut_assertok(run_command("echo", 0));
- ut_asserteq(1, run_command_list("false", -1, 0));
ut_assertok(run_command_list("echo", -1, 0));
-#ifdef CONFIG_HUSH_PARSER
- run_command("setenv foo 'setenv black 1\nsetenv adder 2'", 0);
- run_command("run foo", 0);
- ut_assertnonnull(env_get("black"));
- ut_asserteq(0, strcmp("1", env_get("black")));
- ut_assertnonnull(env_get("adder"));
- ut_asserteq(0, strcmp("2", env_get("adder")));
-#endif
-
- ut_assertok(run_command("", 0));
- ut_assertok(run_command(" ", 0));
+ if (IS_ENABLED(CONFIG_HUSH_PARSER)) {
+ ut_asserteq(1, run_command("false", 0));
+ ut_asserteq(1, run_command_list("false", -1, 0));
+ run_command("setenv foo 'setenv black 1\nsetenv adder 2'", 0);
+ run_command("run foo", 0);
+ ut_assertnonnull(env_get("black"));
+ ut_asserteq(0, strcmp("1", env_get("black")));
+ ut_assertnonnull(env_get("adder"));
+ ut_asserteq(0, strcmp("2", env_get("adder")));
+ ut_assertok(run_command("", 0));
+ ut_assertok(run_command(" ", 0));
+ }
ut_asserteq(1, run_command("'", 0));
/* Variadic function test-cases */
+ if (IS_ENABLED(CONFIG_HUSH_PARSER)) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-zero-length"
- ut_assertok(run_commandf(""));
+ ut_assertok(run_commandf(""));
#pragma GCC diagnostic pop
- ut_assertok(run_commandf(" "));
+ ut_assertok(run_commandf(" "));
+ }
ut_asserteq(1, run_commandf("'"));
ut_assertok(run_commandf("env %s %s", "delete -f", "list"));
diff --git a/test/cmd/spawn.c b/test/cmd/spawn.c
new file mode 100644
index 00000000000..8f48f5ee25c
--- /dev/null
+++ b/test/cmd/spawn.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Tests for spawn and wait commands
+ *
+ * Copyright 2025, Linaro Ltd.
+ */
+
+#include <command.h>
+#include <test/cmd.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+static int test_cmd_spawn(struct unit_test_state *uts)
+{
+ ut_assertok(run_command("wait; spawn sleep 2; setenv j ${job_id}; "
+ "spawn setenv spawned true; "
+ "setenv jj ${job_id}; wait; "
+ "echo ${j} ${jj} ${spawned}", 0));
+ console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+ ut_asserteq_ptr(uts->actual_str,
+ strstr(uts->actual_str, "1 2 true"));
+
+ ut_assertok(run_command("spawn true; wait; setenv t $?; spawn false; "
+ "wait; setenv f $?; wait; echo $t $f $?", 0));
+ console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+ ut_asserteq_ptr(uts->actual_str,
+ strstr(uts->actual_str, "0 1 0"));
+ ut_assert_console_end();
+
+ return 0;
+}
+CMD_TEST(test_cmd_spawn, UTF_CONSOLE);
diff --git a/test/common/Makefile b/test/common/Makefile
index 1ad6c24b7e2..baefc7b3622 100644
--- a/test/common/Makefile
+++ b/test/common/Makefile
@@ -1,13 +1,13 @@
# SPDX-License-Identifier: GPL-2.0+
obj-$(CONFIG_AUTOBOOT) += test_autoboot.o
-ifneq ($(CONFIG_$(XPL_)BLOBLIST),)
+ifneq ($(CONFIG_$(PHASE_)BLOBLIST),)
ifdef CONFIG_BLOBLIST_FIXED
-obj-$(CONFIG_$(XPL_)CMDLINE) += bloblist.o
+obj-$(CONFIG_$(PHASE_)CMDLINE) += bloblist.o
endif
endif
obj-$(CONFIG_CYCLIC) += cyclic.o
obj-$(CONFIG_EVENT_DYNAMIC) += event.o
obj-y += cread.o
-obj-$(CONFIG_$(XPL_)CMDLINE) += print.o
+obj-$(CONFIG_$(PHASE_)CMDLINE) += print.o
diff --git a/test/common/print.c b/test/common/print.c
index e3711b10809..c48efc2783f 100644
--- a/test/common/print.c
+++ b/test/common/print.c
@@ -45,11 +45,11 @@ static int print_guid(struct unit_test_state *uts)
sprintf(str, "%pUL", guid);
ut_asserteq_str("04030201-0605-0807-090A-0B0C0D0E0F10", str);
sprintf(str, "%pUs", guid_esp);
- if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID)) { /* brace needed */
- ut_asserteq_str("system", str);
- } else {
+ if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID) ||
+ IS_ENABLED(CONFIG_CMD_EFIDEBUG) || IS_ENABLED(CONFIG_EFI))
+ ut_asserteq_str("EFI System Partition", str);
+ else
ut_asserteq_str("c12a7328-f81f-11d2-ba4b-00a0c93ec93b", str);
- }
ret = snprintf(str, 4, "%pUL", guid);
ut_asserteq(0, str[3]);
ut_asserteq(36, ret);
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 3afcc26ca57..917dafe7d22 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -46,9 +46,7 @@ obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o
obj-$(CONFIG_DM_DSA) += dsa.o
obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o
obj-$(CONFIG_EFI_MEDIA_SANDBOX) += efi_media.o
-ifdef CONFIG_NET
obj-$(CONFIG_DM_ETH) += eth.o
-endif
obj-$(CONFIG_EXTCON) += extcon.o
ifneq ($(CONFIG_EFI_PARTITION),)
obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o
diff --git a/test/dm/dsa.c b/test/dm/dsa.c
index c6b4e12a758..9a31ae39d95 100644
--- a/test/dm/dsa.c
+++ b/test/dm/dsa.c
@@ -63,15 +63,15 @@ DM_TEST(dm_test_dsa_probe, UTF_SCAN_FDT);
*/
static int dm_test_dsa(struct unit_test_state *uts)
{
- net_ping_ip = string_to_ip("1.2.3.5");
+ char *argv[] = { "ping", "1.1.2.2" };
env_set("ethact", "eth2");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
env_set("ethact", "lan0");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
env_set("ethact", "lan1");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
env_set("ethact", "");
diff --git a/test/dm/eth.c b/test/dm/eth.c
index 467495863e1..1087ae9572d 100644
--- a/test/dm/eth.c
+++ b/test/dm/eth.c
@@ -171,18 +171,18 @@ DM_TEST(dm_test_ip6_make_lladdr, UTF_SCAN_FDT);
static int dm_test_eth(struct unit_test_state *uts)
{
- net_ping_ip = string_to_ip("1.1.2.2");
+ char *argv[] = { "ping", "1.1.2.2" };
env_set("ethact", "eth@10002000");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10002000", env_get("ethact"));
env_set("ethact", "eth@10003000");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10003000", env_get("ethact"));
env_set("ethact", "eth@10004000");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10004000", env_get("ethact"));
return 0;
@@ -191,22 +191,23 @@ DM_TEST(dm_test_eth, UTF_SCAN_FDT);
static int dm_test_eth_alias(struct unit_test_state *uts)
{
- net_ping_ip = string_to_ip("1.1.2.2");
+ char *argv[] = { "ping", "1.1.2.2" };
+
env_set("ethact", "eth0");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10002000", env_get("ethact"));
env_set("ethact", "eth6");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10004000", env_get("ethact"));
/* Expected to fail since eth1 is not defined in the device tree */
env_set("ethact", "eth1");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10002000", env_get("ethact"));
env_set("ethact", "eth5");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10003000", env_get("ethact"));
return 0;
@@ -215,18 +216,18 @@ DM_TEST(dm_test_eth_alias, UTF_SCAN_FDT);
static int dm_test_eth_prime(struct unit_test_state *uts)
{
- net_ping_ip = string_to_ip("1.1.2.2");
+ char *argv[] = { "ping", "1.1.2.2" };
/* Expected to be "eth@10003000" because of ethprime variable */
env_set("ethact", NULL);
env_set("ethprime", "eth5");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10003000", env_get("ethact"));
/* Expected to be "eth@10002000" because it is first */
env_set("ethact", NULL);
env_set("ethprime", NULL);
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10002000", env_get("ethact"));
return 0;
@@ -249,6 +250,7 @@ DM_TEST(dm_test_eth_prime, UTF_SCAN_FDT);
*/
static int dm_test_eth_act(struct unit_test_state *uts)
{
+ char *argv[] = { "ping", "1.1.2.2" };
struct udevice *dev[DM_TEST_ETH_NUM];
const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000",
"sbe5", "eth@10004000"};
@@ -258,7 +260,6 @@ static int dm_test_eth_act(struct unit_test_state *uts)
int i;
memset(ethaddr, '\0', sizeof(ethaddr));
- net_ping_ip = string_to_ip("1.1.2.2");
/* Prepare the test scenario */
for (i = 0; i < DM_TEST_ETH_NUM; i++) {
@@ -281,7 +282,7 @@ static int dm_test_eth_act(struct unit_test_state *uts)
env_set("ethact", ethname[0]);
/* Segment fault might happen if something is wrong */
- ut_asserteq(-ENODEV, net_loop(PING));
+ ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
for (i = 0; i < DM_TEST_ETH_NUM; i++) {
/* Restore the env */
@@ -334,15 +335,17 @@ DM_TEST(dm_test_ethaddr, UTF_SCAN_FDT);
/* The asserts include a return on fail; cleanup in the caller */
static int _dm_test_eth_rotate1(struct unit_test_state *uts)
{
+ char *argv[] = { "ping", "1.1.2.2" };
+
/* Make sure that the default is to rotate to the next interface */
env_set("ethact", "eth@10004000");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10002000", env_get("ethact"));
/* If ethrotate is no, then we should fail on a bad MAC */
env_set("ethact", "eth@10004000");
env_set("ethrotate", "no");
- ut_asserteq(-EINVAL, net_loop(PING));
+ ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10004000", env_get("ethact"));
return 0;
@@ -350,14 +353,16 @@ static int _dm_test_eth_rotate1(struct unit_test_state *uts)
static int _dm_test_eth_rotate2(struct unit_test_state *uts)
{
+ char *argv[] = { "ping", "1.1.2.2" };
+
/* Make sure we can skip invalid devices */
env_set("ethact", "eth@10004000");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("eth@10004000", env_get("ethact"));
/* Make sure we can handle device name which is not eth# */
env_set("ethact", "sbe5");
- ut_assertok(net_loop(PING));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
ut_asserteq_str("sbe5", env_get("ethact"));
return 0;
@@ -368,9 +373,6 @@ static int dm_test_eth_rotate(struct unit_test_state *uts)
char ethaddr[18];
int retval;
- /* Set target IP to mock ping */
- net_ping_ip = string_to_ip("1.1.2.2");
-
/* Invalidate eth1's MAC address */
memset(ethaddr, '\0', sizeof(ethaddr));
strncpy(ethaddr, env_get("eth6addr"), 17);
@@ -396,6 +398,7 @@ static int dm_test_eth_rotate(struct unit_test_state *uts)
/* Restore the env */
env_set("ethaddr", ethaddr);
}
+
/* Restore the env */
env_set(".flags", NULL);
@@ -406,26 +409,28 @@ DM_TEST(dm_test_eth_rotate, UTF_SCAN_FDT);
/* The asserts include a return on fail; cleanup in the caller */
static int _dm_test_net_retry(struct unit_test_state *uts)
{
+ char *argv[] = { "ping", "1.1.2.2" };
+
/*
- * eth1 is disabled and netretry is yes, so the ping should succeed and
- * the active device should be eth0
+ * eth0 is disabled and netretry is yes, so the ping should succeed and
+ * the active device should be eth1
*/
- sandbox_eth_disable_response(1, true);
- env_set("ethact", "lan1");
+ sandbox_eth_disable_response(0, true);
+ env_set("ethact", "eth@10002000");
env_set("netretry", "yes");
sandbox_eth_skip_timeout();
- ut_assertok(net_loop(PING));
- ut_asserteq_str("eth@10002000", env_get("ethact"));
+ ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
+ ut_asserteq_str("eth@10003000", env_get("ethact"));
/*
- * eth1 is disabled and netretry is no, so the ping should fail and the
- * active device should be eth1
+ * eth0 is disabled and netretry is no, so the ping should fail and the
+ * active device should be eth0
*/
- env_set("ethact", "lan1");
+ env_set("ethact", "eth@10002000");
env_set("netretry", "no");
sandbox_eth_skip_timeout();
- ut_asserteq(-ENONET, net_loop(PING));
- ut_asserteq_str("lan1", env_get("ethact"));
+ ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv));
+ ut_asserteq_str("eth@10002000", env_get("ethact"));
return 0;
}
@@ -434,8 +439,6 @@ static int dm_test_net_retry(struct unit_test_state *uts)
{
int retval;
- net_ping_ip = string_to_ip("1.1.2.2");
-
retval = _dm_test_net_retry(uts);
/* Restore the env */
@@ -446,6 +449,7 @@ static int dm_test_net_retry(struct unit_test_state *uts)
}
DM_TEST(dm_test_net_retry, UTF_SCAN_FDT);
+#if CONFIG_IS_ENABLED(NET)
static int sb_check_arp_reply(struct udevice *dev, void *packet,
unsigned int len)
{
@@ -511,7 +515,9 @@ static int sb_with_async_arp_handler(struct udevice *dev, void *packet,
return sb_check_arp_reply(dev, packet, len);
}
+#endif
+#if CONFIG_IS_ENABLED(NET)
static int dm_test_eth_async_arp_reply(struct unit_test_state *uts)
{
net_ping_ip = string_to_ip("1.1.2.2");
@@ -529,7 +535,9 @@ static int dm_test_eth_async_arp_reply(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_eth_async_arp_reply, UTF_SCAN_FDT);
+#endif
+#if CONFIG_IS_ENABLED(NET)
static int sb_check_ping_reply(struct udevice *dev, void *packet,
unsigned int len)
{
@@ -613,6 +621,7 @@ static int dm_test_eth_async_ping_reply(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_eth_async_ping_reply, UTF_SCAN_FDT);
+#endif
#if IS_ENABLED(CONFIG_IPV6_ROUTER_DISCOVERY)
diff --git a/test/dm/power-domain.c b/test/dm/power-domain.c
index 896cf5b2ae9..1002d831764 100644
--- a/test/dm/power-domain.c
+++ b/test/dm/power-domain.c
@@ -27,7 +27,7 @@ static int dm_test_power_domain(struct unit_test_state *uts)
ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "power-domain-test",
&dev_test));
- ut_asserteq(1, sandbox_power_domain_query(dev_power_domain,
+ ut_asserteq(0, sandbox_power_domain_query(dev_power_domain,
TEST_POWER_DOMAIN));
ut_assertok(sandbox_power_domain_test_get(dev_test));
@@ -35,11 +35,20 @@ static int dm_test_power_domain(struct unit_test_state *uts)
ut_asserteq(0, sandbox_power_domain_query(dev_power_domain, 0));
ut_asserteq(1, sandbox_power_domain_query(dev_power_domain,
TEST_POWER_DOMAIN));
+ ut_asserteq(-EALREADY, sandbox_power_domain_test_on_ll(dev_test));
+ ut_asserteq(1, sandbox_power_domain_query(dev_power_domain,
+ TEST_POWER_DOMAIN));
+ ut_asserteq(-EBUSY, sandbox_power_domain_test_off_ll(dev_test));
+ ut_asserteq(1, sandbox_power_domain_query(dev_power_domain,
+ TEST_POWER_DOMAIN));
ut_assertok(sandbox_power_domain_test_off(dev_test));
ut_asserteq(0, sandbox_power_domain_query(dev_power_domain, 0));
ut_asserteq(0, sandbox_power_domain_query(dev_power_domain,
TEST_POWER_DOMAIN));
+ ut_asserteq(-EALREADY, sandbox_power_domain_test_off_ll(dev_test));
+ ut_asserteq(0, sandbox_power_domain_query(dev_power_domain,
+ TEST_POWER_DOMAIN));
ut_assertok(sandbox_power_domain_test_free(dev_test));
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index af8cd617108..295fdcaa0d8 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -792,7 +792,7 @@ DM_TEST(dm_test_fdt_disable_enable_by_path, UTF_SCAN_PDATA | UTF_SCAN_FDT);
/* Test a few uclass phandle functions */
static int dm_test_fdt_phandle(struct unit_test_state *uts)
{
- struct udevice *back, *dev, *dev2;
+ struct udevice *back, *dispc, *panel, *dev, *dev2;
ut_assertok(uclass_find_first_device(UCLASS_PANEL_BACKLIGHT, &back));
ut_assertnonnull(back);
@@ -807,6 +807,24 @@ static int dm_test_fdt_phandle(struct unit_test_state *uts)
"power-supply", &dev2));
ut_asserteq_ptr(dev, dev2);
+ /* Test uclass_get_device_by_endpoint() */
+ ut_assertok(uclass_find_device_by_name(UCLASS_VIDEO_BRIDGE, "lvds-encoder", &dispc));
+ ut_assertnonnull(dispc);
+ ut_asserteq(0, device_active(dispc));
+ ut_assertok(uclass_find_device_by_name(UCLASS_PANEL, "panel", &panel));
+ ut_assertnonnull(panel);
+ ut_asserteq(0, device_active(panel));
+
+ ut_asserteq(-ENODEV, uclass_get_device_by_endpoint(UCLASS_PANEL_BACKLIGHT, dispc, 1, -1, &dev));
+ ut_asserteq(-EINVAL, uclass_get_device_by_endpoint(UCLASS_PANEL, dispc, 0, -1, &dev));
+ ut_assertok(uclass_get_device_by_endpoint(UCLASS_PANEL, dispc, 1, -1, &dev));
+ ut_asserteq_ptr(panel, dev);
+
+ ut_asserteq(-ENODEV, uclass_get_device_by_endpoint(UCLASS_PANEL_BACKLIGHT, panel, -1, -1, &dev2));
+ ut_asserteq(-EINVAL, uclass_get_device_by_endpoint(UCLASS_VIDEO_BRIDGE, panel, 1, -1, &dev2));
+ ut_assertok(uclass_get_device_by_endpoint(UCLASS_VIDEO_BRIDGE, panel, -1, -1, &dev2));
+ ut_asserteq_ptr(dispc, dev2);
+
return 0;
}
DM_TEST(dm_test_fdt_phandle, UTF_SCAN_PDATA | UTF_SCAN_FDT);
diff --git a/test/dm/video.c b/test/dm/video.c
index e347c1403fd..929fc16d0ef 100644
--- a/test/dm/video.c
+++ b/test/dm/video.c
@@ -54,43 +54,64 @@ DM_TEST(dm_test_video_base, UTF_SCAN_PDATA | UTF_SCAN_FDT);
* size of the compressed data. This provides a pretty good level of
* certainty and the resulting tests need only check a single value.
*
- * If the copy framebuffer is enabled, this compares it to the main framebuffer
- * too.
- *
* @uts: Test state
* @dev: Video device
+ * @use_copy: Use copy frame buffer if available
* Return: compressed size of the frame buffer, or -ve on error
*/
static int compress_frame_buffer(struct unit_test_state *uts,
- struct udevice *dev)
+ struct udevice *dev,
+ bool use_copy)
{
struct video_priv *priv = dev_get_uclass_priv(dev);
- struct video_priv *uc_priv = dev_get_uclass_priv(dev);
uint destlen;
void *dest;
int ret;
+ if (!IS_ENABLED(CONFIG_VIDEO_COPY))
+ use_copy = false;
+
destlen = priv->fb_size;
dest = malloc(priv->fb_size);
if (!dest)
return -ENOMEM;
ret = BZ2_bzBuffToBuffCompress(dest, &destlen,
- priv->fb, priv->fb_size,
+ use_copy ? priv->copy_fb : priv->fb,
+ priv->fb_size,
3, 0, 0);
free(dest);
if (ret)
return ret;
- /* Check here that the copy frame buffer is working correctly */
- if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
- ut_assertf(!memcmp(uc_priv->fb, uc_priv->copy_fb,
- uc_priv->fb_size),
- "Copy framebuffer does not match fb");
- }
-
return destlen;
}
+/**
+ * check_copy_frame_buffer() - Compare main frame buffer to copy
+ *
+ * If the copy frame buffer is enabled, this compares it to the main
+ * frame buffer. Normally they should have the same contents after a
+ * sync.
+ *
+ * @uts: Test state
+ * @dev: Video device
+ * Return: 0, or -ve on error
+ */
+static int check_copy_frame_buffer(struct unit_test_state *uts,
+ struct udevice *dev)
+{
+ struct video_priv *priv = dev_get_uclass_priv(dev);
+
+ if (!IS_ENABLED(CONFIG_VIDEO_COPY))
+ return 0;
+
+ video_sync(dev, false);
+ ut_assertf(!memcmp(priv->fb, priv->copy_fb, priv->fb_size),
+ "Copy framebuffer does not match fb");
+
+ return 0;
+}
+
/*
* Call this function at any point to halt and show the current display. Be
* sure to run the test with the -l flag.
@@ -153,25 +174,31 @@ static int dm_test_video_text(struct unit_test_state *uts)
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_asserteq(46, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
vidconsole_putc_xy(con, 0, 0, 'a');
- ut_asserteq(79, compress_frame_buffer(uts, dev));
+ ut_asserteq(79, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
vidconsole_putc_xy(con, 0, 0, ' ');
- ut_asserteq(46, compress_frame_buffer(uts, dev));
+ ut_asserteq(46, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
for (i = 0; i < 20; i++)
vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
- ut_asserteq(273, compress_frame_buffer(uts, dev));
+ ut_asserteq(273, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
vidconsole_set_row(con, 0, WHITE);
- ut_asserteq(46, compress_frame_buffer(uts, dev));
+ ut_asserteq(46, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
for (i = 0; i < 20; i++)
vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
- ut_asserteq(273, compress_frame_buffer(uts, dev));
+ ut_asserteq(273, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -189,25 +216,31 @@ static int dm_test_video_text_12x22(struct unit_test_state *uts)
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_asserteq(46, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_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));
+ ut_asserteq(89, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
vidconsole_putc_xy(con, 0, 0, ' ');
- ut_asserteq(46, compress_frame_buffer(uts, dev));
+ ut_asserteq(46, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_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));
+ ut_asserteq(363, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
vidconsole_set_row(con, 0, WHITE);
- ut_asserteq(46, compress_frame_buffer(uts, dev));
+ ut_asserteq(46, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_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));
+ ut_asserteq(363, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -224,7 +257,8 @@ static int dm_test_video_chars(struct unit_test_state *uts)
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));
+ ut_asserteq(466, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -245,20 +279,24 @@ static int dm_test_video_ansi(struct unit_test_state *uts)
/* reference clear: */
video_clear(con->parent);
video_sync(con->parent, false);
- ut_asserteq(46, compress_frame_buffer(uts, dev));
+ ut_asserteq(46, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
/* test clear escape sequence: [2J */
vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J");
- ut_asserteq(46, compress_frame_buffer(uts, dev));
+ ut_asserteq(46, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
/* test set-cursor: [%d;%df */
vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd");
- ut_asserteq(143, compress_frame_buffer(uts, dev));
+ ut_asserteq(143, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
/* test colors (30-37 fg color, 40-47 bg color) */
vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */
vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */
- ut_asserteq(272, compress_frame_buffer(uts, dev));
+ ut_asserteq(272, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -290,24 +328,28 @@ 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));
+ ut_asserteq(46, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
/* Check display wrap */
for (i = 0; i < 120; i++)
vidconsole_put_char(con, 'A' + i % 50);
- ut_asserteq(wrap_size, compress_frame_buffer(uts, dev));
+ ut_asserteq(wrap_size, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
/* Check display scrolling */
for (i = 0; i < SCROLL_LINES; i++) {
vidconsole_put_char(con, 'A' + i % 50);
vidconsole_put_char(con, '\n');
}
- ut_asserteq(scroll_size, compress_frame_buffer(uts, dev));
+ ut_asserteq(scroll_size, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
/* If we scroll enough, the screen becomes blank again */
for (i = 0; i < SCROLL_LINES; i++)
vidconsole_put_char(con, '\n');
- ut_asserteq(46, compress_frame_buffer(uts, dev));
+ ut_asserteq(46, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -381,7 +423,8 @@ static int dm_test_video_bmp(struct unit_test_state *uts)
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
- ut_asserteq(1368, compress_frame_buffer(uts, dev));
+ ut_asserteq(1368, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -400,7 +443,8 @@ static int dm_test_video_bmp8(struct unit_test_state *uts)
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
- ut_asserteq(1247, compress_frame_buffer(uts, dev));
+ ut_asserteq(1247, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -423,7 +467,8 @@ static int dm_test_video_bmp16(struct unit_test_state *uts)
&src_len));
ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
- ut_asserteq(3700, compress_frame_buffer(uts, dev));
+ ut_asserteq(3700, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -446,7 +491,8 @@ static int dm_test_video_bmp24(struct unit_test_state *uts)
&src_len));
ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
- ut_asserteq(3656, compress_frame_buffer(uts, dev));
+ ut_asserteq(3656, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -469,7 +515,8 @@ static int dm_test_video_bmp24_32(struct unit_test_state *uts)
&src_len));
ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
- ut_asserteq(6827, compress_frame_buffer(uts, dev));
+ ut_asserteq(6827, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -487,7 +534,8 @@ static int dm_test_video_bmp32(struct unit_test_state *uts)
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
- ut_asserteq(2024, compress_frame_buffer(uts, dev));
+ ut_asserteq(2024, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -503,7 +551,8 @@ static int dm_test_video_bmp_comp(struct unit_test_state *uts)
ut_assertok(read_file(uts, "tools/logos/denx-comp.bmp", &addr));
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
- ut_asserteq(1368, compress_frame_buffer(uts, dev));
+ ut_asserteq(1368, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -522,7 +571,8 @@ static int dm_test_video_comp_bmp32(struct unit_test_state *uts)
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
- ut_asserteq(2024, compress_frame_buffer(uts, dev));
+ ut_asserteq(2024, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -541,7 +591,8 @@ static int dm_test_video_comp_bmp8(struct unit_test_state *uts)
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
- ut_asserteq(1247, compress_frame_buffer(uts, dev));
+ ut_asserteq(1247, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -556,7 +607,8 @@ static int dm_test_video_truetype(struct unit_test_state *uts)
ut_assertok(video_get_nologo(uts, &dev));
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
vidconsole_put_string(con, test_string);
- ut_asserteq(12174, compress_frame_buffer(uts, dev));
+ ut_asserteq(12174, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -577,7 +629,8 @@ static int dm_test_video_truetype_scroll(struct unit_test_state *uts)
ut_assertok(video_get_nologo(uts, &dev));
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
vidconsole_put_string(con, test_string);
- ut_asserteq(34287, compress_frame_buffer(uts, dev));
+ ut_asserteq(34287, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
@@ -598,8 +651,129 @@ static int dm_test_video_truetype_bs(struct unit_test_state *uts)
ut_assertok(video_get_nologo(uts, &dev));
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
vidconsole_put_string(con, test_string);
- ut_asserteq(29471, compress_frame_buffer(uts, dev));
+ ut_asserteq(29471, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
return 0;
}
DM_TEST(dm_test_video_truetype_bs, UTF_SCAN_PDATA | UTF_SCAN_FDT);
+
+/* Test partial rendering onto hardware frame buffer */
+static int dm_test_video_copy(struct unit_test_state *uts)
+{
+ struct sandbox_sdl_plat *plat;
+ struct video_uc_plat *uc_plat;
+ struct udevice *dev, *con;
+ struct video_priv *priv;
+ const char *test_string = "\n\tCriticism may not be agreeable, but it is necessary.\t";
+ ulong addr;
+
+ if (!IS_ENABLED(CONFIG_VIDEO_COPY))
+ return -EAGAIN;
+
+ ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
+ ut_assertnonnull(dev);
+ uc_plat = dev_get_uclass_plat(dev);
+ uc_plat->hide_logo = true;
+ plat = dev_get_plat(dev);
+ plat->font_size = 32;
+ ut_assert(!device_active(dev));
+ ut_assertok(uclass_first_device_err(UCLASS_VIDEO, &dev));
+ ut_assertnonnull(dev);
+ priv = dev_get_uclass_priv(dev);
+
+ ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
+ ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
+
+ ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
+ vidconsole_put_string(con, "\n\n\n\n\n");
+ vidconsole_put_string(con, test_string);
+ vidconsole_put_string(con, test_string);
+
+ ut_asserteq(6678, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
+
+ /*
+ * Secretly clear the hardware frame buffer, but in a different
+ * color (black) to see which parts will be overwritten.
+ */
+ memset(priv->copy_fb, 0, priv->fb_size);
+
+ /*
+ * We should have the full content on the main buffer, but only
+ * 'damage' should have been copied to the copy buffer. This consists
+ * of a while rectangle with the Denx logo and four lines of text. The
+ * rest of the display is black.
+ *
+ * An easy way to try this is by changing video_sync() to call
+ * sandbox_sdl_sync(priv->copy_fb) instead of priv->fb then running the
+ * unit test:
+ *
+ * ./u-boot -Tl
+ * ut dm dm_test_video_copy
+ */
+ vidconsole_put_string(con, test_string);
+ vidconsole_put_string(con, test_string);
+ video_sync(dev, true);
+ ut_asserteq(7589, compress_frame_buffer(uts, dev, false));
+ ut_asserteq(7704, compress_frame_buffer(uts, dev, true));
+
+ return 0;
+}
+DM_TEST(dm_test_video_copy, UTF_SCAN_PDATA | UTF_SCAN_FDT);
+
+/* Test video damage tracking */
+static int dm_test_video_damage(struct unit_test_state *uts)
+{
+ struct sandbox_sdl_plat *plat;
+ struct udevice *dev, *con;
+ struct video_priv *priv;
+ const char *test_string_1 = "Criticism may not be agreeable, ";
+ const char *test_string_2 = "but it is necessary.";
+ const char *test_string_3 = "It fulfils the same function as pain in the human body.";
+
+ if (!IS_ENABLED(CONFIG_VIDEO_DAMAGE))
+ return -EAGAIN;
+
+ ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
+ ut_assert(!device_active(dev));
+ plat = dev_get_plat(dev);
+ plat->font_size = 32;
+
+ ut_assertok(video_get_nologo(uts, &dev));
+ ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
+ priv = dev_get_uclass_priv(dev);
+
+ vidconsole_position_cursor(con, 14, 10);
+ vidconsole_put_string(con, test_string_2);
+ ut_asserteq(449, priv->damage.xstart);
+ ut_asserteq(325, priv->damage.ystart);
+ ut_asserteq(661, priv->damage.xend);
+ ut_asserteq(350, priv->damage.yend);
+
+ vidconsole_position_cursor(con, 7, 5);
+ vidconsole_put_string(con, test_string_1);
+ ut_asserteq(225, priv->damage.xstart);
+ ut_asserteq(164, priv->damage.ystart);
+ ut_asserteq(661, priv->damage.xend);
+ ut_asserteq(350, priv->damage.yend);
+
+ vidconsole_position_cursor(con, 21, 15);
+ vidconsole_put_string(con, test_string_3);
+ ut_asserteq(225, priv->damage.xstart);
+ ut_asserteq(164, priv->damage.ystart);
+ ut_asserteq(1280, priv->damage.xend);
+ ut_asserteq(510, priv->damage.yend);
+
+ video_sync(dev, true);
+ ut_asserteq(priv->xsize, priv->damage.xstart);
+ ut_asserteq(priv->ysize, priv->damage.ystart);
+ ut_asserteq(0, priv->damage.xend);
+ ut_asserteq(0, priv->damage.yend);
+
+ ut_asserteq(7339, compress_frame_buffer(uts, dev, false));
+ ut_assertok(check_copy_frame_buffer(uts, dev));
+
+ return 0;
+}
+DM_TEST(dm_test_video_damage, UTF_SCAN_PDATA | UTF_SCAN_FDT);
diff --git a/test/fuzz/Makefile b/test/fuzz/Makefile
index 8a135b65e4b..0a8f3d12239 100644
--- a/test/fuzz/Makefile
+++ b/test/fuzz/Makefile
@@ -4,5 +4,5 @@
# Written by Andrew Scull <ascull@google.com>
#
-obj-$(CONFIG_$(XPL_)CMDLINE) += cmd_fuzz.o
+obj-$(CONFIG_$(PHASE_)CMDLINE) += cmd_fuzz.o
obj-$(CONFIG_VIRTIO_SANDBOX) += virtio.o
diff --git a/test/lib/Makefile b/test/lib/Makefile
index aa89923f786..d620510f998 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -3,7 +3,7 @@
# (C) Copyright 2018
# Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
-obj-$(CONFIG_$(XPL_)UT_COMPRESSION) += compression.o
+obj-$(CONFIG_$(PHASE_)UT_COMPRESSION) += compression.o
ifeq ($(CONFIG_XPL_BUILD),)
obj-y += abuf.o
@@ -15,6 +15,7 @@ obj-$(CONFIG_SANDBOX) += kconfig.o
obj-y += lmb.o
obj-$(CONFIG_HAVE_SETJMP) += longjmp.o
obj-$(CONFIG_SANDBOX) += membuf.o
+obj-$(CONFIG_HAVE_INITJMP) += initjmp.o
obj-$(CONFIG_CONSOLE_RECORD) += test_print.o
obj-$(CONFIG_SSCANF) += sscanf.o
obj-$(CONFIG_$(PHASE_)STRTO) += str.o
@@ -30,7 +31,8 @@ obj-$(CONFIG_GETOPT) += getopt.o
obj-$(CONFIG_CRC8) += test_crc8.o
obj-$(CONFIG_UT_LIB_CRYPT) += test_crypt.o
obj-$(CONFIG_UT_TIME) += time.o
-obj-$(CONFIG_$(XPL_)UT_UNICODE) += unicode.o
+obj-$(CONFIG_$(PHASE_)UT_UNICODE) += unicode.o
+obj-$(CONFIG_UTHREAD) += uthread.o
obj-$(CONFIG_LIB_UUID) += uuid.o
else
obj-$(CONFIG_SANDBOX) += kconfig_spl.o
diff --git a/test/lib/initjmp.c b/test/lib/initjmp.c
new file mode 100644
index 00000000000..5b4b50b3f0f
--- /dev/null
+++ b/test/lib/initjmp.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2025 Linaro Limited
+ *
+ * Unit test for initjmp()
+ */
+
+#include <compiler.h>
+#include <setjmp.h>
+#include <stdbool.h>
+#include <test/lib.h>
+#include <test/ut.h>
+#include <vsprintf.h>
+
+static bool ep_entered;
+static jmp_buf return_buf;
+
+static void __noreturn entrypoint(void)
+{
+ ep_entered = true;
+
+ /* Jump back to the main routine */
+ longjmp(return_buf, 1);
+
+ /* Not reached */
+ panic("longjmp failed\n");
+}
+
+static int lib_initjmp(struct unit_test_state *uts)
+{
+ int ret;
+ void *stack;
+ jmp_buf buf;
+ /* Arbitrary but smaller values (< page size?) fail on SANDBOX */
+ size_t stack_sz = 8192;
+
+ (void)entrypoint;
+
+ ep_entered = false;
+
+ stack = malloc(stack_sz);
+ ut_assertnonnull(stack);
+
+ /*
+ * Prepare return_buf so that entrypoint may jump back just after the
+ * if()
+ */
+ if (!setjmp(return_buf)) {
+ /* return_buf initialized, entrypoint not yet called */
+
+ /*
+ * Prepare another jump buffer to jump into entrypoint with the
+ * given stack
+ */
+ ret = initjmp(buf, entrypoint, stack, stack_sz);
+ ut_assertok(ret);
+
+ /* Jump into entrypoint */
+ longjmp(buf, 1);
+ /*
+ * Not reached since entrypoint is expected to branch after
+ * the if()
+ */
+ ut_assert(false);
+ }
+
+ ut_assert(ep_entered);
+
+ free(stack);
+
+ return 0;
+}
+LIB_TEST(lib_initjmp, 0);
diff --git a/test/lib/uthread.c b/test/lib/uthread.c
new file mode 100644
index 00000000000..10a94d1c560
--- /dev/null
+++ b/test/lib/uthread.c
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 Linaro Limited
+ *
+ * Unit test for uthread
+ */
+
+#include <stdbool.h>
+#include <test/lib.h>
+#include <test/ut.h>
+#include <uthread.h>
+
+static int count;
+
+/* A thread entry point */
+static void worker(void *arg)
+{
+ int loops = (int)(unsigned long)arg;
+ int i;
+
+ for (i = 0; i < loops; i++) {
+ count++;
+ uthread_schedule();
+ }
+}
+
+/*
+ * uthread() - testing the uthread API
+ *
+ * This function creates two threads with the same entry point. The first one
+ * receives 5 as an argument, the second one receives 10. The number indicates
+ * the number of time the worker thread should loop on uthread_schedule()
+ * before returning. The workers increment a global counter each time they loop.
+ * As a result the main thread knows how many times it should call
+ * uthread_schedule() to let the two threads proceed, and it also knows which
+ * value the counter should have at any moment.
+ */
+static int uthread(struct unit_test_state *uts)
+{
+ int i;
+ int id1, id2;
+
+ count = 0;
+ id1 = uthread_grp_new_id();
+ ut_assert(id1 != 0);
+ id2 = uthread_grp_new_id();
+ ut_assert(id2 != 0);
+ ut_assert(id1 != id2);
+ ut_assertok(uthread_create(NULL, worker, (void *)5, 0, id1));
+ ut_assertok(uthread_create(NULL, worker, (void *)10, 0, 0));
+ /*
+ * The first call is expected to schedule the first worker, which will
+ * schedule the second one, which will schedule back to the main thread
+ * (here). Therefore count should be 2.
+ */
+ ut_assert(uthread_schedule());
+ ut_asserteq(2, count);
+ ut_assert(!uthread_grp_done(id1));
+ /* Four more calls should bring the count to 10 */
+ for (i = 0; i < 4; i++) {
+ ut_assert(!uthread_grp_done(id1));
+ ut_assert(uthread_schedule());
+ }
+ ut_asserteq(10, count);
+ /* This one allows the first worker to exit */
+ ut_assert(uthread_schedule());
+ /* At this point there should be no runnable thread in group 'id1' */
+ ut_assert(uthread_grp_done(id1));
+ /* Five more calls for the second worker to finish incrementing */
+ for (i = 0; i < 5; i++)
+ ut_assert(uthread_schedule());
+ ut_asserteq(15, count);
+ /* Plus one call to let the second worker return from its entry point */
+ ut_assert(uthread_schedule());
+ /* Now both tasks should be done, schedule should return false */
+ ut_assert(!uthread_schedule());
+
+ return 0;
+}
+LIB_TEST(uthread, 0);
+
+struct mw_args {
+ struct unit_test_state *uts;
+ struct uthread_mutex *m;
+ int flag;
+};
+
+static int mutex_worker_ret;
+
+static int _mutex_worker(struct mw_args *args)
+{
+ struct unit_test_state *uts = args->uts;
+
+ ut_asserteq(-EBUSY, uthread_mutex_trylock(args->m));
+ ut_assertok(uthread_mutex_lock(args->m));
+ args->flag = 1;
+ ut_assertok(uthread_mutex_unlock(args->m));
+
+ return 0;
+}
+
+static void mutex_worker(void *arg)
+{
+ mutex_worker_ret = _mutex_worker((struct mw_args *)arg);
+}
+
+/*
+ * thread_mutex() - testing uthread mutex operations
+ *
+ */
+static int uthread_mutex(struct unit_test_state *uts)
+{
+ struct uthread_mutex m = UTHREAD_MUTEX_INITIALIZER;
+ struct mw_args args = { .uts = uts, .m = &m, .flag = 0 };
+ int id;
+ int i;
+
+ id = uthread_grp_new_id();
+ ut_assert(id != 0);
+ /* Take the mutex */
+ ut_assertok(uthread_mutex_lock(&m));
+ /* Start a thread */
+ ut_assertok(uthread_create(NULL, mutex_worker, (void *)&args, 0,
+ id));
+ /* Let the thread run for a bit */
+ for (i = 0; i < 100; i++)
+ ut_assert(uthread_schedule());
+ /* Thread should not have set the flag due to the mutex */
+ ut_asserteq(0, args.flag);
+ /* Release the mutex */
+ ut_assertok(uthread_mutex_unlock(&m));
+ /* Schedule the thread until it is done */
+ while (uthread_schedule())
+ ;
+ /* Now the flag should be set */
+ ut_asserteq(1, args.flag);
+ /* And the mutex should be available */
+ ut_assertok(uthread_mutex_trylock(&m));
+ ut_assertok(uthread_mutex_unlock(&m));
+
+ /* Of course no error are expected from the thread routine */
+ ut_assertok(mutex_worker_ret);
+
+ return 0;
+}
+LIB_TEST(uthread_mutex, 0);
diff --git a/test/py/tests/test_fs/conftest.py b/test/py/tests/test_fs/conftest.py
index c73fb4abbcb..0205048e73a 100644
--- a/test/py/tests/test_fs/conftest.py
+++ b/test/py/tests/test_fs/conftest.py
@@ -17,7 +17,7 @@ supported_fs_fat = ['fat12', 'fat16']
supported_fs_mkdir = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
supported_fs_unlink = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
supported_fs_symlink = ['ext4']
-supported_fs_rename = ['fat12', 'fat16', 'fat32']
+supported_fs_rename = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
#
# Filesystem test specific setup
diff --git a/test/py/tests/test_fs/test_basic.py b/test/py/tests/test_fs/test_basic.py
index 64a3b50f52a..88b163ce305 100644
--- a/test/py/tests/test_fs/test_basic.py
+++ b/test/py/tests/test_fs/test_basic.py
@@ -35,6 +35,19 @@ class TestFsBasic(object):
'%sls host 0:0 invalid_d' % fs_cmd_prefix)
assert('' == output)
+ with ubman.log.section('Test Case 1c - test -e'):
+ # Test Case 1 - test -e
+ output = ubman.run_command_list([
+ 'host bind 0 %s' % fs_img,
+ 'test -e host 0:0 1MB.file && echo PASS'])
+ assert('PASS' in ''.join(output))
+
+ with ubman.log.section('Test Case 1d - test -e (invalid file)'):
+ # In addition, test with a nonexistent file to see if we crash.
+ output = ubman.run_command(
+ 'test -e host 0:0 2MB.file || echo PASS')
+ assert('PASS' in ''.join(output))
+
def test_fs2(self, ubman, fs_obj_basic):
"""
Test Case 2 - size command for a small file
diff --git a/test/py/tests/test_memtest.py b/test/py/tests/test_memtest.py
index 0340edbea5a..f24f9f0d67d 100644
--- a/test/py/tests/test_memtest.py
+++ b/test/py/tests/test_memtest.py
@@ -29,12 +29,12 @@ def get_memtest_env(ubman):
if not f:
pytest.skip("memtest is not enabled!")
else:
- start = f.get("start_addr", 0x0)
- size = f.get("size", 0x1000)
- pattern = f.get("pattern", 0x0)
+ start = hex(f.get("start_addr", 0x0))
+ size = hex(f.get("size", 0x1000))
+ pattern = hex(f.get("pattern", 0x0))
iteration = f.get("iteration", 2)
timeout = f.get("timeout", 50000)
- end = hex(int(start) + int(size))
+ end = hex(int(start, 16) + int(size, 16))
return start, end, pattern, iteration, timeout
@pytest.mark.buildconfigspec("cmd_memtest")
diff --git a/test/py/tests/test_spi.py b/test/py/tests/test_spi.py
index dd767528dbf..09174f91e98 100644
--- a/test/py/tests/test_spi.py
+++ b/test/py/tests/test_spi.py
@@ -703,4 +703,33 @@ def test_spi_negative(ubman):
ubman, 'read', start, size, res_area, 1, error_msg, EXPECTED_READ
)
+ # Start reading from the reserved area
+ m = re.search(r'reserved\[0\]\s*\[(0x.+)-(0x.+)\]', output)
+ if not m or int(m.group(1), 16) == 0:
+ ubman.log.info('No reserved area is defined or start addr is 0x0!')
+ else:
+ rstart_area = int(m.group(1), 16)
+ rend_area = int(m.group(2), 16)
+
+ # Case 1: Start reading from the middle of the reserved area
+ r_size = rend_area - rstart_area
+ r_area = rstart_area + r_size
+ flash_ops(
+ ubman, 'read', start, size, r_area, 1, error_msg, EXPECTED_READ
+ )
+
+ # Case 2: Start reading from before the reserved area to cross-over
+ # the reserved area
+ rstart_area = rstart_area - int(size/2)
+ flash_ops(
+ ubman, 'read', start, size, rstart_area, 1, error_msg, EXPECTED_READ
+ )
+
+ # Case 3: Start reading till after the reserved area to cross-over
+ # the reserved area
+ rend_area = rend_area - int(size/2)
+ flash_ops(
+ ubman, 'read', start, size, rend_area, 1, error_msg, EXPECTED_READ
+ )
+
i = i + 1
diff --git a/test/py/tests/test_trace.py b/test/py/tests/test_trace.py
index 6ac1b225465..fcdcbe2c6db 100644
--- a/test/py/tests/test_trace.py
+++ b/test/py/tests/test_trace.py
@@ -201,7 +201,7 @@ def check_funcgraph(ubman, fname, proftool, map_fname, trace_dat):
# Then look for this:
# u-boot-1 0..... 282.101375: funcgraph_exit: 0.006 us | }
# Then check for this:
- # u-boot-1 0..... 282.101375: funcgraph_entry: 0.000 us | calc_reloc_ofs();
+ # u-boot-1 0..... 282.101375: funcgraph_entry: 0.000 us | event_init();
expected_indent = None
found_start = False
@@ -224,8 +224,8 @@ def check_funcgraph(ubman, fname, proftool, map_fname, trace_dat):
found_end = True
# The next function after initf_bootstage() exits should be
- # initcall_is_event()
- assert upto == 'calc_reloc_ofs()'
+ # event_init()
+ assert upto == 'event_init()'
# Now look for initf_dm() and dm_timer_init() so we can check the bootstage
# time
@@ -274,7 +274,7 @@ def check_flamegraph(ubman, fname, proftool, map_fname, trace_fg):
# We expect dm_timer_init() to be called twice: once before relocation and
# once after
look1 = 'initf_dm;dm_timer_init 1'
- look2 = 'board_init_r;initcall_run_list;initr_dm_devices;dm_timer_init 1'
+ look2 = 'board_init_r;initcall_run_r;initr_dm_devices;dm_timer_init 1'
found = 0
with open(trace_fg, 'r') as fd:
for line in fd: