Message ID | 1480902750-839-12-git-send-email-andre.przywara@arm.com |
---|---|
State | Superseded |
Delegated to: | Jagannadha Sutradharudu Teki |
Headers | show |
Hi Andre, On 4 December 2016 at 18:52, Andre Przywara <andre.przywara@arm.com> wrote: > The Allwinner A64 SoC starts execution in AArch32 mode, and both > the boot ROM and Allwinner's boot0 keep running in this mode. > So U-Boot gets entered in 32-bit, although we want it to run in AArch64. > > By using a "magic" instruction, which happens to be an almost-NOP in > AArch64 and a branch in AArch32, we differentiate between being > entered in 64-bit or 32-bit mode. > If in 64-bit mode, we proceed with the branch to reset, but in 32-bit > mode we trigger an RMR write to bring the core into AArch64/EL3 and > re-enter U-Boot at CONFIG_SYS_TEXT_BASE. > This allows a 64-bit U-Boot to be both entered in 32 and 64-bit mode, > so we can use the same start code for the SPL and the U-Boot proper. > > We use the existing custom header (boot0.h) functionality, but restrict > the existing boot0 header reservation to the non-SPL build now. A SPL > wouldn't need such header anyway. This allows to have both options > defined and lets us use one for the SPL and the other for U-Boot proper. > > Signed-off-by: Andre Przywara <andre.przywara@arm.com> > --- > arch/arm/include/asm/arch-sunxi/boot0.h | 27 +++++++++++++++++++++++++++ > board/sunxi/Kconfig | 5 +++++ > 2 files changed, 32 insertions(+) Reviewed-by: Simon Glass <sjg@chromium.org> > > diff --git a/arch/arm/include/asm/arch-sunxi/boot0.h b/arch/arm/include/asm/arch-sunxi/boot0.h > index 6a13db5..7799a03 100644 > --- a/arch/arm/include/asm/arch-sunxi/boot0.h > +++ b/arch/arm/include/asm/arch-sunxi/boot0.h > @@ -4,6 +4,33 @@ > * SPDX-License-Identifier: GPL-2.0+ > */ > > +#if defined(CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER) && !defined(CONFIG_SPL_BUILD) > /* reserve space for BOOT0 header information */ > b reset > .space 1532 > +#elif defined(CONFIG_ARM_BOOT_HOOK_RMR) > +/* switch into AArch64 if needed */ > + tst x0, x0 // this is "b #0x84" in ARM > + b reset > + .space 0x7c > + .word 0xe59f1024 // ldr r1, [pc, #36] ; 0x170000a0 > + .word 0xe59f0024 // ldr r0, [pc, #36] ; CONFIG_*_TEXT_BASE > + .word 0xe5810000 // str r0, [r1] > + .word 0xf57ff04f // dsb sy > + .word 0xf57ff06f // isb sy > + .word 0xee1c0f50 // mrc 15, 0, r0, cr12, cr0, {2} ; RMR > + .word 0xe3800003 // orr r0, r0, #3 > + .word 0xee0c0f50 // mcr 15, 0, r0, cr12, cr0, {2} ; RMR > + .word 0xf57ff06f // isb sy > + .word 0xe320f003 // wfi > + .word 0xeafffffd // b @wfi > + .word 0x017000a0 // writeable RVBAR mapping address How come you cannot use the assembler here? > +#ifdef CONFIG_SPL_BUILD > + .word CONFIG_SPL_TEXT_BASE > +#else > + .word CONFIG_SYS_TEXT_BASE > +#endif > +#else > +/* normal execution */ > + b reset > +#endif > diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig > index 0cd57a2..ba72e76 100644 > --- a/board/sunxi/Kconfig > +++ b/board/sunxi/Kconfig > @@ -142,6 +142,11 @@ config RESERVE_ALLWINNER_BOOT0_HEADER > blob relies on this information to load and execute U-Boot. > Only needed on 64-bit Allwinner boards so far when using boot0. > > +config ARM_BOOT_HOOK_RMR > + bool > + default y if ARM64 > + select ENABLE_ARM_SOC_BOOT0_HOOK help? > + > config DRAM_TYPE > int "sunxi dram type" > depends on MACH_SUN8I_A83T > -- > 2.8.2 > Regards, Simon
Hi Simon, thanks a lot for looking at this! On 05/12/16 06:25, Simon Glass wrote: > Hi Andre, > > On 4 December 2016 at 18:52, Andre Przywara <andre.przywara@arm.com> wrote: >> The Allwinner A64 SoC starts execution in AArch32 mode, and both >> the boot ROM and Allwinner's boot0 keep running in this mode. >> So U-Boot gets entered in 32-bit, although we want it to run in AArch64. >> >> By using a "magic" instruction, which happens to be an almost-NOP in >> AArch64 and a branch in AArch32, we differentiate between being >> entered in 64-bit or 32-bit mode. >> If in 64-bit mode, we proceed with the branch to reset, but in 32-bit >> mode we trigger an RMR write to bring the core into AArch64/EL3 and >> re-enter U-Boot at CONFIG_SYS_TEXT_BASE. >> This allows a 64-bit U-Boot to be both entered in 32 and 64-bit mode, >> so we can use the same start code for the SPL and the U-Boot proper. >> >> We use the existing custom header (boot0.h) functionality, but restrict >> the existing boot0 header reservation to the non-SPL build now. A SPL >> wouldn't need such header anyway. This allows to have both options >> defined and lets us use one for the SPL and the other for U-Boot proper. >> >> Signed-off-by: Andre Przywara <andre.przywara@arm.com> >> --- >> arch/arm/include/asm/arch-sunxi/boot0.h | 27 +++++++++++++++++++++++++++ >> board/sunxi/Kconfig | 5 +++++ >> 2 files changed, 32 insertions(+) > > Reviewed-by: Simon Glass <sjg@chromium.org> > >> >> diff --git a/arch/arm/include/asm/arch-sunxi/boot0.h b/arch/arm/include/asm/arch-sunxi/boot0.h >> index 6a13db5..7799a03 100644 >> --- a/arch/arm/include/asm/arch-sunxi/boot0.h >> +++ b/arch/arm/include/asm/arch-sunxi/boot0.h >> @@ -4,6 +4,33 @@ >> * SPDX-License-Identifier: GPL-2.0+ >> */ >> >> +#if defined(CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER) && !defined(CONFIG_SPL_BUILD) >> /* reserve space for BOOT0 header information */ >> b reset >> .space 1532 >> +#elif defined(CONFIG_ARM_BOOT_HOOK_RMR) >> +/* switch into AArch64 if needed */ >> + tst x0, x0 // this is "b #0x84" in ARM >> + b reset >> + .space 0x7c >> + .word 0xe59f1024 // ldr r1, [pc, #36] ; 0x170000a0 >> + .word 0xe59f0024 // ldr r0, [pc, #36] ; CONFIG_*_TEXT_BASE >> + .word 0xe5810000 // str r0, [r1] >> + .word 0xf57ff04f // dsb sy >> + .word 0xf57ff06f // isb sy >> + .word 0xee1c0f50 // mrc 15, 0, r0, cr12, cr0, {2} ; RMR >> + .word 0xe3800003 // orr r0, r0, #3 >> + .word 0xee0c0f50 // mcr 15, 0, r0, cr12, cr0, {2} ; RMR >> + .word 0xf57ff06f // isb sy >> + .word 0xe320f003 // wfi >> + .word 0xeafffffd // b @wfi >> + .word 0x017000a0 // writeable RVBAR mapping address > > How come you cannot use the assembler here? Because this is ARM code, whereas this file is included in an AArch64 build. In contrast to x86 the AArch64 toolchain does not support both bitnesses in one build, mostly because the two architectures are really different. The actual reason for this exercise is that the Allwinner boot ROM enters the payload in AArch32 mode, but we want to compile and run the SPL in AArch64. So we need some small ARM(32) stub to enter AArch64. Running the whole SPL in 32-bit is the other option which the later patches enable, but I didn't want to call some 32-bit ARM (cross-)compiler just for this handful of instructions in this case here. >> +#ifdef CONFIG_SPL_BUILD >> + .word CONFIG_SPL_TEXT_BASE >> +#else >> + .word CONFIG_SYS_TEXT_BASE >> +#endif >> +#else >> +/* normal execution */ >> + b reset >> +#endif >> diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig >> index 0cd57a2..ba72e76 100644 >> --- a/board/sunxi/Kconfig >> +++ b/board/sunxi/Kconfig >> @@ -142,6 +142,11 @@ config RESERVE_ALLWINNER_BOOT0_HEADER >> blob relies on this information to load and execute U-Boot. >> Only needed on 64-bit Allwinner boards so far when using boot0. >> >> +config ARM_BOOT_HOOK_RMR >> + bool >> + default y if ARM64 >> + select ENABLE_ARM_SOC_BOOT0_HOOK > > help? Good point, I can copy some parts of the commit message into here. Cheers, Andre. > >> + >> config DRAM_TYPE >> int "sunxi dram type" >> depends on MACH_SUN8I_A83T >> -- >> 2.8.2 >> > > Regards, > Simon >
On Mon, Dec 05, 2016 at 10:41:27AM +0000, Andre Przywara wrote: > Hi Simon, > > thanks a lot for looking at this! > > On 05/12/16 06:25, Simon Glass wrote: > > Hi Andre, > > > > On 4 December 2016 at 18:52, Andre Przywara <andre.przywara@arm.com> wrote: > >> The Allwinner A64 SoC starts execution in AArch32 mode, and both > >> the boot ROM and Allwinner's boot0 keep running in this mode. > >> So U-Boot gets entered in 32-bit, although we want it to run in AArch64. > >> > >> By using a "magic" instruction, which happens to be an almost-NOP in > >> AArch64 and a branch in AArch32, we differentiate between being > >> entered in 64-bit or 32-bit mode. > >> If in 64-bit mode, we proceed with the branch to reset, but in 32-bit > >> mode we trigger an RMR write to bring the core into AArch64/EL3 and > >> re-enter U-Boot at CONFIG_SYS_TEXT_BASE. > >> This allows a 64-bit U-Boot to be both entered in 32 and 64-bit mode, > >> so we can use the same start code for the SPL and the U-Boot proper. > >> > >> We use the existing custom header (boot0.h) functionality, but restrict > >> the existing boot0 header reservation to the non-SPL build now. A SPL > >> wouldn't need such header anyway. This allows to have both options > >> defined and lets us use one for the SPL and the other for U-Boot proper. > >> > >> Signed-off-by: Andre Przywara <andre.przywara@arm.com> > >> --- > >> arch/arm/include/asm/arch-sunxi/boot0.h | 27 +++++++++++++++++++++++++++ > >> board/sunxi/Kconfig | 5 +++++ > >> 2 files changed, 32 insertions(+) > > > > Reviewed-by: Simon Glass <sjg@chromium.org> > > > >> > >> diff --git a/arch/arm/include/asm/arch-sunxi/boot0.h b/arch/arm/include/asm/arch-sunxi/boot0.h > >> index 6a13db5..7799a03 100644 > >> --- a/arch/arm/include/asm/arch-sunxi/boot0.h > >> +++ b/arch/arm/include/asm/arch-sunxi/boot0.h > >> @@ -4,6 +4,33 @@ > >> * SPDX-License-Identifier: GPL-2.0+ > >> */ > >> > >> +#if defined(CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER) && !defined(CONFIG_SPL_BUILD) > >> /* reserve space for BOOT0 header information */ > >> b reset > >> .space 1532 > >> +#elif defined(CONFIG_ARM_BOOT_HOOK_RMR) > >> +/* switch into AArch64 if needed */ > >> + tst x0, x0 // this is "b #0x84" in ARM > >> + b reset > >> + .space 0x7c > >> + .word 0xe59f1024 // ldr r1, [pc, #36] ; 0x170000a0 > >> + .word 0xe59f0024 // ldr r0, [pc, #36] ; CONFIG_*_TEXT_BASE > >> + .word 0xe5810000 // str r0, [r1] > >> + .word 0xf57ff04f // dsb sy > >> + .word 0xf57ff06f // isb sy > >> + .word 0xee1c0f50 // mrc 15, 0, r0, cr12, cr0, {2} ; RMR > >> + .word 0xe3800003 // orr r0, r0, #3 > >> + .word 0xee0c0f50 // mcr 15, 0, r0, cr12, cr0, {2} ; RMR > >> + .word 0xf57ff06f // isb sy > >> + .word 0xe320f003 // wfi > >> + .word 0xeafffffd // b @wfi > >> + .word 0x017000a0 // writeable RVBAR mapping address > > > > How come you cannot use the assembler here? > > Because this is ARM code, whereas this file is included in an AArch64 > build. In contrast to x86 the AArch64 toolchain does not support both > bitnesses in one build, mostly because the two architectures are really > different. > > The actual reason for this exercise is that the Allwinner boot ROM > enters the payload in AArch32 mode, but we want to compile and run the > SPL in AArch64. So we need some small ARM(32) stub to enter AArch64. > > Running the whole SPL in 32-bit is the other option which the later > patches enable, but I didn't want to call some 32-bit ARM > (cross-)compiler just for this handful of instructions in this case here. A comment stating that, and how to regenerate that part from a actual assembly source would be great. Maxime
diff --git a/arch/arm/include/asm/arch-sunxi/boot0.h b/arch/arm/include/asm/arch-sunxi/boot0.h index 6a13db5..7799a03 100644 --- a/arch/arm/include/asm/arch-sunxi/boot0.h +++ b/arch/arm/include/asm/arch-sunxi/boot0.h @@ -4,6 +4,33 @@ * SPDX-License-Identifier: GPL-2.0+ */ +#if defined(CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER) && !defined(CONFIG_SPL_BUILD) /* reserve space for BOOT0 header information */ b reset .space 1532 +#elif defined(CONFIG_ARM_BOOT_HOOK_RMR) +/* switch into AArch64 if needed */ + tst x0, x0 // this is "b #0x84" in ARM + b reset + .space 0x7c + .word 0xe59f1024 // ldr r1, [pc, #36] ; 0x170000a0 + .word 0xe59f0024 // ldr r0, [pc, #36] ; CONFIG_*_TEXT_BASE + .word 0xe5810000 // str r0, [r1] + .word 0xf57ff04f // dsb sy + .word 0xf57ff06f // isb sy + .word 0xee1c0f50 // mrc 15, 0, r0, cr12, cr0, {2} ; RMR + .word 0xe3800003 // orr r0, r0, #3 + .word 0xee0c0f50 // mcr 15, 0, r0, cr12, cr0, {2} ; RMR + .word 0xf57ff06f // isb sy + .word 0xe320f003 // wfi + .word 0xeafffffd // b @wfi + .word 0x017000a0 // writeable RVBAR mapping address +#ifdef CONFIG_SPL_BUILD + .word CONFIG_SPL_TEXT_BASE +#else + .word CONFIG_SYS_TEXT_BASE +#endif +#else +/* normal execution */ + b reset +#endif diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 0cd57a2..ba72e76 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -142,6 +142,11 @@ config RESERVE_ALLWINNER_BOOT0_HEADER blob relies on this information to load and execute U-Boot. Only needed on 64-bit Allwinner boards so far when using boot0. +config ARM_BOOT_HOOK_RMR + bool + default y if ARM64 + select ENABLE_ARM_SOC_BOOT0_HOOK + config DRAM_TYPE int "sunxi dram type" depends on MACH_SUN8I_A83T
The Allwinner A64 SoC starts execution in AArch32 mode, and both the boot ROM and Allwinner's boot0 keep running in this mode. So U-Boot gets entered in 32-bit, although we want it to run in AArch64. By using a "magic" instruction, which happens to be an almost-NOP in AArch64 and a branch in AArch32, we differentiate between being entered in 64-bit or 32-bit mode. If in 64-bit mode, we proceed with the branch to reset, but in 32-bit mode we trigger an RMR write to bring the core into AArch64/EL3 and re-enter U-Boot at CONFIG_SYS_TEXT_BASE. This allows a 64-bit U-Boot to be both entered in 32 and 64-bit mode, so we can use the same start code for the SPL and the U-Boot proper. We use the existing custom header (boot0.h) functionality, but restrict the existing boot0 header reservation to the non-SPL build now. A SPL wouldn't need such header anyway. This allows to have both options defined and lets us use one for the SPL and the other for U-Boot proper. Signed-off-by: Andre Przywara <andre.przywara@arm.com> --- arch/arm/include/asm/arch-sunxi/boot0.h | 27 +++++++++++++++++++++++++++ board/sunxi/Kconfig | 5 +++++ 2 files changed, 32 insertions(+)