[PATCH 01/10] microblaze: start.S: remove unused code

in16/out16 routines seem to not be used anywhere in microblaze code, so remove them.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com ---
arch/microblaze/cpu/start.S | 33 --------------------------------- 1 file changed, 33 deletions(-)
diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 645f7cb038..d1b0453caf 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -220,39 +220,6 @@ __setup_exceptions: or r0, r0, r0 .end __setup_exceptions
-/* - * Read 16bit little endian - */ - .text - .global in16 - .ent in16 - .align 2 -in16: lhu r3, r0, r5 - bslli r4, r3, 8 - bsrli r3, r3, 8 - andi r4, r4, 0xffff - or r3, r3, r4 - rtsd r15, 8 - sext16 r3, r3 - .end in16 - -/* - * Write 16bit little endian - * first parameter(r5) - address, second(r6) - short value - */ - .text - .global out16 - .ent out16 - .align 2 -out16: bslli r3, r6, 8 - bsrli r6, r6, 8 - andi r3, r3, 0xffff - or r3, r3, r6 - sh r3, r0, r5 - rtsd r15, 8 - or r0, r0, r0 - .end out16 - /* * Relocate u-boot */

XILINX_USE_DCACHE macro was removed in 7556fa09e0e ("microblaze: Simplify cache handling"), but it was still used in a couple of places.
Replace those occurences with CONFIG_DCACHE.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com ---
arch/microblaze/cpu/cache.c | 2 +- arch/microblaze/lib/bootm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index aa832d6be6..b6126de194 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -49,7 +49,7 @@ void dcache_enable(void)
void dcache_disable(void) { -#ifdef XILINX_USE_DCACHE +#ifdef CONFIG_DCACHE flush_cache(0, XILINX_DCACHE_BYTE_SIZE); #endif MSRCLR(0x80); diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index 12ea32488e..b652d2767a 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -57,7 +57,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) "(fake run for tracing)" : ""); bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
-#ifdef XILINX_USE_DCACHE +#ifdef CONFIG_DCACHE flush_cache(0, XILINX_DCACHE_BYTE_SIZE); #endif

Replace CONFIG_DCACHE with a Kconfig option more limited in scope - XILINX_MICROBLAZE0_USE_WDC. It should be enabled if the processor supports the "wdc" (Write to Data Cache) instruction. It will be used to guard "wdc" invocations in microblaze cache code.
Also, drop all ifdefs around flush_cache() calls and only keep one CONFIG_IS_ENABLED() guard within flush_cache() itself.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com ---
arch/microblaze/Kconfig | 4 ---- arch/microblaze/cpu/cache.c | 15 ++++++++++----- arch/microblaze/lib/bootm.c | 2 -- board/xilinx/microblaze-generic/Kconfig | 7 +++++++ 4 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index d7d1b21970..5a2e91104f 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -25,10 +25,6 @@ config TARGET_MICROBLAZE_GENERIC
endchoice
-config DCACHE - bool "Enable dcache support" - default y - config ICACHE bool "Enable icache support" default y diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index b6126de194..4e8e228a22 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -49,26 +49,31 @@ void dcache_enable(void)
void dcache_disable(void) { -#ifdef CONFIG_DCACHE flush_cache(0, XILINX_DCACHE_BYTE_SIZE); -#endif + MSRCLR(0x80); }
void flush_cache(ulong addr, ulong size) { int i; - for (i = 0; i < size; i += 4) + for (i = 0; i < size; i += 4) { asm volatile ( #ifdef CONFIG_ICACHE "wic %0, r0;" #endif "nop;" -#ifdef CONFIG_DCACHE + : + : "r" (addr + i) + : "memory"); + + if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WDC)) { + asm volatile ( "wdc.flush %0, r0;" -#endif "nop;" : : "r" (addr + i) : "memory"); + } + } } diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index b652d2767a..dba6226ce5 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -57,9 +57,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) "(fake run for tracing)" : ""); bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
-#ifdef CONFIG_DCACHE flush_cache(0, XILINX_DCACHE_BYTE_SIZE); -#endif
if (!fake) { /* diff --git a/board/xilinx/microblaze-generic/Kconfig b/board/xilinx/microblaze-generic/Kconfig index 117b476f3f..0d756ac7ba 100644 --- a/board/xilinx/microblaze-generic/Kconfig +++ b/board/xilinx/microblaze-generic/Kconfig @@ -63,4 +63,11 @@ config XILINX_MICROBLAZE0_VECTOR_BASE_ADDR Memory address location of the exception vector table. It is configurable via the C_BASE_VECTORS hdl parameter.
+config XILINX_MICROBLAZE0_USE_WDC + bool "MicroBlaze wdc instruction support" + default y + help + Enable this option if the MicroBlaze processor is configured with + support for the "wdc" (Write to Data Cache) instruction. + endif

On 4/11/22 18:26, Ovidiu Panait wrote:
Replace CONFIG_DCACHE with a Kconfig option more limited in scope - XILINX_MICROBLAZE0_USE_WDC. It should be enabled if the processor supports the "wdc" (Write to Data Cache) instruction. It will be used to guard "wdc" invocations in microblaze cache code.
Also, drop all ifdefs around flush_cache() calls and only keep one CONFIG_IS_ENABLED() guard within flush_cache() itself.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com
arch/microblaze/Kconfig | 4 ---- arch/microblaze/cpu/cache.c | 15 ++++++++++----- arch/microblaze/lib/bootm.c | 2 -- board/xilinx/microblaze-generic/Kconfig | 7 +++++++ 4 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index d7d1b21970..5a2e91104f 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -25,10 +25,6 @@ config TARGET_MICROBLAZE_GENERIC
endchoice
-config DCACHE
- bool "Enable dcache support"
- default y
- config ICACHE bool "Enable icache support" default y
diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index b6126de194..4e8e228a22 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -49,26 +49,31 @@ void dcache_enable(void)
void dcache_disable(void) { -#ifdef CONFIG_DCACHE flush_cache(0, XILINX_DCACHE_BYTE_SIZE); -#endif
MSRCLR(0x80); }
void flush_cache(ulong addr, ulong size) { int i;
- for (i = 0; i < size; i += 4)
- for (i = 0; i < size; i += 4) { asm volatile ( #ifdef CONFIG_ICACHE "wic %0, r0;" #endif "nop;"
-#ifdef CONFIG_DCACHE
:
: "r" (addr + i)
: "memory");
if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WDC)) {
Based on buildman your patch is removing cache handling from SPL. Here is what I see that there are missing 2 instructions. And 4/10 you see that 8 instructions are missing.
06: microblaze: cache: improve dcache Kconfig options microblaze: (for 1/1 boards) spl/u-boot-spl:all -8.0 spl/u-boot-spl:text -8.0 microblaze-generic: spl/u-boot-spl:all -8 spl/u-boot-spl:text -8 spl-u-boot-spl: add: 0/0, grow: 0/-1 bytes: 0/-8 (-8) function old new delta flush_cache 48 40 -8 07: microblaze: cache: improve icache Kconfig options microblaze: (for 1/1 boards) spl/u-boot-spl:all -32.0 spl/u-boot-spl:text -32.0 microblaze-generic: spl/u-boot-spl:all -32 spl/u-boot-spl:text -32 spl-u-boot-spl: add: 0/0, grow: 0/-1 bytes: 0/-32 (-32) function
This is going to macro explanation where it is clear that you don't define CONFIG_SPL_FOO you only define CONFIG_FOO.
104 * CONFIG_IS_ENABLED(FOO) expands to 105 * 1 if USE_HOSTCC is defined and CONFIG_TOOLS_FOO is set to 'y', 106 * 1 if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y', 107 * 1 if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y', 108 * 1 if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y', 109 * 0 otherwise.
It means you should use different macro or create one more with SPL.
Thanks, Michal

Replace CONFIG_ICACHE with a Kconfig option more limited in scope - XILINX_MICROBLAZE0_USE_WIC. It should be enabled if the processor supports the "wic" (Write to Instruction Cache) instruction. It will be used to guard "wic" invocations in microblaze cache code.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com ---
arch/microblaze/Kconfig | 4 ---- arch/microblaze/cpu/cache.c | 6 +++--- board/xilinx/microblaze-generic/Kconfig | 7 +++++++ 3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 5a2e91104f..a25a95a013 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -25,10 +25,6 @@ config TARGET_MICROBLAZE_GENERIC
endchoice
-config ICACHE - bool "Enable icache support" - default y - source "board/xilinx/Kconfig" source "board/xilinx/microblaze-generic/Kconfig"
diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index 4e8e228a22..b6bbc215b3 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -58,14 +58,14 @@ void flush_cache(ulong addr, ulong size) { int i; for (i = 0; i < size; i += 4) { - asm volatile ( -#ifdef CONFIG_ICACHE + if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WIC)) { + asm volatile ( "wic %0, r0;" -#endif "nop;" : : "r" (addr + i) : "memory"); + }
if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WDC)) { asm volatile ( diff --git a/board/xilinx/microblaze-generic/Kconfig b/board/xilinx/microblaze-generic/Kconfig index 0d756ac7ba..89af8d714f 100644 --- a/board/xilinx/microblaze-generic/Kconfig +++ b/board/xilinx/microblaze-generic/Kconfig @@ -70,4 +70,11 @@ config XILINX_MICROBLAZE0_USE_WDC Enable this option if the MicroBlaze processor is configured with support for the "wdc" (Write to Data Cache) instruction.
+config XILINX_MICROBLAZE0_USE_WIC + bool "MicroBlaze wic instruction support" + default y + help + Enable this option if the MicroBlaze processor is configured with + support for the "wic" (Write to Instruction Cache) instruction. + endif

On 4/11/22 18:26, Ovidiu Panait wrote:
Replace CONFIG_ICACHE with a Kconfig option more limited in scope - XILINX_MICROBLAZE0_USE_WIC. It should be enabled if the processor supports the "wic" (Write to Instruction Cache) instruction. It will be used to guard "wic" invocations in microblaze cache code.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com
arch/microblaze/Kconfig | 4 ---- arch/microblaze/cpu/cache.c | 6 +++--- board/xilinx/microblaze-generic/Kconfig | 7 +++++++ 3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 5a2e91104f..a25a95a013 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -25,10 +25,6 @@ config TARGET_MICROBLAZE_GENERIC
endchoice
-config ICACHE
- bool "Enable icache support"
- default y
- source "board/xilinx/Kconfig" source "board/xilinx/microblaze-generic/Kconfig"
diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index 4e8e228a22..b6bbc215b3 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -58,14 +58,14 @@ void flush_cache(ulong addr, ulong size) { int i; for (i = 0; i < size; i += 4) {
asm volatile (
-#ifdef CONFIG_ICACHE
if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WIC)) {
the same as I commented in 3/10.
M

Factor out icache/dcache components from flush_cache() function. Call the newly added __flush_icache()/__flush_dcache() functions inside icache_disable() and dcache_disable(), respectively. There is no need to flush both caches when disabling a particular cache type.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com ---
arch/microblaze/cpu/cache.c | 55 ++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 22 deletions(-)
diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index b6bbc215b3..e362a34a79 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -10,6 +10,34 @@ #include <asm/asm.h> #include <asm/cache.h>
+static void __invalidate_icache(ulong addr, ulong size) +{ + if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WIC)) { + for (int i = 0; i < size; i += 4) { + asm volatile ( + "wic %0, r0;" + "nop;" + : + : "r" (addr + i) + : "memory"); + } + } +} + +static void __flush_dcache(ulong addr, ulong size) +{ + if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WDC)) { + for (int i = 0; i < size; i += 4) { + asm volatile ( + "wdc.flush %0, r0;" + "nop;" + : + : "r" (addr + i) + : "memory"); + } + } +} + int dcache_status(void) { int i = 0; @@ -38,7 +66,8 @@ void icache_enable(void) void icache_disable(void) { /* we are not generate ICACHE size -> flush whole cache */ - flush_cache(0, 32768); + __invalidate_icache(0, 32768); + MSRCLR(0x20); }
@@ -49,31 +78,13 @@ void dcache_enable(void)
void dcache_disable(void) { - flush_cache(0, XILINX_DCACHE_BYTE_SIZE); + __flush_dcache(0, XILINX_DCACHE_BYTE_SIZE);
MSRCLR(0x80); }
void flush_cache(ulong addr, ulong size) { - int i; - for (i = 0; i < size; i += 4) { - if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WIC)) { - asm volatile ( - "wic %0, r0;" - "nop;" - : - : "r" (addr + i) - : "memory"); - } - - if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WDC)) { - asm volatile ( - "wdc.flush %0, r0;" - "nop;" - : - : "r" (addr + i) - : "memory"); - } - } + __invalidate_icache(addr, size); + __flush_dcache(addr, size); }

On 4/11/22 18:26, Ovidiu Panait wrote:
Factor out icache/dcache components from flush_cache() function. Call the newly added __flush_icache()/__flush_dcache() functions inside icache_disable() and dcache_disable(), respectively. There is no need to flush both caches when disabling a particular cache type.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com
arch/microblaze/cpu/cache.c | 55 ++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 22 deletions(-)
diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index b6bbc215b3..e362a34a79 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -10,6 +10,34 @@ #include <asm/asm.h> #include <asm/cache.h>
+static void __invalidate_icache(ulong addr, ulong size) +{
- if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WIC)) {
when these macros are fixed changes are fine.
M

Migrate XILINX_DCACHE_BYTE_SIZE to Kconfig and rename it to XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE. Use it as the default size for both instruction/data caches and get rid of the hardcoded value in icache_disable().
Signed-off-by: Ovidiu Panait ovpanait@gmail.com ---
arch/microblaze/cpu/cache.c | 5 ++--- arch/microblaze/cpu/start.S | 4 ++-- arch/microblaze/lib/bootm.c | 2 +- board/xilinx/microblaze-generic/Kconfig | 8 ++++++++ include/configs/microblaze-generic.h | 4 ---- 5 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index e362a34a79..2814c1dc07 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -65,8 +65,7 @@ void icache_enable(void)
void icache_disable(void) { - /* we are not generate ICACHE size -> flush whole cache */ - __invalidate_icache(0, 32768); + __invalidate_icache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE);
MSRCLR(0x20); } @@ -78,7 +77,7 @@ void dcache_enable(void)
void dcache_disable(void) { - __flush_dcache(0, XILINX_DCACHE_BYTE_SIZE); + __flush_dcache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE);
MSRCLR(0x80); } diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index d1b0453caf..94984148de 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -53,7 +53,7 @@ _start:
/* Flush cache before enable cache */ addik r5, r0, 0 - addik r6, r0, XILINX_DCACHE_BYTE_SIZE + addik r6, r0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE bralid r15, flush_cache nop
@@ -284,7 +284,7 @@ relocate_code:
/* Flush caches to ensure consistency */ addik r5, r0, 0 - addik r6, r0, XILINX_DCACHE_BYTE_SIZE + addik r6, r0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE bralid r15, flush_cache nop
diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index dba6226ce5..59b757c857 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -57,7 +57,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) "(fake run for tracing)" : ""); bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
- flush_cache(0, XILINX_DCACHE_BYTE_SIZE); + flush_cache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE);
if (!fake) { /* diff --git a/board/xilinx/microblaze-generic/Kconfig b/board/xilinx/microblaze-generic/Kconfig index 89af8d714f..505a3d59cf 100644 --- a/board/xilinx/microblaze-generic/Kconfig +++ b/board/xilinx/microblaze-generic/Kconfig @@ -77,4 +77,12 @@ config XILINX_MICROBLAZE0_USE_WIC Enable this option if the MicroBlaze processor is configured with support for the "wic" (Write to Instruction Cache) instruction.
+config XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE + int "Default instruction/data cache size" + default 32768 + help + This fallback size will be used when no cache info can be found in + the device tree, or when the caches are flushed very early in the + boot process, before device tree is available. + endif diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 663837f33d..7b064eacb2 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -30,10 +30,6 @@ # define CONFIG_SYS_MAX_FLASH_SECT 2048 #endif
-#ifndef XILINX_DCACHE_BYTE_SIZE -#define XILINX_DCACHE_BYTE_SIZE 32768 -#endif - /* size of console buffer */ #define CONFIG_SYS_CBSIZE 512 /* max number of command args */

On 4/11/22 18:26, Ovidiu Panait wrote:
Migrate XILINX_DCACHE_BYTE_SIZE to Kconfig and rename it to XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE. Use it as the default size for both instruction/data caches and get rid of the hardcoded value in icache_disable().
Microblaze can have different icache and dcache sizes that's why there is a need to use two symbols to cover it. cache ranges are from 64B to 64KB.
I think the best way how to handle this is save icache/dcache sizes to one static variable/structure because actually these Kconfig symbols should be really only use as default value. What Xilinx tools is doing that it generates XILINX_DCACHE_BYTE_SIZE based on current design and overwrites that macro. That's why there are ifndef around it.
#ifndef XILINX_DCACHE_BYTE_SIZE #define XILINX_DCACHE_BYTE_SIZE 32768 #endif
icache handling is not that sensitive because it is not working with data and self modifying code is not used.
It means default value for dcache and icache setup to 32kB should be fine.
And saving it to static variable can open good way to overwrite this structure based on information from DT or based on values from PVRs.
Thanks, Michal

All flush_cache() calls in microblaze code are supposed to flush the entire instruction and data caches, so introduce flush_cache_all() helper to handle this.
Also, provide implementations for flush_dcache_all() and invalidate_icache_all() so that icache and dcache u-boot commands can work.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com ---
arch/microblaze/cpu/cache.c | 20 ++++++++++++++++++-- arch/microblaze/cpu/start.S | 8 ++------ arch/microblaze/include/asm/cache.h | 5 +++++ arch/microblaze/lib/bootm.c | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index 2814c1dc07..60b6d549d7 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -24,6 +24,11 @@ static void __invalidate_icache(ulong addr, ulong size) } }
+void invalidate_icache_all(void) +{ + __invalidate_icache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE); +} + static void __flush_dcache(ulong addr, ulong size) { if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WDC)) { @@ -38,6 +43,11 @@ static void __flush_dcache(ulong addr, ulong size) } }
+void flush_dcache_all(void) +{ + __flush_dcache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE); +} + int dcache_status(void) { int i = 0; @@ -65,7 +75,7 @@ void icache_enable(void)
void icache_disable(void) { - __invalidate_icache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE); + invalidate_icache_all();
MSRCLR(0x20); } @@ -77,7 +87,7 @@ void dcache_enable(void)
void dcache_disable(void) { - __flush_dcache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE); + flush_dcache_all();
MSRCLR(0x80); } @@ -87,3 +97,9 @@ void flush_cache(ulong addr, ulong size) __invalidate_icache(addr, size); __flush_dcache(addr, size); } + +void flush_cache_all(void) +{ + invalidate_icache_all(); + flush_dcache_all(); +} diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 94984148de..7f7b5f5cb5 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -52,9 +52,7 @@ _start: #endif
/* Flush cache before enable cache */ - addik r5, r0, 0 - addik r6, r0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE - bralid r15, flush_cache + bralid r15, flush_cache_all nop
/* enable instruction and data cache */ @@ -283,9 +281,7 @@ relocate_code: addk r20, r20, r23
/* Flush caches to ensure consistency */ - addik r5, r0, 0 - addik r6, r0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE - bralid r15, flush_cache + bralid r15, flush_cache_all nop
2: addi r5, r31, 0 /* gd is initialized in board_r.c */ diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h index baee01a0e2..c39b66dd7d 100644 --- a/arch/microblaze/include/asm/cache.h +++ b/arch/microblaze/include/asm/cache.h @@ -18,4 +18,9 @@ #define ARCH_DMA_MINALIGN 16 #endif
+/** + * flush_cache_all - flush the entire instruction/data caches + */ +void flush_cache_all(void); + #endif /* __MICROBLAZE_CACHE_H__ */ diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index 59b757c857..af946b8642 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -57,7 +57,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) "(fake run for tracing)" : ""); bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
- flush_cache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE); + flush_cache_all();
if (!fake) { /*

On 4/11/22 18:26, Ovidiu Panait wrote:
All flush_cache() calls in microblaze code are supposed to flush the entire instruction and data caches, so introduce flush_cache_all() helper to handle this.
Also, provide implementations for flush_dcache_all() and invalidate_icache_all() so that icache and dcache u-boot commands can work.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com
arch/microblaze/cpu/cache.c | 20 ++++++++++++++++++-- arch/microblaze/cpu/start.S | 8 ++------ arch/microblaze/include/asm/cache.h | 5 +++++ arch/microblaze/lib/bootm.c | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index 2814c1dc07..60b6d549d7 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -24,6 +24,11 @@ static void __invalidate_icache(ulong addr, ulong size) } }
+void invalidate_icache_all(void) +{
- __invalidate_icache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE);
+}
- static void __flush_dcache(ulong addr, ulong size) { if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WDC)) {
@@ -38,6 +43,11 @@ static void __flush_dcache(ulong addr, ulong size) } }
+void flush_dcache_all(void) +{
- __flush_dcache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE);
+}
- int dcache_status(void) { int i = 0;
@@ -65,7 +75,7 @@ void icache_enable(void)
void icache_disable(void) {
- __invalidate_icache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE);
invalidate_icache_all();
MSRCLR(0x20); }
@@ -77,7 +87,7 @@ void dcache_enable(void)
void dcache_disable(void) {
- __flush_dcache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE);
flush_dcache_all();
MSRCLR(0x80); }
@@ -87,3 +97,9 @@ void flush_cache(ulong addr, ulong size) __invalidate_icache(addr, size); __flush_dcache(addr, size); }
+void flush_cache_all(void) +{
- invalidate_icache_all();
- flush_dcache_all();
+} diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 94984148de..7f7b5f5cb5 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -52,9 +52,7 @@ _start: #endif
/* Flush cache before enable cache */
- addik r5, r0, 0
- addik r6, r0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE
- bralid r15, flush_cache
bralid r15, flush_cache_all nop
/* enable instruction and data cache */
@@ -283,9 +281,7 @@ relocate_code: addk r20, r20, r23
/* Flush caches to ensure consistency */
- addik r5, r0, 0
- addik r6, r0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE
- bralid r15, flush_cache
bralid r15, flush_cache_all nop
2: addi r5, r31, 0 /* gd is initialized in board_r.c */
diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h index baee01a0e2..c39b66dd7d 100644 --- a/arch/microblaze/include/asm/cache.h +++ b/arch/microblaze/include/asm/cache.h @@ -18,4 +18,9 @@ #define ARCH_DMA_MINALIGN 16 #endif
+/**
- flush_cache_all - flush the entire instruction/data caches
- */
+void flush_cache_all(void);
- #endif /* __MICROBLAZE_CACHE_H__ */
diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index 59b757c857..af946b8642 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -57,7 +57,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) "(fake run for tracing)" : ""); bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
- flush_cache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE);
flush_cache_all();
if (!fake) { /*
This looks good.
M

Align microblaze with the other architectures and provide an implementation for flush_dcache_range(). Also, remove the microblaze exception in drivers/core/device.c.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com ---
arch/microblaze/cpu/cache.c | 8 ++++++++ drivers/core/device.c | 5 ----- 2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index 60b6d549d7..cce33a6eb5 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -43,6 +43,14 @@ static void __flush_dcache(ulong addr, ulong size) } }
+void flush_dcache_range(unsigned long start, unsigned long end) +{ + if (start >= end) + return; + + __flush_dcache(start, end - start); +} + void flush_dcache_all(void) { __flush_dcache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE); diff --git a/drivers/core/device.c b/drivers/core/device.c index 1b356f12dd..16f808f2be 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -328,13 +328,8 @@ static void *alloc_priv(int size, uint flags) * within this range at the start. The driver can then * use normal flush-after-write, invalidate-before-read * procedures. - * - * TODO(sjg@chromium.org): Drop this microblaze - * exception. */ -#ifndef CONFIG_MICROBLAZE flush_dcache_range((ulong)priv, (ulong)priv + size); -#endif } } else { priv = calloc(1, size);

On 4/11/22 18:26, Ovidiu Panait wrote:
Align microblaze with the other architectures and provide an implementation for flush_dcache_range(). Also, remove the microblaze exception in drivers/core/device.c.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com
arch/microblaze/cpu/cache.c | 8 ++++++++ drivers/core/device.c | 5 ----- 2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index 60b6d549d7..cce33a6eb5 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -43,6 +43,14 @@ static void __flush_dcache(ulong addr, ulong size) } }
+void flush_dcache_range(unsigned long start, unsigned long end) +{
- if (start >= end)
return;
I think you should at least print any message when debug is enabled.
Thanks, Michal

Add a basic CPU driver that retrieves information about the microblaze CPU core. At this time, only data related to instruction/data caches is extracted from fdt.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com ---
arch/microblaze/include/asm/cache.h | 5 + arch/microblaze/include/asm/microblaze_cpu.h | 53 +++++++++ drivers/cpu/Kconfig | 6 + drivers/cpu/Makefile | 1 + drivers/cpu/microblaze_cpu.c | 109 +++++++++++++++++++ 5 files changed, 174 insertions(+) create mode 100644 arch/microblaze/include/asm/microblaze_cpu.h create mode 100644 drivers/cpu/microblaze_cpu.c
diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h index c39b66dd7d..58ec69603e 100644 --- a/arch/microblaze/include/asm/cache.h +++ b/arch/microblaze/include/asm/cache.h @@ -23,4 +23,9 @@ */ void flush_cache_all(void);
+enum cache_type { + DCACHE, + ICACHE +}; + #endif /* __MICROBLAZE_CACHE_H__ */ diff --git a/arch/microblaze/include/asm/microblaze_cpu.h b/arch/microblaze/include/asm/microblaze_cpu.h new file mode 100644 index 0000000000..8aad966e54 --- /dev/null +++ b/arch/microblaze/include/asm/microblaze_cpu.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2022, Ovidiu Panait ovpanait@gmail.com + */ + +#ifndef __MICROBLAZE_CPU_H +#define __MICROBLAZE_CPU_H + +#include <asm/cache.h> + +/** + * struct microblaze_cpu_plat - Platform data for microblaze processor core. + * + * @icache_size: Size of instruction cache memory in bytes. + * @icache_line_length: Instruction cache line length in bytes. + * @dcache_size: Size of data cache memory in bytes. + * @dcache_line_length: Data cache line length in bytes. + */ +struct microblaze_cpu_plat { + u32 icache_size; + u32 icache_line_length; + + u32 dcache_size; + u32 dcache_line_length; +}; + +/** + * microblaze_cpu_get_cacheline_size() - Get the cache line size + * + * Returns the cache line size in bytes for the cache memory type specified in + * @type (dcache or icache). Probes the first UCLASS CPU device via + * uclass_get_device() if not already active. + * + * @type: Cache type (dcache or icache) + * Return: + * >= 0 if OK, -ENODEV if there is an error getting cpu device data + */ +int microblaze_cpu_get_cacheline_size(enum cache_type type); + +/** + * microblaze_cpu_get_cache_size() - Get the cache size + * + * Returns the cache size in bytes for the cache memory type specified in @type + * (dcache or icache). Probes the first UCLASS CPU device via + * uclass_get_device() if not already active. + * + * @type: Cache type (dcache or icache) + * Return: + * >= 0 if OK, -ENODEV if there is an error getting cpu device data + */ +int microblaze_cpu_get_cache_size(enum cache_type type); + +#endif /* __MICROBLAZE_CPU_H */ diff --git a/drivers/cpu/Kconfig b/drivers/cpu/Kconfig index 3d5729f6dc..c4b124da3f 100644 --- a/drivers/cpu/Kconfig +++ b/drivers/cpu/Kconfig @@ -19,3 +19,9 @@ config CPU_RISCV depends on CPU && RISCV help Support CPU cores for RISC-V architecture. + +config CPU_MICROBLAZE + bool "Enable Microblaze CPU driver" + depends on CPU && MICROBLAZE + help + Support CPU cores for Microblaze architecture. diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile index c8532637ca..20884b1795 100644 --- a/drivers/cpu/Makefile +++ b/drivers/cpu/Makefile @@ -11,4 +11,5 @@ obj-$(CONFIG_ARCH_IMX8) += imx8_cpu.o obj-$(CONFIG_ARCH_AT91) += at91_cpu.o obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o obj-$(CONFIG_CPU_RISCV) += riscv_cpu.o +obj-$(CONFIG_CPU_MICROBLAZE) += microblaze_cpu.o obj-$(CONFIG_SANDBOX) += cpu_sandbox.o diff --git a/drivers/cpu/microblaze_cpu.c b/drivers/cpu/microblaze_cpu.c new file mode 100644 index 0000000000..823ac5671e --- /dev/null +++ b/drivers/cpu/microblaze_cpu.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022, Ovidiu Panait ovpanait@gmail.com + */ +#include <dm.h> +#include <asm/microblaze_cpu.h> + +static struct microblaze_cpu_plat *get_cpu0_plat(void) +{ + struct udevice *dev; + + if (uclass_get_device(UCLASS_CPU, 0, &dev) == 0) + return dev_get_plat(dev); + + return NULL; +} + +int microblaze_cpu_get_cacheline_size(enum cache_type type) +{ + struct microblaze_cpu_plat *plat = get_cpu0_plat(); + + if (!plat) + return -ENODEV; + + if (type == DCACHE) + return plat->dcache_line_length; + + return plat->icache_line_length; +} + +int microblaze_cpu_get_cache_size(enum cache_type type) +{ + struct microblaze_cpu_plat *plat = get_cpu0_plat(); + + if (!plat) + return -ENODEV; + + if (type == DCACHE) + return plat->dcache_size; + + return plat->icache_size; +} + +static int microblaze_cpu_of_to_plat(struct udevice *dev) +{ + struct microblaze_cpu_plat *plat = dev_get_plat(dev); + + plat->icache_size = dev_read_u32_default(dev, "i-cache-size", 0); + plat->icache_line_length = dev_read_u32_default(dev, + "xlnx,icache-line-len", 0); + plat->icache_line_length <<= 2; + + plat->dcache_size = dev_read_u32_default(dev, "d-cache-size", 0); + plat->dcache_line_length = dev_read_u32_default(dev, + "xlnx,dcache-line-len", 0); + plat->dcache_line_length <<= 2; + + return 0; +} + +static const struct udevice_id microblaze_cpu_ids[] = { + { .compatible = "xlnx,microblaze-11.0" }, + { .compatible = "xlnx,microblaze-10.0" }, + { .compatible = "xlnx,microblaze-9.0.6" }, + { .compatible = "xlnx,microblaze-9.0.5" }, + { .compatible = "xlnx,microblaze-9.0.4" }, + { .compatible = "xlnx,microblaze-9.0.3" }, + { .compatible = "xlnx,microblaze-9.0.2" }, + { .compatible = "xlnx,microblaze-9.0.1" }, + { .compatible = "xlnx,microblaze-9.0.0" }, + { .compatible = "xlnx,microblaze-8.50.c" }, + { .compatible = "xlnx,microblaze-8.50.b" }, + { .compatible = "xlnx,microblaze-8.50.a" }, + { .compatible = "xlnx,microblaze-8.40.b" }, + { .compatible = "xlnx,microblaze-8.40.a" }, + { .compatible = "xlnx,microblaze-8.30.a" }, + { .compatible = "xlnx,microblaze-8.20.b" }, + { .compatible = "xlnx,microblaze-8.20.a" }, + { .compatible = "xlnx,microblaze-8.10.a" }, + { .compatible = "xlnx,microblaze-8.00.b" }, + { .compatible = "xlnx,microblaze-8.00.a" }, + { .compatible = "xlnx,microblaze-7.30.b" }, + { .compatible = "xlnx,microblaze-7.30.a" }, + { .compatible = "xlnx,microblaze-7.20.d" }, + { .compatible = "xlnx,microblaze-7.20.c" }, + { .compatible = "xlnx,microblaze-7.20.b" }, + { .compatible = "xlnx,microblaze-7.20.a" }, + { .compatible = "xlnx,microblaze-7.10.d" }, + { .compatible = "xlnx,microblaze-7.10.c" }, + { .compatible = "xlnx,microblaze-7.10.b" }, + { .compatible = "xlnx,microblaze-7.10.a" }, + { .compatible = "xlnx,microblaze-7.00.b" }, + { .compatible = "xlnx,microblaze-7.00.a" }, + { .compatible = "xlnx,microblaze-6.00.b" }, + { .compatible = "xlnx,microblaze-6.00.a" }, + { .compatible = "xlnx,microblaze-5.00.c" }, + { .compatible = "xlnx,microblaze-5.00.b" }, + { .compatible = "xlnx,microblaze-5.00.a" }, + { } +}; + +U_BOOT_DRIVER(microblaze_cpu) = { + .name = "microblaze_cpu", + .id = UCLASS_CPU, + .of_match = microblaze_cpu_ids, + .of_to_plat = microblaze_cpu_of_to_plat, + .plat_auto = sizeof(struct microblaze_cpu_plat), + .flags = DM_FLAG_PRE_RELOC, +};

On 4/11/22 18:26, Ovidiu Panait wrote:
Add a basic CPU driver that retrieves information about the microblaze CPU core. At this time, only data related to instruction/data caches is extracted from fdt.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com
arch/microblaze/include/asm/cache.h | 5 + arch/microblaze/include/asm/microblaze_cpu.h | 53 +++++++++ drivers/cpu/Kconfig | 6 + drivers/cpu/Makefile | 1 + drivers/cpu/microblaze_cpu.c | 109 +++++++++++++++++++ 5 files changed, 174 insertions(+) create mode 100644 arch/microblaze/include/asm/microblaze_cpu.h create mode 100644 drivers/cpu/microblaze_cpu.c
diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h index c39b66dd7d..58ec69603e 100644 --- a/arch/microblaze/include/asm/cache.h +++ b/arch/microblaze/include/asm/cache.h @@ -23,4 +23,9 @@ */ void flush_cache_all(void);
+enum cache_type {
- DCACHE,
- ICACHE
+};
- #endif /* __MICROBLAZE_CACHE_H__ */
diff --git a/arch/microblaze/include/asm/microblaze_cpu.h b/arch/microblaze/include/asm/microblaze_cpu.h new file mode 100644 index 0000000000..8aad966e54 --- /dev/null +++ b/arch/microblaze/include/asm/microblaze_cpu.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- Copyright (C) 2022, Ovidiu Panait ovpanait@gmail.com
- */
+#ifndef __MICROBLAZE_CPU_H +#define __MICROBLAZE_CPU_H
+#include <asm/cache.h>
+/**
- struct microblaze_cpu_plat - Platform data for microblaze processor core.
- @icache_size: Size of instruction cache memory in bytes.
- @icache_line_length: Instruction cache line length in bytes.
- @dcache_size: Size of data cache memory in bytes.
- @dcache_line_length: Data cache line length in bytes.
- */
+struct microblaze_cpu_plat {
- u32 icache_size;
- u32 icache_line_length;
- u32 dcache_size;
- u32 dcache_line_length;
+};
You should use this structure earlier as I mentioned. And I would also align it with linux and call this file cpuinfo.h
+/**
- microblaze_cpu_get_cacheline_size() - Get the cache line size
- Returns the cache line size in bytes for the cache memory type specified in
- @type (dcache or icache). Probes the first UCLASS CPU device via
- uclass_get_device() if not already active.
- @type: Cache type (dcache or icache)
- Return:
= 0 if OK, -ENODEV if there is an error getting cpu device data- */
+int microblaze_cpu_get_cacheline_size(enum cache_type type);
+/**
- microblaze_cpu_get_cache_size() - Get the cache size
- Returns the cache size in bytes for the cache memory type specified in @type
- (dcache or icache). Probes the first UCLASS CPU device via
- uclass_get_device() if not already active.
- @type: Cache type (dcache or icache)
- Return:
= 0 if OK, -ENODEV if there is an error getting cpu device data- */
+int microblaze_cpu_get_cache_size(enum cache_type type);
+#endif /* __MICROBLAZE_CPU_H */ diff --git a/drivers/cpu/Kconfig b/drivers/cpu/Kconfig index 3d5729f6dc..c4b124da3f 100644 --- a/drivers/cpu/Kconfig +++ b/drivers/cpu/Kconfig @@ -19,3 +19,9 @@ config CPU_RISCV depends on CPU && RISCV help Support CPU cores for RISC-V architecture.
+config CPU_MICROBLAZE
- bool "Enable Microblaze CPU driver"
- depends on CPU && MICROBLAZE
- help
Support CPU cores for Microblaze architecture.
diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile index c8532637ca..20884b1795 100644 --- a/drivers/cpu/Makefile +++ b/drivers/cpu/Makefile @@ -11,4 +11,5 @@ obj-$(CONFIG_ARCH_IMX8) += imx8_cpu.o obj-$(CONFIG_ARCH_AT91) += at91_cpu.o obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o obj-$(CONFIG_CPU_RISCV) += riscv_cpu.o +obj-$(CONFIG_CPU_MICROBLAZE) += microblaze_cpu.o obj-$(CONFIG_SANDBOX) += cpu_sandbox.o diff --git a/drivers/cpu/microblaze_cpu.c b/drivers/cpu/microblaze_cpu.c new file mode 100644 index 0000000000..823ac5671e --- /dev/null +++ b/drivers/cpu/microblaze_cpu.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2022, Ovidiu Panait ovpanait@gmail.com
- */
+#include <dm.h> +#include <asm/microblaze_cpu.h>
+static struct microblaze_cpu_plat *get_cpu0_plat(void) +{
- struct udevice *dev;
- if (uclass_get_device(UCLASS_CPU, 0, &dev) == 0)
return dev_get_plat(dev);
- return NULL;
+}
+int microblaze_cpu_get_cacheline_size(enum cache_type type) +{
- struct microblaze_cpu_plat *plat = get_cpu0_plat();
- if (!plat)
return -ENODEV;
- if (type == DCACHE)
return plat->dcache_line_length;
- return plat->icache_line_length;
+}
+int microblaze_cpu_get_cache_size(enum cache_type type) +{
- struct microblaze_cpu_plat *plat = get_cpu0_plat();
- if (!plat)
return -ENODEV;
- if (type == DCACHE)
return plat->dcache_size;
- return plat->icache_size;
+}
First of all these should be for icache and dcache. But I don't think you actually need this. Just fill that structure in previous patches and if this driver is loaded you can rewrite that values based on information from DT.
You can actually introduce in probe reading PVR register and fill that value based on it. IIRC in the linux kernel I am comparing that values to check if actual DT fits with system where u-boot is running at. If something doesn't match you can just show a message.
+static int microblaze_cpu_of_to_plat(struct udevice *dev) +{
- struct microblaze_cpu_plat *plat = dev_get_plat(dev);
- plat->icache_size = dev_read_u32_default(dev, "i-cache-size", 0);
- plat->icache_line_length = dev_read_u32_default(dev,
"xlnx,icache-line-len", 0);
- plat->icache_line_length <<= 2;
use i-cache-line-size and you don't need to do any shift.
- plat->dcache_size = dev_read_u32_default(dev, "d-cache-size", 0);
- plat->dcache_line_length = dev_read_u32_default(dev,
"xlnx,dcache-line-len", 0);
- plat->dcache_line_length <<= 2;
d-cache-line-size here.
- return 0;
+}
+static const struct udevice_id microblaze_cpu_ids[] = {
- { .compatible = "xlnx,microblaze-11.0" },
- { .compatible = "xlnx,microblaze-10.0" },
- { .compatible = "xlnx,microblaze-9.0.6" },
- { .compatible = "xlnx,microblaze-9.0.5" },
- { .compatible = "xlnx,microblaze-9.0.4" },
- { .compatible = "xlnx,microblaze-9.0.3" },
- { .compatible = "xlnx,microblaze-9.0.2" },
- { .compatible = "xlnx,microblaze-9.0.1" },
- { .compatible = "xlnx,microblaze-9.0.0" },
https://docs.xilinx.com/v/u/en-US/ug984-vivado-microblaze-ref They were 9.6 etc - it means all zeros should be removed.
MicroBlaze release version code Release Specific 0x19 = v8.40.b 0x1B = v9.0 0x1D = v9.1 0x1F = v9.2 0x20 = v9.3 0x21 = v9.4 0x22 = v9.5 0x23 = v9.6 0x24 = v10.0 0x25 = v11.0
- { .compatible = "xlnx,microblaze-8.50.c" },
- { .compatible = "xlnx,microblaze-8.50.b" },
- { .compatible = "xlnx,microblaze-8.50.a" },
- { .compatible = "xlnx,microblaze-8.40.b" },
- { .compatible = "xlnx,microblaze-8.40.a" },
- { .compatible = "xlnx,microblaze-8.30.a" },
- { .compatible = "xlnx,microblaze-8.20.b" },
- { .compatible = "xlnx,microblaze-8.20.a" },
- { .compatible = "xlnx,microblaze-8.10.a" },
- { .compatible = "xlnx,microblaze-8.00.b" },
- { .compatible = "xlnx,microblaze-8.00.a" },
- { .compatible = "xlnx,microblaze-7.30.b" },
- { .compatible = "xlnx,microblaze-7.30.a" },
- { .compatible = "xlnx,microblaze-7.20.d" },
- { .compatible = "xlnx,microblaze-7.20.c" },
- { .compatible = "xlnx,microblaze-7.20.b" },
- { .compatible = "xlnx,microblaze-7.20.a" },
- { .compatible = "xlnx,microblaze-7.10.d" },
- { .compatible = "xlnx,microblaze-7.10.c" },
- { .compatible = "xlnx,microblaze-7.10.b" },
- { .compatible = "xlnx,microblaze-7.10.a" },
- { .compatible = "xlnx,microblaze-7.00.b" },
- { .compatible = "xlnx,microblaze-7.00.a" },
- { .compatible = "xlnx,microblaze-6.00.b" },
- { .compatible = "xlnx,microblaze-6.00.a" },
- { .compatible = "xlnx,microblaze-5.00.c" },
- { .compatible = "xlnx,microblaze-5.00.b" },
- { .compatible = "xlnx,microblaze-5.00.a" },
- { }
+};
+U_BOOT_DRIVER(microblaze_cpu) = {
- .name = "microblaze_cpu",
- .id = UCLASS_CPU,
- .of_match = microblaze_cpu_ids,
- .of_to_plat = microblaze_cpu_of_to_plat,
- .plat_auto = sizeof(struct microblaze_cpu_plat),
- .flags = DM_FLAG_PRE_RELOC,
+};
Based on my look at cpu uclass I think it will be good to provide also ops and provide description and info about cpu itself that would be possible to enable CPU command.
M

If CONFIG_CPU_MICROBLAZE is enabled, the cache size and cache line size are retrieved from the fdt by the microblaze cpu driver. Adjust cache flush code to use those values if available.
If a cache flush is requested very early in the boot (for example the flush_cache_all() call in start.S) or before dm is ready, the default size of CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE will be used instead.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com ---
arch/microblaze/cpu/cache.c | 45 +++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-)
diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index cce33a6eb5..8b7e212a26 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -9,11 +9,21 @@ #include <cpu_func.h> #include <asm/asm.h> #include <asm/cache.h> +#include <asm/microblaze_cpu.h>
static void __invalidate_icache(ulong addr, ulong size) { if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WIC)) { - for (int i = 0; i < size; i += 4) { + int line_length = 4; + + if (CONFIG_IS_ENABLED(CPU_MICROBLAZE)) { + int size = microblaze_cpu_get_cacheline_size(ICACHE); + + if (size > 0) + line_length = size; + } + + for (int i = 0; i < size; i += line_length) { asm volatile ( "wic %0, r0;" "nop;" @@ -26,13 +36,31 @@ static void __invalidate_icache(ulong addr, ulong size)
void invalidate_icache_all(void) { - __invalidate_icache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE); + int cache_size = CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE; + + if (CONFIG_IS_ENABLED(CPU_MICROBLAZE)) { + int size = microblaze_cpu_get_cache_size(ICACHE); + + if (size >= 0) + cache_size = size; + } + + __invalidate_icache(0, cache_size); }
static void __flush_dcache(ulong addr, ulong size) { if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WDC)) { - for (int i = 0; i < size; i += 4) { + int line_length = 4; + + if (CONFIG_IS_ENABLED(CPU_MICROBLAZE)) { + int size = microblaze_cpu_get_cacheline_size(DCACHE); + + if (size > 0) + line_length = size; + } + + for (int i = 0; i < size; i += line_length) { asm volatile ( "wdc.flush %0, r0;" "nop;" @@ -53,7 +81,16 @@ void flush_dcache_range(unsigned long start, unsigned long end)
void flush_dcache_all(void) { - __flush_dcache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE); + int cache_size = CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE; + + if (CONFIG_IS_ENABLED(CPU_MICROBLAZE)) { + int size = microblaze_cpu_get_cache_size(DCACHE); + + if (size >= 0) + cache_size = size; + } + + __flush_dcache(0, cache_size); }
int dcache_status(void)

On 4/11/22 18:26, Ovidiu Panait wrote:
If CONFIG_CPU_MICROBLAZE is enabled, the cache size and cache line size are retrieved from the fdt by the microblaze cpu driver. Adjust cache flush code to use those values if available.
If a cache flush is requested very early in the boot (for example the flush_cache_all() call in start.S) or before dm is ready, the default size of CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE will be used instead.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com
arch/microblaze/cpu/cache.c | 45 +++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-)
diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index cce33a6eb5..8b7e212a26 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -9,11 +9,21 @@ #include <cpu_func.h> #include <asm/asm.h> #include <asm/cache.h> +#include <asm/microblaze_cpu.h>
static void __invalidate_icache(ulong addr, ulong size) { if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WIC)) {
for (int i = 0; i < size; i += 4) {
int line_length = 4;
if (CONFIG_IS_ENABLED(CPU_MICROBLAZE)) {
int size = microblaze_cpu_get_cacheline_size(ICACHE);
if (size > 0)
line_length = size;
}
for (int i = 0; i < size; i += line_length) { asm volatile ( "wic %0, r0;" "nop;"
@@ -26,13 +36,31 @@ static void __invalidate_icache(ulong addr, ulong size)
void invalidate_icache_all(void) {
- __invalidate_icache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE);
int cache_size = CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE;
if (CONFIG_IS_ENABLED(CPU_MICROBLAZE)) {
int size = microblaze_cpu_get_cache_size(ICACHE);
if (size >= 0)
cache_size = size;
}
__invalidate_icache(0, cache_size); }
static void __flush_dcache(ulong addr, ulong size) { if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WDC)) {
for (int i = 0; i < size; i += 4) {
int line_length = 4;
if (CONFIG_IS_ENABLED(CPU_MICROBLAZE)) {
int size = microblaze_cpu_get_cacheline_size(DCACHE);
if (size > 0)
line_length = size;
}
for (int i = 0; i < size; i += line_length) { asm volatile ( "wdc.flush %0, r0;" "nop;"
@@ -53,7 +81,16 @@ void flush_dcache_range(unsigned long start, unsigned long end)
void flush_dcache_all(void) {
- __flush_dcache(0, CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE);
int cache_size = CONFIG_XILINX_MICROBLAZE0_DEFAULT_CACHE_SIZE;
if (CONFIG_IS_ENABLED(CPU_MICROBLAZE)) {
int size = microblaze_cpu_get_cache_size(DCACHE);
if (size >= 0)
cache_size = size;
}
__flush_dcache(0, cache_size); }
int dcache_status(void)
This patch can be dropped because these functions should only work based on data from cpuinfo structure that's why you don't need to call special function which are only available when driver is enabled.
M
participants (2)
-
Michal Simek
-
Ovidiu Panait