[PATCH v2 0/5] mips: Improve initial Octeon MIPS64 support

This patchset improves the Octeon base support by adding a very early copy of the U-Boot image from bootspace (e.g. parallel NOR CFI flash) to the L2 cache and continue execution there.
This is done by introducing the optional hook mips_mach_early_init() to start.S for very early machine specific code. This code can be selected via the new Kconfig symbol CONFIG_MIPS_MACH_EARLY_INIT.
Additionally, the common invalidate_dcache_range() implementation is also changed to a weak function allowing Octeon to adds its own no-op cache function (Octeon is cache coherent).
This patchset is based on the base Octeon patchsert in v4.
Thanks, Stefan
Changes in v2: - Change mips_mach_early_init() as suggested by Daniel to make it easier to understand and smaller - Drop CONFIG_BOARD_SIZE_LIMIT
Stefan Roese (5): mips: Add CONFIG_MIPS_MACH_EARLY_INIT for very early mach init code mips: octeon: use mips_mach_early_init() to copy to L2 cache mips: octeon: octeon_ebb7304: Change TEXT_BASE to L2 cache mips: cache: Make invalidate_dcache_range() weak to enable overwrite mips: octeon: Add empty invalidate_dcache_range()
arch/mips/Kconfig | 10 ++++++ arch/mips/cpu/start.S | 5 +++ arch/mips/lib/cache.c | 2 +- arch/mips/mach-octeon/cache.c | 4 +++ arch/mips/mach-octeon/lowlevel_init.S | 50 +++++++++++++++++++++++++++ configs/octeon_ebb7304_defconfig | 3 +- 6 files changed, 72 insertions(+), 2 deletions(-)

This patch adds the optional call to mips_mach_early_init() to start.S at a very early stage. Its disabled per default. It can be used for very early machine / platform specific init code. Its called very early and at this stage the PC is allowed to differ from the linking address (CONFIG_TEXT_BASE) as no absolute jump has been performed until this call.
It will be used by thje Octeon platform.
Signed-off-by: Stefan Roese sr@denx.de Reviewed-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
(no changes since v1)
arch/mips/Kconfig | 9 +++++++++ arch/mips/cpu/start.S | 5 +++++ 2 files changed, 14 insertions(+)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index dd56da6dae..327fd4848a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -296,6 +296,15 @@ config MIPS_CACHE_INDEX_BASE Normally this is CKSEG0. If the MIPS system needs to move this block to some SRAM or ScratchPad RAM, adapt this option accordingly.
+config MIPS_MACH_EARLY_INIT + bool "Enable mach specific very early init code" + help + Use this to enable the call to mips_mach_early_init() very early + from start.S. This function can be used e.g. to do some very early + CPU / SoC intitialization or image copying. Its called very early + and at this stage the PC might not match the linking address + (CONFIG_TEXT_BASE) - no absolute jump done until this call. + config MIPS_CACHE_SETUP bool "Enable startup code to initialize and setup caches" default n if SKIP_LOWLEVEL_INIT diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S index 08dddbdf5f..a7190ec3b2 100644 --- a/arch/mips/cpu/start.S +++ b/arch/mips/cpu/start.S @@ -195,6 +195,11 @@ wr_done: /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */ mtc0 zero, CP0_COMPARE
+#ifdef CONFIG_MIPS_MACH_EARLY_INIT + bal mips_mach_early_init + nop +#endif + #ifdef CONFIG_MIPS_CACHE_SETUP /* Disable caches */ PTR_LA t9, mips_cache_disable

This patch adds the code to copy itself from bootrom location to a different location (TEXT_BASE) to the Octeon platform. Its used in this case to copy the complete U-Boot image into L2 cache, which greatly improves the bootup time - especially in regard to the very long and complex DDR4 init code.
The Kconfig symbol CONFIG_MIPS_MACH_EARLY_INIT is enabled with this patch for Octeon.
Signed-off-by: Stefan Roese sr@denx.de
---
Changes in v2: - Change mips_mach_early_init() as suggested by Daniel to make it easier to understand and smaller - Drop CONFIG_BOARD_SIZE_LIMIT
arch/mips/Kconfig | 1 + arch/mips/mach-octeon/lowlevel_init.S | 50 +++++++++++++++++++++++++++ 2 files changed, 51 insertions(+)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 327fd4848a..bcf6f26457 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -114,6 +114,7 @@ config ARCH_OCTEON select DM select DM_SERIAL select MIPS_L2_CACHE + select MIPS_MACH_EARLY_INIT select MIPS_TUNE_OCTEON3 select ROM_EXCEPTION_VECTORS select SUPPORTS_BIG_ENDIAN diff --git a/arch/mips/mach-octeon/lowlevel_init.S b/arch/mips/mach-octeon/lowlevel_init.S index d9aab38cde..fa87cb4e34 100644 --- a/arch/mips/mach-octeon/lowlevel_init.S +++ b/arch/mips/mach-octeon/lowlevel_init.S @@ -17,3 +17,53 @@ LEAF(lowlevel_init) jr ra nop END(lowlevel_init) + +LEAF(mips_mach_early_init) + + move s0, ra + + bal __dummy + nop + +__dummy: + /* Get the actual address that we are running at */ + PTR_LA a7, __dummy + dsubu t3, ra, a7 /* t3 now has reloc offset */ + + PTR_LA t1, _start + daddu t0, t1, t3 /* t0 now has actual address of _start */ + + /* Calculate end address of copy loop */ + PTR_LA t2, _end + daddiu t2, t2, 0x4000 /* Increase size to include appended DTB */ + daddiu t2, t2, 127 + ins t2, zero, 0, 7 /* Round up to cache line for memcpy */ + + /* Copy ourself to the L2 cache from flash, 32 bytes at a time */ +1: + ld a0, 0(t0) + ld a1, 8(t0) + ld a2, 16(t0) + ld a3, 24(t0) + sd a0, 0(t1) + sd a1, 8(t1) + sd a2, 16(t1) + sd a3, 24(t1) + addiu t0, 32 + addiu t1, 32 + bne t1, t2, 1b + nop + + sync + + /* + * Return to start.S now running from TEXT_BASE, which points + * to DRAM address space, which effectively is L2 cache now. + * This speeds up the init process extremely, especially the + * DDR init code. + */ + dsubu s0, s0, t3 /* Fixup return address with reloc offset */ + jr.hb s0 /* Jump back with hazard barrier */ + nop + + END(mips_mach_early_init)

