summaryrefslogtreecommitdiff
path: root/common/cmd_bootm.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/cmd_bootm.c')
-rw-r--r--common/cmd_bootm.c65
1 files changed, 38 insertions, 27 deletions
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index ba0bcd4e32..3009ecee54 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -345,8 +345,10 @@ static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc,
#define BOOTM_ERR_RESET -1
#define BOOTM_ERR_OVERLAP -2
#define BOOTM_ERR_UNIMPLEMENTED -3
-static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
+static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
+ int boot_progress)
{
+ image_info_t os = images->os;
uint8_t comp = os.comp;
ulong load = os.load;
ulong blob_start = os.start;
@@ -464,7 +466,17 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
*load_end);
- return BOOTM_ERR_OVERLAP;
+ /* Check what type of image this is. */
+ if (images->legacy_hdr_valid) {
+ if (image_get_type(&images->legacy_hdr_os_copy)
+ == IH_TYPE_MULTI)
+ puts("WARNING: legacy format multi component image overwritten\n");
+ return BOOTM_ERR_OVERLAP;
+ } else {
+ puts("ERROR: new format image overwritten - must RESET the board to recover\n");
+ bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
+ return BOOTM_ERR_RESET;
+ }
}
return 0;
@@ -558,6 +570,10 @@ static int boot_selected_os(int argc, char * const argv[], int state,
* 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)
@@ -599,11 +615,15 @@ static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc,
if (!ret && (states & BOOTM_STATE_LOADOS)) {
ulong load_end;
- ret = bootm_load_os(images->os, &load_end, 0);
- if (!ret) {
+ ret = bootm_load_os(images, &load_end, 0);
+ if (ret && ret != BOOTM_ERR_OVERLAP)
+ goto err;
+
+ if (ret == 0)
lmb_reserve(&images->lmb, images->os.load,
(load_end - images->os.load));
- }
+ else if (ret == BOOTM_ERR_OVERLAP)
+ ret = 0;
}
/* Relocate the ramdisk */
@@ -660,34 +680,25 @@ static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc,
}
#endif
/* Now run the OS! We hope this doesn't return */
- if (!ret && (states & BOOTM_STATE_OS_GO))
+ if (!ret && (states & BOOTM_STATE_OS_GO)) {
ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
images, boot_fn, &iflag);
+ if (ret)
+ goto err;
+ }
+
+ return ret;
/* Deal with any fallout */
- if (ret < 0) {
- if (ret == BOOTM_ERR_UNIMPLEMENTED) {
- if (iflag)
- enable_interrupts();
- bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
- return 1;
- } else if (ret == BOOTM_ERR_OVERLAP) {
- if (images->legacy_hdr_valid) {
- if (image_get_type(&images->legacy_hdr_os_copy)
- == IH_TYPE_MULTI)
- puts("WARNING: legacy format multi component image overwritten\n");
- } else {
- puts("ERROR: new format image overwritten - must RESET the board to recover\n");
- bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
- ret = BOOTM_ERR_RESET;
- }
- }
- if (ret == BOOTM_ERR_RESET)
- do_reset(cmdtp, flag, argc, argv);
- }
+err:
if (iflag)
enable_interrupts();
- if (ret)
+
+ if (ret == BOOTM_ERR_UNIMPLEMENTED)
+ bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
+ else if (ret == BOOTM_ERR_RESET)
+ do_reset(cmdtp, flag, argc, argv);
+ else
puts("subcommand not supported\n");
return ret;