On 19/11/2020 19:59, Priit Laes wrote:
> On Thu, Nov 19, 2020 at 10:54:42AM +0000, Andre Przywara wrote:
>> So far we did not support the BootROM based FEL USB debug mode on the
>> 64-bit builds for Allwinner SoCs: The BootROM is using AArch32, but the
>> SPL runs in AArch64.
>> Returning back to AArch32 was not working as expected, since the RMR
>> reset into 32-bit mode always starts execution in the BootROM, but not
>> in the FEL routine.
>>
>> After some debug and research and with help via IRC, the CPU hotplug
>> mechanism emerged as a solution: If a certain R_CPUCFG register contains
>> some magic, the BootROM will immediately branch to an address stored in
>> some other register. This works well for our purposes.
>>
>> Enable the FEL feature by providing early AArch32 code to first save the
>> FEL state, *before* initially entering AArch64.
>> If we eventually determine that we should return to FEL, we reset back
>> into AArch32, and use the CPU hotplug mechanism to run some small
>> AArch32 code snippet that restores the initially saved FEL state.
>>
>> That allows the normal AArch64 SPL build to be loaded via the sunxi-fel
>> tool, with it returning into FEL mode, so that other payloads can be
>> transferred via FEL as well.
>>
>> Tested on A64, H5 and H6.
>>
>> Signed-off-by: Andre Przywara <andre.przyw...@arm.com>
>> ---
>>  arch/arm/cpu/armv8/Makefile             |  2 +
>>  arch/arm/cpu/armv8/fel_utils.S          | 78 +++++++++++++++++++++++++
>>  arch/arm/include/asm/arch-sunxi/boot0.h | 14 +++++
>>  include/configs/sunxi-common.h          |  2 -
>>  4 files changed, 94 insertions(+), 2 deletions(-)
>>  create mode 100644 arch/arm/cpu/armv8/fel_utils.S
> 
> Don't you want to also update board/sunxi/README.sunxi64 ?

Yes, but I am in the process of rewriting this anyway, since some parts
apply to 32-bit SoCs as well (SD card, SPI flash), and there is
currently no documentation about them. So bear with me, I will post a
documentation update ASAP, just didn't want to hold back this patch.

Thanks!
Andre.

