From acc7d9bd3cd833ff6600a522e1415d5b0b405316 Mon Sep 17 00:00:00 2001 From: "Daniel P. Carvalho" Date: Sun, 4 Oct 2026 00:54:54 -0300 Subject: [PATCH] arch/mips/pic32mz: initialize both L1 caches when KSEG0 is cacheable. The Config.K0 cache algorithm applies to both the I- and the D-Cache, but the startup code only initialized the tags of the caches that were selected in Kconfig. With only MIPS32_ICACHE the D-Cache was enabled with indeterminate tags. Initialize the tags of both caches whenever K0 is made cacheable (like the XC32 startup code does), and add the missing hazard barrier after writing Config. MIPS32_ICACHE now selects MIPS32_DCACHE when the chip has one, so that the D-Cache maintenance needed for DMA is built whenever the D-Cache is in use. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Daniel P. Carvalho --- arch/mips/src/mips32/Kconfig | 7 ++++-- arch/mips/src/pic32mz/pic32mz_head.S | 36 +++++++++++++++++----------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/arch/mips/src/mips32/Kconfig b/arch/mips/src/mips32/Kconfig index c30962ed7b2..efa9f924e9a 100644 --- a/arch/mips/src/mips32/Kconfig +++ b/arch/mips/src/mips32/Kconfig @@ -119,8 +119,10 @@ config MIPS32_ICACHE default n depends on MIPS32_HAVE_ICACHE select ARCH_ICACHE + select MIPS32_DCACHE if MIPS32_HAVE_DCACHE ---help--- - Enable K0 I-Cache + Enable K0 I-Cache. The K0 cache algorithm applies to both caches, + so this also enables the D-Cache when there is one. config MIPS32_ICACHE_SIZE int "I-Cache Size" @@ -149,7 +151,8 @@ config MIPS32_DCACHE depends on MIPS32_HAVE_DCACHE select ARCH_DCACHE ---help--- - Enable K0 D-Cache + Enable K0 D-Cache. The K0 cache algorithm applies to both caches, + so the I-Cache is active too. config MIPS32_DCACHE_SIZE int "D-Cache Size" diff --git a/arch/mips/src/pic32mz/pic32mz_head.S b/arch/mips/src/pic32mz/pic32mz_head.S index 29c47915358..f96b812d630 100644 --- a/arch/mips/src/pic32mz/pic32mz_head.S +++ b/arch/mips/src/pic32mz/pic32mz_head.S @@ -94,13 +94,15 @@ # define PIC32MZ_HEAP_BASE PIC32MZ_STACK_TOP #endif +/* Config.K0 sets the cache algorithm for both the I- and the D-Cache, so + * the tags of both caches must be initialized when K0 is made cacheable, + * even if only one of them is enabled. The fallback sizes are an upper + * bound: index operations on non-existent lines just wrap around. + */ + #if defined (CONFIG_MIPS32_ICACHE) || defined (CONFIG_MIPS32_DCACHE) # define K0_CACHE_ALGORITHM CP0_CONFIG_K0_CACHEABLE -#else -# define K0_CACHE_ALGORITHM CP0_CONFIG_K0_UNCACHED -#endif -#ifdef CONFIG_MIPS32_ICACHE # ifdef CONFIG_MIPS32_ICACHE_SIZE # define PIC32MZ_ICACHE_SIZE CONFIG_MIPS32_ICACHE_SIZE # else @@ -113,15 +115,16 @@ # define PIC32MZ_ILINE_SIZE 16 # endif -# define PIC32MZ_KSEG0_IBASE CONFIG_MIPS32_KSEG0_IBASE -# define PIC32MZ_INDEXSTORETAG_I 8 -#endif +# ifdef CONFIG_MIPS32_KSEG0_IBASE +# define PIC32MZ_KSEG0_IBASE CONFIG_MIPS32_KSEG0_IBASE +# else +# define PIC32MZ_KSEG0_IBASE 0x9d000000 +# endif -#ifdef CONFIG_MIPS32_DCACHE # ifdef CONFIG_MIPS32_DCACHE_SIZE # define PIC32MZ_DCACHE_SIZE CONFIG_MIPS32_DCACHE_SIZE # else -# define PIC32MZ_DCACHE_SIZE 4096 +# define PIC32MZ_DCACHE_SIZE 16384 # endif # ifdef CONFIG_MIPS32_DLINE_SIZE @@ -130,8 +133,16 @@ # define PIC32MZ_DLINE_SIZE 16 # endif -# define PIC32MZ_KSEG0_DBASE CONFIG_MIPS32_KSEG0_DBASE +# ifdef CONFIG_MIPS32_KSEG0_DBASE +# define PIC32MZ_KSEG0_DBASE CONFIG_MIPS32_KSEG0_DBASE +# else +# define PIC32MZ_KSEG0_DBASE 0x80000000 +# endif + +# define PIC32MZ_INDEXSTORETAG_I 8 # define PIC32MZ_INDEXSTORETAG_D 9 +#else +# define K0_CACHE_ALGORITHM CP0_CONFIG_K0_UNCACHED #endif /**************************************************************************** @@ -480,7 +491,6 @@ __start: mtc0 zero, PIC32MZ_CP0_TAGLO ehb -# ifdef CONFIG_MIPS32_ICACHE /* Init I-Cache (Copy content of TagLo) */ li t0, PIC32MZ_KSEG0_IBASE @@ -489,9 +499,7 @@ __start: addu t0, t0, PIC32MZ_ILINE_SIZE bne t0, t1, .icacheloop cache PIC32MZ_INDEXSTORETAG_I, -4(t0) -# endif -# ifdef CONFIG_MIPS32_DCACHE /* Init D-Cache (Copy content of TagLo) */ li t0, PIC32MZ_KSEG0_DBASE @@ -500,7 +508,6 @@ __start: addu t0, t0, PIC32MZ_DLINE_SIZE bne t0, t1, .dcacheloop cache PIC32MZ_INDEXSTORETAG_D, -4(t0) -# endif /* Force memory synchronization */ @@ -521,6 +528,7 @@ __start: xori t0, CP0_CONFIG_K0_MASK ori t0, K0_CACHE_ALGORITHM mtc0 t0, PIC32MZ_CP0_CONFIG + ehb showprogress 'C'