Merge branch '2023-01-11-assorted-general-updates'

- Assorted Kconfig cleanups, code clean ups, env+ubi updates, correct
  return value propagation out of environment scripts, and update CI to
  latest "jammy" tag.
This commit is contained in:
Tom Rini 2023-01-12 10:15:24 -05:00
commit f58885d002
44 changed files with 588 additions and 272 deletions

View File

@ -2,7 +2,7 @@ variables:
windows_vm: windows-2019 windows_vm: windows-2019
ubuntu_vm: ubuntu-22.04 ubuntu_vm: ubuntu-22.04
macos_vm: macOS-12 macos_vm: macOS-12
ci_runner_image: trini/u-boot-gitlab-ci-runner:jammy-20221101-22Nov2022 ci_runner_image: trini/u-boot-gitlab-ci-runner:jammy-20221130-11Jan2023
# Add '-u 0' options for Azure pipelines, otherwise we get "permission # Add '-u 0' options for Azure pipelines, otherwise we get "permission
# denied" error when it tries to "useradd -m -u 1001 vsts_azpcontainer", # denied" error when it tries to "useradd -m -u 1001 vsts_azpcontainer",
# since our $(ci_runner_image) user is not root. # since our $(ci_runner_image) user is not root.

View File

@ -2,7 +2,7 @@
# Grab our configured image. The source for this is found # Grab our configured image. The source for this is found
# in the u-boot tree at tools/docker/Dockerfile # in the u-boot tree at tools/docker/Dockerfile
image: trini/u-boot-gitlab-ci-runner:jammy-20221101-22Nov2022 image: trini/u-boot-gitlab-ci-runner:jammy-20221130-11Jan2023
# We run some tests in different order, to catch some failures quicker. # We run some tests in different order, to catch some failures quicker.
stages: stages:

View File

@ -1198,6 +1198,7 @@ M: Sean Anderson <seanga2@gmail.com>
S: Maintained S: Maintained
F: doc/api/nvmem.rst F: doc/api/nvmem.rst
F: drivers/misc/nvmem.c F: drivers/misc/nvmem.c
F: drivers/reboot-mode/reboot-mode-nvmem.c
F: include/nvmem.h F: include/nvmem.h
NXP C45 TJA11XX PHY DRIVER NXP C45 TJA11XX PHY DRIVER

View File