Change the linking address (TEXT_BASE) to point to the L2 cache. This way, mips_mach_early_init() will copy itself into L2 cache and run from there to improve the bootup speed.
Also CONFIG_MIPS_CACHE_SETUP needs to be disabled, as now the cache is used at this time and can't be resetted.
Signed-off-by: Stefan Roese sr@denx.de ---
(no changes since v1)
configs/octeon_ebb7304_defconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/configs/octeon_ebb7304_defconfig b/configs/octeon_ebb7304_defconfig index 0304b1ef8d..dc80fba848 100644 --- a/configs/octeon_ebb7304_defconfig +++ b/configs/octeon_ebb7304_defconfig @@ -1,5 +1,5 @@ CONFIG_MIPS=y -CONFIG_SYS_TEXT_BASE=0xffffffffbfc00000 +CONFIG_SYS_TEXT_BASE=0xffffffff80000000 CONFIG_SYS_MALLOC_F_LEN=0x4000 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_SECT_SIZE=0x10000 @@ -7,6 +7,7 @@ CONFIG_NR_DRAM_BANKS=2 CONFIG_DEBUG_UART_BASE=0x8001180000000800 CONFIG_DEBUG_UART_CLOCK=1200000000 CONFIG_ARCH_OCTEON=y +# CONFIG_MIPS_CACHE_SETUP is not set CONFIG_DEBUG_UART=y CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_HUSH_PARSER=y

This patch adds __weak to invalidate_dcache_range() in lib/cache.c. This makes it possible to overwrite this function by a platforms specific version, which will be done for Octeon.
Signed-off-by: Stefan Roese sr@denx.de ---
(no changes since v1)
arch/mips/lib/cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/mips/lib/cache.c b/arch/mips/lib/cache.c index ad37f05802..cf29994a7a 100644 --- a/arch/mips/lib/cache.c +++ b/arch/mips/lib/cache.c @@ -159,7 +159,7 @@ void __weak flush_dcache_range(ulong start_addr, ulong stop) sync(); }
-void invalidate_dcache_range(ulong start_addr, ulong stop) +void __weak invalidate_dcache_range(ulong start_addr, ulong stop) { unsigned long lsize = dcache_line_size(); unsigned long slsize = scache_line_size();

This patch adds __weak to invalidate_dcache_range() in lib/cache.c. This makes it possible to overwrite this function by a platforms specific version, which will be done for Octeon.
Signed-off-by: Stefan Roese sr@denx.de
(no changes since v1)
arch/mips/lib/cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
applied to u-boot-mips/next, thanks.
Stefan, I'll apply the two Octeon MIPS64 base support series after I have applied my start.S refactoring and header sync series.

Hi Daniel,
On 12.07.20 00:45, Daniel Schwierzeck wrote:
This patch adds __weak to invalidate_dcache_range() in lib/cache.c. This makes it possible to overwrite this function by a platforms specific version, which will be done for Octeon.
Signed-off-by: Stefan Roese sr@denx.de
(no changes since v1)
arch/mips/lib/cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
applied to u-boot-mips/next, thanks.
Stefan, I'll apply the two Octeon MIPS64 base support series after I have applied my start.S refactoring and header sync series.
Thanks a lot.
Thanks, Stefan

As Octeon is cache coherent, lets add an empty version of invalidate_dcache_range(). With this, all global cache functions are replaced by no-ops on Octeon.
Signed-off-by: Stefan Roese sr@denx.de
---
(no changes since v1)
arch/mips/mach-octeon/cache.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/mips/mach-octeon/cache.c b/arch/mips/mach-octeon/cache.c index bea846d757..9a88bb97c7 100644 --- a/arch/mips/mach-octeon/cache.c +++ b/arch/mips/mach-octeon/cache.c @@ -18,3 +18,7 @@ void flush_dcache_range(ulong start_addr, ulong stop) void flush_cache(ulong start_addr, ulong size) { } + +void invalidate_dcache_range(ulong start_addr, ulong stop) +{ +}
participants (2)
-
Daniel Schwierzeck
-
Stefan Roese