MIPS cache cleanups
cover MIPS cache cleanups
This short series cleans up the MIPS cache code in preparation for introducing support for L2 cache support. It's hopefully a useful standalone cleanup as-is, so I'll submit it now.
Paul Burton (3):
MIPS: Move cache sizes to Kconfig
MIPS: Split I & D cache line size config
MIPS: Abstract cache op loops with a macro
arch/mips/Kconfig | 16 ++++++++ arch/mips/lib/cache.c | 79 ++++++++++++---------------------------- arch/mips/lib/cache_init.S | 10 ++--- board/dbau1x00/Kconfig | 12 ++++++ board/micronas/vct/Kconfig | 12 ++++++ board/pb1x00/Kconfig | 12 ++++++ board/qca/ap121/Kconfig | 12 ++++++ board/qca/ap143/Kconfig | 12 ++++++ board/qemu-mips/Kconfig | 12 ++++++ board/tplink/wdr4300/Kconfig | 12 ++++++ include/configs/ap121.h | 5 --- include/configs/ap143.h | 5 --- include/configs/dbau1x00.h | 7 ---- include/configs/pb1x00.h | 6 --- include/configs/qemu-mips.h | 7 ---- include/configs/qemu-mips64.h | 7 ---- include/configs/tplink_wdr4300.h | 5 --- include/configs/vct.h | 7 ---- 18 files changed, 129 insertions(+), 109 deletions(-)
Signature · 1 line
2.8.3
PATCH 1/3 MIPS: Move cache sizes to Kconfig
Move details of the L1 cache line sizes & total sizes into Kconfig, defaulting to 0 & using 0 to indicate that the value should be autodetected.
---
arch/mips/Kconfig | 12 ++++++++++++ arch/mips/lib/cache.c | 2 +- arch/mips/lib/cache_init.S | 6 +++--- board/dbau1x00/Kconfig | 9 +++++++++ board/micronas/vct/Kconfig | 9 +++++++++ board/pb1x00/Kconfig | 9 +++++++++ board/qca/ap121/Kconfig | 9 +++++++++ board/qca/ap143/Kconfig | 9 +++++++++ board/qemu-mips/Kconfig | 9 +++++++++ board/tplink/wdr4300/Kconfig | 9 +++++++++ include/configs/ap121.h | 5 ----- include/configs/ap143.h | 5 ----- include/configs/dbau1x00.h | 7 ------- include/configs/pb1x00.h | 6 ------ include/configs/qemu-mips.h | 7 ------- include/configs/qemu-mips64.h | 7 ------- include/configs/tplink_wdr4300.h | 5 ----- include/configs/vct.h | 7 ------- 18 files changed, 79 insertions(+), 53 deletions(-)
arch/mips/Kconfig +12 -0
@@ -243,6 +243,18 @@ config SWAP_IO_SPACE config SYS_MIPS_CACHE_INIT_RAM_LOAD bool +config SYS_DCACHE_SIZE + hex + default 0 + +config SYS_ICACHE_SIZE + hex + default 0 + +config SYS_CACHELINE_SIZE + hex + default 0 + config MIPS_L1_CACHE_SHIFT_4 bool
arch/mips/lib/cache.c +1 -1
@@ -9,7 +9,7 @@#include <asm/cacheops.h> #include <asm/mipsregs.h> -#ifdef CONFIG_SYS_CACHELINE_SIZE +#if CONFIG_SYS_CACHELINE_SIZE !=0 static inline unsigned long icache_line_size (void ) {
arch/mips/lib/cache_init.S +3 -3
@@ -99,14 +99,14 @@ * */ LEAF(mips_cache_reset) -#ifdef CONFIG_SYS_ICACHE_SIZE +#if CONFIG_SYS_ICACHE_SIZE != 0 li t2, CONFIG_SYS_ICACHE_SIZE li t8, CONFIG_SYS_CACHELINE_SIZE #else l1_info t2, t8, MIPS_CONF1_IA_SHF #endif -#ifdef CONFIG_SYS_DCACHE_SIZE +#if CONFIG_SYS_DCACHE_SIZE != 0 li t3, CONFIG_SYS_DCACHE_SIZE li t9, CONFIG_SYS_CACHELINE_SIZE #else
@@ -116,7 +116,7 @@ LEAF(mips_cache_reset) #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD /* Determine the largest L1 cache size */ -#if defined(CONFIG_SYS_ICACHE_SIZE) && defined(CONFIG_SYS_DCACHE_SIZE) +#if (CONFIG_SYS_ICACHE_SIZE != 0) && (CONFIG_SYS_DCACHE_SIZE != 0) #if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE li v0, CONFIG_SYS_ICACHE_SIZE #else
board/dbau1x00/Kconfig +9 -0
@@ -12,6 +12,15 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0xbfc00000 +config SYS_DCACHE_SIZE + default 16384 + +config SYS_ICACHE_SIZE + default 16384 + +config SYS_CACHELINE_SIZE + default 32 + menu "dbau1x00 board options" choice
board/micronas/vct/Kconfig +9 -0
@@ -12,6 +12,15 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0x87000000 +config SYS_DCACHE_SIZE + default 16384 + +config SYS_ICACHE_SIZE + default 16384 + +config SYS_CACHELINE_SIZE + default 32 + menu "vct board options" choice
board/pb1x00/Kconfig +9 -0
@@ -12,4 +12,13 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0x83800000 +config SYS_DCACHE_SIZE + default 16384 + +config SYS_ICACHE_SIZE + default 16384 + +config SYS_CACHELINE_SIZE + default 32 + endif
board/qca/ap121/Kconfig +9 -0
@@ -12,4 +12,13 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0x9f000000 +config SYS_DCACHE_SIZE + default 0x8000 + +config SYS_ICACHE_SIZE + default 0x10000 + +config SYS_CACHELINE_SIZE + default 32 + endif
board/qca/ap143/Kconfig +9 -0
@@ -12,4 +12,13 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0x9f000000 +config SYS_DCACHE_SIZE + default 0x8000 + +config SYS_ICACHE_SIZE + default 0x10000 + +config SYS_CACHELINE_SIZE + default 32 + endif
board/qemu-mips/Kconfig +9 -0
@@ -11,4 +11,13 @@ config SYS_TEXT_BASE default 0xbfc00000 if 32BIT default 0xffffffffbfc00000 if 64BIT +config SYS_DCACHE_SIZE + default 16384 + +config SYS_ICACHE_SIZE + default 16384 + +config SYS_CACHELINE_SIZE + default 32 + endif
board/tplink/wdr4300/Kconfig +9 -0
@@ -15,4 +15,13 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0xa1000000 +config SYS_DCACHE_SIZE + default 0x8000 + +config SYS_ICACHE_SIZE + default 0x10000 + +config SYS_CACHELINE_SIZE + default 32 + endif
include/configs/ap121.h +0 -5
@@ -15,11 +15,6 @@#define CONFIG_SYS_MHZ 200#define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000) -/* Cache Configuration */ -#define CONFIG_SYS_DCACHE_SIZE 0x8000 -#define CONFIG_SYS_ICACHE_SIZE 0x10000 -#define CONFIG_SYS_CACHELINE_SIZE 32 -#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE#define CONFIG_SYS_MALLOC_LEN 0x40000
include/configs/ap143.h +0 -5
@@ -15,11 +15,6 @@#define CONFIG_SYS_MHZ 325#define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000) -/* Cache Configuration */ -#define CONFIG_SYS_DCACHE_SIZE 0x8000 -#define CONFIG_SYS_ICACHE_SIZE 0x10000 -#define CONFIG_SYS_CACHELINE_SIZE 32 -#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE#define CONFIG_SYS_MALLOC_LEN 0x40000
include/configs/dbau1x00.h +0 -7
@@ -202,11 +202,4 @@#define CONFIG_SYS_ATA_ALT_OFFSET 0x0100#endif /* CONFIG_DBAU1550 */ -/*----------------------------------------------------------------------- -* Cache Configuration -*/ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32 -#endif /* __CONFIG_H */
include/configs/pb1x00.h +0 -6
@@ -144,12 +144,6 @@#define CONFIG_SYS_ATA_ALT_OFFSET 0x0100#endif -/*----------------------------------------------------------------------- -* Cache Configuration -*/ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32/* * BOOTP options
include/configs/qemu-mips.h +0 -7
@@ -132,11 +132,4 @@#define CONFIG_LZMA -/*----------------------------------------------------------------------- -* Cache Configuration -*/ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32 -#endif /* __CONFIG_H */
include/configs/qemu-mips64.h +0 -7
@@ -132,11 +132,4 @@#define CONFIG_LZMA -/*----------------------------------------------------------------------- -* Cache Configuration -*/ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32 -#endif /* __CONFIG_H */
include/configs/tplink_wdr4300.h +0 -5
@@ -15,11 +15,6 @@#define CONFIG_SYS_MHZ 280#define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000) -/* Cache Configuration */ -#define CONFIG_SYS_DCACHE_SIZE 0x8000 -#define CONFIG_SYS_ICACHE_SIZE 0x10000 -#define CONFIG_SYS_CACHELINE_SIZE 32 -#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE#define CONFIG_SYS_MALLOC_LEN 0x40000
include/configs/vct.h +0 -7
@@ -204,13 +204,6 @@#endif /* CONFIG_VCT_ONENAND */ /* -* Cache Configuration -*/ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32 - -/* * I2C/EEPROM */ #define CONFIG_SYS_I2C
Signature · 1 line
2.8.3
PATCH 1/3 MIPS: Move cache sizes to Kconfig
Quoted 37 lines · Paul Burton
Move details of the L1 cache line sizes & total sizes into
Kconfig, defaulting to 0 & using 0 to indicate that the value should be autodetected.Signed-off-by Paul Burton <[email protected]>---
arch/mips/Kconfig | 12 ++++++++++++ arch/mips/lib/cache.c | 2 +- arch/mips/lib/cache_init.S | 6 +++--- board/dbau1x00/Kconfig | 9 +++++++++ board/micronas/vct/Kconfig | 9 +++++++++ board/pb1x00/Kconfig | 9 +++++++++ board/qca/ap121/Kconfig | 9 +++++++++ board/qca/ap143/Kconfig | 9 +++++++++ board/qemu-mips/Kconfig | 9 +++++++++ board/tplink/wdr4300/Kconfig | 9 +++++++++ include/configs/ap121.h | 5 ----- include/configs/ap143.h | 5 ----- include/configs/dbau1x00.h | 7 ------- include/configs/pb1x00.h | 6 ------ include/configs/qemu-mips.h | 7 ------- include/configs/qemu-mips64.h | 7 ------- include/configs/tplink_wdr4300.h | 5 ----- include/configs/vct.h | 7 ------- 18 files changed, 79 insertions(+), 53 deletions(-)arch/mips/Kconfig +2
-0@@ -243,6 +243,18 @@ config SWAP_IO_SPACE config SYS_MIPS_CACHE_INIT_RAM_LOAD bool +config SYS_DCACHE_SIZE + hex
arch/mips/Kconfig config SWAP_IO_SPACE · line 257
Quoted 10 lines
arch/mips/Kconfig +10
-0+ default 0 + +config SYS_ICACHE_SIZE + hex + default 0 + +config SYS_CACHELINE_SIZE + hex + default 0 +
Please add some short help text to those options.
arch/mips/lib/cache.c line 12
Quoted 13 lines
arch/mips/Kconfig +0
-0config MIPS_L1_CACHE_SHIFT_4 boolarch/mips/lib/cache.c +1
-1@@ -9,7 +9,7 @@#include <asm/cacheops.h> #include <asm/mipsregs.h> -#ifdef CONFIG_SYS_CACHELINE_SIZE +#if CONFIG_SYS_CACHELINE_SIZE !=0
Wouldn't it make more sense to introduce something like CONFIG_HAVE_CACHE_SUPPORT instead , so you don't need this #if CONFIG_FOO != 0 construct all over the place ?
Cool stuff otherwise, thanks!
Quoted 295 lines
arch/mips/lib/cache.c +0
-0static inline unsigned long icache_line_size (void ) {arch/mips/lib/cache_init.S +3
-3@@ -99,14 +99,14 @@ * */ LEAF(mips_cache_reset) -#ifdef CONFIG_SYS_ICACHE_SIZE +#if CONFIG_SYS_ICACHE_SIZE != 0 li t2, CONFIG_SYS_ICACHE_SIZE li t8, CONFIG_SYS_CACHELINE_SIZE #else l1_info t2, t8, MIPS_CONF1_IA_SHF #endif -#ifdef CONFIG_SYS_DCACHE_SIZE +#if CONFIG_SYS_DCACHE_SIZE != 0 li t3, CONFIG_SYS_DCACHE_SIZE li t9, CONFIG_SYS_CACHELINE_SIZE #else@@ -116,7 +116,7 @@ LEAF(mips_cache_reset) #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD /* Determine the largest L1 cache size */ -#if defined(CONFIG_SYS_ICACHE_SIZE) && defined(CONFIG_SYS_DCACHE_SIZE) +#if (CONFIG_SYS_ICACHE_SIZE != 0) && (CONFIG_SYS_DCACHE_SIZE != 0) #if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE li v0, CONFIG_SYS_ICACHE_SIZE #elseboard/dbau1x00/Kconfig +9
-0@@ -12,6 +12,15 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0xbfc00000 +config SYS_DCACHE_SIZE + default 16384 + +config SYS_ICACHE_SIZE + default 16384 + +config SYS_CACHELINE_SIZE + default 32 + menu "dbau1x00 board options" choiceboard/micronas/vct/Kconfig +9
-0@@ -12,6 +12,15 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0x87000000 +config SYS_DCACHE_SIZE + default 16384 + +config SYS_ICACHE_SIZE + default 16384 + +config SYS_CACHELINE_SIZE + default 32 + menu "vct board options" choiceboard/pb1x00/Kconfig +9
-0@@ -12,4 +12,13 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0x83800000 +config SYS_DCACHE_SIZE + default 16384 + +config SYS_ICACHE_SIZE + default 16384 + +config SYS_CACHELINE_SIZE + default 32 + endifboard/qca/ap121/Kconfig +9
-0@@ -12,4 +12,13 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0x9f000000 +config SYS_DCACHE_SIZE + default 0x8000 + +config SYS_ICACHE_SIZE + default 0x10000 + +config SYS_CACHELINE_SIZE + default 32 + endifboard/qca/ap143/Kconfig +9
-0@@ -12,4 +12,13 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0x9f000000 +config SYS_DCACHE_SIZE + default 0x8000 + +config SYS_ICACHE_SIZE + default 0x10000 + +config SYS_CACHELINE_SIZE + default 32 + endifboard/qemu-mips/Kconfig +9
-0@@ -11,4 +11,13 @@ config SYS_TEXT_BASE default 0xbfc00000 if 32BIT default 0xffffffffbfc00000 if 64BIT +config SYS_DCACHE_SIZE + default 16384 + +config SYS_ICACHE_SIZE + default 16384 + +config SYS_CACHELINE_SIZE + default 32 + endifboard/tplink/wdr4300/Kconfig +9
-0@@ -15,4 +15,13 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0xa1000000 +config SYS_DCACHE_SIZE + default 0x8000 + +config SYS_ICACHE_SIZE + default 0x10000 + +config SYS_CACHELINE_SIZE + default 32 + endifinclude/configs/ap121.h +0
-5@@ -15,11 +15,6 @@#define CONFIG_SYS_MHZ 200#define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000) -/* Cache Configuration */ -#define CONFIG_SYS_DCACHE_SIZE 0x8000 -#define CONFIG_SYS_ICACHE_SIZE 0x10000 -#define CONFIG_SYS_CACHELINE_SIZE 32 -#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE#define CONFIG_SYS_MALLOC_LEN 0x40000include/configs/ap143.h +0
-5@@ -15,11 +15,6 @@#define CONFIG_SYS_MHZ 325#define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000) -/* Cache Configuration */ -#define CONFIG_SYS_DCACHE_SIZE 0x8000 -#define CONFIG_SYS_ICACHE_SIZE 0x10000 -#define CONFIG_SYS_CACHELINE_SIZE 32 -#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE#define CONFIG_SYS_MALLOC_LEN 0x40000include/configs/dbau1x00.h +0
-7@@ -202,11 +202,4 @@#define CONFIG_SYS_ATA_ALT_OFFSET 0x0100#endif /* CONFIG_DBAU1550 */ -/*----------------------------------------------------------------------- -* Cache Configuration -*/ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32 -#endif /* __CONFIG_H */ include/configs/pb1x00.h +0
-6@@ -144,12 +144,6 @@#define CONFIG_SYS_ATA_ALT_OFFSET 0x0100#endif -/*----------------------------------------------------------------------- -* Cache Configuration -*/ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32/* * BOOTP options include/configs/qemu-mips.h +0
-7@@ -132,11 +132,4 @@#define CONFIG_LZMA -/*----------------------------------------------------------------------- -* Cache Configuration -*/ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32 -#endif /* __CONFIG_H */ include/configs/qemu-mips64.h +0
-7@@ -132,11 +132,4 @@#define CONFIG_LZMA -/*----------------------------------------------------------------------- -* Cache Configuration -*/ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32 -#endif /* __CONFIG_H */ include/configs/tplink_wdr4300.h +0
-5@@ -15,11 +15,6 @@#define CONFIG_SYS_MHZ 280#define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000) -/* Cache Configuration */ -#define CONFIG_SYS_DCACHE_SIZE 0x8000 -#define CONFIG_SYS_ICACHE_SIZE 0x10000 -#define CONFIG_SYS_CACHELINE_SIZE 32 -#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE#define CONFIG_SYS_MALLOC_LEN 0x40000include/configs/vct.h +0
-7@@ -204,13 +204,6 @@#endif /* CONFIG_VCT_ONENAND */ /* -* Cache Configuration -*/ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32 - -/* * I2C/EEPROM */ #define CONFIG_SYS_I2C
Signature · 2 lines
Best regards, Marek Vasut
PATCH 1/3 MIPS: Move cache sizes to Kconfig
Quoted 8 lines · Marek Vasut
Quoted 8 lines
arch/mips/lib/cache.c +0
-0@@ -9,7 +9,7 @@#include <asm/cacheops.h> #include <asm/mipsregs.h>
Quoted 6 lines
arch/mips/lib/cache.c line 12
Quoted 2 lines
arch/mips/lib/cache.c +1
-1-#ifdef CONFIG_SYS_CACHELINE_SIZE +#if CONFIG_SYS_CACHELINE_SIZE !=0 Wouldn't it make more sense to introduce something like
CONFIG_HAVE_CACHE_SUPPORTinstead , so you don't need this #ifCONFIG_FOO!= 0 construct all over the place ?
Hi Marek,
It's not about whether cache support is present (we always build cache support), it's about whether we are hardcoding the sizes of the caches or detecting them at runtime. The latter is especially useful on FPGA-based platforms like Malta where the CPU (& caches) can change. I suppose I could add something like CONFIG_SYS_CACHE_SIZE_AUTO, but I still think it would be cleanest to have that default to a value based upon whether a board has set a non-zero size for any of the caches.
Quoted 1 line
Cool stuff otherwise, thanks!
Thanks,
Paul
PATCH 1/3 MIPS: Move cache sizes to Kconfig
Quoted 18 lines · Paul Burton
Quoted 8 lines · Marek Vasut
Quoted 8 lines
arch/mips/lib/cache.c +0
-0@@ -9,7 +9,7 @@#include <asm/cacheops.h> #include <asm/mipsregs.h> Quoted 6 lines
arch/mips/lib/cache.c line 12
Quoted 2 lines
arch/mips/lib/cache.c +1
-1-#ifdef CONFIG_SYS_CACHELINE_SIZE +#if CONFIG_SYS_CACHELINE_SIZE !=0 Wouldn't it make more sense to introduce something like
CONFIG_HAVE_CACHE_SUPPORTinstead , so you don't need this #ifCONFIG_FOO!= 0 construct all over the place ?Hi Marek,
Quoted 7 lines
It's not about whether cache support is present (we always build cache support), it's about whether we are hardcoding the sizes of the caches or detecting them at runtime. The latter is especially useful on FPGA-based platforms like Malta where the CPU (& caches) can change. I suppose I could add something like
CONFIG_SYS_CACHE_SIZE_AUTO, but I still think it would be cleanest to have that default to a value based upon whether a board has set a non-zero size for any of the caches.
Auto-detecting cacheline size is cool, but that'd need much more work. Just grep through drivers/ for CONFIG_SYS_CACHELINE_SIZE and you'll see a lot of code depends on non-zero value in it. Setting it to zero will just bite you at some point in a nasty way.
Quoted 5 lines
Quoted 1 line
Cool stuff otherwise, thanks!
Thanks,
Paul
Signature · 2 lines
Best regards, Marek Vasut
PATCH 1/3 MIPS: Move cache sizes to Kconfig
Quoted 27 lines · Marek Vasut
Quoted 18 lines · Paul Burton
Quoted 8 lines · Marek Vasut
Quoted 8 lines
arch/mips/lib/cache.c +0
-0@@ -9,7 +9,7 @@#include <asm/cacheops.h> #include <asm/mipsregs.h> Quoted 6 lines
arch/mips/lib/cache.c line 12
Quoted 2 lines
arch/mips/lib/cache.c +1
-1-#ifdef CONFIG_SYS_CACHELINE_SIZE +#if CONFIG_SYS_CACHELINE_SIZE !=0 Wouldn't it make more sense to introduce something like
CONFIG_HAVE_CACHE_SUPPORTinstead , so you don't need this #ifCONFIG_FOO!= 0 construct all over the place ?Hi Marek,
Quoted 7 lines
It's not about whether cache support is present (we always build cache support), it's about whether we are hardcoding the sizes of the caches or detecting them at runtime. The latter is especially useful on FPGA-based platforms like Malta where the CPU (& caches) can change. I suppose I could add something like
CONFIG_SYS_CACHE_SIZE_AUTO, but I still think it would be cleanest to have that default to a value based upon whether a board has set a non-zero size for any of the caches.
Quoted 4 lines
Auto-detecting cacheline size is cool, but that'd need much more work. Just grep through
drivers/forCONFIG_SYS_CACHELINE_SIZEand you'll see a lot of code depends on non-zero value in it. Setting it to zero will just bite you at some point in a nasty way.
Hi Marek,
We're already using the cache size auto-detection on Malta, and on 2 other FPGA-based boards internally. I've submitted v2 which preserves CONFIG_SYS_CACHELINE_SIZE as a synonym of ARCH_DMA_MINALIGN for the drivers that are still using it.
Thanks,
Paul
PATCH 1/3 MIPS: Move cache sizes to Kconfig
Quoted 28 lines · Paul Burton
Quoted 27 lines · Marek Vasut
Quoted 25 lines · Paul Burton
Quoted 8 lines · Marek Vasut
Quoted 8 lines
arch/mips/lib/cache.c +0
-0@@ -9,7 +9,7 @@#include <asm/cacheops.h> #include <asm/mipsregs.h> Quoted 6 lines
arch/mips/lib/cache.c line 12
Quoted 2 lines
arch/mips/lib/cache.c +1
-1-#ifdef CONFIG_SYS_CACHELINE_SIZE +#if CONFIG_SYS_CACHELINE_SIZE !=0 Wouldn't it make more sense to introduce something like
CONFIG_HAVE_CACHE_SUPPORTinstead , so you don't need this #ifCONFIG_FOO!= 0 construct all over the place ?Hi Marek,
It's not about whether cache support is present (we always build cache support), it's about whether we are hardcoding the sizes of the caches or detecting them at runtime. The latter is especially useful on FPGA-based platforms like Malta where the CPU (& caches) can change. I suppose I could add something like
CONFIG_SYS_CACHE_SIZE_AUTO, but I still think it would be cleanest to have that default to a value based upon whether a board has set a non-zero size for any of the caches.
Quoted 6 lines
Quoted 4 lines
Auto-detecting cacheline size is cool, but that'd need much more work. Just grep through
drivers/forCONFIG_SYS_CACHELINE_SIZEand you'll see a lot of code depends on non-zero value in it. Setting it to zero will just bite you at some point in a nasty way.Hi Marek,
Hi!
Quoted 4 lines
We're already using the cache size auto-detection on Malta, and on 2 other FPGA-based boards internally. I've submitted v2 which preserves
CONFIG_SYS_CACHELINE_SIZEas a synonym ofARCH_DMA_MINALIGNfor the drivers that are still using it.
That's a good workaround for now. Would you be interested in fixing this runtime cache configuration properly ?
Off-topic: Is malta that mipsfpga or is that something else ? Can I synthesise that mipsfpga into some altera FPGA ? If so, which one is a good pick ?
Quoted 3 lines
Thanks,
Paul
Signature · 2 lines
Best regards, Marek Vasut
PATCH 1/3 MIPS: Move cache sizes to Kconfig
Quoted 3 lines · Marek Vasut
Quoted 1 line
Hi Marek,
Hi!
Hi again Marek :)
Quoted 7 lines
Quoted 4 lines
We're already using the cache size auto-detection on Malta, and on 2 other FPGA-based boards internally. I've submitted v2 which preserves
CONFIG_SYS_CACHELINE_SIZEas a synonym ofARCH_DMA_MINALIGNfor the drivers that are still using it.That's a good workaround for now. Would you be interested in fixing this runtime cache configuration properly ?
We use the runtime cache size detection on Malta, on SEAD3 & on Boston. The latter 2 aren't upstream yet of course, but all 3 are FPGA-based platforms used to develop, test & showcase new CPUs. As such the CPU (& by association the cache) can change just by flashing a new bitfile to the board, and it's very convenient for a single build of U-Boot to work regardless of the bitfile in use.
It all works fine so long as drivers are well behaved, and nothing on any of those platforms uses CONFIG_SYS_CACHELINE_SIZE. I'm not sure there's anything to fix really apart from drivers should possibly move to use ARCH_DMA_MINALIGN, but I wouldn't feel comfortable doing a global replacement as I don't have a way to test many boards for other architectures.
Quoted 3 lines
Off-topic: Is malta that mipsfpga or is that something else ? Can I synthesise that mipsfpga into some altera FPGA ? If so, which one is a good pick ?
I don't know much about the MIPSfpga project to be honest, but I can forward your question to someone who does.
Thanks,
Paul
PATCH 1/3 MIPS: Move cache sizes to Kconfig
Quoted 6 lines · Paul Burton
Quoted 3 lines · Marek Vasut
Quoted 1 line
Hi Marek,
Hi!
Hi again Marek :)
Hi!
Quoted 8 lines
Quoted 7 lines
Quoted 4 lines
We're already using the cache size auto-detection on Malta, and on 2 other FPGA-based boards internally. I've submitted v2 which preserves
CONFIG_SYS_CACHELINE_SIZEas a synonym ofARCH_DMA_MINALIGNfor the drivers that are still using it.That's a good workaround for now. Would you be interested in fixing this runtime cache configuration properly ?
Quoted 6 lines
We use the runtime cache size detection on Malta, on SEAD3 & on Boston. The latter 2 aren't upstream yet of course, but all 3 are FPGA-based platforms used to develop, test & showcase new CPUs. As such the CPU (& by association the cache) can change just by flashing a new bitfile to the board, and it's very convenient for a single build of U-Boot to work regardless of the bitfile in use.
Right, this much I understand.
Quoted 6 lines
It all works fine so long as drivers are well behaved, and nothing on any of those platforms uses
CONFIG_SYS_CACHELINE_SIZE. I'm not sure there's anything to fix really apart from drivers should possibly move to useARCH_DMA_MINALIGN, but I wouldn't feel comfortable doing a global replacement as I don't have a way to test many boards for other architectures.
I went through the u-boot sources again and it's mostly USB to blame, but I don't think USB should use ARCH_DMA_MINALIGN. USB controllers usually have their own DMA engine which might have different alignment requirements from the one in the CPU. This would imply that the entire concept of ARCH_DMA_MINALIGN is becoming increasingly inapplicable to modern CPUs and we might need some sort of DMA API to deal with that.
But ok, that would be a lot of work far beyond the scope of this patchset. I suspect setting CONFIG_SYS_CACHELINE_SIZE to sensible default so it wouldn't break USB would be a good start. 128 might be a good pick, since I don't think there are systems with cache line size longer than that and so flushing/invalidating that much would assure it works on whole cacheline at least.
Quoted 6 lines
Quoted 3 lines
Off-topic: Is malta that mipsfpga or is that something else ? Can I synthesise that mipsfpga into some altera FPGA ? If so, which one is a good pick ?
I don't know much about the MIPSfpga project to be honest, but I can forward your question to someone who does.
That's OK, I will poke myself into it before bothering you with it, thanks!
Quoted 3 lines
Thanks,
Paul
Signature · 2 lines
Best regards, Marek Vasut
PATCH 1/3 MIPS: Move cache sizes to Kconfig
In reply to Marek VasutAm 27.05.2016 um 16:40 schrieb Marek Vasut:
Quoted 38 lines · Paul Burton
Quoted 28 lines · Marek Vasut
Quoted 27 lines · Paul Burton
Quoted 25 lines · Marek Vasut
Quoted 8 lines
Quoted 8 lines
arch/mips/lib/cache.c +0
-0@@ -9,7 +9,7 @@#include <asm/cacheops.h> #include <asm/mipsregs.h> Quoted 6 lines
arch/mips/lib/cache.c line 12
Quoted 2 lines
arch/mips/lib/cache.c +1
-1-#ifdef CONFIG_SYS_CACHELINE_SIZE +#if CONFIG_SYS_CACHELINE_SIZE !=0 Wouldn't it make more sense to introduce something like
CONFIG_HAVE_CACHE_SUPPORTinstead , so you don't need this #ifCONFIG_FOO!= 0 construct all over the place ?Hi Marek,
It's not about whether cache support is present (we always build cache support), it's about whether we are hardcoding the sizes of the caches or detecting them at runtime. The latter is especially useful on FPGA-based platforms like Malta where the CPU (& caches) can change. I suppose I could add something like
CONFIG_SYS_CACHE_SIZE_AUTO, but I still think it would be cleanest to have that default to a value based upon whether a board has set a non-zero size for any of the caches.Quoted 6 lines
Quoted 4 lines
Auto-detecting cacheline size is cool, but that'd need much more work. Just grep through
drivers/forCONFIG_SYS_CACHELINE_SIZEand you'll see a lot of code depends on non-zero value in it. Setting it to zero will just bite you at some point in a nasty way.Hi Marek,
Hi!
Quoted 8 lines
Quoted 4 lines
We're already using the cache size auto-detection on Malta, and on 2 other FPGA-based boards internally. I've submitted v2 which preserves
CONFIG_SYS_CACHELINE_SIZEas a synonym ofARCH_DMA_MINALIGNfor the drivers that are still using it.That's a good workaround for now. Would you be interested in fixing this runtime cache configuration properly ?
there is no runtime configuration for ARCH_DMA_MINALIGN. This value is defined at compile-time by Kconfig option MIPS_L1_CACHE_SHIFT. This is similar to what Linux is doing.
Signature · 9 lines
- Daniel -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: OpenPGP digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20160527/35c32fbb/attachment.sig>
PATCH 1/3 MIPS: Move cache sizes to Kconfig
Quoted 46 lines · Daniel Schwierzeck
Am 27.05.2016 um 16:40 schrieb Marek Vasut:
Quoted 43 lines · Paul Burton
Quoted 28 lines · Marek Vasut
Quoted 27 lines · Paul Burton
Quoted 25 lines · Marek Vasut
Quoted 8 lines
Quoted 8 lines
arch/mips/lib/cache.c +0
-0@@ -9,7 +9,7 @@#include <asm/cacheops.h> #include <asm/mipsregs.h> Quoted 6 lines
arch/mips/lib/cache.c line 12
Quoted 2 lines
arch/mips/lib/cache.c +1
-1-#ifdef CONFIG_SYS_CACHELINE_SIZE +#if CONFIG_SYS_CACHELINE_SIZE !=0 Wouldn't it make more sense to introduce something like
CONFIG_HAVE_CACHE_SUPPORTinstead , so you don't need this #ifCONFIG_FOO!= 0 construct all over the place ?Hi Marek,
It's not about whether cache support is present (we always build cache support), it's about whether we are hardcoding the sizes of the caches or detecting them at runtime. The latter is especially useful on FPGA-based platforms like Malta where the CPU (& caches) can change. I suppose I could add something like
CONFIG_SYS_CACHE_SIZE_AUTO, but I still think it would be cleanest to have that default to a value based upon whether a board has set a non-zero size for any of the caches.Quoted 6 lines
Quoted 4 lines
Auto-detecting cacheline size is cool, but that'd need much more work. Just grep through
drivers/forCONFIG_SYS_CACHELINE_SIZEand you'll see a lot of code depends on non-zero value in it. Setting it to zero will just bite you at some point in a nasty way.Hi Marek,
Hi!
Quoted 4 lines
We're already using the cache size auto-detection on Malta, and on 2 other FPGA-based boards internally. I've submitted v2 which preserves
CONFIG_SYS_CACHELINE_SIZEas a synonym ofARCH_DMA_MINALIGNfor the drivers that are still using it.
Quoted 8 lines
Quoted 3 lines
That's a good workaround for now. Would you be interested in fixing this runtime cache configuration properly ?
there is no runtime configuration for
ARCH_DMA_MINALIGN. This value is defined at compile-time byKconfigoptionMIPS_L1_CACHE_SHIFT. This is similar to what Linux is doing.
So the DMA_MINALIGN is always a multiple of cacheline size on MIPS ?
Signature · 2 lines
Best regards, Marek Vasut
PATCH 1/3 MIPS: Move cache sizes to Kconfig
In reply to Marek VasutMarek Vasut <marex <at> denx.de> writes:
...
Quoted 4 lines
Off-topic: Is malta that mipsfpga or is that something else ? Can I synthesise that mipsfpga into some altera FPGA ? If so, which one is a good pick ?
Hi Marek
Malta is a generic MIPS evaluation platform.
https://www.linux-mips.org/wiki/MIPS_Malta
MIPSfpga is currently for universities/academics.
A microAptiv core (including verilog source code) is given to academics to play with. The whole pack includes teaching resources, exercises, guides etc.
If you do come under the definition of a University/Academic, do check it out https://community.imgtec.com/university/
Reference designs to run bare metal code runs on both Xilinx/Altera FPGAs.
However, reference designs to run the Linux Kernel are Xilinx specific.
Some more detail here.
https://kernel.org/doc/Documentation/devicetree/bindings/mips/img/xilfpga.txt
Hope that helps.
Thanks
ZubairLK
PATCH 1/3 MIPS: Move cache sizes to Kconfig
In reply to Paul BurtonAm 26.05.2016 um 17:58 schrieb Paul Burton:
Quoted 18 lines
Move details of the L1 cache line sizes & total sizes into
Kconfig, defaulting to 0 & using 0 to indicate that the value should be autodetected.Signed-off-by Paul Burton <[email protected]>---
arch/mips/Kconfig | 12 ++++++++++++ arch/mips/lib/cache.c | 2 +- arch/mips/lib/cache_init.S | 6 +++--- board/dbau1x00/Kconfig | 9 +++++++++ board/micronas/vct/Kconfig | 9 +++++++++ board/pb1x00/Kconfig | 9 +++++++++ board/qca/ap121/Kconfig | 9 +++++++++ board/qca/ap143/Kconfig | 9 +++++++++ board/qemu-mips/Kconfig | 9 +++++++++ board/tplink/wdr4300/Kconfig | 9 +++++++++ include/configs/ap121.h | 5 -----
Quoted 9 lines
include/configs/ap143.h | 5 ----- include/configs/dbau1x00.h | 7 ------- include/configs/pb1x00.h | 6 ------ include/configs/qemu-mips.h | 7 ------- include/configs/qemu-mips64.h | 7 ------- include/configs/tplink_wdr4300.h | 5 ----- include/configs/vct.h | 7 ------- 18 files changed, 79 insertions(+), 53 deletions(-)
applied to u-boot-mips, thanks!
Signature · 9 lines
- Daniel -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: OpenPGP digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20160531/7538be9d/attachment.sig>
PATCH 2/3 MIPS: Split I & D cache line size config
In reply to Paul BurtonAllow L1 Icache & L1 Dcache line size to be specified separately, since there's no architectural mandate that they be the same. The [id]cache_line_size functions are tidied up to take advantage of the fact that the Kconfig entries are always present to simply check them for zero rather than needing to #ifdef on their presence.
---
arch/mips/Kconfig | 6 +++++- arch/mips/lib/cache.c | 22 +++++++--------------- arch/mips/lib/cache_init.S | 4 ++-- board/dbau1x00/Kconfig | 5 ++++- board/micronas/vct/Kconfig | 5 ++++- board/pb1x00/Kconfig | 5 ++++- board/qca/ap121/Kconfig | 5 ++++- board/qca/ap143/Kconfig | 5 ++++- board/qemu-mips/Kconfig | 5 ++++- board/tplink/wdr4300/Kconfig | 5 ++++- 10 files changed, 42 insertions(+), 25 deletions(-)
arch/mips/Kconfig +5 -1
@@ -247,11 +247,15 @@ config SYS_DCACHE_SIZE hex default 0 +config SYS_DCACHE_LINE_SIZE + hex + default 0 + config SYS_ICACHE_SIZE hex default 0 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE hex default 0
arch/mips/lib/cache.c +7 -15
@@ -9,23 +9,13 @@#include <asm/cacheops.h> #include <asm/mipsregs.h> -#if CONFIG_SYS_CACHELINE_SIZE !=0 -static inline unsigned long icache_line_size (void ) { -return CONFIG_SYS_CACHELINE_SIZE ; -} - -static inline unsigned long dcache_line_size (void ) -{ -return CONFIG_SYS_CACHELINE_SIZE ; -} +unsigned long conf1, il; -#else /* !CONFIG_SYS_CACHELINE_SIZE */ +if (CONFIG_SYS_ICACHE_LINE_SIZE !=0 ) +return CONFIG_SYS_ICACHE_LINE_SIZE ; -static inline unsigned long icache_line_size (void ) -{ -unsigned long conf1, il; conf1 =read_c0_config1 (); il = (conf1 &MIPS_CONF1_IL ) >>MIPS_CONF1_IL_SHF ;if (!il)
@@ -36,6 +26,10 @@ static inline unsigned long icache_line_size(void)static inline unsigned long dcache_line_size (void ) {unsigned long conf1, dl; + +if (CONFIG_SYS_DCACHE_LINE_SIZE !=0 ) +return CONFIG_SYS_DCACHE_LINE_SIZE ; + conf1 =read_c0_config1 (); dl = (conf1 &MIPS_CONF1_DL ) >>MIPS_CONF1_DL_SHF ;if (!dl)
@@ -43,8 +37,6 @@ static inline unsigned long dcache_line_size(void)return 2 << dl; } -#endif /* !CONFIG_SYS_CACHELINE_SIZE */ -void flush_cache (ulong start_addr,ulong size) {unsigned long ilsize =icache_line_size ();
arch/mips/lib/cache_init.S +2 -2
@@ -101,14 +101,14 @@ LEAF(mips_cache_reset) #if CONFIG_SYS_ICACHE_SIZE != 0 li t2, CONFIG_SYS_ICACHE_SIZE - li t8, CONFIG_SYS_CACHELINE_SIZE + li t8, CONFIG_SYS_ICACHE_LINE_SIZE #else l1_info t2, t8, MIPS_CONF1_IA_SHF #endif #if CONFIG_SYS_DCACHE_SIZE != 0 li t3, CONFIG_SYS_DCACHE_SIZE - li t9, CONFIG_SYS_CACHELINE_SIZE + li t9, CONFIG_SYS_DCACHE_LINE_SIZE #else l1_info t3, t9, MIPS_CONF1_DA_SHF #endif
board/dbau1x00/Kconfig +4 -1
@@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 16384 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 16384 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 menu "dbau1x00 board options"
board/micronas/vct/Kconfig +4 -1
@@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 16384 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 16384 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 menu "vct board options"
board/pb1x00/Kconfig +4 -1
@@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 16384 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 16384 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endif
board/qca/ap121/Kconfig +4 -1
@@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 0x8000 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 0x10000 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endif
board/qca/ap143/Kconfig +4 -1
@@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 0x8000 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 0x10000 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endif
board/qemu-mips/Kconfig +4 -1
@@ -14,10 +14,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 16384 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 16384 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endif
board/tplink/wdr4300/Kconfig +4 -1
@@ -18,10 +18,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 0x8000 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 0x10000 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endif
Signature · 1 line
2.8.3
PATCH 2/3 MIPS: Split I & D cache line size config
Quoted 29 lines · Paul Burton
Allow L1 Icache & L1 Dcache line size to be specified separately, since there's no architectural mandate that they be the same. The [id]cache_line_size functions are tidied up to take advantage of the fact that the
Kconfigentries are always present to simply check them for zero rather than needing to #ifdef on their presence.Signed-off-by Paul Burton <[email protected]>---
arch/mips/Kconfig | 6 +++++- arch/mips/lib/cache.c | 22 +++++++--------------- arch/mips/lib/cache_init.S | 4 ++-- board/dbau1x00/Kconfig | 5 ++++- board/micronas/vct/Kconfig | 5 ++++- board/pb1x00/Kconfig | 5 ++++- board/qca/ap121/Kconfig | 5 ++++- board/qca/ap143/Kconfig | 5 ++++- board/qemu-mips/Kconfig | 5 ++++- board/tplink/wdr4300/Kconfig | 5 ++++- 10 files changed, 42 insertions(+), 25 deletions(-)arch/mips/Kconfig +0
-0@@ -247,11 +247,15 @@ config SYS_DCACHE_SIZE hex default 0
arch/mips/Kconfig config SYS_DCACHE_SIZE · line 258
Quoted 10 lines
arch/mips/Kconfig +5
-1+config SYS_DCACHE_LINE_SIZE + hex + default 0 + config SYS_ICACHE_SIZE hex default 0 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE
Be careful here, CONFIG_SYS_CACHELINE_SIZE is established all over the u-boot, so this might cause build breakage. You should keep some compatibility CONFIG_SYS_CACHELINE_SIZE entry and set it to default to SYS_DCACHE_LINE_SIZE , since it's mostly used for DMA anyway.
Quoted 209 lines
arch/mips/Kconfig +0
-0hex default 0arch/mips/lib/cache.c +7
-15@@ -9,23 +9,13 @@#include <asm/cacheops.h> #include <asm/mipsregs.h> -#if CONFIG_SYS_CACHELINE_SIZE !=0 -static inline unsigned long icache_line_size (void ) { -return CONFIG_SYS_CACHELINE_SIZE ; -} - -static inline unsigned long dcache_line_size (void ) -{ -return CONFIG_SYS_CACHELINE_SIZE ; -} +unsigned long conf1, il; -#else /* !CONFIG_SYS_CACHELINE_SIZE */ +if (CONFIG_SYS_ICACHE_LINE_SIZE !=0 ) +return CONFIG_SYS_ICACHE_LINE_SIZE ; -static inline unsigned long icache_line_size (void ) -{ -unsigned long conf1, il; conf1 =read_c0_config1 (); il = (conf1 &MIPS_CONF1_IL ) >>MIPS_CONF1_IL_SHF ;if (!il)@@ -36,6 +26,10 @@ static inline unsigned long icache_line_size(void)static inline unsigned long dcache_line_size (void ) {unsigned long conf1, dl; + +if (CONFIG_SYS_DCACHE_LINE_SIZE !=0 ) +return CONFIG_SYS_DCACHE_LINE_SIZE ; + conf1 =read_c0_config1 (); dl = (conf1 &MIPS_CONF1_DL ) >>MIPS_CONF1_DL_SHF ;if (!dl)@@ -43,8 +37,6 @@ static inline unsigned long dcache_line_size(void)return 2 << dl; } -#endif /* !CONFIG_SYS_CACHELINE_SIZE */ -void flush_cache (ulong start_addr,ulong size) {unsigned long ilsize =icache_line_size ();arch/mips/lib/cache_init.S +2
-2@@ -101,14 +101,14 @@ LEAF(mips_cache_reset) #if CONFIG_SYS_ICACHE_SIZE != 0 li t2, CONFIG_SYS_ICACHE_SIZE - li t8, CONFIG_SYS_CACHELINE_SIZE + li t8, CONFIG_SYS_ICACHE_LINE_SIZE #else l1_info t2, t8, MIPS_CONF1_IA_SHF #endif #if CONFIG_SYS_DCACHE_SIZE != 0 li t3, CONFIG_SYS_DCACHE_SIZE - li t9, CONFIG_SYS_CACHELINE_SIZE + li t9, CONFIG_SYS_DCACHE_LINE_SIZE #else l1_info t3, t9, MIPS_CONF1_DA_SHF #endifboard/dbau1x00/Kconfig +4
-1@@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 16384 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 16384 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 menu "dbau1x00 board options"board/micronas/vct/Kconfig +4
-1@@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 16384 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 16384 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 menu "vct board options"board/pb1x00/Kconfig +4
-1@@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 16384 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 16384 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endifboard/qca/ap121/Kconfig +4
-1@@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 0x8000 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 0x10000 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endifboard/qca/ap143/Kconfig +4
-1@@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 0x8000 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 0x10000 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endifboard/qemu-mips/Kconfig +4
-1@@ -14,10 +14,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 16384 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 16384 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endifboard/tplink/wdr4300/Kconfig +4
-1@@ -18,10 +18,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 0x8000 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 0x10000 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endif
Signature · 2 lines
Best regards, Marek Vasut
PATCH 2/3 MIPS: Split I & D cache line size config
Am 26.05.2016 um 18:12 schrieb Marek Vasut:
Quoted 38 lines · Paul Burton
Quoted 37 lines
Allow L1 Icache & L1 Dcache line size to be specified separately, since there's no architectural mandate that they be the same. The [id]cache_line_size functions are tidied up to take advantage of the fact that the
Kconfigentries are always present to simply check them for zero rather than needing to #ifdef on their presence.Signed-off-by Paul Burton <[email protected]>---
arch/mips/Kconfig | 6 +++++- arch/mips/lib/cache.c | 22 +++++++--------------- arch/mips/lib/cache_init.S | 4 ++-- board/dbau1x00/Kconfig | 5 ++++- board/micronas/vct/Kconfig | 5 ++++- board/pb1x00/Kconfig | 5 ++++- board/qca/ap121/Kconfig | 5 ++++- board/qca/ap143/Kconfig | 5 ++++- board/qemu-mips/Kconfig | 5 ++++- board/tplink/wdr4300/Kconfig | 5 ++++- 10 files changed, 42 insertions(+), 25 deletions(-)arch/mips/Kconfig +4
-0@@ -247,11 +247,15 @@ config SYS_DCACHE_SIZE hex default 0 +config SYS_DCACHE_LINE_SIZE + hex + default 0 + config SYS_ICACHE_SIZE hex default 0
Quoted 7 lines
arch/mips/Kconfig config SYS_DCACHE_SIZE · line 258
Quoted 2 lines
arch/mips/Kconfig +1
-1-config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZEBe careful here,
CONFIG_SYS_CACHELINE_SIZEis established all over the u-boot, so this might cause build breakage. You should keep some compatibilityCONFIG_SYS_CACHELINE_SIZEentry and set it to default toSYS_DCACHE_LINE_SIZE, since it's mostly used for DMA anyway.
Marek is right. Some USB drivers still use CONFIG_SYS_CACHELINE_SIZE instead of ARCH_DMA_MINALIGN so CONFIG_SYS_CACHELINE_SIZE needs to be kept as Kconfig symbol.
Signature · 9 lines
- Daniel -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: OpenPGP digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20160527/3e0cdb3d/attachment.sig>
PATCH 2/3 MIPS: Split I & D cache line size config
In reply to Paul BurtonAm 26.05.2016 um 17:58 schrieb Paul Burton:
Quoted 9 lines
Allow L1 Icache & L1 Dcache line size to be specified separately, since there's no architectural mandate that they be the same. The [id]cache_line_size functions are tidied up to take advantage of the fact that the
Kconfigentries are always present to simply check them for zero rather than needing to #ifdef on their presence.Signed-off-by Paul Burton <[email protected]>---
Quoted 12 lines
arch/mips/Kconfig | 6 +++++- arch/mips/lib/cache.c | 22 +++++++--------------- arch/mips/lib/cache_init.S | 4 ++-- board/dbau1x00/Kconfig | 5 ++++- board/micronas/vct/Kconfig | 5 ++++- board/pb1x00/Kconfig | 5 ++++- board/qca/ap121/Kconfig | 5 ++++- board/qca/ap143/Kconfig | 5 ++++- board/qemu-mips/Kconfig | 5 ++++- board/tplink/wdr4300/Kconfig | 5 ++++- 10 files changed, 42 insertions(+), 25 deletions(-)
applied to u-boot-mips, thanks!
Signature · 9 lines
- Daniel -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: OpenPGP digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20160531/c045619e/attachment.sig>
PATCH 3/3 MIPS: Abstract cache op loops with a macro
In reply to Paul BurtonThe various cache maintenance routines perform a number of loops over cache lines. Rather than duplicate the code for performing such loops, abstract it out into a new cache_loop macro which performs an arbitrary number of cache ops on a range of addresses. This reduces duplication in the existing L1 cache maintenance code & will allow for not adding further duplication when introducing L2 cache support.
---
arch/mips/lib/cache.c | 59 ++++++++++++++++----------------------------------- 1 file changed, 18 insertions(+), 41 deletions(-)
arch/mips/lib/cache.c +18 -41
@@ -37,82 +37,59 @@ static inline unsigned long dcache_line_size(void)return 2 << dl; } +#define cache_loop(start, end, lsize, ops...) do { \ + const void *addr = (const void *)(start & ~(lsize - 1)); \ + const void *aend = (const void *)((end - 1) & ~(lsize - 1)); \ + const unsigned int cache_ops[] = { ops }; \ + unsigned int i; \ + \ + for (; addr <= aend; addr += lsize) { \ + for (i = 0; i < ARRAY_SIZE(cache_ops); i++) \ + mips_cache(cache_ops[i], addr); \ + } \ +} while (0) +void flush_cache (ulong start_addr,ulong size) {unsigned long ilsize =icache_line_size ();unsigned long dlsize =dcache_line_size (); -const void *addr, *aend;/* aend will be miscalculated when size is zero, so we return here */ if (size ==0 )return ; - addr = (const void *)(start_addr & ~(dlsize -1 )); - aend = (const void *)((start_addr + size -1 ) & ~(dlsize -1 )); -if (ilsize == dlsize) {/* flush I-cache & D-cache simultaneously */ -while (1 ) { -mips_cache (HIT_WRITEBACK_INV_D , addr); -mips_cache (HIT_INVALIDATE_I , addr); -if (addr == aend) -break ; - addr += dlsize; - } +cache_loop (start_addr, start_addr + size, ilsize, +HIT_WRITEBACK_INV_D ,HIT_INVALIDATE_I );return ; }/* flush D-cache */ -while (1 ) { -mips_cache (HIT_WRITEBACK_INV_D , addr); -if (addr == aend) -break ; - addr += dlsize; - } +cache_loop (start_addr, start_addr + size, dlsize,HIT_WRITEBACK_INV_D );/* flush I-cache */ - addr = (const void *)(start_addr & ~(ilsize -1 )); - aend = (const void *)((start_addr + size -1 ) & ~(ilsize -1 )); -while (1 ) { -mips_cache (HIT_INVALIDATE_I , addr); -if (addr == aend) -break ; - addr += ilsize; - } +cache_loop (start_addr, start_addr + size, ilsize,HIT_INVALIDATE_I ); }void flush_dcache_range (ulong start_addr,ulong stop) {unsigned long lsize =dcache_line_size (); -const void *addr = (const void *)(start_addr & ~(lsize -1 )); -const void *aend = (const void *)((stop -1 ) & ~(lsize -1 ));/* aend will be miscalculated when size is zero, so we return here */ if (start_addr == stop)return ; -while (1 ) { -mips_cache (HIT_WRITEBACK_INV_D , addr); -if (addr == aend) -break ; - addr += lsize; - } +cache_loop (start_addr, stop, lsize,HIT_WRITEBACK_INV_D ); }void invalidate_dcache_range (ulong start_addr,ulong stop) {unsigned long lsize =dcache_line_size (); -const void *addr = (const void *)(start_addr & ~(lsize -1 )); -const void *aend = (const void *)((stop -1 ) & ~(lsize -1 ));/* aend will be miscalculated when size is zero, so we return here */ if (start_addr == stop)return ; -while (1 ) { -mips_cache (HIT_INVALIDATE_D , addr); -if (addr == aend) -break ; - addr += lsize; - } +cache_loop (start_addr, stop, lsize,HIT_INVALIDATE_I ); }
Signature · 1 line
2.8.3
PATCH 3/3 MIPS: Abstract cache op loops with a macro
Quoted 19 lines · Paul Burton
The various cache maintenance routines perform a number of loops over cache lines. Rather than duplicate the code for performing such loops, abstract it out into a new
cache_loopmacro which performs an arbitrary number of cache ops on a range of addresses. This reduces duplication in the existing L1 cache maintenance code & will allow for not adding further duplication when introducing L2 cache support.Signed-off-by Paul Burton <[email protected]>---
arch/mips/lib/cache.c | 59 ++++++++++++++++----------------------------------- 1 file changed, 18 insertions(+), 41 deletions(-)arch/mips/lib/cache.c +0
-0
arch/mips/lib/cache.c static inline unsigned long dcache_line_size(void) · line 43
Quoted 7 lines
arch/mips/lib/cache.c +4
-0@@ -37,82 +37,59 @@ static inline unsigned long dcache_line_size(void)return 2 << dl; } +#define cache_loop(start, end, lsize, ops...) do { \ + const void *addr = (const void *)(start & ~(lsize - 1)); \ + const void *aend = (const void *)((end - 1) & ~(lsize - 1)); \ + const unsigned int cache_ops[] = { ops }; \
Can't you turn this into a function instead and pass some flags to select the ops instead ?
Quoted 94 lines
arch/mips/lib/cache.c +14
-41+unsigned int i; \ + \ +for (; addr <= aend; addr += lsize) { \ +for (i =0 ; i <ARRAY_SIZE (cache_ops); i++) \ +mips_cache (cache_ops[i], addr); \ + } \ +}while (0 ) + void flush_cache(ulong start_addr, ulong size) {unsigned long ilsize =icache_line_size ();unsigned long dlsize =dcache_line_size (); -const void *addr, *aend;/* aend will be miscalculated when size is zero, so we return here */ if (size ==0 )return ; - addr = (const void *)(start_addr & ~(dlsize -1 )); - aend = (const void *)((start_addr + size -1 ) & ~(dlsize -1 )); -if (ilsize == dlsize) {/* flush I-cache & D-cache simultaneously */ -while (1 ) { -mips_cache (HIT_WRITEBACK_INV_D , addr); -mips_cache (HIT_INVALIDATE_I , addr); -if (addr == aend) -break ; - addr += dlsize; - } +cache_loop (start_addr, start_addr + size, ilsize, +HIT_WRITEBACK_INV_D ,HIT_INVALIDATE_I );return ; }/* flush D-cache */ -while (1 ) { -mips_cache (HIT_WRITEBACK_INV_D , addr); -if (addr == aend) -break ; - addr += dlsize; - } +cache_loop (start_addr, start_addr + size, dlsize,HIT_WRITEBACK_INV_D );/* flush I-cache */ - addr = (const void *)(start_addr & ~(ilsize -1 )); - aend = (const void *)((start_addr + size -1 ) & ~(ilsize -1 )); -while (1 ) { -mips_cache (HIT_INVALIDATE_I , addr); -if (addr == aend) -break ; - addr += ilsize; - } +cache_loop (start_addr, start_addr + size, ilsize,HIT_INVALIDATE_I ); }void flush_dcache_range (ulong start_addr,ulong stop) {unsigned long lsize =dcache_line_size (); -const void *addr = (const void *)(start_addr & ~(lsize -1 )); -const void *aend = (const void *)((stop -1 ) & ~(lsize -1 ));/* aend will be miscalculated when size is zero, so we return here */ if (start_addr == stop)return ; -while (1 ) { -mips_cache (HIT_WRITEBACK_INV_D , addr); -if (addr == aend) -break ; - addr += lsize; - } +cache_loop (start_addr, stop, lsize,HIT_WRITEBACK_INV_D ); }void invalidate_dcache_range (ulong start_addr,ulong stop) {unsigned long lsize =dcache_line_size (); -const void *addr = (const void *)(start_addr & ~(lsize -1 )); -const void *aend = (const void *)((stop -1 ) & ~(lsize -1 ));/* aend will be miscalculated when size is zero, so we return here */ if (start_addr == stop)return ; -while (1 ) { -mips_cache (HIT_INVALIDATE_D , addr); -if (addr == aend) -break ; - addr += lsize; - } +cache_loop (start_addr, stop, lsize,HIT_INVALIDATE_I ); }
Signature · 2 lines
Best regards, Marek Vasut
PATCH 3/3 MIPS: Abstract cache op loops with a macro
Quoted 23 lines · Marek Vasut
Quoted 22 lines · Paul Burton
The various cache maintenance routines perform a number of loops over cache lines. Rather than duplicate the code for performing such loops, abstract it out into a new
cache_loopmacro which performs an arbitrary number of cache ops on a range of addresses. This reduces duplication in the existing L1 cache maintenance code & will allow for not adding further duplication when introducing L2 cache support.Signed-off-by Paul Burton <[email protected]>---
arch/mips/lib/cache.c | 59 ++++++++++++++++----------------------------------- 1 file changed, 18 insertions(+), 41 deletions(-)arch/mips/lib/cache.c +0
-0@@ -37,82 +37,59 @@ static inline unsigned long dcache_line_size(void)return 2 << dl; }
Quoted 7 lines
arch/mips/lib/cache.c static inline unsigned long dcache_line_size(void) · line 43
Quoted 4 lines
arch/mips/lib/cache.c +4
-0+#define cache_loop(start, end, lsize, ops...) do { \ + const void *addr = (const void *)(start & ~(lsize - 1)); \ + const void *aend = (const void *)((end - 1) & ~(lsize - 1)); \ + const unsigned int cache_ops[] = { ops }; \Can't you turn this into a function instead and pass some flags to select the ops instead ?
Hi Marek,
The problem is that then both that function & its callers would need to know about the types of cache ops, and there'd need to be some mapping from flags to the actual cache op values (of which there'll be a couple more once L2 support is added). I think it's much simpler & cleaner to just go with the macro in this case - it keeps knowledge of which cache ops to use with the callers, and it ends up generating the same code as before (ie. the inner loop gets unrolled to just the relevant cache instructions).
Thanks,
Paul
Quoted 100 lines
Quoted 95 lines
arch/mips/lib/cache.c +14
-41+unsigned int i; \ + \ +for (; addr <= aend; addr += lsize) { \ +for (i =0 ; i <ARRAY_SIZE (cache_ops); i++) \ +mips_cache (cache_ops[i], addr); \ + } \ +}while (0 ) + void flush_cache(ulong start_addr, ulong size) {unsigned long ilsize =icache_line_size ();unsigned long dlsize =dcache_line_size (); -const void *addr, *aend;/* aend will be miscalculated when size is zero, so we return here */ if (size ==0 )return ; - addr = (const void *)(start_addr & ~(dlsize -1 )); - aend = (const void *)((start_addr + size -1 ) & ~(dlsize -1 )); -if (ilsize == dlsize) {/* flush I-cache & D-cache simultaneously */ -while (1 ) { -mips_cache (HIT_WRITEBACK_INV_D , addr); -mips_cache (HIT_INVALIDATE_I , addr); -if (addr == aend) -break ; - addr += dlsize; - } +cache_loop (start_addr, start_addr + size, ilsize, +HIT_WRITEBACK_INV_D ,HIT_INVALIDATE_I );return ; }/* flush D-cache */ -while (1 ) { -mips_cache (HIT_WRITEBACK_INV_D , addr); -if (addr == aend) -break ; - addr += dlsize; - } +cache_loop (start_addr, start_addr + size, dlsize,HIT_WRITEBACK_INV_D );/* flush I-cache */ - addr = (const void *)(start_addr & ~(ilsize -1 )); - aend = (const void *)((start_addr + size -1 ) & ~(ilsize -1 )); -while (1 ) { -mips_cache (HIT_INVALIDATE_I , addr); -if (addr == aend) -break ; - addr += ilsize; - } +cache_loop (start_addr, start_addr + size, ilsize,HIT_INVALIDATE_I ); }void flush_dcache_range (ulong start_addr,ulong stop) {unsigned long lsize =dcache_line_size (); -const void *addr = (const void *)(start_addr & ~(lsize -1 )); -const void *aend = (const void *)((stop -1 ) & ~(lsize -1 ));/* aend will be miscalculated when size is zero, so we return here */ if (start_addr == stop)return ; -while (1 ) { -mips_cache (HIT_WRITEBACK_INV_D , addr); -if (addr == aend) -break ; - addr += lsize; - } +cache_loop (start_addr, stop, lsize,HIT_WRITEBACK_INV_D ); }void invalidate_dcache_range (ulong start_addr,ulong stop) {unsigned long lsize =dcache_line_size (); -const void *addr = (const void *)(start_addr & ~(lsize -1 )); -const void *aend = (const void *)((stop -1 ) & ~(lsize -1 ));/* aend will be miscalculated when size is zero, so we return here */ if (start_addr == stop)return ; -while (1 ) { -mips_cache (HIT_INVALIDATE_D , addr); -if (addr == aend) -break ; - addr += lsize; - } +cache_loop (start_addr, stop, lsize,HIT_INVALIDATE_I ); }Signature · 2 lines
Best regards, Marek Vasut
PATCH 3/3 MIPS: Abstract cache op loops with a macro
Quoted 32 lines · Paul Burton
Quoted 23 lines · Marek Vasut
Quoted 22 lines · Paul Burton
The various cache maintenance routines perform a number of loops over cache lines. Rather than duplicate the code for performing such loops, abstract it out into a new
cache_loopmacro which performs an arbitrary number of cache ops on a range of addresses. This reduces duplication in the existing L1 cache maintenance code & will allow for not adding further duplication when introducing L2 cache support.Signed-off-by Paul Burton <[email protected]>---
arch/mips/lib/cache.c | 59 ++++++++++++++++----------------------------------- 1 file changed, 18 insertions(+), 41 deletions(-)arch/mips/lib/cache.c +0
-0@@ -37,82 +37,59 @@ static inline unsigned long dcache_line_size(void)return 2 << dl; }Quoted 7 lines
arch/mips/lib/cache.c static inline unsigned long dcache_line_size(void) · line 43
Quoted 4 lines
arch/mips/lib/cache.c +4
-0+#define cache_loop(start, end, lsize, ops...) do { \ + const void *addr = (const void *)(start & ~(lsize - 1)); \ + const void *aend = (const void *)((end - 1) & ~(lsize - 1)); \ + const unsigned int cache_ops[] = { ops }; \Can't you turn this into a function instead and pass some flags to select the ops instead ?
Quoted 1 line
Hi Marek,
Hi!
Quoted 4 lines
The problem is that then both that function & its callers would need to know about the types of cache ops, and there'd need to be some mapping from flags to the actual cache op values (of which there'll be a couple more once L2 support is added).
But the callers already know which ops they must invoke, right ? You can just have enum {} for the bit definitions. It's all local to this file, so I don't see a problem.
Quoted 5 lines
I think it's much simpler & cleaner to
just go with the macro in this case - it keeps knowledge of which cache ops to use with the callers, and it ends up generating the same code as before (ie. the inner loop gets unrolled to just the relevant cache instructions).
I would expect GCC to take care of inlining the code, but you can always use the always_inline directive if that's your concern. Even cleaner way might be to use CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED and compile the cache file with -O2 .
Quoted 103 lines
Thanks,
PaulQuoted 100 lines
Quoted 95 lines
arch/mips/lib/cache.c +14
-41+unsigned int i; \ + \ +for (; addr <= aend; addr += lsize) { \ +for (i =0 ; i <ARRAY_SIZE (cache_ops); i++) \ +mips_cache (cache_ops[i], addr); \ + } \ +}while (0 ) + void flush_cache(ulong start_addr, ulong size) {unsigned long ilsize =icache_line_size ();unsigned long dlsize =dcache_line_size (); -const void *addr, *aend;/* aend will be miscalculated when size is zero, so we return here */ if (size ==0 )return ; - addr = (const void *)(start_addr & ~(dlsize -1 )); - aend = (const void *)((start_addr + size -1 ) & ~(dlsize -1 )); -if (ilsize == dlsize) {/* flush I-cache & D-cache simultaneously */ -while (1 ) { -mips_cache (HIT_WRITEBACK_INV_D , addr); -mips_cache (HIT_INVALIDATE_I , addr); -if (addr == aend) -break ; - addr += dlsize; - } +cache_loop (start_addr, start_addr + size, ilsize, +HIT_WRITEBACK_INV_D ,HIT_INVALIDATE_I );return ; }/* flush D-cache */ -while (1 ) { -mips_cache (HIT_WRITEBACK_INV_D , addr); -if (addr == aend) -break ; - addr += dlsize; - } +cache_loop (start_addr, start_addr + size, dlsize,HIT_WRITEBACK_INV_D );/* flush I-cache */ - addr = (const void *)(start_addr & ~(ilsize -1 )); - aend = (const void *)((start_addr + size -1 ) & ~(ilsize -1 )); -while (1 ) { -mips_cache (HIT_INVALIDATE_I , addr); -if (addr == aend) -break ; - addr += ilsize; - } +cache_loop (start_addr, start_addr + size, ilsize,HIT_INVALIDATE_I ); }void flush_dcache_range (ulong start_addr,ulong stop) {unsigned long lsize =dcache_line_size (); -const void *addr = (const void *)(start_addr & ~(lsize -1 )); -const void *aend = (const void *)((stop -1 ) & ~(lsize -1 ));/* aend will be miscalculated when size is zero, so we return here */ if (start_addr == stop)return ; -while (1 ) { -mips_cache (HIT_WRITEBACK_INV_D , addr); -if (addr == aend) -break ; - addr += lsize; - } +cache_loop (start_addr, stop, lsize,HIT_WRITEBACK_INV_D ); }void invalidate_dcache_range (ulong start_addr,ulong stop) {unsigned long lsize =dcache_line_size (); -const void *addr = (const void *)(start_addr & ~(lsize -1 )); -const void *aend = (const void *)((stop -1 ) & ~(lsize -1 ));/* aend will be miscalculated when size is zero, so we return here */ if (start_addr == stop)return ; -while (1 ) { -mips_cache (HIT_INVALIDATE_D , addr); -if (addr == aend) -break ; - addr += lsize; - } +cache_loop (start_addr, stop, lsize,HIT_INVALIDATE_I ); }Signature · 2 lines
Best regards, Marek Vasut
Signature · 2 lines
Best regards, Marek Vasut
PATCH 3/3 MIPS: Abstract cache op loops with a macro
Quoted 8 lines · Marek Vasut
Quoted 4 lines
The problem is that then both that function & its callers would need to know about the types of cache ops, and there'd need to be some mapping from flags to the actual cache op values (of which there'll be a couple more once L2 support is added).
But the callers already know which ops they must invoke, right ? You can just have enum {} for the bit definitions. It's all local to this file, so I don't see a problem.
It's all local to the file, but it's still an extra level of abstraction that I don't see the value of. It just means that both callers & callee have to know about various cache ops, and I don't see the point in duplicating that knowledge. I think it's much cleaner to keep that knowledge in one place - the caller.
Quoted 10 lines
Quoted 5 lines
I think it's much simpler & cleaner to
just go with the macro in this case - it keeps knowledge of which cache ops to use with the callers, and it ends up generating the same code as before (ie. the inner loop gets unrolled to just the relevant cache instructions).I would expect GCC to take care of inlining the code, but you can always use the
always_inlinedirective if that's your concern. Even cleaner way might be to useCONFIG_CC_OPTIMIZE_LIBS_FOR_SPEEDand compile the cache file with -O2 .
It may well inline it, remove the flags indirection & generate the same code - I haven't tried it to find out. Making the code less clear with that abstraction, even if the compiler will come along & clean it back up, doesn't make much sense to me as someone who has to read the code.
I understand the preference for functions over macros, but I think this is a case where the macro has strengths that a function cannot provide (ignoring perhaps varargs which would be even more messy).
Thanks,
Paul
PATCH 3/3 MIPS: Abstract cache op loops with a macro
Quoted 10 lines · Paul Burton
Quoted 8 lines · Marek Vasut
Quoted 4 lines
The problem is that then both that function & its callers would need to know about the types of cache ops, and there'd need to be some mapping from flags to the actual cache op values (of which there'll be a couple more once L2 support is added).
But the callers already know which ops they must invoke, right ? You can just have enum {} for the bit definitions. It's all local to this file, so I don't see a problem.
Quoted 5 lines
It's all local to the file, but it's still an extra level of abstraction that I don't see the value of. It just means that both callers & callee have to know about various cache ops, and I don't see the point in duplicating that knowledge. I think it's much cleaner to keep that knowledge in one place - the caller.
OK, I see what you mean.
Quoted 11 lines
Quoted 10 lines
Quoted 5 lines
I think it's much simpler & cleaner to
just go with the macro in this case - it keeps knowledge of which cache ops to use with the callers, and it ends up generating the same code as before (ie. the inner loop gets unrolled to just the relevant cache instructions).I would expect GCC to take care of inlining the code, but you can always use the
always_inlinedirective if that's your concern. Even cleaner way might be to useCONFIG_CC_OPTIMIZE_LIBS_FOR_SPEEDand compile the cache file with -O2 .
Quoted 4 lines
It may well inline it, remove the flags indirection & generate the same code - I haven't tried it to find out. Making the code less clear with that abstraction, even if the compiler will come along & clean it back up, doesn't make much sense to me as someone who has to read the code.
It makes sense when you debug the code with GDB though. It's much easier to locate lines if you don't use huge variadic macros.
Quoted 3 lines
I understand the preference for functions over macros, but I think this is a case where the macro has strengths that a function cannot provide (ignoring perhaps varargs which would be even more messy).
What would you say to turning this into a variadic function then ? It would avoid having the same knowledge in both caller and callee and it would not be a macro, so it's a win-win. What do you think ?
Quoted 3 lines
Thanks,
Paul
Signature · 2 lines
Best regards, Marek Vasut