diff options
author | Tom Rini <trini@konsulko.com> | 2023-12-21 16:10:00 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-12-21 16:10:00 -0500 |
commit | 7c4647b8fb448ac658a9bc726681ad9e75e6b9e8 (patch) | |
tree | 5ecb1a3c90c2fc5c16176914748ad207005772a3 /boot | |
parent | ced928b1994b6dd8d133797f506c0991b0e6196d (diff) | |
parent | d37086a95f4b2c39f9ecfe602b792df8ab3bd8f9 (diff) | |
download | u-boot-7c4647b8fb448ac658a9bc726681ad9e75e6b9e8.tar.gz u-boot-7c4647b8fb448ac658a9bc726681ad9e75e6b9e8.tar.bz2 u-boot-7c4647b8fb448ac658a9bc726681ad9e75e6b9e8.zip |
Merge patch series "Complete decoupling of bootm logic from commands"
Simon Glass <sjg@chromium.org> says:
This series continues refactoring the bootm code to allow it to be used
with CONFIG_COMMAND disabled. The OS-handling code is refactored and
a new bootm_run() function is created to run through the bootm stages.
This completes the work.
A booti_go() function is created also, in case it proves useful, but at
last for now standard boot does not use this.
This is cmdd (part d of CMDLINE refactoring)
It depends on dm/bootstda-working
which depends on dm/cmdc-working
Diffstat (limited to 'boot')
-rw-r--r-- | boot/bootm.c | 119 | ||||
-rw-r--r-- | boot/bootm_os.c | 78 |
2 files changed, 103 insertions, 94 deletions
diff --git a/boot/bootm.c b/boot/bootm.c index 4cf66cca0d..7a050ed41a 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -6,6 +6,7 @@ #ifndef USE_HOSTCC #include <common.h> +#include <bootm.h> #include <bootstage.h> #include <cli.h> #include <command.h> @@ -989,35 +990,9 @@ unmap_image: return ret; } -/** - * Execute selected states of the bootm command. - * - * Note the arguments to this state must be the first argument, Any 'bootm' - * or sub-command arguments must have already been taken. - * - * Note that if states contains more than one flag it MUST contain - * BOOTM_STATE_START, since this handles and consumes the command line args. - * - * Also note that aside from boot_os_fn functions and bootm_load_os no other - * functions we store the return value of in 'ret' may use a negative return - * value, without special handling. - * - * @param cmdtp Pointer to bootm command table entry - * @param flag Command flags (CMD_FLAG_...) - * @param argc Number of subcommand arguments (0 = no arguments) - * @param argv Arguments - * @param states Mask containing states to run (BOOTM_STATE_...) - * @param images Image header information - * @param boot_progress 1 to show boot progress, 0 to not do this - * Return: 0 if ok, something else on error. Some errors will cause this - * function to perform a reboot! If states contains BOOTM_STATE_OS_GO - * then the intent is to boot an OS, so this function will not return - * unless the image type is standalone. - */ -int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], int states, struct bootm_headers *images, - int boot_progress) +int bootm_run_states(struct bootm_info *bmi, int states) { + struct bootm_headers *images = bmi->images; boot_os_fn *boot_fn; ulong iflag = 0; int ret = 0, need_boot_fn; @@ -1032,17 +1007,18 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, ret = bootm_start(); if (!ret && (states & BOOTM_STATE_PRE_LOAD)) - ret = bootm_pre_load(argv[0]); + ret = bootm_pre_load(bmi->addr_img); if (!ret && (states & BOOTM_STATE_FINDOS)) - ret = bootm_find_os(cmdtp->name, argv[0]); + ret = bootm_find_os(bmi->cmd_name, bmi->addr_img); if (!ret && (states & BOOTM_STATE_FINDOTHER)) { ulong img_addr; - img_addr = argc ? hextoul(argv[0], NULL) : image_load_addr; - ret = bootm_find_other(img_addr, cmd_arg1(argc, argv), - cmd_arg2(argc, argv)); + img_addr = bmi->addr_img ? hextoul(bmi->addr_img, NULL) + : image_load_addr; + ret = bootm_find_other(img_addr, bmi->conf_ramdisk, + bmi->conf_fdt); } if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !ret && @@ -1096,12 +1072,11 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, return 1; } - /* Call various other states that are not generally used */ if (!ret && (states & BOOTM_STATE_OS_CMDLINE)) - ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images); + ret = boot_fn(BOOTM_STATE_OS_CMDLINE, bmi); if (!ret && (states & BOOTM_STATE_OS_BD_T)) - ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images); + ret = boot_fn(BOOTM_STATE_OS_BD_T, bmi); if (!ret && (states & BOOTM_STATE_OS_PREP)) { int flags = 0; /* For Linux OS do all substitutions at console processing */ @@ -1113,7 +1088,7 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, ret = CMD_RET_FAILURE; goto err; } - ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images); + ret = boot_fn(BOOTM_STATE_OS_PREP, bmi); } #ifdef CONFIG_TRACE @@ -1121,10 +1096,9 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) { char *cmd_list = env_get("fakegocmd"); - ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO, - images, boot_fn); + ret = boot_selected_os(BOOTM_STATE_OS_FAKE_GO, bmi, boot_fn); if (!ret && cmd_list) - ret = run_command_list(cmd_list, -1, flag); + ret = run_command_list(cmd_list, -1, 0); } #endif @@ -1136,37 +1110,61 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, /* Now run the OS! We hope this doesn't return */ if (!ret && (states & BOOTM_STATE_OS_GO)) - ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO, - images, boot_fn); + ret = boot_selected_os(BOOTM_STATE_OS_GO, bmi, boot_fn); /* Deal with any fallout */ err: if (iflag) enable_interrupts(); - if (ret == BOOTM_ERR_UNIMPLEMENTED) + if (ret == BOOTM_ERR_UNIMPLEMENTED) { bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL); - else if (ret == BOOTM_ERR_RESET) - do_reset(cmdtp, flag, argc, argv); + } else if (ret == BOOTM_ERR_RESET) { + printf("Resetting the board...\n"); + reset_cpu(); + } return ret; } +int boot_run(struct bootm_info *bmi, const char *cmd, int extra_states) +{ + int states; + + bmi->cmd_name = cmd; + states = BOOTM_STATE_MEASURE | BOOTM_STATE_OS_PREP | + BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO; + if (IS_ENABLED(CONFIG_SYS_BOOT_RAMDISK_HIGH)) + states |= BOOTM_STATE_RAMDISK; + states |= extra_states; + + return bootm_run_states(bmi, states); +} + +int bootm_run(struct bootm_info *bmi) +{ + return boot_run(bmi, "bootm", BOOTM_STATE_START | BOOTM_STATE_FINDOS | + BOOTM_STATE_PRE_LOAD | BOOTM_STATE_FINDOTHER | + BOOTM_STATE_LOADOS); +} + +int bootz_run(struct bootm_info *bmi) +{ + return boot_run(bmi, "bootz", 0); +} + +int booti_run(struct bootm_info *bmi) +{ + return boot_run(bmi, "booti", 0); +} + int bootm_boot_start(ulong addr, const char *cmdline) { - static struct cmd_tbl cmd = {"bootm"}; char addr_str[30]; - char *argv[] = {addr_str, NULL}; + struct bootm_info bmi; int states; int ret; - /* - * TODO(sjg@chromium.org): This uses the command-line interface, but - * should not. To clean this up, the various bootm states need to be - * passed an info structure instead of cmdline flags. Then this can - * set up the required info and move through the states without needing - * the command line. - */ states = BOOTM_STATE_START | BOOTM_STATE_FINDOS | BOOTM_STATE_PRE_LOAD | BOOTM_STATE_FINDOTHER | BOOTM_STATE_LOADOS | BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | @@ -1184,11 +1182,22 @@ int bootm_boot_start(ulong addr, const char *cmdline) printf("Failed to set cmdline\n"); return ret; } - ret = do_bootm_states(&cmd, 0, 1, argv, states, &images, 1); + bootm_init(&bmi); + bmi.addr_img = addr_str; + bmi.cmd_name = "bootm"; + ret = bootm_run_states(&bmi, states); return ret; } +void bootm_init(struct bootm_info *bmi) +{ + memset(bmi, '\0', sizeof(struct bootm_info)); + bmi->boot_progress = true; + if (IS_ENABLED(CONFIG_CMD_BOOTM)) + bmi->images = &images; +} + /** * switch_to_non_secure_mode() - switch to non-secure mode * diff --git a/boot/bootm_os.c b/boot/bootm_os.c index dc4046ad08..ccde72d22c 100644 --- a/boot/bootm_os.c +++ b/boot/bootm_os.c @@ -23,9 +23,9 @@ DECLARE_GLOBAL_DATA_PTR; -static int do_bootm_standalone(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_standalone(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; int (*appl)(int, char *const[]); if (!env_get_autostart()) { @@ -33,7 +33,7 @@ static int do_bootm_standalone(int flag, int argc, char *const argv[], return 0; } appl = (int (*)(int, char * const []))images->ep; - appl(argc, argv); + appl(bmi->argc, bmi->argv); return 0; } @@ -64,9 +64,9 @@ static void __maybe_unused fit_unsupported_reset(const char *msg) } #ifdef CONFIG_BOOTM_NETBSD -static int do_bootm_netbsd(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_netbsd(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; void (*loader)(struct bd_info *bd, struct legacy_img_hdr *hdr, char *console, char *cmdline); struct legacy_img_hdr *os_hdr, *hdr; @@ -102,14 +102,14 @@ static int do_bootm_netbsd(int flag, int argc, char *const argv[], os_hdr = hdr; } - if (argc > 0) { + if (bmi->argc > 0) { ulong len; int i; - for (i = 0, len = 0; i < argc; i += 1) - len += strlen(argv[i]) + 1; + for (i = 0, len = 0; i < bmi->argc; i += 1) + len += strlen(bmi->argv[i]) + 1; cmdline = malloc(len); - copy_args(cmdline, argc, argv, ' '); + copy_args(cmdline, bmi->argc, bmi->argv, ' '); } else { cmdline = env_get("bootargs"); if (cmdline == NULL) @@ -137,9 +137,9 @@ static int do_bootm_netbsd(int flag, int argc, char *const argv[], #endif /* CONFIG_BOOTM_NETBSD*/ #ifdef CONFIG_BOOTM_RTEMS -static int do_bootm_rtems(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_rtems(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; void (*entry_point)(struct bd_info *); if (flag != BOOTM_STATE_OS_GO) @@ -170,9 +170,9 @@ static int do_bootm_rtems(int flag, int argc, char *const argv[], #endif /* CONFIG_BOOTM_RTEMS */ #if defined(CONFIG_BOOTM_OSE) -static int do_bootm_ose(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_ose(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; void (*entry_point)(void); if (flag != BOOTM_STATE_OS_GO) @@ -203,9 +203,9 @@ static int do_bootm_ose(int flag, int argc, char *const argv[], #endif /* CONFIG_BOOTM_OSE */ #if defined(CONFIG_BOOTM_PLAN9) -static int do_bootm_plan9(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_plan9(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; void (*entry_point)(void); char *s; @@ -224,8 +224,8 @@ static int do_bootm_plan9(int flag, int argc, char *const argv[], if (s != NULL) { char *confaddr = (char *)hextoul(s, NULL); - if (argc > 0) { - copy_args(confaddr, argc, argv, '\n'); + if (bmi->argc) { + copy_args(confaddr, bmi->argc, bmi->argv, '\n'); } else { s = env_get("bootargs"); if (s != NULL) @@ -311,9 +311,10 @@ static void do_bootvx_fdt(struct bootm_headers *images) puts("## vxWorks terminated\n"); } -static int do_bootm_vxworks_legacy(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_vxworks_legacy(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; + if (flag != BOOTM_STATE_OS_GO) return 0; @@ -322,8 +323,7 @@ static int do_bootm_vxworks_legacy(int flag, int argc, char *const argv[], return 1; } -int do_bootm_vxworks(int flag, int argc, char *const argv[], - struct bootm_headers *images) +int do_bootm_vxworks(int flag, struct bootm_info *bmi) { char *bootargs; int pos; @@ -348,19 +348,19 @@ int do_bootm_vxworks(int flag, int argc, char *const argv[], if (std_dtb) { if (flag & BOOTM_STATE_OS_PREP) printf(" Using standard DTB\n"); - return do_bootm_linux(flag, argc, argv, images); + return do_bootm_linux(flag, bmi); } else { if (flag & BOOTM_STATE_OS_PREP) printf(" !!! WARNING !!! Using legacy DTB\n"); - return do_bootm_vxworks_legacy(flag, argc, argv, images); + return do_bootm_vxworks_legacy(flag, bmi); } } #endif #if defined(CONFIG_CMD_ELF) -static int do_bootm_qnxelf(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_qnxelf(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; char *local_args[2]; char str[16]; int dcache; @@ -376,7 +376,7 @@ static int do_bootm_qnxelf(int flag, int argc, char *const argv[], #endif sprintf(str, "%lx", images->ep); /* write entry-point into string */ - local_args[0] = argv[0]; + local_args[0] = bmi->argv[0]; local_args[1] = str; /* and provide it via the arguments */ /* @@ -396,9 +396,9 @@ static int do_bootm_qnxelf(int flag, int argc, char *const argv[], #endif #ifdef CONFIG_INTEGRITY -static int do_bootm_integrity(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_integrity(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; void (*entry_point)(void); if (flag != BOOTM_STATE_OS_GO) @@ -429,9 +429,9 @@ static int do_bootm_integrity(int flag, int argc, char *const argv[], #endif #ifdef CONFIG_BOOTM_OPENRTOS -static int do_bootm_openrtos(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_openrtos(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; void (*entry_point)(void); if (flag != BOOTM_STATE_OS_GO) @@ -455,9 +455,9 @@ static int do_bootm_openrtos(int flag, int argc, char *const argv[], #endif #ifdef CONFIG_BOOTM_OPTEE -static int do_bootm_tee(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_tee(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; int ret; /* Validate OPTEE header */ @@ -468,14 +468,14 @@ static int do_bootm_tee(int flag, int argc, char *const argv[], return ret; /* From here we can run the regular linux boot path */ - return do_bootm_linux(flag, argc, argv, images); + return do_bootm_linux(flag, bmi); } #endif #ifdef CONFIG_BOOTM_EFI -static int do_bootm_efi(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_efi(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; int ret; void *image_buf; @@ -550,15 +550,15 @@ __weak void board_preboot_os(void) /* please define board specific board_preboot_os() */ } -int boot_selected_os(int argc, char *const argv[], int state, - struct bootm_headers *images, boot_os_fn *boot_fn) +int boot_selected_os(int state, struct bootm_info *bmi, boot_os_fn *boot_fn) { arch_preboot_os(); board_preboot_os(); - boot_fn(state, argc, argv, images); + + boot_fn(state, bmi); /* Stand-alone may return when 'autostart' is 'no' */ - if (images->os.type == IH_TYPE_STANDALONE || + if (bmi->images->os.type == IH_TYPE_STANDALONE || IS_ENABLED(CONFIG_SANDBOX) || state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */ return 0; |