>>
>> diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
>> index 93d26f98568..f7b4a5ee46c 100644
>> --- a/arch/arm/cpu/armv8/Makefile
>> +++ b/arch/arm/cpu/armv8/Makefile
>> @@ -27,6 +27,8 @@ obj-$(CONFIG_ARM_SMCCC)            += smccc-call.o
>>  
>>  ifndef CONFIG_SPL_BUILD
>>  obj-$(CONFIG_ARMV8_SPIN_TABLE) += spin_table.o spin_table_v8.o
>> +else
>> +obj-$(CONFIG_ARCH_SUNXI) += fel_utils.o
>>  endif
>>  obj-$(CONFIG_$(SPL_)ARMV8_SEC_FIRMWARE_SUPPORT) += sec_firmware.o 
>> sec_firmware_asm.o
>>  
>> diff --git a/arch/arm/cpu/armv8/fel_utils.S b/arch/arm/cpu/armv8/fel_utils.S
>> new file mode 100644
>> index 00000000000..334fdef7fa0
>> --- /dev/null
>> +++ b/arch/arm/cpu/armv8/fel_utils.S
>> @@ -0,0 +1,78 @@
>> +/*
>> + * Utility functions for FEL mode, when running SPL in AArch64.
>> + *
>> + * Copyright (c) 2017 Arm Ltd.
>> + *
>> + * SPDX-License-Identifier: GPL-2.0+
>> + */
>> +
>> +#include <asm-offsets.h>
>> +#include <config.h>
>> +#include <asm/system.h>
>> +#include <linux/linkage.h>
>> +
>> +/*
>> + * We don't overwrite save_boot_params() here, to save the FEL state upon
>> + * entry, since this would run *after* the RMR reset, which clobbers that
>> + * state.
>> + * Instead we store the state _very_ early in the boot0 hook, *before*
>> + * resetting to AArch64.
>> + */
>> +
>> +/*
>> + * The FEL routines in BROM run in AArch32.
>> + * Reset back into 32-bit mode here and restore the saved FEL state
>> + * afterwards.
>> + * Resetting back into AArch32/EL3 using the RMR always enters the BROM,
>> + * but we can use the CPU hotplug mechanism to branch back to our code
>> + * immediately.
>> + */
>> +ENTRY(return_to_fel)
>> +    /*
>> +     * the RMR reset will clear all registers, so save the arguments
>> +     * (LR and SP) in the fel_stash structure, which we read anyways later
>> +     */
>> +    adr     x2, fel_stash
>> +    str     w0, [x2]
>> +    str     w1, [x2, #4]
>> +
>> +    adr     x1, fel_stash_addr      // to find the fel_stash address in AA32
>> +    str     w2, [x1]
>> +
>> +    ldr     x0, =0xfa50392f         // CPU hotplug magic
>> +#ifndef CONFIG_MACH_SUN50I_H6
>> +    ldr     x2, =(SUNXI_CPUCFG_BASE + 0x1a4) // offset for CPU hotplug base
>> +    str     w0, [x2, #0x8]
>> +#else
>> +    ldr     x2, =(SUNXI_RTC_BASE + 0x1b8)   // BOOT_CPU_HP_FLAG_REG
>> +    str     w0, [x2], #0x4
>> +#endif
>> +    adr     x0, back_in_32
>> +    str     w0, [x2]
>> +
>> +    dsb     sy
>> +    isb     sy
>> +    mov     x0, #2                  // RMR reset into AArch32
>> +    dsb     sy
>> +    msr     RMR_EL3, x0
>> +    isb     sy
>> +1:  wfi
>> +    b       1b
>> +
>> +/* AArch32 code to restore the state from fel_stash and return back to FEL. 
>> */
>> +back_in_32:
>> +    .word   0xe59f0028      // ldr  r0, [pc, #40]   ; load fel_stash address
>> +    .word   0xe5901008      // ldr  r1, [r0, #8]
>> +    .word   0xe129f001      // msr  CPSR_fc, r1
>> +    .word   0xf57ff06f      // isb
>> +    .word   0xe590d000      // ldr  sp, [r0]
>> +    .word   0xe590e004      // ldr  lr, [r0, #4]
>> +    .word   0xe5901010      // ldr  r1, [r0, #16]
>> +    .word   0xee0c1f10      // mcr  15, 0, r1, cr12, cr0, {0} ; VBAR
>> +    .word   0xe590100c      // ldr  r1, [r0, #12]
>> +    .word   0xee011f10      // mcr  15, 0, r1, cr1, cr0, {0}  ; SCTLR
>> +    .word   0xf57ff06f      // isb
>> +    .word   0xe12fff1e      // bx   lr              ; return to FEL
>> +fel_stash_addr:
>> +    .word   0x00000000      // receives fel_stash addr, by AA64 code above
>> +ENDPROC(return_to_fel)
>> diff --git a/arch/arm/include/asm/arch-sunxi/boot0.h 
>> b/arch/arm/include/asm/arch-sunxi/boot0.h
>> index 54c144afd8c..46d0f0666c2 100644
>> --- a/arch/arm/include/asm/arch-sunxi/boot0.h
>> +++ b/arch/arm/include/asm/arch-sunxi/boot0.h
>> @@ -15,6 +15,19 @@
>>      tst     x0, x0                  // this is "b #0x84" in ARM
>>      b       reset
>>      .space  0x7c
>> +
>> +    .word   0xe28f0058      // add     r0, pc, #88
>> +    .word   0xe59f1054      // ldr     r1, [pc, #84]
>> +    .word   0xe0800001      // add     r0, r0, r1
>> +    .word   0xe580d000      // str     sp, [r0]
>> +    .word   0xe580e004      // str     lr, [r0, #4]
>> +    .word   0xe10fe000      // mrs     lr, CPSR
>> +    .word   0xe580e008      // str     lr, [r0, #8]
>> +    .word   0xee11ef10      // mrc     15, 0, lr, cr1, cr0, {0}
>> +    .word   0xe580e00c      // str     lr, [r0, #12]
>> +    .word   0xee1cef10      // mrc     15, 0, lr, cr12, cr0, {0}
>> +    .word   0xe580e010      // str     lr, [r0, #16]
>> +
>>      .word   0xe59f1024      // ldr     r1, [pc, #36] ; 0x170000a0
>>      .word   0xe59f0024      // ldr     r0, [pc, #36] ; CONFIG_*_TEXT_BASE
>>      .word   0xe5810000      // str     r0, [r1]
>> @@ -36,6 +49,7 @@
>>  #else
>>      .word   CONFIG_SYS_TEXT_BASE
>>  #endif
>> +    .word   fel_stash - .
>>  #else
>>  /* normal execution */
>>      b       reset
>> diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
>> index a6a4879523a..203cb10fbab 100644
>> --- a/include/configs/sunxi-common.h
>> +++ b/include/configs/sunxi-common.h
>> @@ -163,9 +163,7 @@
>>  
>>  #define CONFIG_SYS_MONITOR_LEN              (768 << 10)     /* 768 KiB */
>>  
>> -#ifndef CONFIG_ARM64                /* AArch64 FEL support is not ready yet 
>> */
>>  #define CONFIG_SPL_BOARD_LOAD_IMAGE
>> -#endif
>>  
>>  /*
>>   * We cannot use expressions here, because expressions won't be evaluated in
>> -- 
>> 2.17.5
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "linux-sunxi" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to linux-sunxi+unsubscr...@googlegroups.com.
>> To view this discussion on the web, visit 
>> https://groups.google.com/d/msgid/linux-sunxi/20201119105442.24711-1-andre.przywara%40arm.com.

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/0fd3cbb4-a2c9-85d5-5fbd-057bb654863d%40arm.com.

Reply via email to