aboutsummaryrefslogtreecommitdiff
path: root/common/cmd_bootm.c
diff options
context:
space:
mode:
authorSimon Glass2013-07-04 13:26:08 -0700
committerTom Rini2013-07-10 09:15:14 -0400
commit385501d38b406c2d65b47c3978af2f659df89b28 (patch)
treecd0f1a930c59a8b40320f9203f07b3bbae0f5a8b /common/cmd_bootm.c
parent2f4998ab4429af4b805f8566268c3b761aa4babd (diff)
bootm: Disable interrupts only when loading
With the move of the interrupt code to earlier in the sequence, we exposed a problem where the interrupts are disabled at each bootm stage. This is not correct - it should be done only once. Let's disable interrupts in the LOAD stage. Put the code in a function for clarity. Also, bootz lost its interrupt code altogether, so reinstate it. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'common/cmd_bootm.c')
-rw-r--r--common/cmd_bootm.c67
1 files changed, 43 insertions, 24 deletions
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index a36e0197f55..e712602b8d2 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -539,6 +539,42 @@ static int boot_selected_os(int argc, char * const argv[], int state,
}
/**
+ * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot
+ *
+ * @return interrupt flag (0 if interrupts were disabled, non-zero if they were
+ * enabled)
+ */
+static ulong bootm_disable_interrupts(void)
+{
+ ulong iflag;
+
+ /*
+ * We have reached the point of no return: we are going to
+ * overwrite all exception vector code, so we cannot easily
+ * recover from any failures any more...
+ */
+ iflag = disable_interrupts();
+#ifdef CONFIG_NETCONSOLE
+ /* Stop the ethernet stack if NetConsole could have left it up */
+ eth_halt();
+#endif
+
+#if defined(CONFIG_CMD_USB)
+ /*
+ * turn off USB to prevent the host controller from writing to the
+ * SDRAM while Linux is booting. This could happen (at least for OHCI
+ * controller), because the HCCA (Host Controller Communication Area)
+ * lies within the SDRAM and the host controller writes continously to
+ * this area (as busmaster!). The HccaFrameNumber is for example
+ * updated every 1 ms within the HCCA structure in SDRAM! For more
+ * details see the OpenHCI specification.
+ */
+ usb_stop();
+#endif
+ return iflag;
+}
+
+/**
* Execute selected states of the bootm command.
*
* Note the arguments to this state must be the first argument, Any 'bootm'
@@ -588,34 +624,11 @@ static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc,
argc = 0; /* consume the args */
}
- /*
- * We have reached the point of no return: we are going to
- * overwrite all exception vector code, so we cannot easily
- * recover from any failures any more...
- */
- iflag = disable_interrupts();
-#ifdef CONFIG_NETCONSOLE
- /* Stop the ethernet stack if NetConsole could have left it up */
- eth_halt();
-#endif
-
-#if defined(CONFIG_CMD_USB)
- /*
- * turn off USB to prevent the host controller from writing to the
- * SDRAM while Linux is booting. This could happen (at least for OHCI
- * controller), because the HCCA (Host Controller Communication Area)
- * lies within the SDRAM and the host controller writes continously to
- * this area (as busmaster!). The HccaFrameNumber is for example
- * updated every 1 ms within the HCCA structure in SDRAM! For more
- * details see the OpenHCI specification.
- */
- usb_stop();
-#endif
-
/* Load the OS */
if (!ret && (states & BOOTM_STATE_LOADOS)) {
ulong load_end;
+ iflag = bootm_disable_interrupts();
ret = bootm_load_os(images, &load_end, 0);
if (ret && ret != BOOTM_ERR_OVERLAP)
goto err;
@@ -1783,6 +1796,12 @@ int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (bootz_start(cmdtp, flag, argc, argv, &images))
return 1;
+ /*
+ * We are doing the BOOTM_STATE_LOADOS state ourselves, so must
+ * disable interrupts ourselves
+ */
+ bootm_disable_interrupts();
+
ret = do_bootm_states(cmdtp, flag, argc, argv,
BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO,
&images, 1);