@ -384,9 +384,11 @@ config MONITOR_IS_IN_RAM
bool "U-Boot is loaded in to RAM by a pre-loader" bool "U-Boot is loaded in to RAM by a pre-loader"
depends on M68K || NIOS2 depends on M68K || NIOS2
config SKIP_LOWLEVEL_INIT menu "Skipping low level initialization functions"
bool "Skip the calls to certain low level initialization functions"
depends on ARM || MIPS || RISCV depends on ARM || MIPS || RISCV
config SKIP_LOWLEVEL_INIT
bool "Skip calls to certain low level initialization functions"
help help
If enabled, then certain low level initializations (like setting up If enabled, then certain low level initializations (like setting up
the memory controller) are omitted and/or U-Boot does not relocate the memory controller) are omitted and/or U-Boot does not relocate
@ -396,8 +398,8 @@ config SKIP_LOWLEVEL_INIT
debugger which performs these initializations itself. debugger which performs these initializations itself.
config SPL_SKIP_LOWLEVEL_INIT config SPL_SKIP_LOWLEVEL_INIT
bool "Skip the calls to certain low level initialization functions" bool "Skip calls to certain low level initialization functions in SPL"
depends on SPL && (ARM || MIPS || RISCV) depends on SPL
help help
If enabled, then certain low level initializations (like setting up If enabled, then certain low level initializations (like setting up
the memory controller) are omitted and/or U-Boot does not relocate the memory controller) are omitted and/or U-Boot does not relocate
@ -407,7 +409,7 @@ config SPL_SKIP_LOWLEVEL_INIT
debugger which performs these initializations itself. debugger which performs these initializations itself.
config TPL_SKIP_LOWLEVEL_INIT config TPL_SKIP_LOWLEVEL_INIT
bool "Skip the calls to certain low level initialization functions" bool "Skip calls to certain low level initialization functions in TPL"
depends on SPL && ARM depends on SPL && ARM
help help
If enabled, then certain low level initializations (like setting up If enabled, then certain low level initializations (like setting up
@ -418,7 +420,7 @@ config TPL_SKIP_LOWLEVEL_INIT
debugger which performs these initializations itself. debugger which performs these initializations itself.
config SKIP_LOWLEVEL_INIT_ONLY config SKIP_LOWLEVEL_INIT_ONLY
bool "Skip the call to lowlevel_init during early boot ONLY" bool "Skip call to lowlevel_init during early boot ONLY"
depends on ARM depends on ARM
help help
This allows just the call to lowlevel_init() to be skipped. The This allows just the call to lowlevel_init() to be skipped. The
@ -426,7 +428,7 @@ config SKIP_LOWLEVEL_INIT_ONLY
performed. performed.
config SPL_SKIP_LOWLEVEL_INIT_ONLY config SPL_SKIP_LOWLEVEL_INIT_ONLY
bool "Skip the call to lowlevel_init during early boot ONLY" bool "Skip call to lowlevel_init during early SPL boot ONLY"
depends on SPL && ARM depends on SPL && ARM
help help
This allows just the call to lowlevel_init() to be skipped. The This allows just the call to lowlevel_init() to be skipped. The
@ -434,13 +436,15 @@ config SPL_SKIP_LOWLEVEL_INIT_ONLY
performed. performed.
config TPL_SKIP_LOWLEVEL_INIT_ONLY config TPL_SKIP_LOWLEVEL_INIT_ONLY
bool "Skip the call to lowlevel_init during early boot ONLY" bool "Skip call to lowlevel_init during early TPL boot ONLY"
depends on TPL && ARM depends on TPL && ARM
help help
This allows just the call to lowlevel_init() to be skipped. The This allows just the call to lowlevel_init() to be skipped. The
normal CP15 init (such as enabling the instruction cache) is still normal CP15 init (such as enabling the instruction cache) is still
performed. performed.
endmenu
config SYS_HAS_NONCACHED_MEMORY config SYS_HAS_NONCACHED_MEMORY
bool "Enable reserving a non-cached memory area for drivers" bool "Enable reserving a non-cached memory area for drivers"
depends on (ARM || MIPS) && (RTL8169 || MEDIATEK_ETH) depends on (ARM || MIPS) && (RTL8169 || MEDIATEK_ETH)

View File

@ -1,3 +1,5 @@
menu "Functionality shared between NXP SoCs"
config FSL_TRUST_ARCH_v1 config FSL_TRUST_ARCH_v1
bool bool
@ -142,8 +144,6 @@ config KEY_REVOCATION
endmenu endmenu
comment "Other functionality shared between NXP SoCs"
config DEEP_SLEEP config DEEP_SLEEP
bool "Enable SoC deep sleep feature" bool "Enable SoC deep sleep feature"
depends on ARCH_T1024 || ARCH_T1040 || ARCH_T1042 || ARCH_LS1021A depends on ARCH_T1024 || ARCH_T1040 || ARCH_T1042 || ARCH_LS1021A
@ -271,3 +271,5 @@ config HAS_FSL_DR_USB
config SYS_DPAA_FMAN config SYS_DPAA_FMAN
bool bool
endmenu

View File

@ -10,7 +10,7 @@ fix_newlines_in_macros() {
#filter out only what we need from a10 hps.xml #filter out only what we need from a10 hps.xml
grep_a10_hps_config() { grep_a10_hps_config() {
egrep "clk_hz|i_clk_mgr|i_io48_pin_mux|AXI_SLAVE|AXI_MASTER" grep -E "clk_hz|i_clk_mgr|i_io48_pin_mux|AXI_SLAVE|AXI_MASTER"
} }
# #
@ -35,35 +35,35 @@ EOF
echo "/* Clocks */" echo "/* Clocks */"
fix_newlines_in_macros \ fix_newlines_in_macros \
${hps_xml} | egrep "clk_hz" | ${hps_xml} | grep "clk_hz" |
awk -F"'" '{ gsub("\\.","_",$2) ; \ awk -F"'" '{ gsub("\\.","_",$2) ; \
print "#define" " " toupper($2) " " $4}' | print "#define" " " toupper($2) " " $4}' |
sed 's/\.[0-9]//' | sed 's/\.[0-9]//' |
sed 's/I_CLK_MGR_//' | sed 's/I_CLK_MGR_//' |
sort sort
fix_newlines_in_macros \ fix_newlines_in_macros \
${hps_xml} | egrep "i_clk_mgr_mainpll" | ${hps_xml} | grep "i_clk_mgr_mainpll" |
awk -F"'" '{ gsub("\\.","_",$2) ; \ awk -F"'" '{ gsub("\\.","_",$2) ; \
print "#define" " " toupper($2) " " $4}' | print "#define" " " toupper($2) " " $4}' |
sed 's/\.[0-9]//' | sed 's/\.[0-9]//' |
sed 's/I_CLK_MGR_//' | sed 's/I_CLK_MGR_//' |
sort sort
fix_newlines_in_macros \ fix_newlines_in_macros \
${hps_xml} | egrep "i_clk_mgr_perpll" | ${hps_xml} | grep "i_clk_mgr_perpll" |
awk -F"'" '{ gsub("\\.","_",$2) ; \ awk -F"'" '{ gsub("\\.","_",$2) ; \
print "#define" " " toupper($2) " " $4}' | print "#define" " " toupper($2) " " $4}' |
sed 's/\.[0-9]//' | sed 's/\.[0-9]//' |
sed 's/I_CLK_MGR_//' | sed 's/I_CLK_MGR_//' |
sort sort
fix_newlines_in_macros \ fix_newlines_in_macros \
${hps_xml} | egrep "i_clk_mgr_clkmgr" | ${hps_xml} | grep "i_clk_mgr_clkmgr" |
awk -F"'" '{ gsub("\\.","_",$2) ; \ awk -F"'" '{ gsub("\\.","_",$2) ; \
print "#define" " " toupper($2) " " $4}' | print "#define" " " toupper($2) " " $4}' |
sed 's/\.[0-9]//' | sed 's/\.[0-9]//' |
sed 's/I_CLK_MGR_//' | sed 's/I_CLK_MGR_//' |
sort sort
fix_newlines_in_macros \ fix_newlines_in_macros \
${hps_xml} | egrep "i_clk_mgr_alteragrp" | ${hps_xml} | grep "i_clk_mgr_alteragrp" |
awk -F"'" '{ gsub("\\.","_",$2) ; \ awk -F"'" '{ gsub("\\.","_",$2) ; \
print "#define" " " toupper($2) " " $4}' | print "#define" " " toupper($2) " " $4}' |
sed 's/\.[0-9]//' | sed 's/\.[0-9]//' |
@ -77,7 +77,7 @@ EOF
echo echo
echo "/* Pin Mux Configuration */" echo "/* Pin Mux Configuration */"
fix_newlines_in_macros \ fix_newlines_in_macros \
${hps_xml} | egrep "i_io48_pin_mux" | ${hps_xml} | grep "i_io48_pin_mux" |
awk -F"'" '{ gsub("\\.","_",$2) ; \ awk -F"'" '{ gsub("\\.","_",$2) ; \
print "#define" " " toupper($2) " " $4}' | print "#define" " " toupper($2) " " $4}' |
sed 's/I_IO48_PIN_MUX_//' | sed 's/I_IO48_PIN_MUX_//' |
@ -90,7 +90,7 @@ EOF
echo echo
echo "/* Bridge Configuration */" echo "/* Bridge Configuration */"
fix_newlines_in_macros \ fix_newlines_in_macros \
${hps_xml} | egrep "AXI_SLAVE|AXI_MASTER" | ${hps_xml} | grep -E "AXI_SLAVE|AXI_MASTER" |
awk -F"'" '{ gsub("\\.","_",$2) ; \ awk -F"'" '{ gsub("\\.","_",$2) ; \
print "#define" " " toupper($2) " " $4}' | print "#define" " " toupper($2) " " $4}' |
sed 's/true/1/' | sed 's/true/1/' |

File diff suppressed because one or more lines are too long

View File

@ -2539,6 +2539,7 @@ config CMD_MTDPARTS_SHOW_NET_SIZES
config MTDIDS_DEFAULT config MTDIDS_DEFAULT
string "Default MTD IDs" string "Default MTD IDs"
depends on MTD || SPI_FLASH depends on MTD || SPI_FLASH
depends on !SYS_MTDPARTS_RUNTIME
help help
Defines a default MTD IDs list for use with MTD partitions in the Defines a default MTD IDs list for use with MTD partitions in the
Linux MTD command line partitions format. Linux MTD command line partitions format.
@ -2546,6 +2547,7 @@ config MTDIDS_DEFAULT
config MTDPARTS_DEFAULT config MTDPARTS_DEFAULT
string "Default MTD partition scheme" string "Default MTD partition scheme"
depends on MTD || SPI_FLASH depends on MTD || SPI_FLASH
depends on !SYS_MTDPARTS_RUNTIME
help help
Defines a default MTD partitioning scheme in the Linux MTD command Defines a default MTD partitioning scheme in the Linux MTD command
line partitions format line partitions format

View File

@ -10,10 +10,13 @@
static int do_exit(struct cmd_tbl *cmdtp, int flag, int argc, static int do_exit(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[]) char *const argv[])
{ {
if (argc > 1) int r;
return dectoul(argv[1], NULL);
return 0; r = 0;
if (argc > 1)
r = simple_strtoul(argv[1], NULL, 10);
return -r - 2;
} }
U_BOOT_CMD( U_BOOT_CMD(

View File

@ -19,8 +19,14 @@
static int do_fastboot_udp(int argc, char *const argv[], static int do_fastboot_udp(int argc, char *const argv[],
uintptr_t buf_addr, size_t buf_size) uintptr_t buf_addr, size_t buf_size)
{ {
#if CONFIG_IS_ENABLED(UDP_FUNCTION_FASTBOOT) int err;
int err = net_loop(FASTBOOT);
if (!CONFIG_IS_ENABLED(UDP_FUNCTION_FASTBOOT)) {
pr_err("Fastboot UDP not enabled\n");
return CMD_RET_FAILURE;
}
err = net_loop(FASTBOOT);
if (err < 0) { if (err < 0) {
printf("fastboot udp error: %d\n", err); printf("fastboot udp error: %d\n", err);
@ -28,21 +34,21 @@ static int do_fastboot_udp(int argc, char *const argv[],
} }
return CMD_RET_SUCCESS; return CMD_RET_SUCCESS;
#else
pr_err("Fastboot UDP not enabled\n");
return CMD_RET_FAILURE;
#endif
} }
static int do_fastboot_usb(int argc, char *const argv[], static int do_fastboot_usb(int argc, char *const argv[],
uintptr_t buf_addr, size_t buf_size) uintptr_t buf_addr, size_t buf_size)
{ {
#if CONFIG_IS_ENABLED(USB_FUNCTION_FASTBOOT)
int controller_index; int controller_index;
char *usb_controller; char *usb_controller;
char *endp; char *endp;
int ret; int ret;
if (!CONFIG_IS_ENABLED(USB_FUNCTION_FASTBOOT)) {
pr_err("Fastboot USB not enabled\n");
return CMD_RET_FAILURE;
}
if (argc < 2) if (argc < 2)
return CMD_RET_USAGE; return CMD_RET_USAGE;
@ -88,10 +94,6 @@ exit:
g_dnl_clear_detach(); g_dnl_clear_detach();
return ret; return ret;
#else
pr_err("Fastboot USB not enabled\n");
return CMD_RET_FAILURE;
#endif
} }
static int do_fastboot(struct cmd_tbl *cmdtp, int flag, int argc, static int do_fastboot(struct cmd_tbl *cmdtp, int flag, int argc,
@ -148,17 +150,12 @@ NXTARG:
return do_fastboot_usb(argc, argv, buf_addr, buf_size); return do_fastboot_usb(argc, argv, buf_addr, buf_size);
} }
#ifdef CONFIG_SYS_LONGHELP U_BOOT_CMD(
static char fastboot_help_text[] = fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot,
"run as a fastboot usb or udp device",
"[-l addr] [-s size] usb <controller> | udp\n" "[-l addr] [-s size] usb <controller> | udp\n"
"\taddr - address of buffer used during data transfers (" "\taddr - address of buffer used during data transfers ("
__stringify(CONFIG_FASTBOOT_BUF_ADDR) ")\n" __stringify(CONFIG_FASTBOOT_BUF_ADDR) ")\n"
"\tsize - size of buffer used during data transfers (" "\tsize - size of buffer used during data transfers ("
__stringify(CONFIG_FASTBOOT_BUF_SIZE) ")" __stringify(CONFIG_FASTBOOT_BUF_SIZE) ")"
;
#endif
U_BOOT_CMD(
fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot,
"run as a fastboot usb or udp device", fastboot_help_text
); );

View File

@ -22,7 +22,7 @@ int mvebu_comphy_rx_training_cmd(struct cmd_tbl *cmdtp, int flag, int argc,
if (argc != 3) { if (argc != 3) {
printf("missing arguments\n"); printf("missing arguments\n");
return -1; return CMD_RET_USAGE;
} }
cp_index = hextoul(argv[1], NULL); cp_index = hextoul(argv[1], NULL);

View File

@ -422,7 +422,7 @@ static int abortboot(int bootdelay)
return abort; return abort;
} }
static void process_fdt_options(const void *blob) static void process_fdt_options(void)
{ {
#ifdef CONFIG_TEXT_BASE #ifdef CONFIG_TEXT_BASE
ulong addr; ulong addr;
@ -474,7 +474,7 @@ const char *bootdelay_process(void)
s = env_get("bootcmd"); s = env_get("bootcmd");
if (IS_ENABLED(CONFIG_OF_CONTROL)) if (IS_ENABLED(CONFIG_OF_CONTROL))
process_fdt_options(gd->fdt_blob); process_fdt_options();
stored_bootdelay = bootdelay; stored_bootdelay = bootdelay;
return s; return s;

View File

@ -146,7 +146,7 @@ int run_commandf(const char *fmt, ...)
#if defined(CONFIG_CMD_RUN) #if defined(CONFIG_CMD_RUN)
int do_run(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int do_run(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{ {
int i; int i, ret;
if (argc < 2) if (argc < 2)
return CMD_RET_USAGE; return CMD_RET_USAGE;
@ -160,8 +160,9 @@ int do_run(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
return 1; return 1;
} }
if (run_command(arg, flag | CMD_FLAG_ENV) != 0) ret = run_command(arg, flag | CMD_FLAG_ENV);
return 1; if (ret)
return ret;
} }
return 0; return 0;
} }

View File

@ -1901,7 +1901,7 @@ static int run_list_real(struct pipe *pi)
last_return_code = -rcode - 2; last_return_code = -rcode - 2;
return -2; /* exit */ return -2; /* exit */
} }
last_return_code=(rcode == 0) ? 0 : 1; last_return_code = rcode;
#endif #endif
#ifndef __U_BOOT__ #ifndef __U_BOOT__
pi->num_progs = save_num_progs; /* restore number of programs */ pi->num_progs = save_num_progs; /* restore number of programs */
@ -3211,7 +3211,15 @@ static int parse_stream_outer(struct in_str *inp, int flag)
printf("exit not allowed from main input shell.\n"); printf("exit not allowed from main input shell.\n");
continue; continue;
} }
break; /*
* DANGER
* Return code -2 is special in this context,
* it indicates exit from inner pipe instead
* of return code itself, the return code is
* stored in 'last_return_code' variable!
* DANGER
*/
return -2;
} }
if (code == -1) if (code == -1)
flag_repeat = 0; flag_repeat = 0;
@ -3248,9 +3256,9 @@ int parse_string_outer(const char *s, int flag)
#endif /* __U_BOOT__ */ #endif /* __U_BOOT__ */
{ {
struct in_str input; struct in_str input;
int rcode;
#ifdef __U_BOOT__ #ifdef __U_BOOT__
char *p = NULL; char *p = NULL;
int rcode;
if (!s) if (!s)
return 1; return 1;
if (!*s) if (!*s)
@ -3262,11 +3270,12 @@ int parse_string_outer(const char *s, int flag)
setup_string_in_str(&input, p); setup_string_in_str(&input, p);
rcode = parse_stream_outer(&input, flag); rcode = parse_stream_outer(&input, flag);
free(p); free(p);
return rcode; return rcode == -2 ? last_return_code : rcode;
} else { } else {
#endif #endif
setup_string_in_str(&input, s); setup_string_in_str(&input, s);
return parse_stream_outer(&input, flag); rcode = parse_stream_outer(&input, flag);
return rcode == -2 ? last_return_code : rcode;
#ifdef __U_BOOT__ #ifdef __U_BOOT__
} }
#endif #endif
@ -3286,7 +3295,7 @@ int parse_file_outer(void)
setup_file_in_str(&input); setup_file_in_str(&input);
#endif #endif
rcode = parse_stream_outer(&input, FLAG_PARSE_SEMICOLON); rcode = parse_stream_outer(&input, FLAG_PARSE_SEMICOLON);
return rcode; return rcode == -2 ? last_return_code : rcode;
} }
#ifdef __U_BOOT__ #ifdef __U_BOOT__

