diff mbox series

[RFC] sunxi: arm64: boot0.h: runtime check for RVBAR address

Message ID 20230405203011.10325-1-andre.przywara@arm.com
State Accepted
Delegated to: Andre Przywara
Headers show
Series [RFC] sunxi: arm64: boot0.h: runtime check for RVBAR address | expand

Commit Message

Andre Przywara April 5, 2023, 8:30 p.m. UTC
Some SoCs of the H616 family use a die variant, that puts some CPU power
and reset control registers at a different address. There are examples
of two instances of the same board, using different die revisions of the
otherwise same H313 SoC. We need to write to a register in that block
*very* early in the SPL boot, to switch the core to AArch64.

Since the devices are otherwise indistinguishable, let the SPL code read
that die variant and use the respective RVBAR address based on that.
That is a bit tricky, since we need to do that in hand-coded AArch32
machine language, shared by all 64-bit SoCs. To avoid build dependencies
in this mess, we always provide two addresses to choose from, and just
give identical values for all other SoCs. This allows the same code to
run on all 64-bit SoCs, and controls this switch behaviour purely from
Kconfig.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
Hi,

this patch goes on top of the two patches I sent earlier, that
introduce CONFIG_SUNXI_RVBAR_ADDRESS. I don't have a device with that
die variant, so just roughly tested this by inverting the ldrne and
swapping the addresses.
Please let me know if you have such a device and can confirm that this
code works on the original and alternative die alike.

Cheers,
Andre

 arch/arm/include/asm/arch-sunxi/boot0.h | 14 ++++++++++----
 arch/arm/mach-sunxi/Kconfig             | 17 ++++++++++++++++-
 2 files changed, 26 insertions(+), 5 deletions(-)

Comments

Jernej Škrabec April 8, 2023, 6:27 a.m. UTC | #1
Dne sreda, 05. april 2023 ob 22:30:11 CEST je Andre Przywara napisal(a):
> Some SoCs of the H616 family use a die variant, that puts some CPU power
> and reset control registers at a different address. There are examples
> of two instances of the same board, using different die revisions of the
> otherwise same H313 SoC. We need to write to a register in that block
> *very* early in the SPL boot, to switch the core to AArch64.
> 
> Since the devices are otherwise indistinguishable, let the SPL code read
> that die variant and use the respective RVBAR address based on that.
> That is a bit tricky, since we need to do that in hand-coded AArch32
> machine language, shared by all 64-bit SoCs. To avoid build dependencies
> in this mess, we always provide two addresses to choose from, and just
> give identical values for all other SoCs. This allows the same code to
> run on all 64-bit SoCs, and controls this switch behaviour purely from
> Kconfig.
> 
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
> Hi,
> 
> this patch goes on top of the two patches I sent earlier, that
> introduce CONFIG_SUNXI_RVBAR_ADDRESS. I don't have a device with that
> die variant, so just roughly tested this by inverting the ldrne and
> swapping the addresses.
> Please let me know if you have such a device and can confirm that this
> code works on the original and alternative die alike.
> 
> Cheers,
> Andre
> 
>  arch/arm/include/asm/arch-sunxi/boot0.h | 14 ++++++++++----
>  arch/arm/mach-sunxi/Kconfig             | 17 ++++++++++++++++-
>  2 files changed, 26 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-sunxi/boot0.h
> b/arch/arm/include/asm/arch-sunxi/boot0.h index 1a396f78488..b27df3b9b5e
> 100644
> --- a/arch/arm/include/asm/arch-sunxi/boot0.h
> +++ b/arch/arm/include/asm/arch-sunxi/boot0.h
> @@ -20,8 +20,8 @@
>  	b       reset
>  	.space  0x7c
> 
> -	.word	0xe28f0058	// add     r0, pc, #88
> -	.word	0xe59f1054	// ldr     r1, [pc, #84]
> +	.word	0xe28f0070	// add     r0, pc, #112	 // @(fel_stash - 
.)
> +	.word	0xe59f106c	// ldr     r1, [pc, #108] // fel_stash - .
>  	.word	0xe0800001	// add     r0, r0, r1
>  	.word	0xe580d000	// str     sp, [r0]
>  	.word	0xe580e004	// str     lr, [r0, #4]
> @@ -32,8 +32,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	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
> +	.word	0xe21000ff	// ands    r0, r0, #255    ; 0xff
> +	.word	0x159f102c	// ldrne   r1, [pc, #44] ; RVBAR_ALTERNATIVE
> +	.word	0xe59f002c	// ldr     r0, [pc, #44] ; CONFIG_*TEXT_BASE
>  	.word	0xe5810000	// str     r0, [r1]
>  	.word	0xf57ff04f	// dsb     sy
>  	.word	0xf57ff06f	// isb     sy
> @@ -45,6 +49,8 @@
>  	.word	0xeafffffd	// b       @wfi
> 
>  	.word	CONFIG_SUNXI_RVBAR_ADDRESS	// writable RVBAR 
mapping addr
> +	.word	SUNXI_SRAMC_BASE
> +	.word	CONFIG_SUNXI_RVBAR_ALTERNATIVE	// address for die 
variant
>  #ifdef CONFIG_SPL_BUILD
>  	.word	CONFIG_SPL_TEXT_BASE
>  #else
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index 0527b3863a7..be0910499bb 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -111,7 +111,7 @@ config SUNXI_SRAM_ADDRESS
>  	SRAM to a different address.
> 
>  config SUNXI_RVBAR_ADDRESS
> -	hex "RVBAR address"
> +	hex
>  	depends on ARM64
>  	default 0x09010040 if SUN50I_GEN_H6
>  	default 0x017000a0
> @@ -122,6 +122,21 @@ config SUNXI_RVBAR_ADDRESS
>  	entry point when switching to AArch64. This store is on different
>  	addresses, depending on the SoC.
> 
> +config SUNXI_RVBAR_ALTERNATIVE
> +	hex
> +	depends on ARM64
> +	default 0x81000040 if MACH_SUN50I_H616

