diff options
author | Tom Rini <trini@konsulko.com> | 2022-09-02 21:51:21 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-09-02 21:53:36 -0400 |
commit | 98b3a998b31a83d8167f888b11ddd5cce8194f35 (patch) | |
tree | 91e5c815982e9f1823f86f61bc49e28d948d1b4c | |
parent | 2d7069126d11f8708ee38c68b1c6cafae5e50dae (diff) | |
parent | 21ddac140e3040b2693c1a5558a84c19a879c04f (diff) | |
download | u-boot-98b3a998b31a83d8167f888b11ddd5cce8194f35.zip u-boot-98b3a998b31a83d8167f888b11ddd5cce8194f35.tar.gz u-boot-98b3a998b31a83d8167f888b11ddd5cce8194f35.tar.bz2 |
Merge branch '2022-09-02-assorted-improvements' into next
- DM RTC improvements that should help in CI, allow disabling LTO from
the make line, add extension (cape, etc) support to distro bootcmd,
add a pause command and re-enable ARM v4T support.
-rw-r--r-- | .azure-pipelines.yml | 4 | ||||
-rw-r--r-- | .gitlab-ci.yml | 7 | ||||
-rw-r--r-- | Makefile | 17 | ||||
-rw-r--r-- | arch/arm/config.mk | 4 | ||||
-rw-r--r-- | arch/arm/include/asm/assembler.h | 10 | ||||
-rw-r--r-- | arch/arm/include/asm/global_data.h | 2 | ||||
-rw-r--r-- | arch/arm/lib/lib1funcs.S | 8 | ||||
-rw-r--r-- | arch/arm/lib/memcpy.S | 6 | ||||
-rw-r--r-- | arch/arm/lib/relocate.S | 10 | ||||
-rw-r--r-- | arch/arm/lib/setjmp.S | 4 | ||||
-rw-r--r-- | arch/sandbox/cpu/spl.c | 2 | ||||
-rw-r--r-- | cmd/Kconfig | 6 | ||||
-rw-r--r-- | cmd/Makefile | 1 | ||||
-rw-r--r-- | cmd/pause.c | 32 | ||||
-rw-r--r-- | configs/sandbox64_defconfig | 1 | ||||
-rw-r--r-- | configs/sandbox_defconfig | 1 | ||||
-rw-r--r-- | doc/build/gcc.rst | 17 | ||||
-rw-r--r-- | doc/develop/tests_sandbox.rst | 24 | ||||
-rw-r--r-- | doc/usage/cmd/pause.rst | 53 | ||||
-rw-r--r-- | doc/usage/index.rst | 1 | ||||
-rw-r--r-- | include/config_distro_bootcmd.h | 32 | ||||
-rw-r--r-- | include/test/test.h | 2 | ||||
-rw-r--r-- | include/test/ut.h | 3 | ||||
-rw-r--r-- | scripts/Makefile.spl | 2 | ||||
-rw-r--r-- | test/cmd/Makefile | 3 | ||||
-rw-r--r-- | test/cmd/test_pause.c | 45 | ||||
-rw-r--r-- | test/cmd_ut.c | 12 | ||||
-rw-r--r-- | test/dm/rtc.c | 53 | ||||
-rw-r--r-- | test/dm/test-dm.c | 13 | ||||
-rw-r--r-- | test/test-main.c | 14 |
30 files changed, 336 insertions, 53 deletions
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 0fa9247..d78a170 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -243,6 +243,9 @@ stages: sandbox_clang: TEST_PY_BD: "sandbox" OVERRIDE: "-O clang-13" + sandbox_nolto: + TEST_PY_BD: "sandbox" + BUILD_ENV: "NO_LTO=1" sandbox_spl: TEST_PY_BD: "sandbox_spl" TEST_PY_TEST_SPEC: "test_ofplatdata or test_handoff or test_spl" @@ -354,6 +357,7 @@ stages: export TEST_PY_ID="${TEST_PY_ID}" export TEST_PY_TEST_SPEC="${TEST_PY_TEST_SPEC}" export OVERRIDE="${OVERRIDE}" + export BUILD_ENV="${BUILD_ENV}" EOF cat << "EOF" >> test.sh # the below corresponds to .gitlab-ci.yml "before_script" diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5592862..8e94bf8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -33,6 +33,7 @@ stages: script: # If we've been asked to use clang only do one configuration. - export UBOOT_TRAVIS_BUILD_DIR=/tmp/${TEST_PY_BD} + - echo BUILD_ENV ${BUILD_ENV} - tools/buildman/buildman -o ${UBOOT_TRAVIS_BUILD_DIR} -w -E -W -e --board ${TEST_PY_BD} ${OVERRIDE} - cp ~/grub_x86.efi $UBOOT_TRAVIS_BUILD_DIR/ @@ -254,6 +255,12 @@ sandbox with clang test.py: OVERRIDE: "-O clang-13" <<: *buildman_and_testpy_dfn +sandbox without LTO test.py: + variables: + TEST_PY_BD: "sandbox" + BUILD_ENV: "NO_LTO=1" + <<: *buildman_and_testpy_dfn + sandbox_spl test.py: variables: TEST_PY_BD: "sandbox_spl" @@ -643,6 +643,13 @@ export CFLAGS_EFI # Compiler flags to add when building EFI app export CFLAGS_NON_EFI # Compiler flags to remove when building EFI app export EFI_TARGET # binutils target if EFI is natively supported +export LTO_ENABLE + +# This is y if LTO is enabled for this build. See NO_LTO=1 to disable LTO +ifeq ($(NO_LTO),) +LTO_ENABLE=$(if $(CONFIG_LTO),y) +endif + # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use # that (or fail if absent). Otherwise, search for a linker script in a # standard location. @@ -708,16 +715,16 @@ endif LTO_CFLAGS := LTO_FINAL_LDFLAGS := export LTO_CFLAGS LTO_FINAL_LDFLAGS -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) ifeq ($(cc-name),clang) - LTO_CFLAGS += -flto + LTO_CFLAGS += -DLTO_ENABLE -flto LTO_FINAL_LDFLAGS += -flto AR = $(shell $(CC) -print-prog-name=llvm-ar) NM = $(shell $(CC) -print-prog-name=llvm-nm) else NPROC := $(shell nproc 2>/dev/null || echo 1) - LTO_CFLAGS += -flto=$(NPROC) + LTO_CFLAGS += -DLTO_ENABLE -flto=$(NPROC) LTO_FINAL_LDFLAGS += -fuse-linker-plugin -flto=$(NPROC) # use plugin aware tools @@ -1765,7 +1772,7 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink) # Generate linker list symbols references to force compiler to not optimize # them away when compiling with LTO -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) u-boot-keep-syms-lto := keep-syms-lto.o u-boot-keep-syms-lto_c := $(patsubst %.o,%.c,$(u-boot-keep-syms-lto)) @@ -1787,7 +1794,7 @@ endif # Rule to link u-boot # May be overridden by arch/$(ARCH)/config.mk -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) quiet_cmd_u-boot__ ?= LTO $@ cmd_u-boot__ ?= \ $(CC) -nostdlib -nostartfiles \ diff --git a/arch/arm/config.mk b/arch/arm/config.mk index b3548ce..2065438 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -15,11 +15,11 @@ CFLAGS_NON_EFI := -fno-pic -ffixed-r9 -ffunction-sections -fdata-sections \ -fstack-protector-strong CFLAGS_EFI := -fpic -fshort-wchar -ifneq ($(CONFIG_LTO)$(CONFIG_USE_PRIVATE_LIBGCC),yy) +ifneq ($(LTO_ENABLE)$(CONFIG_USE_PRIVATE_LIBGCC),yy) LDFLAGS_FINAL += --gc-sections endif -ifndef CONFIG_LTO +ifneq ($(LTO_ENABLE),y) PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections endif diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index b146918..8d42ef4 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -58,16 +58,22 @@ #endif /* - * We only support cores that support at least Thumb-1 and thus we use - * 'bx lr' + * Use 'bx lr' everywhere except ARMv4 (without 'T') where only 'mov pc, lr' + * works */ .irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo .macro ret\c, reg + + /* ARMv4- don't know bx lr but the assembler fails to see that */ +#ifdef __ARM_ARCH_4__ + mov\c pc, \reg +#else .ifeqs "\reg", "lr" bx\c \reg .else mov\c pc, \reg .endif +#endif .endm .endr diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index 6ee2a76..cd6112d 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -101,7 +101,7 @@ struct arch_global_data { #include <asm-generic/global_data.h> -#if defined(__clang__) || defined(CONFIG_LTO) +#if defined(__clang__) || defined(LTO_ENABLE) #define DECLARE_GLOBAL_DATA_PTR #define gd get_gd() diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S index 700eee5..7ff4446 100644 --- a/arch/arm/lib/lib1funcs.S +++ b/arch/arm/lib/lib1funcs.S @@ -377,7 +377,7 @@ ENTRY(__gnu_thumb1_case_sqi) lsls r1, r1, #1 add lr, lr, r1 pop {r1} - bx lr + ret lr ENDPROC(__gnu_thumb1_case_sqi) .popsection @@ -391,7 +391,7 @@ ENTRY(__gnu_thumb1_case_uqi) lsls r1, r1, #1 add lr, lr, r1 pop {r1} - bx lr + ret lr ENDPROC(__gnu_thumb1_case_uqi) .popsection @@ -406,7 +406,7 @@ ENTRY(__gnu_thumb1_case_shi) lsls r1, r1, #1 add lr, lr, r1 pop {r0, r1} - bx lr + ret lr ENDPROC(__gnu_thumb1_case_shi) .popsection @@ -421,7 +421,7 @@ ENTRY(__gnu_thumb1_case_uhi) lsls r1, r1, #1 add lr, lr, r1 pop {r0, r1} - bx lr + ret lr ENDPROC(__gnu_thumb1_case_uhi) .popsection #endif diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S index eee7a21..a1c996f 100644 --- a/arch/arm/lib/memcpy.S +++ b/arch/arm/lib/memcpy.S @@ -59,7 +59,7 @@ #endif ENTRY(memcpy) cmp r0, r1 - bxeq lr + reteq lr enter r4, lr @@ -148,7 +148,7 @@ ENTRY(memcpy) str1b r0, ip, cs, abort=21f exit r4, lr - bx lr + ret lr 9: rsb ip, ip, #4 cmp ip, #2 @@ -258,7 +258,7 @@ ENTRY(memcpy) .macro copy_abort_end ldmfd sp!, {r4, lr} - bx lr + ret lr .endm ENDPROC(memcpy) diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S index 5102bfa..dd6f2e3 100644 --- a/arch/arm/lib/relocate.S +++ b/arch/arm/lib/relocate.S @@ -61,7 +61,7 @@ ENTRY(relocate_vectors) stmia r1!, {r2-r8,r10} #endif #endif - bx lr + ret lr ENDPROC(relocate_vectors) @@ -127,13 +127,7 @@ relocate_done: mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ #endif - /* ARMv4- don't know bx lr but the assembler fails to see that */ - -#ifdef __ARM_ARCH_4__ - mov pc, lr -#else - bx lr -#endif + ret lr ENDPROC(relocate_code) diff --git a/arch/arm/lib/setjmp.S b/arch/arm/lib/setjmp.S index 176a1d5..2f041ae 100644 --- a/arch/arm/lib/setjmp.S +++ b/arch/arm/lib/setjmp.S @@ -17,7 +17,7 @@ ENTRY(setjmp) mov ip, sp stm a1, {v1-v8, ip, lr} mov a1, #0 - bx lr + ret lr ENDPROC(setjmp) .popsection @@ -31,6 +31,6 @@ ENTRY(longjmp) bne 1f mov a1, #1 1: - bx lr + ret lr ENDPROC(longjmp) .popsection diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c index fe5d44d..1d49a9b 100644 --- a/arch/sandbox/cpu/spl.c +++ b/arch/sandbox/cpu/spl.c @@ -89,7 +89,7 @@ void spl_board_init(void) int ret; ret = ut_run_list("spl", NULL, tests, count, - state->select_unittests); + state->select_unittests, 1); /* continue execution into U-Boot */ } } diff --git a/cmd/Kconfig b/cmd/Kconfig index 211ebe9..67c7d25 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1971,6 +1971,12 @@ config CMD_GETTIME milliseconds. See also the 'bootstage' command which provides more flexibility for boot timing. +config CMD_PAUSE + bool "pause command" + help + Delay execution waiting for any user input. + Useful to allow the user to read a failure log. + config CMD_RNG bool "rng command" depends on DM_RNG diff --git a/cmd/Makefile b/cmd/Makefile index 6e87522..7abe1d3 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -102,6 +102,7 @@ obj-$(CONFIG_CMD_MFSL) += mfsl.o obj-$(CONFIG_CMD_MII) += mii.o obj-$(CONFIG_CMD_MISC) += misc.o obj-$(CONFIG_CMD_MDIO) += mdio.o +obj-$(CONFIG_CMD_PAUSE) += pause.o obj-$(CONFIG_CMD_SLEEP) += sleep.o obj-$(CONFIG_CMD_MMC) += mmc.o obj-$(CONFIG_CMD_OPTEE_RPMB) += optee_rpmb.o diff --git a/cmd/pause.c b/cmd/pause.c new file mode 100644 index 0000000..c97833c --- /dev/null +++ b/cmd/pause.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2021 + * Samuel Dionne-Riel <samuel@dionne-riel.com> + */ + +#include <command.h> +#include <stdio.h> + +static int do_pause(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + char *message = "Press any key to continue..."; + + if (argc == 2) + message = argv[1]; + + /* No newline, so it sticks to the bottom of the screen */ + printf("%s", message); + + /* Wait on "any" key... */ + (void) getchar(); + + /* Since there was no newline, we need it now */ + printf("\n"); + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(pause, 2, 1, do_pause, + "delay until user input", + "[prompt] - Wait until users presses any key. [prompt] can be used to customize the message.\n" +); diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 4599db7..9a1b6e4 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -67,6 +67,7 @@ CONFIG_CMD_BMP=y CONFIG_CMD_EFIDEBUG=y CONFIG_CMD_RTC=y CONFIG_CMD_TIME=y +CONFIG_CMD_PAUSE=y CONFIG_CMD_TIMER=y CONFIG_CMD_SOUND=y CONFIG_CMD_QFW=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 4a0c51c..e6a1718 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -96,6 +96,7 @@ CONFIG_CMD_BOOTCOUNT=y CONFIG_CMD_EFIDEBUG=y CONFIG_CMD_RTC=y CONFIG_CMD_TIME=y +CONFIG_CMD_PAUSE=y CONFIG_CMD_TIMER=y CONFIG_CMD_SOUND=y CONFIG_CMD_QFW=y diff --git a/doc/build/gcc.rst b/doc/build/gcc.rst index ee544ad..a71f860 100644 --- a/doc/build/gcc.rst +++ b/doc/build/gcc.rst @@ -152,6 +152,23 @@ of dtc is new enough. It also makes sure that pylibfdt is present, if needed Note that the :doc:`tools` are always built with the included version of libfdt so it is not possible to build U-Boot tools with a system libfdt, at present. +Link-time optimisation (LTO) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +U-Boot supports link-time optimisation which can reduce the size of the final +U-Boot binaries, particularly with SPL. + +At present this can be enabled by ARM boards by adding `CONFIG_LTO=y` into the +defconfig file. Other architectures are not supported. LTO is enabled by default +for sandbox. + +This does incur a link-time penalty of several seconds. For faster incremental +builds during development, you can disable it by setting `NO_LTO` to `1`. + +.. code-block:: bash + + NO_LTO=1 make + Other build targets ~~~~~~~~~~~~~~~~~~~ diff --git a/doc/develop/tests_sandbox.rst b/doc/develop/tests_sandbox.rst index 40cf8ec..8e42a32 100644 --- a/doc/develop/tests_sandbox.rst +++ b/doc/develop/tests_sandbox.rst @@ -119,6 +119,30 @@ You can easily use gdb on these tests, without needing --gdbserver:: You can then single-step and look at variables as needed. +Running tests multiple times +---------------------------- + +Some tests can have race conditions which are hard to detect on a single +one. It is possible to run each individual test multiple times, before moving +to the next test, with the '-r' flag. + +This is most useful when running a single test, since running all tests +multiple times can take a while. + +For example:: + + => ut dm -r1000 dm_test_rtc_set_get + ... + Test: dm_test_rtc_set_get: rtc.c (flat tree) + Test: dm_test_rtc_set_get: rtc.c + test/dm/rtc.c:257, dm_test_rtc_reset(): old_base_time == base_time: Expected 0x62e7453c (1659323708), got 0x62e7453d (1659323709) + Test: dm_test_rtc_set_get: rtc.c (flat tree) + Test: dm_test_rtc_set_get: rtc.c + Test: dm_test_rtc_set_get: rtc.c (flat tree) + ... + Test dm_test_rtc_reset failed 3 times + + Running sandbox_spl tests directly ---------------------------------- diff --git a/doc/usage/cmd/pause.rst b/doc/usage/cmd/pause.rst new file mode 100644 index 0000000..c79e399 --- /dev/null +++ b/doc/usage/cmd/pause.rst @@ -0,0 +1,53 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later: + +pause command +============= + +Synopsis +-------- + +:: + + pause [prompt] + + +Description +----------- + +The pause command delays execution waiting for any user input. + +It can accept a single parameter to change the prompt message. + +Examples +-------- + +Using with the default prompt: + +:: + + => pause + Press any key to continue... + + +Using with a custom prompt: + +:: + + => pause 'Prompt for pause...' + Prompt for pause... + +Note that complex prompts require proper quoting: + +:: + + => pause Prompt for pause... + pause - delay until user input + + Usage: + pause [prompt] - Wait until users presses any key. [prompt] can be used to customize the message. + +Return value +------------ + +The return value $? is always set to 0 (true), unless invoked in an invalid +manner. diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 28f9683..5170fa8 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -52,6 +52,7 @@ Shell commands cmd/mbr cmd/md cmd/mmc + cmd/pause cmd/pinmux cmd/printenv cmd/pstore diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index c6e9c49..2157f35 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -160,11 +160,13 @@ "scan_dev_for_efi=" \ "setenv efi_fdtfile ${fdtfile}; " \ BOOTENV_EFI_SET_FDTFILE_FALLBACK \ + BOOTENV_RUN_EXTENSION_INIT \ "for prefix in ${efi_dtb_prefixes}; do " \ "if test -e ${devtype} " \ "${devnum}:${distro_bootpart} " \ "${prefix}${efi_fdtfile}; then " \ "run load_efi_dtb; " \ + BOOTENV_RUN_EXTENSION_APPLY \ "fi;" \ "done;" \ "run boot_efi_bootmgr;" \ @@ -416,6 +418,34 @@ BOOT_TARGET_DEVICES_references_PXE_without_CONFIG_CMD_DHCP_or_PXE #endif +#if defined(CONFIG_CMD_EXTENSION) +#define BOOTENV_RUN_EXTENSION_INIT "run extension_init; " +#define BOOTENV_RUN_EXTENSION_APPLY "run extension_apply; " +#define BOOTENV_SET_EXTENSION_NEED_INIT \ + "extension_need_init=; " \ + "setenv extension_overlay_addr ${fdtoverlay_addr_r}; " +#define BOOTENV_SHARED_EXTENSION \ + "extension_init=" \ + "echo Extension init...; " \ + "if ${extension_need_init}; then " \ + "extension_need_init=false; " \ + "extension scan; " \ + "fi\0" \ + \ + "extension_overlay_cmd=" \ + "load ${devtype} ${devnum}:${distro_bootpart} " \ + "${extension_overlay_addr} ${prefix}${extension_overlay_name}\0" \ + "extension_apply=" \ + "if fdt addr -q ${fdt_addr_r}; then " \ + "extension apply all; " \ + "fi\0" +#else +#define BOOTENV_RUN_EXTENSION_INIT +#define BOOTENV_RUN_EXTENSION_APPLY +#define BOOTENV_SET_EXTENSION_NEED_INIT +#define BOOTENV_SHARED_EXTENSION +#endif + #define BOOTENV_DEV_NAME(devtypeu, devtypel, instance, ...) \ BOOTENV_DEV_NAME_##devtypeu(devtypeu, devtypel, instance, ## __VA_ARGS__) #define BOOTENV_BOOT_TARGETS \ @@ -435,6 +465,7 @@ BOOTENV_SHARED_UBIFS \ BOOTENV_SHARED_EFI \ BOOTENV_SHARED_VIRTIO \ + BOOTENV_SHARED_EXTENSION \ "boot_prefixes=/ /boot/\0" \ "boot_scripts=boot.scr.uimg boot.scr\0" \ "boot_script_dhcp=boot.scr.uimg\0" \ @@ -499,6 +530,7 @@ BOOTENV_SET_NVME_NEED_INIT \ BOOTENV_SET_IDE_NEED_INIT \ BOOTENV_SET_VIRTIO_NEED_INIT \ + BOOTENV_SET_EXTENSION_NEED_INIT \ "for target in ${boot_targets}; do " \ "run bootcmd_${target}; " \ "done\0" diff --git a/include/test/test.h b/include/test/test.h index c888d68..2b68331 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -20,6 +20,7 @@ * @testdev: Test device * @force_fail_alloc: Force all memory allocs to fail * @skip_post_probe: Skip uclass post-probe processing + * @runs_per_test: Number of times to run each test (typically 1) * @expect_str: Temporary string used to hold expected string value * @actual_str: Temporary string used to hold actual string value */ @@ -32,6 +33,7 @@ struct unit_test_state { struct udevice *testdev; int force_fail_alloc; int skip_post_probe; + int runs_per_test; char expect_str[512]; char actual_str[512]; }; diff --git a/include/test/ut.h b/include/test/ut.h index 18740f5..f7d1d18 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -403,9 +403,10 @@ void test_set_state(struct unit_test_state *uts); * @count: Number of tests to run * @select_name: Name of a single test to run (from the list provided). If NULL * then all tests are run + * @runs_per_test: Number of times to run each test (typically 1) * Return: 0 if all tests passed, -1 if any failed */ int ut_run_list(const char *name, const char *prefix, struct unit_test *tests, - int count, const char *select_name); + int count, const char *select_name, int runs_per_test); #endif diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index 3bafeb4..0b3a51d 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -489,7 +489,7 @@ endif # Rule to link u-boot-spl # May be overridden by arch/$(ARCH)/config.mk -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) quiet_cmd_u-boot-spl ?= LTO $@ cmd_u-boot-spl ?= \ ( \ diff --git a/test/cmd/Makefile b/test/cmd/Makefile index c331757..1bb02d9 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -5,6 +5,9 @@ ifdef CONFIG_HUSH_PARSER obj-$(CONFIG_CONSOLE_RECORD) += test_echo.o endif +ifdef CONFIG_CONSOLE_RECORD +obj-$(CONFIG_CMD_PAUSE) += test_pause.o +endif obj-y += mem.o obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o obj-$(CONFIG_CMD_FDT) += fdt.o diff --git a/test/cmd/test_pause.c b/test/cmd/test_pause.c new file mode 100644 index 0000000..2b85cce --- /dev/null +++ b/test/cmd/test_pause.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Tests for pause command + * + * Copyright 2022, Samuel Dionne-Riel <samuel@dionne-riel.com> + */ + +#include <common.h> +#include <asm/global_data.h> +#include <test/lib.h> +#include <test/ut.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int lib_test_hush_pause(struct unit_test_state *uts) +{ + /* Test default message */ + console_record_reset_enable(); + /* Cook a newline when the command is expected to pause */ + console_in_puts("\n"); + ut_assertok(run_command("pause", 0)); + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + ut_asserteq_str("Press any key to continue...", uts->actual_str); + ut_assertok(ut_check_console_end(uts)); + + /* Test provided message */ + console_record_reset_enable(); + /* Cook a newline when the command is expected to pause */ + console_in_puts("\n"); + ut_assertok(run_command("pause 'Prompt for pause...'", 0)); + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + ut_asserteq_str("Prompt for pause...", uts->actual_str); + ut_assertok(ut_check_console_end(uts)); + + /* Test providing more than one params */ + console_record_reset_enable(); + /* No newline cooked here since the command is expected to fail */ + ut_asserteq(1, run_command("pause a b", 0)); + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + ut_asserteq_str("pause - delay until user input", uts->actual_str); + ut_asserteq(1, ut_check_console_end(uts)); + + return 0; +} +LIB_TEST(lib_test_hush_pause, 0); diff --git a/test/cmd_ut.c b/test/cmd_ut.c index 3789c6b..11c219b 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -18,10 +18,17 @@ int cmd_ut_category(const char *name, const char *prefix, struct unit_test *tests, int n_ents, int argc, char *const argv[]) { + int runs_per_text = 1; int ret; + if (argc > 1 && !strncmp("-r", argv[1], 2)) { + runs_per_text = dectoul(argv[1] + 2, NULL); + argv++; + argc++; + } + ret = ut_run_list(name, prefix, tests, n_ents, - argc > 1 ? argv[1] : NULL); + argc > 1 ? argv[1] : NULL, runs_per_text); return ret ? CMD_RET_FAILURE : 0; } @@ -168,7 +175,8 @@ static char ut_help_text[] = #ifdef CONFIG_CMD_LOADM "ut loadm [test-name]- test of parameters and load memory blob\n" #endif - ; + "All commands accept an optional [-r<runs>] flag before [test-name], to\n" + "run each test multiple times (<runs> is in decimal)"; #endif /* CONFIG_SYS_LONGHELP */ U_BOOT_CMD( diff --git a/test/dm/rtc.c b/test/dm/rtc.c index c7f9f8f..bf97dbb 100644 --- a/test/dm/rtc.c +++ b/test/dm/rtc.c @@ -60,16 +60,27 @@ static int dm_test_rtc_set_get(struct unit_test_state *uts) { struct rtc_time now, time, cmp; struct udevice *dev, *emul; - long offset, old_offset, old_base_time; + long offset, check_offset, old_offset, old_base_time; + int i; ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev)); - ut_assertok(dm_rtc_get(dev, &now)); ut_assertok(i2c_emul_find(dev, &emul)); - ut_assert(emul != NULL); + ut_assertnonnull(emul); + + /* Get the offset, putting the RTC into manual mode */ + i = 0; + do { + check_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); + ut_assertok(dm_rtc_get(dev, &now)); + + /* Tell the RTC to go into manual mode */ + old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); + + /* If the times changed in that period, read it again */ + } while (++i < 2 && check_offset != old_offset); + ut_asserteq(check_offset, old_offset); - /* Tell the RTC to go into manual mode */ - old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1); memset(&time, '\0', sizeof(time)); @@ -127,7 +138,8 @@ static int dm_test_rtc_set_get(struct unit_test_state *uts) ut_asserteq(now.tm_sec + 1, cmp.tm_sec); } - old_offset = sandbox_i2c_rtc_set_offset(emul, true, 0); + /* return RTC to normal mode */ + sandbox_i2c_rtc_set_offset(emul, true, 0); return 0; } @@ -161,7 +173,7 @@ static int dm_test_rtc_read_write(struct unit_test_state *uts) ut_asserteq(memcmp(buf, "at", 3), 0); ut_assertok(i2c_emul_find(dev, &emul)); - ut_assert(emul != NULL); + ut_assertnonnull(emul); old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); ut_assertok(dm_rtc_get(dev, &time)); @@ -240,20 +252,31 @@ static int dm_test_rtc_reset(struct unit_test_state *uts) struct rtc_time now; struct udevice *dev, *emul; long old_base_time, base_time; + int i; ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev)); ut_assertok(dm_rtc_get(dev, &now)); ut_assertok(i2c_emul_find(dev, &emul)); - ut_assert(emul != NULL); + ut_assertnonnull(emul); + + i = 0; + do { + old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, 0); - old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, 0); + ut_asserteq(0, sandbox_i2c_rtc_get_set_base_time(emul, -1)); - ut_asserteq(0, sandbox_i2c_rtc_get_set_base_time(emul, -1)); + ut_assertok(dm_rtc_reset(dev)); + base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1); - /* Resetting the RTC should put he base time back to normal */ - ut_assertok(dm_rtc_reset(dev)); - base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1); + /* + * Resetting the RTC should put the base time back to normal. + * Allow for a one-timeadjustment in case the time flips over + * while this test process is pre-empted (either by a second + * or a daylight-saving change), since reset_time() in + * i2c_rtc_emul.c reads the time from the OS. + */ + } while (++i < 2 && base_time != old_base_time); ut_asserteq(old_base_time, base_time); return 0; @@ -274,9 +297,9 @@ static int dm_test_rtc_dual(struct unit_test_state *uts) ut_assertok(dm_rtc_get(dev2, &now2)); ut_assertok(i2c_emul_find(dev1, &emul1)); - ut_assert(emul1 != NULL); + ut_assertnonnull(emul1); ut_assertok(i2c_emul_find(dev2, &emul2)); - ut_assert(emul2 != NULL); + ut_assertnonnull(emul2); offset = sandbox_i2c_rtc_set_offset(emul1, false, -1); sandbox_i2c_rtc_set_offset(emul2, false, offset + 1); diff --git a/test/dm/test-dm.c b/test/dm/test-dm.c index f5cda81..eb35813 100644 --- a/test/dm/test-dm.c +++ b/test/dm/test-dm.c @@ -29,13 +29,14 @@ DECLARE_GLOBAL_DATA_PTR; * "fdt_pre_reloc"), or NULL to run all * Return: 0 if all tests passed, 1 if not */ -static int dm_test_run(const char *test_name) +static int dm_test_run(const char *test_name, int runs_per_text) { struct unit_test *tests = UNIT_TEST_SUITE_START(dm_test); const int n_ents = UNIT_TEST_SUITE_COUNT(dm_test); int ret; - ret = ut_run_list("driver model", "dm_test_", tests, n_ents, test_name); + ret = ut_run_list("driver model", "dm_test_", tests, n_ents, test_name, + runs_per_text); return ret ? CMD_RET_FAILURE : 0; } @@ -43,9 +44,15 @@ static int dm_test_run(const char *test_name) int do_ut_dm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { const char *test_name = NULL; + int runs_per_text = 1; + if (argc > 1 && !strncmp("-r", argv[1], 2)) { + runs_per_text = dectoul(argv[1] + 2, NULL); + argv++; + argc++; + } if (argc > 1) test_name = argv[1]; - return dm_test_run(test_name); + return dm_test_run(test_name, runs_per_text); } diff --git a/test/test-main.c b/test/test-main.c index 31837e5..4f1c54b 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -390,11 +390,17 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, for (test = tests; test < tests + count; test++) { const char *test_name = test->name; - int ret; + int ret, i, old_fail_count; if (!test_matches(prefix, test_name, select_name)) continue; - ret = ut_run_test_live_flat(uts, test, select_name); + old_fail_count = uts->fail_count; + for (i = 0; i < uts->runs_per_test; i++) + ret = ut_run_test_live_flat(uts, test, select_name); + if (uts->fail_count != old_fail_count) { + printf("Test %s failed %d times\n", select_name, + uts->fail_count - old_fail_count); + } found++; if (ret == -EAGAIN) continue; @@ -408,7 +414,8 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, } int ut_run_list(const char *category, const char *prefix, - struct unit_test *tests, int count, const char *select_name) + struct unit_test *tests, int count, const char *select_name, + int runs_per_test) { struct unit_test_state uts = { .fail_count = 0 }; bool has_dm_tests = false; @@ -432,6 +439,7 @@ int ut_run_list(const char *category, const char *prefix, printf("Running %d %s tests\n", count, category); uts.of_root = gd_of_root(); + uts.runs_per_test = runs_per_test; ret = ut_run_tests(&uts, prefix, tests, count, select_name); if (ret == -ENOENT) |