View File

@ -28,6 +28,7 @@ The following OEM commands are supported (if enabled):
- ``oem partconf`` - this executes ``mmc partconf %x <arg> 0`` to configure eMMC - ``oem partconf`` - this executes ``mmc partconf %x <arg> 0`` to configure eMMC
with <arg> = boot_ack boot_partition with <arg> = boot_ack boot_partition
- ``oem bootbus`` - this executes ``mmc bootbus %x %s`` to configure eMMC - ``oem bootbus`` - this executes ``mmc bootbus %x %s`` to configure eMMC
- ``oem run`` - this executes an arbitrary U-Boot command
Support for both eMMC and NAND devices is included. Support for both eMMC and NAND devices is included.
@ -227,6 +228,23 @@ and on the U-Boot side you should see::
Starting kernel ... Starting kernel ...
Running Shell Commands
^^^^^^^^^^^^^^^^^^^^^^
Normally, arbitrary U-Boot command execution is not enabled. This is so
fastboot can be used to update systems using verified boot. However, such
functionality can be useful for production or when verified boot is not in use.
Enable ``CONFIG_FASTBOOT_OEM_RUN`` to use this functionality. This will enable
``oem run`` command, which can be used with the fastboot client. For example,
to print "Hello at 115200 baud" (or whatever ``CONFIG_BAUDRATE`` is), run::
$ fastboot oem run:'echo Hello at $baudrate baud'
You can run any command you would normally run on the U-Boot command line,
including multiple commands (using e.g. ``;`` or ``&&``) and control structures
(``if``, ``while``, etc.). The exit code of ``fastboot`` will reflect the exit
code of the command you ran.
References References
---------- ----------

View File

@ -90,7 +90,7 @@ If you want to check if the board is ready, type:
.. code-block:: none .. code-block:: none
lsusb | egrep "8087|8086" lsusb | grep -E "8087|8086"
Bus 001 Device 004: ID 8086:e005 Intel Corp. Bus 001 Device 004: ID 8086:e005 Intel Corp.
If you see a device with the same ID as above, the board is waiting for your If you see a device with the same ID as above, the board is waiting for your

View File

@ -37,4 +37,6 @@ executed.
Return value Return value
------------ ------------
$? is always set to 0 (true). $? is default set to 0 (true). In case zero or positive integer parameter
is passed to the command, the return value is the parameter value. In case
negative integer parameter is passed to the command, the return value is 0.

View File

@ -135,6 +135,7 @@ config SATA_MV
config SATA_SIL config SATA_SIL
bool "Enable Silicon Image SIL3131 / SIL3132 / SIL3124 SATA driver support" bool "Enable Silicon Image SIL3131 / SIL3132 / SIL3124 SATA driver support"
depends on PCI
select AHCI select AHCI
select LIBATA select LIBATA
help help

View File

@ -80,12 +80,13 @@ config FASTBOOT_FLASH
this to enable the "fastboot flash" command. this to enable the "fastboot flash" command.
config FASTBOOT_UUU_SUPPORT config FASTBOOT_UUU_SUPPORT
bool "Enable FASTBOOT i.MX UUU special command" bool "Enable UUU support"
help help
The fastboot protocol includes "UCmd" and "ACmd" command. This extends the fastboot protocol with the "UCmd" and "ACmd"
Be aware that you provide full access to any U-Boot command, commands, which are used by NXP's "universal update utility" (UUU).
including working with memory and may open a huge backdoor, These commands allow running any shell command. Do not enable this
when enabling this option. feature if you are using verified boot, as it will allow an attacker
to bypass any restrictions you have in place.
choice choice
prompt "Flash provider for FASTBOOT" prompt "Flash provider for FASTBOOT"
@ -218,6 +219,14 @@ config FASTBOOT_CMD_OEM_BOOTBUS
Add support for the "oem bootbus" command from a client. This set Add support for the "oem bootbus" command from a client. This set
the mmc boot configuration for the selecting eMMC device. the mmc boot configuration for the selecting eMMC device.
config FASTBOOT_OEM_RUN
bool "Enable the 'oem run' command"
help
This extends the fastboot protocol with an "oem run" command. This
command allows running arbitrary U-Boot shell commands. Do not enable
this feature if you are using verified boot, as it will allow an
attacker to bypass any restrictions you have in place.
endif # FASTBOOT endif # FASTBOOT
endmenu endmenu

View File

