Because the Allwinner BootROM always runs in AArch32, even on ARMv8 SoCs, we need to switch to AArch64 first, but also need to save the CPU state, when we later may need to return to the BootROM, for continuing with the FEL USB protocol. This is done in 32-bit code, which we include into the AArch64 boot assembly file as a series of .word directives, containing the encoded AArch32 instructions. To be able to change and verify that code, we also kept an assembly file with the respective 32-bit code, but just for reference.
As this code is never compiled or assembled - it's just for documentation - it became stale over time: we didn't really update this along with the changes we made to the boot code. In particular the FEL save code was completely missing. Update that 32-bit assembly file, to match the current version used in boot0.h, including the FEL save routine. Also update the build instructions in the comments, to give people an actual chance to assemble this code. Signed-off-by: Andre Przywara <andre.przyw...@arm.com> --- arch/arm/mach-sunxi/rmr_switch.S | 40 +++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-sunxi/rmr_switch.S b/arch/arm/mach-sunxi/rmr_switch.S index 33e55d49686..422007c985b 100644 --- a/arch/arm/mach-sunxi/rmr_switch.S +++ b/arch/arm/mach-sunxi/rmr_switch.S @@ -16,7 +16,9 @@ @ the machine code must be inserted as verbatim .word statements into the @ beginning of the AArch64 U-Boot code. @ To get the encoded bytes, use: -@ ${CROSS_COMPILE}gcc -c -o rmr_switch.o rmr_switch.S +@ ${CROSS_COMPILE}gcc -c -Iinclude -Iarch/arm/include \ +@ -D__ASSEMBLY__ -DCONFIG_ARM64 \ +@ -o rmr_switch.o arch/arm/mach-sunxi/rmr_switch.S @ ${CROSS_COMPILE}objdump -d rmr_switch.o @ @ The resulting words should be inserted into the U-Boot file at @@ -29,14 +31,40 @@ #include <config.h> .text + b start32 // this is "tst x0, x0" in AArch64 + .word 0x14000047 // this is "b reset" in AArch64 -#ifndef CONFIG_SUN50I_GEN_H6 - ldr r1, =0x017000a0 @ MMIO mapped RVBAR[0] register + .space 0x78 // gap distance set by the common + // encoding of the first instruction +fel_stash_addr: + .word fel_stash - . // distance to fel_stash buffer + +start32: + adr r0, fel_stash_addr // absolute location of fel_stash_addr + ldr r1, fel_stash_addr // distance to actual fel_stash + add r0, r0, r1 // real address of fel_stash + + /* save the current state as needed by the BROM for a later return */ + str sp, [r0] + str lr, [r0, #4] + mrs lr, CPSR + str lr, [r0, #8] + mrc p15, 0, lr, cr1, cr0, 0 // SCTLR + str lr, [r0, #12] + mrc p15, 0, lr, cr12, cr0, 0 // VBAR + str lr, [r0, #16] + + ldr r1, =CONFIG_SUNXI_RVBAR_ADDRESS + ldr r0, =SUNXI_SRAMC_BASE + ldr r0, [r0, #36] // SRAM_VER_REG + ands r0, r0, #0xff + ldrne r1, =CONFIG_SUNXI_RVBAR_ALTERNATIVE +#ifdef CONFIG_XPL_BUILD + ldr r0, =CONFIG_SPL_TEXT_BASE #else - ldr r1, =0x09010040 @ MMIO mapped RVBAR[0] register + ldr r0, =CONFIG_TEXT_BASE #endif - ldr r0, =0x57aA7add @ start address, to be replaced - str r0, [r1] + str r0, [r1] // store start address in RVBAR dsb sy isb sy mrc 15, 0, r0, cr12, cr0, 2 @ read RMR register -- 2.46.3