diff mbox

[U-Boot,10/11] Exynos542x: Make A7s boot with thumb-mode U-Boot on warm reset

Message ID 1421329328-18070-9-git-send-email-akshay.s@samsung.com
State Changes Requested
Delegated to: Minkyu Kang
Headers show

Commit Message

Akshay Saraswat Jan. 15, 2015, 1:42 p.m. UTC
On warm reset, all cores jump to the low_power_start function because iRAM
data is retained and because while executing iROM code all cores find
the jump flag 0x02020028 set. In low_power_start, cores check the reset
status and if true they clear the jump flag and jump back to 0x0.

The A7 cores do jump to 0x0 but consider following instructions as a Thumb
instructions which in turn makes them loop inside the iROM code instead of
jumping to power_down_core.

This issue is fixed by replacing the "mov pc" instruction with a "bx"
instruction which switches state along with the jump to make the execution
unit consider the branch target as an ARM instruction.

Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
---
 arch/arm/cpu/armv7/exynos/lowlevel_init.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Simon Glass Jan. 28, 2015, 4:11 a.m. UTC | #1
On 15 January 2015 at 06:42, Akshay Saraswat <akshay.s@samsung.com> wrote:
> On warm reset, all cores jump to the low_power_start function because iRAM
> data is retained and because while executing iROM code all cores find
> the jump flag 0x02020028 set. In low_power_start, cores check the reset
> status and if true they clear the jump flag and jump back to 0x0.
>
> The A7 cores do jump to 0x0 but consider following instructions as a Thumb
> instructions which in turn makes them loop inside the iROM code instead of
> jumping to power_down_core.
>
> This issue is fixed by replacing the "mov pc" instruction with a "bx"
> instruction which switches state along with the jump to make the execution
> unit consider the branch target as an ARM instruction.
>
> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
> ---
>  arch/arm/cpu/armv7/exynos/lowlevel_init.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/cpu/armv7/exynos/lowlevel_init.c b/arch/arm/cpu/armv7/exynos/lowlevel_init.c
> index d9f3f4b..a459432 100644
> --- a/arch/arm/cpu/armv7/exynos/lowlevel_init.c
> +++ b/arch/arm/cpu/armv7/exynos/lowlevel_init.c
> @@ -124,7 +124,7 @@ static void low_power_start(void)
>         reg_val = readl(RST_FLAG_REG);
>         if (reg_val != RST_FLAG_VAL) {
>                 writel(0x0, CONFIG_LOWPOWER_FLAG);
> -               set_pc(0x0);
> +               branch_bx(0x0);
>         }
>
>         reg_val = readl(CONFIG_PHY_IRAM_BASE + 0x4);
> --
> 1.9.1
>

Reviewed-by: Simon Glass <sjg@chromium.org>

Tested on snow, pit, pi
Tested-by: Simon Glass <sjg@chromium.org>
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/exynos/lowlevel_init.c b/arch/arm/cpu/armv7/exynos/lowlevel_init.c
index d9f3f4b..a459432 100644
--- a/arch/arm/cpu/armv7/exynos/lowlevel_init.c
+++ b/arch/arm/cpu/armv7/exynos/lowlevel_init.c
@@ -124,7 +124,7 @@  static void low_power_start(void)
 	reg_val = readl(RST_FLAG_REG);
 	if (reg_val != RST_FLAG_VAL) {
 		writel(0x0, CONFIG_LOWPOWER_FLAG);
-		set_pc(0x0);
+		branch_bx(0x0);
 	}
 
 	reg_val = readl(CONFIG_PHY_IRAM_BASE + 0x4);