[PATCH 0/4] MIPS: refactor and cleanup start.S (part 1)

This is the first part of upcoming refactorings in start.S to cleanup the multiple and hard-to-follow code flows as well as adding more extension points required for modern and complex multi-core SoC's. The first parts concentrates on caches.
Daniel Schwierzeck (4): mips: start.S: remove dead code mips: add KSEG1 wrapper for change_k0_cca mips: refactor disabling of caches mips: add config options for generic cache setup code
arch/mips/Kconfig | 24 ++++++++++++++++++++++++ arch/mips/cpu/start.S | 24 +++++++++--------------- arch/mips/lib/cache_init.S | 38 ++++++++++++++++++++++++-------------- 3 files changed, 57 insertions(+), 29 deletions(-)

Since commit 703ec9ddf965 ("MIPS: Stop building position independent code") the relocation code was completely reworked and removed from start.S. Remove some left-overs of the old code.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
arch/mips/cpu/start.S | 9 --------- 1 file changed, 9 deletions(-)
diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S index 6de9a2f362..c3d1e64c1c 100644 --- a/arch/mips/cpu/start.S +++ b/arch/mips/cpu/start.S @@ -17,19 +17,10 @@ #endif
#ifdef CONFIG_32BIT -# define MIPS_RELOC 3 # define STATUS_SET 0 #endif
#ifdef CONFIG_64BIT -# ifdef CONFIG_SYS_LITTLE_ENDIAN -# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ - (((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym)) -# else -# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ - ((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24) -# endif -# define MIPS_RELOC MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03) # define STATUS_SET ST0_KX #endif

