From patchwork Tue Jun 30 10:33:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Roese X-Patchwork-Id: 243122 List-Id: U-Boot discussion From: sr at denx.de (Stefan Roese) Date: Tue, 30 Jun 2020 12:33:16 +0200 Subject: [PATCH v2 1/5] mips: Add CONFIG_MIPS_MACH_EARLY_INIT for very early mach init code In-Reply-To: <20200630103320.1290545-1-sr@denx.de> References: <20200630103320.1290545-1-sr@denx.de> Message-ID: <20200630103320.1290545-2-sr@denx.de> 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 Reviewed-by: Daniel Schwierzeck --- (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 From patchwork Tue Jun 30 10:33:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Roese X-Patchwork-Id: 243124 List-Id: U-Boot discussion From: sr at denx.de (Stefan Roese) Date: Tue, 30 Jun 2020 12:33:17 +0200 Subject: [PATCH v2 2/5] mips: octeon: use mips_mach_early_init() to copy to L2 cache In-Reply-To: <20200630103320.1290545-1-sr@denx.de> References: <20200630103320.1290545-1-sr@denx.de> Message-ID: <20200630103320.1290545-3-sr@denx.de> 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 --- 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) From patchwork Tue Jun 30 10:33:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Roese X-Patchwork-Id: 243123 List-Id: U-Boot discussion From: sr at denx.de (Stefan Roese) Date: Tue, 30 Jun 2020 12:33:18 +0200 Subject: [PATCH v2 3/5] mips: octeon: octeon_ebb7304: Change TEXT_BASE to L2 cache In-Reply-To: <20200630103320.1290545-1-sr@denx.de> References: <20200630103320.1290545-1-sr@denx.de> Message-ID: <20200630103320.1290545-4-sr@denx.de> 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 --- (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 From patchwork Tue Jun 30 10:33:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Roese X-Patchwork-Id: 243126 List-Id: U-Boot discussion From: sr at denx.de (Stefan Roese) Date: Tue, 30 Jun 2020 12:33:19 +0200 Subject: [PATCH v2 4/5] mips: cache: Make invalidate_dcache_range() weak to enable overwrite In-Reply-To: <20200630103320.1290545-1-sr@denx.de> References: <20200630103320.1290545-1-sr@denx.de> Message-ID: <20200630103320.1290545-5-sr@denx.de> 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 --- (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(); From patchwork Tue Jun 30 10:33:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Roese X-Patchwork-Id: 243125 List-Id: U-Boot discussion From: sr at denx.de (Stefan Roese) Date: Tue, 30 Jun 2020 12:33:20 +0200 Subject: [PATCH v2 5/5] mips: octeon: Add empty invalidate_dcache_range() In-Reply-To: <20200630103320.1290545-1-sr@denx.de> References: <20200630103320.1290545-1-sr@denx.de> Message-ID: <20200630103320.1290545-6-sr@denx.de> 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 --- (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) +{ +}