
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