On 12.07.20 00:45, Daniel Schwierzeck wrote:
Since commit 703ec9ddf965 ("MIPS: Stop building position independent code") the relocation code was completely reworked and removed from start.S. Remove some left-overs of the old code.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
Reviewed-by: Stefan Roese sr@denx.de Tested-by: Stefan Roese sr@denx.de
Thanks, Stefan
arch/mips/cpu/start.S | 9 --------- 1 file changed, 9 deletions(-)
diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S index 6de9a2f362..c3d1e64c1c 100644 --- a/arch/mips/cpu/start.S +++ b/arch/mips/cpu/start.S @@ -17,19 +17,10 @@ #endif
#ifdef CONFIG_32BIT -# define MIPS_RELOC 3 # define STATUS_SET 0 #endif
#ifdef CONFIG_64BIT -# ifdef CONFIG_SYS_LITTLE_ENDIAN -# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
- (((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym))
-# else -# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
- ((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24)
-# endif -# define MIPS_RELOC MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03) # define STATUS_SET ST0_KX #endif
Viele Grüße, Stefan

change_k0_cca() is called multiple times. Move the code for changing to KSEG1 to a macro to avoid code duplication.
Also fix missing change to KSEG1 when changing to CONF_CM_CACHABLE_COW.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
arch/mips/lib/cache_init.S | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/arch/mips/lib/cache_init.S b/arch/mips/lib/cache_init.S index cfad1d9c8a..2233d27137 100644 --- a/arch/mips/lib/cache_init.S +++ b/arch/mips/lib/cache_init.S @@ -79,6 +79,21 @@ .set pop .endm
+ /* + * The changing of Kernel mode cacheability must be done from KSEG1. + * If the code is executing from KSEG0, jump to KSEG1 during the execution + * of change_k0_cca. change_k0_cca itself clears all hazards when returning. + */ + .macro change_k0_cca_kseg1 mode + PTR_LA t0, change_k0_cca + li t1, CPHYSADDR(~0) + and t0, t0, t1 + PTR_LI t1, CKSEG1 + or t0, t0, t1 + li a0, \mode + jalr t0 + .endm + /* * mips_cache_reset - low level initialisation of the primary caches * @@ -317,18 +332,9 @@ l1_init: sync
/* - * Enable use of the I-cache by setting Config.K0. The code for this - * must be executed from KSEG1. Jump from KSEG0 to KSEG1 to do this. - * Jump back to KSEG0 after caches are enabled and insert an - * instruction hazard barrier. + * Enable use of the I-cache by setting Config.K0. */ - PTR_LA t0, change_k0_cca - li t1, CPHYSADDR(~0) - and t0, t0, t1 - PTR_LI t1, CKSEG1 - or t0, t0, t1 - li a0, CONF_CM_CACHABLE_NONCOHERENT - jalr.hb t0 + change_k0_cca_kseg1 CONF_CM_CACHABLE_NONCOHERENT
/* * then initialize D-cache. @@ -388,9 +394,7 @@ l2_unbypass: beqz t0, 2f
/* Change Config.K0 to a coherent CCA */ - PTR_LA t0, change_k0_cca - li a0, CONF_CM_CACHABLE_COW - jalr t0 + change_k0_cca_kseg1 CONF_CM_CACHABLE_COW
/* * Join the coherent domain such that the caches of this core are kept

On 12.07.20 00:45, Daniel Schwierzeck wrote:
change_k0_cca() is called multiple times. Move the code for changing to KSEG1 to a macro to avoid code duplication.
Also fix missing change to KSEG1 when changing to CONF_CM_CACHABLE_COW.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
Reviewed-by: Stefan Roese sr@denx.de Tested-by: Stefan Roese sr@denx.de
Thanks, Stefan
arch/mips/lib/cache_init.S | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/arch/mips/lib/cache_init.S b/arch/mips/lib/cache_init.S index cfad1d9c8a..2233d27137 100644 --- a/arch/mips/lib/cache_init.S +++ b/arch/mips/lib/cache_init.S @@ -79,6 +79,21 @@ .set pop .endm
- /*
* The changing of Kernel mode cacheability must be done from KSEG1.
* If the code is executing from KSEG0, jump to KSEG1 during the execution
* of change_k0_cca. change_k0_cca itself clears all hazards when returning.
*/
- .macro change_k0_cca_kseg1 mode
- PTR_LA t0, change_k0_cca
- li t1, CPHYSADDR(~0)
- and t0, t0, t1
- PTR_LI t1, CKSEG1
- or t0, t0, t1
- li a0, \mode
- jalr t0
- .endm
- /*
- mips_cache_reset - low level initialisation of the primary caches
@@ -317,18 +332,9 @@ l1_init: sync
/*
* Enable use of the I-cache by setting Config.K0. The code for this
* must be executed from KSEG1. Jump from KSEG0 to KSEG1 to do this.
* Jump back to KSEG0 after caches are enabled and insert an
* instruction hazard barrier.
*/* Enable use of the I-cache by setting Config.K0.
- PTR_LA t0, change_k0_cca
- li t1, CPHYSADDR(~0)
- and t0, t0, t1
- PTR_LI t1, CKSEG1
- or t0, t0, t1
- li a0, CONF_CM_CACHABLE_NONCOHERENT
- jalr.hb t0
change_k0_cca_kseg1 CONF_CM_CACHABLE_NONCOHERENT
/*
- then initialize D-cache.
@@ -388,9 +394,7 @@ l2_unbypass: beqz t0, 2f
/* Change Config.K0 to a coherent CCA */
- PTR_LA t0, change_k0_cca
- li a0, CONF_CM_CACHABLE_COW
- jalr t0
change_k0_cca_kseg1 CONF_CM_CACHABLE_COW
/*
- Join the coherent domain such that the caches of this core are kept
Viele Grüße, Stefan

Logically this code belongs to cache_init.S.
If a complex SoC needs to replace the generic cache init, mips_cache_disable() can now be called from custom start.S files.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
arch/mips/cpu/start.S | 9 ++++----- arch/mips/lib/cache_init.S | 6 ++++++ 2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S index c3d1e64c1c..a9f8743717 100644 --- a/arch/mips/cpu/start.S +++ b/arch/mips/cpu/start.S @@ -196,11 +196,10 @@ wr_done: mtc0 zero, CP0_COMPARE
#ifndef CONFIG_SKIP_LOWLEVEL_INIT - mfc0 t0, CP0_CONFIG - and t0, t0, MIPS_CONF_IMPL - or t0, t0, CONF_CM_UNCACHED - mtc0 t0, CP0_CONFIG - ehb + /* Disable caches */ + PTR_LA t9, mips_cache_disable + jalr t9 + nop #endif
#ifdef CONFIG_MIPS_CM diff --git a/arch/mips/lib/cache_init.S b/arch/mips/lib/cache_init.S index 2233d27137..602741c65d 100644 --- a/arch/mips/lib/cache_init.S +++ b/arch/mips/lib/cache_init.S @@ -418,6 +418,12 @@ return: jr R_RETURN END(mips_cache_reset)
+LEAF(mips_cache_disable) + move R_RETURN, ra + change_k0_cca_kseg1 CONF_CM_UNCACHED + jr R_RETURN + END(mips_cache_disable) + LEAF(change_k0_cca) mfc0 t0, CP0_CONFIG #if __mips_isa_rev >= 2

On 12.07.20 00:45, Daniel Schwierzeck wrote:
Logically this code belongs to cache_init.S.
If a complex SoC needs to replace the generic cache init, mips_cache_disable() can now be called from custom start.S files.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
Reviewed-by: Stefan Roese sr@denx.de Tested-by: Stefan Roese sr@denx.de
Thanks, Stefan
arch/mips/cpu/start.S | 9 ++++----- arch/mips/lib/cache_init.S | 6 ++++++ 2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S index c3d1e64c1c..a9f8743717 100644 --- a/arch/mips/cpu/start.S +++ b/arch/mips/cpu/start.S @@ -196,11 +196,10 @@ wr_done: mtc0 zero, CP0_COMPARE
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
- mfc0 t0, CP0_CONFIG
- and t0, t0, MIPS_CONF_IMPL
- or t0, t0, CONF_CM_UNCACHED
- mtc0 t0, CP0_CONFIG
- ehb
/* Disable caches */
PTR_LA t9, mips_cache_disable
jalr t9
nop
#endif
#ifdef CONFIG_MIPS_CM
diff --git a/arch/mips/lib/cache_init.S b/arch/mips/lib/cache_init.S index 2233d27137..602741c65d 100644 --- a/arch/mips/lib/cache_init.S +++ b/arch/mips/lib/cache_init.S @@ -418,6 +418,12 @@ return: jr R_RETURN END(mips_cache_reset)
+LEAF(mips_cache_disable)
- move R_RETURN, ra
- change_k0_cca_kseg1 CONF_CM_UNCACHED
- jr R_RETURN
- END(mips_cache_disable)
- LEAF(change_k0_cca) mfc0 t0, CP0_CONFIG #if __mips_isa_rev >= 2
Viele Grüße, Stefan

Add an own Kconfig symbol for the initial disabling of caches invoked from generic start code.
Also add an own Kconfig symbols for the initialization of caches invoked from generic start code.
Until now both code paths could only be disabled with CONFIG_SKIP_LOWLEVEL_INIT. But this is not flexible enough for RAM boot scenarios like EJTAG or SPL payload or for machines which don't require cache initialization or which want to provide their own cache implementation.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
---
arch/mips/Kconfig | 24 ++++++++++++++++++++++++ arch/mips/cpu/start.S | 6 +++++- 2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 48e754cc46..eb00ee71bc 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -270,6 +270,30 @@ 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_CACHE_SETUP + bool "Allow generic start code to initialize and setup caches" + default n if SKIP_LOWLEVEL_INIT + default y + help + This allows the generic start code to invoke the generic initialization + of the CPU caches. Disabling this can be useful for RAM boot scenarios + (EJTAG, SPL payload) or for machines which don't need cache initialization + or which want to provide their own cache implementation. + + If unsure, say yes. + +config MIPS_CACHE_DISABLE + bool "Allow generic start code to initially disable caches" + default n if SKIP_LOWLEVEL_INIT + default y + help + This allows the generic start code to initially disable the CPU caches + and run uncached until the caches are initialized and enabled. Disabling + this can be useful on machines which don't need cache initialization or + which want to provide their own cache implementation. + + If unsure, say yes. + config MIPS_RELOCATION_TABLE_SIZE hex "Relocation table size" range 0x100 0x10000 diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S index a9f8743717..0c303031ad 100644 --- a/arch/mips/cpu/start.S +++ b/arch/mips/cpu/start.S @@ -195,7 +195,7 @@ wr_done: /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */ mtc0 zero, CP0_COMPARE
-#ifndef CONFIG_SKIP_LOWLEVEL_INIT +#ifdef CONFIG_MIPS_CACHE_DISABLE /* Disable caches */ PTR_LA t9, mips_cache_disable jalr t9 @@ -234,12 +234,16 @@ wr_done: jalr t9 nop # endif +#endif
+#ifdef CONFIG_MIPS_CACHE_SETUP /* Initialize caches... */ PTR_LA t9, mips_cache_reset jalr t9 nop +#endif
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT # ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD /* Initialize any external memory */ PTR_LA t9, lowlevel_init

On 12.07.20 00:45, Daniel Schwierzeck wrote:
Add an own Kconfig symbol for the initial disabling of caches invoked from generic start code.
Also add an own Kconfig symbols for the initialization of caches invoked from generic start code.
Until now both code paths could only be disabled with CONFIG_SKIP_LOWLEVEL_INIT. But this is not flexible enough for RAM boot scenarios like EJTAG or SPL payload or for machines which don't require cache initialization or which want to provide their own cache implementation.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
Reviewed-by: Stefan Roese sr@denx.de Tested-by: Stefan Roese sr@denx.de
Thanks, Stefan
arch/mips/Kconfig | 24 ++++++++++++++++++++++++ arch/mips/cpu/start.S | 6 +++++- 2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 48e754cc46..eb00ee71bc 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -270,6 +270,30 @@ 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_CACHE_SETUP
- bool "Allow generic start code to initialize and setup caches"
- default n if SKIP_LOWLEVEL_INIT
- default y
- help
This allows the generic start code to invoke the generic initialization
of the CPU caches. Disabling this can be useful for RAM boot scenarios
(EJTAG, SPL payload) or for machines which don't need cache initialization
or which want to provide their own cache implementation.
If unsure, say yes.
+config MIPS_CACHE_DISABLE
- bool "Allow generic start code to initially disable caches"
- default n if SKIP_LOWLEVEL_INIT
- default y
- help
This allows the generic start code to initially disable the CPU caches
and run uncached until the caches are initialized and enabled. Disabling
this can be useful on machines which don't need cache initialization or
which want to provide their own cache implementation.
If unsure, say yes.
- config MIPS_RELOCATION_TABLE_SIZE hex "Relocation table size" range 0x100 0x10000
diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S index a9f8743717..0c303031ad 100644 --- a/arch/mips/cpu/start.S +++ b/arch/mips/cpu/start.S @@ -195,7 +195,7 @@ wr_done: /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */ mtc0 zero, CP0_COMPARE
-#ifndef CONFIG_SKIP_LOWLEVEL_INIT +#ifdef CONFIG_MIPS_CACHE_DISABLE /* Disable caches */ PTR_LA t9, mips_cache_disable jalr t9 @@ -234,12 +234,16 @@ wr_done: jalr t9 nop # endif +#endif
+#ifdef CONFIG_MIPS_CACHE_SETUP /* Initialize caches... */ PTR_LA t9, mips_cache_reset jalr t9 nop +#endif
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT # ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD /* Initialize any external memory */ PTR_LA t9, lowlevel_init
Viele Grüße, Stefan
participants (2)
-
Daniel Schwierzeck
-
Stefan Roese