]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
sunxi: armv8: FEL: save and restore GICv3 registers
authorAndre Przywara <andre.przywara@arm.com>
Sun, 5 Jan 2025 21:51:59 +0000 (21:51 +0000)
committerTom Rini <trini@konsulko.com>
Mon, 28 Apr 2025 18:45:44 +0000 (12:45 -0600)
To be able to return to the BootROM FEL USB debug code, we must restore
the core's state as accurately as possible after the SPL has been run.
Since the BootROM runs in AArch32, but the SPL uses AArch64, this requires
a core reset, which clears the core's state.
So far we were saving and restoring the required registers like SCTLR
and VBAR, but could ignore the interrupt controller's state (GICC), since
that lives in MMIO registers, unaffected by a core reset.
Newer Allwinner SoCs now feature a GICv3 interrupt controller, which keeps
some GIC state in architected system registers, and those are cleared
when we switch back to AArch32.

To enable FEL operation on the Allwinner A523 SoC,
Add AArch32 assembly code to save and restore the ICC_PMR and ICC_IGRPEN1
system registers. The other GICv3 sysregs are either not relevant for the
BROM operation, or haven't been changed from their reset defaults by the
BROM anyway.

This enables FEL operation on the Allwinner A523 family of SoCs.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
arch/arm/cpu/armv8/fel_utils.S
arch/arm/include/asm/arch-sunxi/boot0.h
arch/arm/mach-sunxi/board.c
arch/arm/mach-sunxi/rmr_switch.S

index f7707acdf1ae59dd2ec81685830709c7128d0bde..f9d0c9e1d0aabad6920f8609b2da580159841524 100644 (file)
@@ -79,5 +79,12 @@ back_in_32:
        .word   0xe590100c      // ldr  r1, [r0, #12]
        .word   0xee011f10      // mcr  15, 0, r1, cr1, cr0, {0}  ; SCTLR
        .word   0xf57ff06f      // isb
+#ifdef CONFIG_MACH_SUN55I_A523
+       .word   0xe5901014      // ldr  r1, [r0, #20]
+       .word   0xee041f16      // mcr  15, 0, r1, cr4, cr6, {0}; ICC_PMR
+       .word   0xe5901018      // ldr  r1, [r0, #24]
+       .word   0xee0c1ffc      // mcr  15, 0, r1, cr12, cr12, {7}; ICC_IGRPEN1
+#endif
+
        .word   0xe12fff1e      // bx   lr              ; return to FEL
 ENDPROC(return_to_fel)
index 24c81391d5814b88fe945899c55c58553fa49ab0..9baedc2e9af190a00f46a5ddecb72c8d0f9e0392 100644 (file)
        .word   0xe580e00c      // str     lr, [r0, #12]
        .word   0xee1cef10      // mrc     15, 0, lr, cr12, cr0, {0}
        .word   0xe580e010      // str     lr, [r0, #16]
-
+#ifdef CONFIG_MACH_SUN55I_A523
+       .word   0xee1cefbc      // mrc     15, 0, lr, cr12, cr12, {5}
+       .word   0xe31e0001      // tst     lr, #1
+       .word   0x0a000003      // beq     cc <start32+0x48>
+       .word   0xee14ef16      // mrc     15, 0, lr, cr4, cr6, {0}
+       .word   0xe580e014      // str     lr, [r0, #20]
+       .word   0xee1ceffc      // mrc     15, 0, lr, cr12, cr12, {7}
+       .word   0xe580e018      // str     lr, [r0, #24]
+#endif
        .word   0xe59f1034      // ldr     r1, [pc, #52] ; RVBAR_ADDRESS
        .word   0xe59f0034      // ldr     r0, [pc, #52] ; SUNXI_SRAMC_BASE
        .word   0xe5900024      // ldr     r0, [r0, #36] ; SRAM_VER_REG
index 701899ee4b2a206fb396bd935300773cc017fa4a..d1ad72ed368e31622db77e419a3821b460302954 100644 (file)
@@ -35,6 +35,8 @@ struct fel_stash {
        uint32_t cpsr;
        uint32_t sctlr;
        uint32_t vbar;
+       uint32_t icc_pmr;
+       uint32_t icc_igrpen1;
 };
 
 struct fel_stash fel_stash __section(".data");
index 422007c985b6eb98a7d9d8e8b7e5a415e0ae6eae..de284c16b0be16e441a8322d9ba103579948a1f1 100644 (file)
@@ -53,6 +53,16 @@ start32:
        str     lr, [r0, #12]
        mrc     p15, 0, lr, cr12, cr0, 0        // VBAR
        str     lr, [r0, #16]
+//#ifdef CONFIG_MACH_SUN55I_A523
+       mrc     p15, 0, lr, cr12, cr12, 5       // ICC_SRE
+       tst     lr, #1
+       beq     1f
+       mrc     p15, 0, lr, c4, c6, 0           // ICC_PMR
+       str     lr, [r0, #20]
+       mrc     p15, 0, lr, c12, c12, 7         // ICC_IGRPEN1
+       str     lr, [r0, #24]
+1:
+//#endif
 
        ldr     r1, =CONFIG_SUNXI_RVBAR_ADDRESS
        ldr     r0, =SUNXI_SRAMC_BASE