@ -31,27 +31,16 @@ static u32 fastboot_bytes_expected;
static void okay(char *, char *); static void okay(char *, char *);
static void getvar(char *, char *); static void getvar(char *, char *);
static void download(char *, char *); static void download(char *, char *);
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
static void flash(char *, char *); static void flash(char *, char *);
static void erase(char *, char *); static void erase(char *, char *);
#endif
static void reboot_bootloader(char *, char *); static void reboot_bootloader(char *, char *);
static void reboot_fastbootd(char *, char *); static void reboot_fastbootd(char *, char *);
static void reboot_recovery(char *, char *); static void reboot_recovery(char *, char *);
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
static void oem_format(char *, char *); static void oem_format(char *, char *);
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
static void oem_partconf(char *, char *); static void oem_partconf(char *, char *);
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
static void oem_bootbus(char *, char *); static void oem_bootbus(char *, char *);
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
static void run_ucmd(char *, char *); static void run_ucmd(char *, char *);
static void run_acmd(char *, char *); static void run_acmd(char *, char *);
#endif
static const struct { static const struct {
const char *command; const char *command;
@ -65,16 +54,14 @@ static const struct {
.command = "download", .command = "download",
.dispatch = download .dispatch = download
}, },
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
[FASTBOOT_COMMAND_FLASH] = { [FASTBOOT_COMMAND_FLASH] = {
.command = "flash", .command = "flash",
.dispatch = flash .dispatch = CONFIG_IS_ENABLED(FASTBOOT_FLASH, (flash), (NULL))
}, },
[FASTBOOT_COMMAND_ERASE] = { [FASTBOOT_COMMAND_ERASE] = {
.command = "erase", .command = "erase",
.dispatch = erase .dispatch = CONFIG_IS_ENABLED(FASTBOOT_FLASH, (erase), (NULL))
}, },
#endif
[FASTBOOT_COMMAND_BOOT] = { [FASTBOOT_COMMAND_BOOT] = {
.command = "boot", .command = "boot",
.dispatch = okay .dispatch = okay
@ -103,34 +90,30 @@ static const struct {
.command = "set_active", .command = "set_active",
.dispatch = okay .dispatch = okay
}, },
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
[FASTBOOT_COMMAND_OEM_FORMAT] = { [FASTBOOT_COMMAND_OEM_FORMAT] = {
.command = "oem format", .command = "oem format",
.dispatch = oem_format, .dispatch = CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT, (oem_format), (NULL))
}, },
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
[FASTBOOT_COMMAND_OEM_PARTCONF] = { [FASTBOOT_COMMAND_OEM_PARTCONF] = {
.command = "oem partconf", .command = "oem partconf",
.dispatch = oem_partconf, .dispatch = CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF, (oem_partconf), (NULL))
}, },
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
[FASTBOOT_COMMAND_OEM_BOOTBUS] = { [FASTBOOT_COMMAND_OEM_BOOTBUS] = {
.command = "oem bootbus", .command = "oem bootbus",
.dispatch = oem_bootbus, .dispatch = CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS, (oem_bootbus), (NULL))
},
[FASTBOOT_COMMAND_OEM_RUN] = {
.command = "oem run",
.dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_RUN, (run_ucmd), (NULL))
}, },
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
[FASTBOOT_COMMAND_UCMD] = { [FASTBOOT_COMMAND_UCMD] = {
.command = "UCmd", .command = "UCmd",
.dispatch = run_ucmd, .dispatch = CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT, (run_ucmd), (NULL))
}, },
[FASTBOOT_COMMAND_ACMD] = { [FASTBOOT_COMMAND_ACMD] = {
.command = "ACmd", .command = "ACmd",
.dispatch = run_acmd, .dispatch = CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT, (run_acmd), (NULL))
}, },
#endif
}; };
/** /**
@ -156,7 +139,9 @@ int fastboot_handle_command(char *cmd_string, char *response)
response); response);
return i; return i;
} else { } else {
break; pr_err("command %s not supported.\n", cmd_string);
fastboot_fail("Unsupported command", response);
return -1;
} }
} }
} }
@ -299,7 +284,6 @@ void fastboot_data_complete(char *response)
fastboot_bytes_received = 0; fastboot_bytes_received = 0;
} }
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
/** /**
* flash() - write the downloaded image to the indicated partition. * flash() - write the downloaded image to the indicated partition.
* *
@ -309,16 +293,15 @@ void fastboot_data_complete(char *response)
* Writes the previously downloaded image to the partition indicated by * Writes the previously downloaded image to the partition indicated by
* cmd_parameter. Writes to response. * cmd_parameter. Writes to response.
*/ */
static void flash(char *cmd_parameter, char *response) static void __maybe_unused flash(char *cmd_parameter, char *response)
{ {
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC) if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC))
fastboot_mmc_flash_write(cmd_parameter, fastboot_buf_addr, image_size, fastboot_mmc_flash_write(cmd_parameter, fastboot_buf_addr,
response); image_size, response);
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND) if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND))
fastboot_nand_flash_write(cmd_parameter, fastboot_buf_addr, image_size, fastboot_nand_flash_write(cmd_parameter, fastboot_buf_addr,
response); image_size, response);
#endif
} }
/** /**
@ -330,25 +313,22 @@ static void flash(char *cmd_parameter, char *response)
* Erases the partition indicated by cmd_parameter (clear to 0x00s). Writes * Erases the partition indicated by cmd_parameter (clear to 0x00s). Writes
* to response. * to response.
*/ */
static void erase(char *cmd_parameter, char *response) static void __maybe_unused erase(char *cmd_parameter, char *response)
{ {
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC) if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC))
fastboot_mmc_erase(cmd_parameter, response); fastboot_mmc_erase(cmd_parameter, response);
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND) if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND))
fastboot_nand_erase(cmd_parameter, response); fastboot_nand_erase(cmd_parameter, response);
#endif }
}
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
/** /**
* run_ucmd() - Execute the UCmd command * run_ucmd() - Execute the UCmd command
* *
* @cmd_parameter: Pointer to command parameter * @cmd_parameter: Pointer to command parameter
* @response: Pointer to fastboot response buffer * @response: Pointer to fastboot response buffer
*/ */
static void run_ucmd(char *cmd_parameter, char *response) static void __maybe_unused run_ucmd(char *cmd_parameter, char *response)
{ {
if (!cmd_parameter) { if (!cmd_parameter) {
pr_err("missing slot suffix\n"); pr_err("missing slot suffix\n");
@ -375,7 +355,7 @@ void fastboot_acmd_complete(void)
* @cmd_parameter: Pointer to command parameter * @cmd_parameter: Pointer to command parameter
* @response: Pointer to fastboot response buffer * @response: Pointer to fastboot response buffer
*/ */
static void run_acmd(char *cmd_parameter, char *response) static void __maybe_unused run_acmd(char *cmd_parameter, char *response)
{ {
if (!cmd_parameter) { if (!cmd_parameter) {
pr_err("missing slot suffix\n"); pr_err("missing slot suffix\n");
@ -392,7 +372,6 @@ static void run_acmd(char *cmd_parameter, char *response)
strcpy(g_a_cmd_buff, cmd_parameter); strcpy(g_a_cmd_buff, cmd_parameter);
fastboot_okay(NULL, response); fastboot_okay(NULL, response);
} }
#endif
/** /**
* reboot_bootloader() - Sets reboot bootloader flag. * reboot_bootloader() - Sets reboot bootloader flag.
@ -436,40 +415,40 @@ static void reboot_recovery(char *cmd_parameter, char *response)
fastboot_okay(NULL, response); fastboot_okay(NULL, response);
} }
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
/** /**
* oem_format() - Execute the OEM format command * oem_format() - Execute the OEM format command
* *
* @cmd_parameter: Pointer to command parameter * @cmd_parameter: Pointer to command parameter
* @response: Pointer to fastboot response buffer * @response: Pointer to fastboot response buffer
*/ */
static void oem_format(char *cmd_parameter, char *response) static void __maybe_unused oem_format(char *cmd_parameter, char *response)
{ {
char cmdbuf[32]; char cmdbuf[32];
const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
CONFIG_FASTBOOT_FLASH_MMC_DEV, -1);
if (!env_get("partitions")) { if (!env_get("partitions")) {
fastboot_fail("partitions not set", response); fastboot_fail("partitions not set", response);
} else { } else {
sprintf(cmdbuf, "gpt write mmc %x $partitions", sprintf(cmdbuf, "gpt write mmc %x $partitions", mmc_dev);
CONFIG_FASTBOOT_FLASH_MMC_DEV);
if (run_command(cmdbuf, 0)) if (run_command(cmdbuf, 0))
fastboot_fail("", response); fastboot_fail("", response);
else else
fastboot_okay(NULL, response); fastboot_okay(NULL, response);
} }
} }
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
/** /**
* oem_partconf() - Execute the OEM partconf command * oem_partconf() - Execute the OEM partconf command
* *
* @cmd_parameter: Pointer to command parameter * @cmd_parameter: Pointer to command parameter
* @response: Pointer to fastboot response buffer * @response: Pointer to fastboot response buffer
*/ */
static void oem_partconf(char *cmd_parameter, char *response) static void __maybe_unused oem_partconf(char *cmd_parameter, char *response)
{ {
char cmdbuf[32]; char cmdbuf[32];
const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
CONFIG_FASTBOOT_FLASH_MMC_DEV, -1);
if (!cmd_parameter) { if (!cmd_parameter) {
fastboot_fail("Expected command parameter", response); fastboot_fail("Expected command parameter", response);
@ -477,26 +456,25 @@ static void oem_partconf(char *cmd_parameter, char *response)
} }
/* execute 'mmc partconfg' command with cmd_parameter arguments*/ /* execute 'mmc partconfg' command with cmd_parameter arguments*/
snprintf(cmdbuf, sizeof(cmdbuf), "mmc partconf %x %s 0", snprintf(cmdbuf, sizeof(cmdbuf), "mmc partconf %x %s 0", mmc_dev, cmd_parameter);
CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
printf("Execute: %s\n", cmdbuf); printf("Execute: %s\n", cmdbuf);
if (run_command(cmdbuf, 0)) if (run_command(cmdbuf, 0))
fastboot_fail("Cannot set oem partconf", response); fastboot_fail("Cannot set oem partconf", response);
else else
fastboot_okay(NULL, response); fastboot_okay(NULL, response);
} }
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
/** /**
* oem_bootbus() - Execute the OEM bootbus command * oem_bootbus() - Execute the OEM bootbus command
* *
* @cmd_parameter: Pointer to command parameter * @cmd_parameter: Pointer to command parameter
* @response: Pointer to fastboot response buffer * @response: Pointer to fastboot response buffer
*/ */
static void oem_bootbus(char *cmd_parameter, char *response) static void __maybe_unused oem_bootbus(char *cmd_parameter, char *response)
{ {
char cmdbuf[32]; char cmdbuf[32];
const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
CONFIG_FASTBOOT_FLASH_MMC_DEV, -1);
if (!cmd_parameter) { if (!cmd_parameter) {
fastboot_fail("Expected command parameter", response); fastboot_fail("Expected command parameter", response);
@ -504,12 +482,10 @@ static void oem_bootbus(char *cmd_parameter, char *response)
} }
/* execute 'mmc bootbus' command with cmd_parameter arguments*/ /* execute 'mmc bootbus' command with cmd_parameter arguments*/
snprintf(cmdbuf, sizeof(cmdbuf), "mmc bootbus %x %s", snprintf(cmdbuf, sizeof(cmdbuf), "mmc bootbus %x %s", mmc_dev, cmd_parameter);
CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
printf("Execute: %s\n", cmdbuf); printf("Execute: %s\n", cmdbuf);
if (run_command(cmdbuf, 0)) if (run_command(cmdbuf, 0))
fastboot_fail("Cannot set oem bootbus", response); fastboot_fail("Cannot set oem bootbus", response);
else else
fastboot_okay(NULL, response); fastboot_okay(NULL, response);
} }
#endif

View File

@ -91,20 +91,21 @@ void fastboot_okay(const char *reason, char *response)
*/ */
int __weak fastboot_set_reboot_flag(enum fastboot_reboot_reason reason) int __weak fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
{ {
#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
static const char * const boot_cmds[] = { static const char * const boot_cmds[] = {
[FASTBOOT_REBOOT_REASON_BOOTLOADER] = "bootonce-bootloader", [FASTBOOT_REBOOT_REASON_BOOTLOADER] = "bootonce-bootloader",
[FASTBOOT_REBOOT_REASON_FASTBOOTD] = "boot-fastboot", [FASTBOOT_REBOOT_REASON_FASTBOOTD] = "boot-fastboot",
[FASTBOOT_REBOOT_REASON_RECOVERY] = "boot-recovery" [FASTBOOT_REBOOT_REASON_RECOVERY] = "boot-recovery"
}; };
const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
CONFIG_FASTBOOT_FLASH_MMC_DEV, -1);
if (!CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC))
return -EINVAL;
if (reason >= FASTBOOT_REBOOT_REASONS_COUNT) if (reason >= FASTBOOT_REBOOT_REASONS_COUNT)
return -EINVAL; return -EINVAL;
return bcb_write_reboot_reason(CONFIG_FASTBOOT_FLASH_MMC_DEV, "misc", boot_cmds[reason]); return bcb_write_reboot_reason(mmc_dev, "misc", boot_cmds[reason]);
#else
return -EINVAL;
#endif
} }
/** /**

View File

@ -21,15 +21,9 @@ static void getvar_version_baseband(char *var_parameter, char *response);
static void getvar_product(char *var_parameter, char *response); static void getvar_product(char *var_parameter, char *response);
static void getvar_platform(char *var_parameter, char *response); static void getvar_platform(char *var_parameter, char *response);
static void getvar_current_slot(char *var_parameter, char *response); static void getvar_current_slot(char *var_parameter, char *response);
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
static void getvar_has_slot(char *var_parameter, char *response); static void getvar_has_slot(char *var_parameter, char *response);
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
static void getvar_partition_type(char *part_name, char *response); static void getvar_partition_type(char *part_name, char *response);
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
static void getvar_partition_size(char *part_name, char *response); static void getvar_partition_size(char *part_name, char *response);
#endif
static void getvar_is_userspace(char *var_parameter, char *response); static void getvar_is_userspace(char *var_parameter, char *response);
static const struct { static const struct {
@ -84,7 +78,6 @@ static const struct {
} }
}; };
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
/** /**
* Get partition number and size for any storage type. * Get partition number and size for any storage type.
* *
@ -102,28 +95,26 @@ static int getvar_get_part_info(const char *part_name, char *response,
size_t *size) size_t *size)
{ {
int r; int r;
# if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
struct blk_desc *dev_desc; struct blk_desc *dev_desc;
struct disk_partition part_info; struct disk_partition disk_part;
r = fastboot_mmc_get_part_info(part_name, &dev_desc, &part_info,
response);
if (r >= 0 && size)
*size = part_info.size * part_info.blksz;
# elif CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
struct part_info *part_info; struct part_info *part_info;
r = fastboot_nand_get_part_info(part_name, &part_info, response); if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)) {
if (r >= 0 && size) r = fastboot_mmc_get_part_info(part_name, &dev_desc, &disk_part,
*size = part_info->size; response);
# else if (r >= 0 && size)
fastboot_fail("this storage is not supported in bootloader", response); *size = disk_part.size * disk_part.blksz;
r = -ENODEV; } else if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)) {
# endif r = fastboot_nand_get_part_info(part_name, &part_info, response);
if (r >= 0 && size)
*size = part_info->size;
} else {
fastboot_fail("this storage is not supported in bootloader", response);
r = -ENODEV;
}
return r; return r;
} }
#endif
static void getvar_version(char *var_parameter, char *response) static void getvar_version(char *var_parameter, char *response)
{ {
@ -181,8 +172,7 @@ static void getvar_current_slot(char *var_parameter, char *response)
fastboot_okay("a", response); fastboot_okay("a", response);
} }
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH) static void __maybe_unused getvar_has_slot(char *part_name, char *response)
static void getvar_has_slot(char *part_name, char *response)
{ {
char part_name_wslot[PART_NAME_LEN]; char part_name_wslot[PART_NAME_LEN];
size_t len; size_t len;
@ -213,10 +203,8 @@ static void getvar_has_slot(char *part_name, char *response)
fail: fail:
fastboot_fail("invalid partition name", response); fastboot_fail("invalid partition name", response);
} }
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC) static void __maybe_unused getvar_partition_type(char *part_name, char *response)
static void getvar_partition_type(char *part_name, char *response)
{ {
int r; int r;
struct blk_desc *dev_desc; struct blk_desc *dev_desc;
@ -232,10 +220,8 @@ static void getvar_partition_type(char *part_name, char *response)
fastboot_okay(fs_get_type_name(), response); fastboot_okay(fs_get_type_name(), response);
} }
} }
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH) static void __maybe_unused getvar_partition_size(char *part_name, char *response)
static void getvar_partition_size(char *part_name, char *response)
{ {
int r; int r;
size_t size; size_t size;
@ -244,7 +230,6 @@ static void getvar_partition_size(char *part_name, char *response)
if (r >= 0) if (r >= 0)
fastboot_response("OKAY", response, "0x%016zx", size); fastboot_response("OKAY", response, "0x%016zx", size);
} }
#endif
static void getvar_is_userspace(char *var_parameter, char *response) static void getvar_is_userspace(char *var_parameter, char *response)
{ {

View File

@ -30,4 +30,11 @@ config DM_REBOOT_MODE_RTC
a device in a specific mode by using a register(s) that can be controlled a device in a specific mode by using a register(s) that can be controlled
outside U-Boot (e.g. Kernel). outside U-Boot (e.g. Kernel).
config REBOOT_MODE_NVMEM
bool "Use NVMEM reboot mode"
depends on DM_REBOOT_MODE && NVMEM
help
Use any kind of non-volatile memory (EEPROM, RTC, etc) to control the
reboot mode.
endmenu endmenu

View File

@ -7,3 +7,4 @@
obj-$(CONFIG_DM_REBOOT_MODE) += reboot-mode-uclass.o obj-$(CONFIG_DM_REBOOT_MODE) += reboot-mode-uclass.o
obj-$(CONFIG_DM_REBOOT_MODE_GPIO) += reboot-mode-gpio.o obj-$(CONFIG_DM_REBOOT_MODE_GPIO) += reboot-mode-gpio.o
obj-$(CONFIG_DM_REBOOT_MODE_RTC) += reboot-mode-rtc.o obj-$(CONFIG_DM_REBOOT_MODE_RTC) += reboot-mode-rtc.o
obj-$(CONFIG_REBOOT_MODE_NVMEM) += reboot-mode-nvmem.o

View File

@ -0,0 +1,57 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
*/
#include <common.h>
#include <dm.h>
#include <nvmem.h>
#include <reboot-mode/reboot-mode.h>
/**
* struct nvmem_reboot_mode_priv - Private data for the nvmem reboot mode device
* @cell: The nvmem cell to store the mode in
*/
struct nvmem_reboot_mode_priv {
struct nvmem_cell cell;
};
static int reboot_mode_get(struct udevice *dev, u32 *mode)
{
struct nvmem_reboot_mode_priv *priv = dev_get_priv(dev);
return nvmem_cell_read(&priv->cell, mode, sizeof(*mode));
}
static int reboot_mode_set(struct udevice *dev, u32 mode)
{
struct nvmem_reboot_mode_priv *priv = dev_get_priv(dev);
return nvmem_cell_write(&priv->cell, &mode, sizeof(mode));
}
static const struct reboot_mode_ops nvmem_reboot_mode_ops = {
.get = reboot_mode_get,
.set = reboot_mode_set,
};
static int reboot_mode_probe(struct udevice *dev)
{
struct nvmem_reboot_mode_priv *priv = dev_get_priv(dev);
return nvmem_cell_get_by_name(dev, "reboot-mode", &priv->cell);
}
static const struct udevice_id nvmem_reboot_mode_ids[] = {
{ .compatible = "nvmem-reboot-mode" },
{ }
};
U_BOOT_DRIVER(nvmem_reboot_mode) = {
.name = "nvmem-reboot-mode",
.id = UCLASS_REBOOT_MODE,
.of_match = nvmem_reboot_mode_ids,
.probe = reboot_mode_probe,
.priv_auto = sizeof(struct nvmem_reboot_mode_priv),
.ops = &nvmem_reboot_mode_ops,
};

View File

@ -17,6 +17,7 @@
#include <i2c.h> #include <i2c.h>
#include <rtc.h> #include <rtc.h>
#include <log.h> #include <log.h>
#include <linux/bitfield.h>
#define ABX8XX_REG_HTH 0x00 #define ABX8XX_REG_HTH 0x00
#define ABX8XX_REG_SC 0x01 #define ABX8XX_REG_SC 0x01
@ -88,6 +89,16 @@
#define ABX8XX_TRICKLE_STANDARD_DIODE 0x8 #define ABX8XX_TRICKLE_STANDARD_DIODE 0x8
#define ABX8XX_TRICKLE_SCHOTTKY_DIODE 0x4 #define ABX8XX_TRICKLE_SCHOTTKY_DIODE 0x4
#define ABX8XX_REG_EXTRAM 0x3f
#define ABX8XX_EXTRAM_XADS GENMASK(1, 0)
#define ABX8XX_SRAM_BASE 0x40
#define ABX8XX_SRAM_WIN_SIZE 0x40U
#define ABX8XX_RAM_SIZE 256
#define RAM_ADDR_LOWER GENMASK(5, 0)
#define RAM_ADDR_UPPER GENMASK(7, 6)
static u8 trickle_resistors[] = {0, 3, 6, 11}; static u8 trickle_resistors[] = {0, 3, 6, 11};
enum abx80x_chip {AB0801, AB0803, AB0804, AB0805, enum abx80x_chip {AB0801, AB0803, AB0804, AB0805,
@ -112,29 +123,52 @@ static struct abx80x_cap abx80x_caps[] = {
[ABX80X] = {.pn = 0} [ABX80X] = {.pn = 0}
}; };
static int abx80x_rtc_read8(struct udevice *dev, unsigned int reg) static int abx80x_rtc_xfer(struct udevice *dev, unsigned int offset,
u8 *val, unsigned int bytes, bool write)
{ {
int ret = 0; int ret;
u8 buf;
if (reg > 0xff) if (offset + bytes > ABX8XX_RAM_SIZE)
return -EINVAL; return -EINVAL;
ret = dm_i2c_read(dev, reg, &buf, sizeof(buf)); while (bytes) {
if (ret < 0) u8 extram, reg, len, lower, upper;
return ret;
return buf; lower = FIELD_GET(RAM_ADDR_LOWER, offset);
upper = FIELD_GET(RAM_ADDR_UPPER, offset);
extram = FIELD_PREP(ABX8XX_EXTRAM_XADS, upper);
reg = ABX8XX_SRAM_BASE + lower;
len = min(lower + bytes, ABX8XX_SRAM_WIN_SIZE) - lower;
ret = dm_i2c_reg_write(dev, ABX8XX_REG_EXTRAM, extram);
if (ret)
return ret;
if (write)
ret = dm_i2c_write(dev, reg, val, len);
else
ret = dm_i2c_read(dev, reg, val, len);
if (ret)
return ret;
offset += len;
val += len;
bytes -= len;
}
return 0;
} }
static int abx80x_rtc_write8(struct udevice *dev, unsigned int reg, int val) static int abx80x_rtc_read(struct udevice *dev, unsigned int offset, u8 *val,
unsigned int bytes)
{ {
u8 buf = (u8)val; return abx80x_rtc_xfer(dev, offset, val, bytes, false);
}
if (reg > 0xff) static int abx80x_rtc_write(struct udevice *dev, unsigned int offset,
return -EINVAL; const u8 *val, unsigned int bytes)
{
return dm_i2c_write(dev, reg, &buf, sizeof(buf)); return abx80x_rtc_xfer(dev, offset, (u8 *)val, bytes, true);
} }
static int abx80x_is_rc_mode(struct udevice *dev) static int abx80x_is_rc_mode(struct udevice *dev)
@ -334,9 +368,9 @@ static int abx80x_rtc_reset(struct udevice *dev)
static const struct rtc_ops abx80x_rtc_ops = { static const struct rtc_ops abx80x_rtc_ops = {
.get = abx80x_rtc_read_time, .get = abx80x_rtc_read_time,
.set = abx80x_rtc_set_time, .set = abx80x_rtc_set_time,
.reset = abx80x_rtc_reset, .reset = abx80x_rtc_reset,
.read8 = abx80x_rtc_read8, .read = abx80x_rtc_read,
.write8 = abx80x_rtc_write8 .write = abx80x_rtc_write,
}; };
static int abx80x_dt_trickle_cfg(struct udevice *dev) static int abx80x_dt_trickle_cfg(struct udevice *dev)

View File

@ -92,7 +92,8 @@ static int bind_service_list(struct udevice *dev, struct tee_shm *service_list,
if (!service) if (!service)
continue; continue;
ret = device_bind_driver(dev, service->driver_name, service->driver_name, NULL); ret = device_bind_driver_to_node(dev, service->driver_name, service->driver_name,
dev_ofnode(dev), NULL);
if (ret) { if (ret) {
dev_warn(dev, "%s was not bound: %d, ignored\n", service->driver_name, ret); dev_warn(dev, "%s was not bound: %d, ignored\n", service->driver_name, ret);
continue; continue;
@ -846,7 +847,8 @@ static int optee_probe(struct udevice *dev)
* Discovery of TAs on the TEE bus is not supported in U-Boot: * Discovery of TAs on the TEE bus is not supported in U-Boot:
* only bind the drivers associated to the supported OP-TEE TA * only bind the drivers associated to the supported OP-TEE TA
*/ */
ret = device_bind_driver(dev, "optee-rng", "optee-rng", NULL); ret = device_bind_driver_to_node(dev, "optee-rng", "optee-rng",
dev_ofnode(dev), NULL);
if (ret) if (ret)
dev_warn(dev, "ftpm_tee failed to bind: %d\n", ret); dev_warn(dev, "ftpm_tee failed to bind: %d\n", ret);
} }

View File

@ -495,7 +495,6 @@ static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req)
do_exit_on_complete(ep, req); do_exit_on_complete(ep, req);
} }
#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
static void do_acmd_complete(struct usb_ep *ep, struct usb_request *req) static void do_acmd_complete(struct usb_ep *ep, struct usb_request *req)
{ {
/* When usb dequeue complete will be called /* When usb dequeue complete will be called
@ -505,7 +504,6 @@ static void do_acmd_complete(struct usb_ep *ep, struct usb_request *req)
if (req->status == 0) if (req->status == 0)
fastboot_acmd_complete(); fastboot_acmd_complete();
} }
#endif
static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
{ {
@ -546,11 +544,10 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
fastboot_func->in_req->complete = compl_do_reset; fastboot_func->in_req->complete = compl_do_reset;
g_dnl_trigger_detach(); g_dnl_trigger_detach();
break; break;
#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
case FASTBOOT_COMMAND_ACMD: case FASTBOOT_COMMAND_ACMD:
fastboot_func->in_req->complete = do_acmd_complete; if (CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT))
fastboot_func->in_req->complete = do_acmd_complete;
break; break;
#endif
} }
} }

8
env/env.c vendored
View File

@ -311,11 +311,15 @@ int env_erase(void)
if (drv) { if (drv) {
int ret; int ret;
if (!drv->erase) if (!drv->erase) {
printf("not possible\n");
return -ENODEV; return -ENODEV;
}
if (!env_has_inited(drv->location)) if (!env_has_inited(drv->location)) {
printf("not initialized\n");
return -ENODEV; return -ENODEV;
}
printf("Erasing Environment on %s... ", drv->name); printf("Erasing Environment on %s... ", drv->name);
ret = drv->erase(); ret = drv->erase();

40
env/ubi.c vendored
View File

@ -28,6 +28,12 @@
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
#if CONFIG_SYS_REDUNDAND_ENVIRONMENT
#define ENV_UBI_VOLUME_REDUND CONFIG_ENV_UBI_VOLUME_REDUND
#else
#define ENV_UBI_VOLUME_REDUND "invalid"
#endif
#ifdef CONFIG_CMD_SAVEENV #ifdef CONFIG_CMD_SAVEENV
#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
static int env_ubi_save(void) static int env_ubi_save(void)
@ -177,9 +183,43 @@ static int env_ubi_load(void)
} }
#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */ #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
static int env_ubi_erase(void)
{
ALLOC_CACHE_ALIGN_BUFFER(char, env_buf, CONFIG_ENV_SIZE);
int ret = 0;
if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
printf("\n** Cannot find mtd partition \"%s\"\n",
CONFIG_ENV_UBI_PART);
return 1;
}
memset(env_buf, 0x0, CONFIG_ENV_SIZE);
if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
(void *)env_buf, CONFIG_ENV_SIZE)) {
printf("\n** Unable to erase env to %s:%s **\n",
CONFIG_ENV_UBI_PART,
CONFIG_ENV_UBI_VOLUME);
ret = 1;
}
if (IS_ENABLED(CONFIG_SYS_REDUNDAND_ENVIRONMENT)) {
if (ubi_volume_write(ENV_UBI_VOLUME_REDUND,
(void *)env_buf, CONFIG_ENV_SIZE)) {
printf("\n** Unable to erase env to %s:%s **\n",
CONFIG_ENV_UBI_PART,
ENV_UBI_VOLUME_REDUND);
ret = 1;
}
}
return ret;
}
U_BOOT_ENV_LOCATION(ubi) = { U_BOOT_ENV_LOCATION(ubi) = {
.location = ENVL_UBI, .location = ENVL_UBI,
ENV_NAME("UBI") ENV_NAME("UBI")
.load = env_ubi_load, .load = env_ubi_load,
.save = env_save_ptr(env_ubi_save), .save = env_save_ptr(env_ubi_save),
.erase = ENV_ERASE_PTR(env_ubi_erase),
}; };

View File

@ -541,34 +541,39 @@ struct extent_buffer* read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
int read_extent_data(struct btrfs_fs_info *fs_info, char *data, u64 logical, int read_extent_data(struct btrfs_fs_info *fs_info, char *data, u64 logical,
u64 *len, int mirror) u64 *len, int mirror)
{ {
u64 offset = 0; u64 orig_len = *len;
u64 cur = logical;
struct btrfs_multi_bio *multi = NULL; struct btrfs_multi_bio *multi = NULL;
struct btrfs_device *device; struct btrfs_device *device;
int ret = 0; int ret = 0;
u64 max_len = *len;
ret = btrfs_map_block(fs_info, READ, logical, len, &multi, mirror, while (cur < logical + orig_len) {
NULL); u64 cur_len = logical + orig_len - cur;
if (ret) {
fprintf(stderr, "Couldn't map the block %llu\n",
logical + offset);
goto err;
}
device = multi->stripes[0].dev;
if (*len > max_len) ret = btrfs_map_block(fs_info, READ, cur, &cur_len, &multi,
*len = max_len; mirror, NULL);
if (!device->desc || !device->part) { if (ret) {
ret = -EIO; error("Couldn't map the block %llu", cur);
goto err; goto err;
} }
device = multi->stripes[0].dev;
ret = __btrfs_devread(device->desc, device->part, data, *len, if (!device->desc || !device->part) {
multi->stripes[0].physical); error("devid %llu is missing", device->devid);
if (ret != *len) ret = -EIO;
ret = -EIO; goto err;
else }
ret = __btrfs_devread(device->desc, device->part,
data + (cur - logical), cur_len,
multi->stripes[0].physical);
if (ret != cur_len) {
error("read failed on devid %llu physical %llu",
device->devid, multi->stripes[0].physical);
ret = -EIO;
goto err;
}
cur += cur_len;
ret = 0; ret = 0;
}
err: err:
kfree(multi); kfree(multi);
return ret; return ret;

View File

@ -100,7 +100,7 @@ static int sqfs_calc_n_blks(__le64 start, __le64 end, u64 *offset)
static int sqfs_frag_lookup(u32 inode_fragment_index, static int sqfs_frag_lookup(u32 inode_fragment_index,
struct squashfs_fragment_block_entry *e) struct squashfs_fragment_block_entry *e)
{ {
u64 start, n_blks, src_len, table_offset, start_block; u64 start, end, exp_tbl, n_blks, src_len, table_offset, start_block;
unsigned char *metadata_buffer, *metadata, *table; unsigned char *metadata_buffer, *metadata, *table;
struct squashfs_fragment_block_entry *entries; struct squashfs_fragment_block_entry *entries;
struct squashfs_super_block *sblk = ctxt.sblk; struct squashfs_super_block *sblk = ctxt.sblk;
@ -115,11 +115,17 @@ static int sqfs_frag_lookup(u32 inode_fragment_index,
if (inode_fragment_index >= get_unaligned_le32(&sblk->fragments)) if (inode_fragment_index >= get_unaligned_le32(&sblk->fragments))
return -EINVAL; return -EINVAL;
start = get_unaligned_le64(&sblk->fragment_table_start) / start = get_unaligned_le64(&sblk->fragment_table_start);
ctxt.cur_dev->blksz; end = get_unaligned_le64(&sblk->id_table_start);
exp_tbl = get_unaligned_le64(&sblk->export_table_start);
if (exp_tbl > start && exp_tbl < end)
end = exp_tbl;
n_blks = sqfs_calc_n_blks(sblk->fragment_table_start, n_blks = sqfs_calc_n_blks(sblk->fragment_table_start,
sblk->export_table_start, cpu_to_le64(end), &table_offset);
&table_offset);
start /= ctxt.cur_dev->blksz;
/* Allocate a proper sized buffer to store the fragment index table */ /* Allocate a proper sized buffer to store the fragment index table */
table = malloc_cache_aligned(n_blks * ctxt.cur_dev->blksz); table = malloc_cache_aligned(n_blks * ctxt.cur_dev->blksz);

View File

@ -24,10 +24,8 @@
enum { enum {
FASTBOOT_COMMAND_GETVAR = 0, FASTBOOT_COMMAND_GETVAR = 0,
FASTBOOT_COMMAND_DOWNLOAD, FASTBOOT_COMMAND_DOWNLOAD,
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
FASTBOOT_COMMAND_FLASH, FASTBOOT_COMMAND_FLASH,
FASTBOOT_COMMAND_ERASE, FASTBOOT_COMMAND_ERASE,
#endif
FASTBOOT_COMMAND_BOOT, FASTBOOT_COMMAND_BOOT,
FASTBOOT_COMMAND_CONTINUE, FASTBOOT_COMMAND_CONTINUE,
FASTBOOT_COMMAND_REBOOT, FASTBOOT_COMMAND_REBOOT,
@ -35,20 +33,12 @@ enum {
FASTBOOT_COMMAND_REBOOT_FASTBOOTD, FASTBOOT_COMMAND_REBOOT_FASTBOOTD,
FASTBOOT_COMMAND_REBOOT_RECOVERY, FASTBOOT_COMMAND_REBOOT_RECOVERY,
FASTBOOT_COMMAND_SET_ACTIVE, FASTBOOT_COMMAND_SET_ACTIVE,
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
FASTBOOT_COMMAND_OEM_FORMAT, FASTBOOT_COMMAND_OEM_FORMAT,
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
FASTBOOT_COMMAND_OEM_PARTCONF, FASTBOOT_COMMAND_OEM_PARTCONF,
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
FASTBOOT_COMMAND_OEM_BOOTBUS, FASTBOOT_COMMAND_OEM_BOOTBUS,
#endif FASTBOOT_COMMAND_OEM_RUN,
#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
FASTBOOT_COMMAND_ACMD, FASTBOOT_COMMAND_ACMD,
FASTBOOT_COMMAND_UCMD, FASTBOOT_COMMAND_UCMD,
#endif
FASTBOOT_COMMAND_COUNT FASTBOOT_COMMAND_COUNT
}; };
@ -173,7 +163,5 @@ void fastboot_data_download(const void *fastboot_data,
*/ */
void fastboot_data_complete(char *response); void fastboot_data_complete(char *response);
#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
void fastboot_acmd_complete(void); void fastboot_acmd_complete(void);
#endif
#endif /* _FASTBOOT_H_ */ #endif /* _FASTBOOT_H_ */

View File

@ -38,6 +38,7 @@ int do_ut_compression(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[]); char *const argv[]);
int do_ut_dm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_dm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
int do_ut_env(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_env(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
int do_ut_exit(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
int do_ut_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);

View File

@ -608,7 +608,7 @@ int rsa_add_verify_data(struct image_sign_info *info, void *keydest)
BIGNUM *modulus, *r_squared; BIGNUM *modulus, *r_squared;
uint64_t exponent; uint64_t exponent;
uint32_t n0_inv; uint32_t n0_inv;
int parent, node; int parent, node = -FDT_ERR_NOTFOUND;
char name[100]; char name[100];
int ret; int ret;
int bits; int bits;

View File

@ -42,7 +42,6 @@ static int fastboot_our_port;
static void boot_downloaded_image(void); static void boot_downloaded_image(void);
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
/** /**
* fastboot_udp_send_info() - Send an INFO packet during long commands. * fastboot_udp_send_info() - Send an INFO packet during long commands.
* *
@ -104,7 +103,6 @@ static void fastboot_timed_send_info(const char *msg)
fastboot_udp_send_info(msg); fastboot_udp_send_info(msg);
} }
} }
#endif
/** /**
* fastboot_send() - Sends a packet in response to received fastboot packet * fastboot_send() - Sends a packet in response to received fastboot packet
@ -309,9 +307,9 @@ void fastboot_start_server(void)
fastboot_our_port = CONFIG_UDP_FUNCTION_FASTBOOT_PORT; fastboot_our_port = CONFIG_UDP_FUNCTION_FASTBOOT_PORT;
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH) if (CONFIG_IS_ENABLED(FASTBOOT_FLASH))
fastboot_set_progress_callback(fastboot_timed_send_info); fastboot_set_progress_callback(fastboot_timed_send_info);
#endif
net_set_udp_handler(fastboot_handler); net_set_udp_handler(fastboot_handler);
/* zero out server ether in case the server ip has changed */ /* zero out server ether in case the server ip has changed */

View File

@ -54,7 +54,7 @@ FLAGS="--very-quiet"
# inspected there. # inspected there.
# #
# --profile will not output if --very-quiet is used, so avoid it. # --profile will not output if --very-quiet is used, so avoid it.
echo $SPFLAGS | egrep -e "--profile|--show-trying" 2>&1 > /dev/null echo $SPFLAGS | grep -Ee "--profile|--show-trying" 2>&1 > /dev/null
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
FLAGS="--quiet" FLAGS="--quiet"
fi fi

View File

@ -8,7 +8,7 @@ endif
ifdef CONFIG_CONSOLE_RECORD ifdef CONFIG_CONSOLE_RECORD
obj-$(CONFIG_CMD_PAUSE) += test_pause.o obj-$(CONFIG_CMD_PAUSE) += test_pause.o
endif endif
obj-y += mem.o obj-y += exit.o mem.o
obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o
obj-$(CONFIG_CMD_FDT) += fdt.o obj-$(CONFIG_CMD_FDT) += fdt.o
obj-$(CONFIG_CONSOLE_TRUETYPE) += font.o obj-$(CONFIG_CONSOLE_TRUETYPE) += font.o

135
test/cmd/exit.c Normal file
View File

@ -0,0 +1,135 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Tests for exit command
*
* Copyright 2022 Marek Vasut <marex@denx.de>
*/
#include <common.h>
#include <console.h>
#include <mapmem.h>
#include <asm/global_data.h>
#include <test/suites.h>
#include <test/ut.h>
DECLARE_GLOBAL_DATA_PTR;
/* Declare a new exit test */
#define EXIT_TEST(_name, _flags) UNIT_TEST(_name, _flags, exit_test)
/* Test 'exit addr' getting/setting address */
static int cmd_exit_test(struct unit_test_state *uts)
{
int i;
/*
* Test 'exit' with parameter -3, -2, -1, 0, 1, 2, 3 . Use all those
* parameters to cover also the special return value -2 that is used
* in HUSH to detect exit command.
*
* Always test whether 'exit' command:
* - exits out of the 'run' command
* - return value is propagated out of the 'run' command
* - return value can be tested on outside of 'run' command
* - return value can be printed outside of 'run' command
*/
for (i = -3; i <= 3; i++) {
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; exit %d ; echo baz' ; run foo ; echo $?", i));
ut_assert_nextline("bar");
ut_assert_nextline("%d", i > 0 ? i : 0);
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; exit %d ; echo baz' ; run foo && echo quux ; echo $?", i));
ut_assert_nextline("bar");
if (i <= 0)
ut_assert_nextline("quux");
ut_assert_nextline("%d", i > 0 ? i : 0);
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; exit %d ; echo baz' ; run foo || echo quux ; echo $?", i));
ut_assert_nextline("bar");
if (i > 0)
ut_assert_nextline("quux");
/* Either 'exit' returns 0, or 'echo quux' returns 0 */
ut_assert_nextline("0");
ut_assertok(ut_check_console_end(uts));
}
/* Validate that 'exit' behaves the same way as 'exit 0' */
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo ; echo $?", i));
ut_assert_nextline("bar");
ut_assert_nextline("0");
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo && echo quux ; echo $?", i));
ut_assert_nextline("bar");
ut_assert_nextline("quux");
ut_assert_nextline("0");
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo || echo quux ; echo $?", i));
ut_assert_nextline("bar");
/* Either 'exit' returns 0, or 'echo quux' returns 0 */
ut_assert_nextline("0");
ut_assertok(ut_check_console_end(uts));
/* Validate that return value still propagates from 'run' command */
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo ; echo $?", i));
ut_assert_nextline("bar");
ut_assert_nextline("0");
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo && echo quux ; echo $?", i));
ut_assert_nextline("bar");
ut_assert_nextline("quux");
ut_assert_nextline("0");
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo || echo quux ; echo $?", i));
ut_assert_nextline("bar");
/* The 'true' returns 0 */
ut_assert_nextline("0");
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo ; echo $?", i));
ut_assert_nextline("bar");
ut_assert_nextline("1");
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo && echo quux ; echo $?", i));
ut_assert_nextline("bar");
ut_assert_nextline("1");
ut_assertok(ut_check_console_end(uts));
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo || echo quux ; echo $?", i));
ut_assert_nextline("bar");
ut_assert_nextline("quux");
/* The 'echo quux' returns 0 */
ut_assert_nextline("0");
ut_assertok(ut_check_console_end(uts));
return 0;
}
EXIT_TEST(cmd_exit_test, UT_TESTF_CONSOLE_REC);
int do_ut_exit(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
struct unit_test *tests = UNIT_TEST_SUITE_START(exit_test);
const int n_ents = UNIT_TEST_SUITE_COUNT(exit_test);
return cmd_ut_category("cmd_exit", "exit_test_", tests, n_ents,
argc, argv);
}

View File

@ -65,6 +65,7 @@ static struct cmd_tbl cmd_ut_sub[] = {
#if defined(CONFIG_UT_ENV) #if defined(CONFIG_UT_ENV)
U_BOOT_CMD_MKENT(env, CONFIG_SYS_MAXARGS, 1, do_ut_env, "", ""), U_BOOT_CMD_MKENT(env, CONFIG_SYS_MAXARGS, 1, do_ut_env, "", ""),
#endif #endif
U_BOOT_CMD_MKENT(exit, CONFIG_SYS_MAXARGS, 1, do_ut_exit, "", ""),
#ifdef CONFIG_CMD_FDT #ifdef CONFIG_CMD_FDT
U_BOOT_CMD_MKENT(fdt, CONFIG_SYS_MAXARGS, 1, do_ut_fdt, "", ""), U_BOOT_CMD_MKENT(fdt, CONFIG_SYS_MAXARGS, 1, do_ut_fdt, "", ""),
#endif #endif

View File

@ -321,42 +321,48 @@ static int run_test_internal(struct unit_test_state *uts, char *name,
/* Compress works as expected. */ /* Compress works as expected. */
printf("\torig_size:%lu\n", buf->orig_size); printf("\torig_size:%lu\n", buf->orig_size);
memset(buf->compressed_buf, 'A', TEST_BUFFER_SIZE); memset(buf->compressed_buf, 'A', TEST_BUFFER_SIZE);
errcheck(compress(uts, buf->orig_buf, buf->orig_size, ut_assertok(compress(uts, buf->orig_buf, buf->orig_size,
buf->compressed_buf, buf->compressed_size, buf->compressed_buf, buf->compressed_size,
&buf->compressed_size) == 0); &buf->compressed_size));
printf("\tcompressed_size:%lu\n", buf->compressed_size); printf("\tcompressed_size:%lu\n", buf->compressed_size);
errcheck(buf->compressed_size > 0); ut_assert(buf->compressed_size > 0);
errcheck(buf->compressed_size < buf->orig_size); ut_assert(buf->compressed_size < buf->orig_size);
errcheck(((char *)buf->compressed_buf)[buf->compressed_size - 1] != ut_assert(((char *)buf->compressed_buf)[buf->compressed_size - 1]
'A'); != 'A');
errcheck(((char *)buf->compressed_buf)[buf->compressed_size] == 'A'); ut_asserteq(((char *)buf->compressed_buf)[buf->compressed_size], 'A');
/* Uncompresses with space remaining. */ /* Uncompresses with space remaining. */
errcheck(uncompress(uts, buf->compressed_buf, buf->compressed_size, ut_assertok(uncompress(uts, buf->compressed_buf, buf->compressed_size,
buf->uncompressed_buf, buf->uncompressed_size, buf->uncompressed_buf, buf->uncompressed_size,
&buf->uncompressed_size) == 0); &buf->uncompressed_size));
printf("\tuncompressed_size:%lu\n", buf->uncompressed_size); printf("\tuncompressed_size:%lu\n", buf->uncompressed_size);
errcheck(buf->uncompressed_size == buf->orig_size); ut_asserteq(buf->uncompressed_size, buf->orig_size);
errcheck(memcmp(buf->orig_buf, buf->uncompressed_buf, ut_asserteq_mem(buf->orig_buf, buf->uncompressed_buf, buf->orig_size);
buf->orig_size) == 0);
/* Uncompresses with exactly the right size output buffer. */ /* Uncompresses with exactly the right size output buffer. */
memset(buf->uncompressed_buf, 'A', TEST_BUFFER_SIZE); memset(buf->uncompressed_buf, 'A', TEST_BUFFER_SIZE);
errcheck(uncompress(uts, buf->compressed_buf, buf->compressed_size, ut_assertok(uncompress(uts, buf->compressed_buf, buf->compressed_size,
buf->uncompressed_buf, buf->orig_size, buf->uncompressed_buf, buf->orig_size,
&buf->uncompressed_size) == 0); &buf->uncompressed_size));
errcheck(buf->uncompressed_size == buf->orig_size); ut_asserteq(buf->uncompressed_size, buf->orig_size);
errcheck(memcmp(buf->orig_buf, buf->uncompressed_buf, ut_asserteq_mem(buf->orig_buf, buf->uncompressed_buf, buf->orig_size);
buf->orig_size) == 0); ut_asserteq(((char *)buf->uncompressed_buf)[buf->orig_size], 'A');
errcheck(((char *)buf->uncompressed_buf)[buf->orig_size] == 'A');
/* Uncompresses with trailing garbage in input buffer. */
memset(buf->uncompressed_buf, 'A', TEST_BUFFER_SIZE);
ut_assertok(uncompress(uts, buf->compressed_buf, buf->compressed_size + 4,
buf->uncompressed_buf, buf->uncompressed_size,
&buf->uncompressed_size));
ut_asserteq(buf->uncompressed_size, buf->orig_size);
ut_asserteq_mem(buf->orig_buf, buf->uncompressed_buf, buf->orig_size);
/* Make sure compression does not over-run. */ /* Make sure compression does not over-run. */
memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE); memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE);
ret = compress(uts, buf->orig_buf, buf->orig_size, ret = compress(uts, buf->orig_buf, buf->orig_size,
buf->compare_buf, buf->compressed_size - 1, buf->compare_buf, buf->compressed_size - 1,
NULL); NULL);
errcheck(((char *)buf->compare_buf)[buf->compressed_size] == 'A'); ut_asserteq(((char *)buf->compare_buf)[buf->compressed_size], 'A');
errcheck(ret != 0); ut_assert(ret != 0);
printf("\tcompress does not overrun\n"); printf("\tcompress does not overrun\n");
/* Make sure decompression does not over-run. */ /* Make sure decompression does not over-run. */
@ -364,15 +370,12 @@ static int run_test_internal(struct unit_test_state *uts, char *name,
ret = uncompress(uts, buf->compressed_buf, buf->compressed_size, ret = uncompress(uts, buf->compressed_buf, buf->compressed_size,
buf->compare_buf, buf->uncompressed_size - 1, buf->compare_buf, buf->uncompressed_size - 1,
NULL); NULL);
errcheck(((char *)buf->compare_buf)[buf->uncompressed_size - 1] == 'A'); ut_asserteq(((char *)buf->compare_buf)[buf->uncompressed_size - 1], 'A');
errcheck(ret != 0); ut_assert(ret != 0);
printf("\tuncompress does not overrun\n"); printf("\tuncompress does not overrun\n");
/* Got here, everything is fine. */ /* Got here, everything is fine. */
ret = 0; return 0;
out:
return ret;
} }
static int run_test(struct unit_test_state *uts, char *name, static int run_test(struct unit_test_state *uts, char *name,

View File

@ -462,22 +462,22 @@ function check_results() {
FAIL=0 FAIL=0
# Check if the ls is showing correct results for 2.5 gb file # Check if the ls is showing correct results for 2.5 gb file
grep -A7 "Test Case 1 " "$1" | egrep -iq "2621440000 *$4" grep -A7 "Test Case 1 " "$1" | grep -Eiq "2621440000 *$4"
pass_fail "TC1: ls of $4" pass_fail "TC1: ls of $4"
# Check if the ls is showing correct results for 1 mb file # Check if the ls is showing correct results for 1 mb file
grep -A7 "Test Case 1 " "$1" | egrep -iq "1048576 *$3" grep -A7 "Test Case 1 " "$1" | grep -Eiq "1048576 *$3"
pass_fail "TC1: ls of $3" pass_fail "TC1: ls of $3"
# Check size command on 1MB.file # Check size command on 1MB.file
egrep -A3 "Test Case 2a " "$1" | grep -q "filesize=100000" grep -A3 "Test Case 2a " "$1" | grep -q "filesize=100000"
pass_fail "TC2: size of $3" pass_fail "TC2: size of $3"
# Check size command on 1MB.file via a path using '..' # Check size command on 1MB.file via a path using '..'
egrep -A3 "Test Case 2b " "$1" | grep -q "filesize=100000" grep -A3 "Test Case 2b " "$1" | grep -q "filesize=100000"
pass_fail "TC2: size of $3 via a path using '..'" pass_fail "TC2: size of $3 via a path using '..'"
# Check size command on 2.5GB.file # Check size command on 2.5GB.file
egrep -A3 "Test Case 3 " "$1" | grep -q "filesize=9c400000" grep -A3 "Test Case 3 " "$1" | grep -q "filesize=9c400000"
pass_fail "TC3: size of $4" pass_fail "TC3: size of $4"
# Check read full mb of 1MB.file # Check read full mb of 1MB.file

View File

@ -8,6 +8,7 @@ Test operation of shell commands relating to environment variables.
import os import os
import os.path import os.path
import re
from subprocess import call, CalledProcessError from subprocess import call, CalledProcessError
import tempfile import tempfile
@ -173,6 +174,29 @@ def validate_set(state_test_env, var, value):
response = state_test_env.u_boot_console.run_command('printenv %s' % var) response = state_test_env.u_boot_console.run_command('printenv %s' % var)
assert response == ('%s=%s' % (var, value)) assert response == ('%s=%s' % (var, value))
@pytest.mark.boardspec('sandbox')
def test_env_initial_env_file(u_boot_console):
"""Test that the u-boot-initial-env make target works"""
cons = u_boot_console
builddir = 'O=' + cons.config.build_dir
envfile = cons.config.build_dir + '/u-boot-initial-env'
# remove if already exists from an older run
try:
os.remove(envfile)
except:
pass
u_boot_utils.run_and_log(cons, ['make', builddir, 'u-boot-initial-env'])
assert os.path.exists(envfile)
# assume that every environment has a board variable, e.g. board=sandbox
with open(envfile, 'r') as file:
env = file.read()
regex = re.compile('board=.+\\n')
assert re.search(regex, env)
def test_env_echo_exists(state_test_env): def test_env_echo_exists(state_test_env):
"""Test echoing a variable that exists.""" """Test echoing a variable that exists."""

View File

@ -2,7 +2,7 @@
# This Dockerfile is used to build an image containing basic stuff to be used # This Dockerfile is used to build an image containing basic stuff to be used
# to build U-Boot and run our test suites. # to build U-Boot and run our test suites.
FROM ubuntu:jammy-20221101 FROM ubuntu:jammy-20221130
MAINTAINER Tom Rini <trini@konsulko.com> MAINTAINER Tom Rini <trini@konsulko.com>
LABEL Description=" This image is for building U-Boot inside a container" LABEL Description=" This image is for building U-Boot inside a container"
@ -64,6 +64,7 @@ RUN apt-get update && apt-get install -y \
iasl \ iasl \
imagemagick \ imagemagick \
iputils-ping \ iputils-ping \
libc6-i386 \
libconfuse-dev \ libconfuse-dev \
libgit2-dev \ libgit2-dev \
libjson-glib-dev \ libjson-glib-dev \
@ -109,6 +110,7 @@ RUN apt-get update && apt-get install -y \
srecord \ srecord \
sudo \ sudo \
swig \ swig \
texinfo \
util-linux \ util-linux \
uuid-dev \ uuid-dev \
virtualenv \ virtualenv \