[U-Boot] [PATCH v2 11/23] sunxi: A64: do an RMR switch if started in AArch32 mode

Andre Przywara andre.przywara at arm.com
Mon Dec 5 11:41:27 CET 2016


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 at 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 at 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 at 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
> 


More information about the U-Boot mailing list