As discussed on IRC by warpme, above default has a typo.

Apart from that, changes look good, so once fixed:
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>

Best regards,
Jernej

> +	default 0x09010040 if SUN50I_GEN_H6
> +	default 0x017000a0
> +	---help---
> +	The H616 die exists is at least two variants, with one having the
> +	RVBAR registers at a different address. If the SoC variant ID
> +	(stored in SRAM_VER_REG[7:0]) is not 0, we need to use the
> +	other address.
> +	Set this alternative address to the same as the normal address
> +	for all other SoCs, so the content of the SRAM_VER_REG becomes
> +	irrelevant there, and we can use the same code.
> +
>  config SUNXI_A64_TIMER_ERRATUM
>  	bool
diff mbox series

Patch

diff --git a/arch/arm/include/asm/arch-sunxi/boot0.h b/arch/arm/include/asm/arch-sunxi/boot0.h
index 1a396f78488..b27df3b9b5e 100644
--- a/arch/arm/include/asm/arch-sunxi/boot0.h
+++ b/arch/arm/include/asm/arch-sunxi/boot0.h
@@ -20,8 +20,8 @@ 
 	b       reset
 	.space  0x7c
 
-	.word	0xe28f0058	// add     r0, pc, #88
-	.word	0xe59f1054	// ldr     r1, [pc, #84]
+	.word	0xe28f0070	// add     r0, pc, #112	 // @(fel_stash - .)
+	.word	0xe59f106c	// ldr     r1, [pc, #108] // fel_stash - .
 	.word	0xe0800001	// add     r0, r0, r1
 	.word	0xe580d000	// str     sp, [r0]
 	.word	0xe580e004	// str     lr, [r0, #4]
@@ -32,8 +32,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	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
+	.word	0xe21000ff	// ands    r0, r0, #255    ; 0xff
+	.word	0x159f102c	// ldrne   r1, [pc, #44] ; RVBAR_ALTERNATIVE
+	.word	0xe59f002c	// ldr     r0, [pc, #44] ; CONFIG_*TEXT_BASE
 	.word	0xe5810000	// str     r0, [r1]
 	.word	0xf57ff04f	// dsb     sy
 	.word	0xf57ff06f	// isb     sy
@@ -45,6 +49,8 @@ 
 	.word	0xeafffffd	// b       @wfi
 
 	.word	CONFIG_SUNXI_RVBAR_ADDRESS	// writable RVBAR mapping addr
+	.word	SUNXI_SRAMC_BASE
+	.word	CONFIG_SUNXI_RVBAR_ALTERNATIVE	// address for die variant
 #ifdef CONFIG_SPL_BUILD
 	.word	CONFIG_SPL_TEXT_BASE
 #else
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 0527b3863a7..be0910499bb 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -111,7 +111,7 @@  config SUNXI_SRAM_ADDRESS
 	SRAM to a different address.
 
 config SUNXI_RVBAR_ADDRESS
-	hex "RVBAR address"
+	hex
 	depends on ARM64
 	default 0x09010040 if SUN50I_GEN_H6
 	default 0x017000a0
@@ -122,6 +122,21 @@  config SUNXI_RVBAR_ADDRESS
 	entry point when switching to AArch64. This store is on different
 	addresses, depending on the SoC.
 
+config SUNXI_RVBAR_ALTERNATIVE
+	hex
+	depends on ARM64
+	default 0x81000040 if MACH_SUN50I_H616
+	default 0x09010040 if SUN50I_GEN_H6
+	default 0x017000a0
+	---help---
+	The H616 die exists is at least two variants, with one having the
+	RVBAR registers at a different address. If the SoC variant ID
+	(stored in SRAM_VER_REG[7:0]) is not 0, we need to use the
+	other address.
+	Set this alternative address to the same as the normal address
+	for all other SoCs, so the content of the SRAM_VER_REG becomes
+	irrelevant there, and we can use the same code.
+
 config SUNXI_A64_TIMER_ERRATUM
 	bool