diff options
| author | Simon Glass <sjg@chromium.org> | 2013-07-04 13:26:08 -0700 | 
|---|---|---|
| committer | Tom Rini <trini@ti.com> | 2013-07-10 09:15:14 -0400 | 
| commit | 385501d38b406c2d65b47c3978af2f659df89b28 (patch) | |
| tree | cd0f1a930c59a8b40320f9203f07b3bbae0f5a8b /common/cmd_bootm.c | |
| parent | 2f4998ab4429af4b805f8566268c3b761aa4babd (diff) | |
| download | olio-uboot-2014.01-385501d38b406c2d65b47c3978af2f659df89b28.tar.xz olio-uboot-2014.01-385501d38b406c2d65b47c3978af2f659df89b28.zip | |
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.c | 67 | 
1 files changed, 43 insertions, 24 deletions
| diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index a36e0197f..e712602b8 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); |