[U-Boot] [PATCH] armv7:cache: D cache line size read method

This commit adds support for reading the D cache line size for armv7 architecture.
The get_dcache_line_size() function is supposed to work in conjunction with memalign call to provide D cache aligned DMA buffers.
Signed-off-by: Lukasz Majewski l.majewski@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Aneesh V aneesh@ti.com CC: Albert ARIBAUD albert.u.boot@aribaud.net --- arch/arm/cpu/armv7/cache_v7.c | 25 +++++++++++++++++++++++++ include/common.h | 1 + 2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 3e1e1bf..bd0b1a8 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -246,6 +246,21 @@ static void v7_inval_tlb(void) CP15ISB; }
+/* Read the cache line size (bytes) */ +static int v7_dcache_line_size(void) +{ + u32 ccsidr, log2_line_len; + + ccsidr = get_ccsidr(); + + log2_line_len = ((ccsidr & CCSIDR_LINE_SIZE_MASK) >> + CCSIDR_LINE_SIZE_OFFSET) + 2; + /* Converting from words to bytes */ + log2_line_len += 2; + + return 1 << log2_line_len; +} + void invalidate_dcache_all(void) { v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL); @@ -303,6 +318,11 @@ void flush_cache(unsigned long start, unsigned long size) { flush_dcache_range(start, start + size); } + +int get_dcache_line_size(void) +{ + return v7_dcache_line_size(); +} #else /* #ifndef CONFIG_SYS_DCACHE_OFF */ void invalidate_dcache_all(void) { @@ -327,6 +347,11 @@ void arm_init_before_mmu(void) void flush_cache(unsigned long start, unsigned long size) { } + +int get_dcache_line_size(void) +{ + return 0; +} #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
#ifndef CONFIG_SYS_ICACHE_OFF diff --git a/include/common.h b/include/common.h index 12a1074..b535300 100644 --- a/include/common.h +++ b/include/common.h @@ -622,6 +622,7 @@ void flush_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_all(void); void invalidate_icache_all(void); +int get_dcache_line_size(void);
/* arch/$(ARCH)/lib/ticks.S */ unsigned long long get_ticks(void);

Hi Lukasz,
On 12/08/2011 10:24, Lukasz Majewski wrote:
This commit adds support for reading the D cache line size for armv7 architecture.
The get_dcache_line_size() function is supposed to work in conjunction with memalign call to provide D cache aligned DMA buffers.
Signed-off-by: Lukasz Majewskil.majewski@samsung.com Signed-off-by: Kyungmin Parkkyungmin.park@samsung.com CC: Aneesh Vaneesh@ti.com CC: Albert ARIBAUDalbert.u.boot@aribaud.net
arch/arm/cpu/armv7/cache_v7.c | 25 +++++++++++++++++++++++++ include/common.h | 1 + 2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 3e1e1bf..bd0b1a8 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -246,6 +246,21 @@ static void v7_inval_tlb(void) CP15ISB; }
+/* Read the cache line size (bytes) */ +static int v7_dcache_line_size(void) +{
- u32 ccsidr, log2_line_len;
- ccsidr = get_ccsidr();
- log2_line_len = ((ccsidr& CCSIDR_LINE_SIZE_MASK)>>
CCSIDR_LINE_SIZE_OFFSET) + 2;
- /* Converting from words to bytes */
- log2_line_len += 2;
- return 1<< log2_line_len;
+}
- void invalidate_dcache_all(void) { v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL);
@@ -303,6 +318,11 @@ void flush_cache(unsigned long start, unsigned long size) { flush_dcache_range(start, start + size); }
+int get_dcache_line_size(void) +{
- return v7_dcache_line_size();
+} #else /* #ifndef CONFIG_SYS_DCACHE_OFF */ void invalidate_dcache_all(void) { @@ -327,6 +347,11 @@ void arm_init_before_mmu(void) void flush_cache(unsigned long start, unsigned long size) { }
+int get_dcache_line_size(void) +{
- return 0;
+} #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
#ifndef CONFIG_SYS_ICACHE_OFF diff --git a/include/common.h b/include/common.h index 12a1074..b535300 100644 --- a/include/common.h +++ b/include/common.h @@ -622,6 +622,7 @@ void flush_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_all(void); void invalidate_icache_all(void); +int get_dcache_line_size(void);
/* arch/$(ARCH)/lib/ticks.S */ unsigned long long get_ticks(void);
I like the idea of a global cache line accessor, but:
1) Does it have to be a function? I don't know cache implementations where line size is not a constant, and a function might be overkill.
2) If it has to be a function, then I'd rather have the function introduced in arch/arm/lib/cache.c as a weak function returning 32, with armv7 providing a replacement.
Aneesh, that patch could affect your patch series as the magic 32 could then come from this weak function rather than be hard-coded.
Amicalement,

Hi Albert, Lukasz,
On Friday 12 August 2011 02:28 PM, Albert ARIBAUD wrote:
Hi Lukasz,
On 12/08/2011 10:24, Lukasz Majewski wrote:
This commit adds support for reading the D cache line size for armv7 architecture.
The get_dcache_line_size() function is supposed to work in conjunction with memalign call to provide D cache aligned DMA buffers.
Signed-off-by: Lukasz Majewskil.majewski@samsung.com Signed-off-by: Kyungmin Parkkyungmin.park@samsung.com CC: Aneesh Vaneesh@ti.com CC: Albert ARIBAUDalbert.u.boot@aribaud.net
arch/arm/cpu/armv7/cache_v7.c | 25 +++++++++++++++++++++++++ include/common.h | 1 + 2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 3e1e1bf..bd0b1a8 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -246,6 +246,21 @@ static void v7_inval_tlb(void) CP15ISB; }
+/* Read the cache line size (bytes) */ +static int v7_dcache_line_size(void) +{
- u32 ccsidr, log2_line_len;
- ccsidr = get_ccsidr();
- log2_line_len = ((ccsidr& CCSIDR_LINE_SIZE_MASK)>>
- CCSIDR_LINE_SIZE_OFFSET) + 2;
- /* Converting from words to bytes */
- log2_line_len += 2;
- return 1<< log2_line_len;
+}
void invalidate_dcache_all(void) { v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL); @@ -303,6 +318,11 @@ void flush_cache(unsigned long start, unsigned long size) { flush_dcache_range(start, start + size); }
+int get_dcache_line_size(void) +{
- return v7_dcache_line_size();
+} #else /* #ifndef CONFIG_SYS_DCACHE_OFF */ void invalidate_dcache_all(void) { @@ -327,6 +347,11 @@ void arm_init_before_mmu(void) void flush_cache(unsigned long start, unsigned long size) { }
+int get_dcache_line_size(void) +{
- return 0;
+} #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
#ifndef CONFIG_SYS_ICACHE_OFF diff --git a/include/common.h b/include/common.h index 12a1074..b535300 100644 --- a/include/common.h +++ b/include/common.h @@ -622,6 +622,7 @@ void flush_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_all(void); void invalidate_icache_all(void); +int get_dcache_line_size(void);
/* arch/$(ARCH)/lib/ticks.S */ unsigned long long get_ticks(void);
I like the idea of a global cache line accessor, but:
- Does it have to be a function? I don't know cache implementations
where line size is not a constant, and a function might be overkill.
- If it has to be a function, then I'd rather have the function
introduced in arch/arm/lib/cache.c as a weak function returning 32, with armv7 providing a replacement.
Since this is used from generic drivers I think this should be defined all ARCHs. How about something like this.
int __weak get_dcache_line_size(void) { #if defined(CONFIG_SYS_CACHE_LINE_SIZE) && !defined(CONFIG_SYS_DCACHE_OFF) return CONFIG_SYS_CACHE_LINE_SIZE; #else return sizeof(int); /* or 0 - whatever is appropriate for memalign() */ #endif }
Then over-ride this from the respective ARCH implementation if there is a cache-type registers. I see that armv5/6/7 all can find this at run-time from CP15 registers.
Aneesh, that patch could affect your patch series as the magic 32 could then come from this weak function rather than be hard-coded.
I think you are referring to Hong's series. In armv7 series we are getting the size by reading ccsidr register just like Lukasz is doing here - no magic values. I think in Hong's series also this can be found from the cache type CP15 register.
br, Aneesh

(Added Hong Xu)
Hi Aneesh,
On 12/08/2011 11:16, Aneesh V wrote:
Hi Albert, Lukasz,
On Friday 12 August 2011 02:28 PM, Albert ARIBAUD wrote:
Hi Lukasz,
On 12/08/2011 10:24, Lukasz Majewski wrote:
This commit adds support for reading the D cache line size for armv7 architecture.
The get_dcache_line_size() function is supposed to work in conjunction with memalign call to provide D cache aligned DMA buffers.
Signed-off-by: Lukasz Majewskil.majewski@samsung.com Signed-off-by: Kyungmin Parkkyungmin.park@samsung.com CC: Aneesh Vaneesh@ti.com CC: Albert ARIBAUDalbert.u.boot@aribaud.net
arch/arm/cpu/armv7/cache_v7.c | 25 +++++++++++++++++++++++++ include/common.h | 1 + 2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 3e1e1bf..bd0b1a8 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -246,6 +246,21 @@ static void v7_inval_tlb(void) CP15ISB; }
+/* Read the cache line size (bytes) */ +static int v7_dcache_line_size(void) +{
- u32 ccsidr, log2_line_len;
- ccsidr = get_ccsidr();
- log2_line_len = ((ccsidr& CCSIDR_LINE_SIZE_MASK)>>
- CCSIDR_LINE_SIZE_OFFSET) + 2;
- /* Converting from words to bytes */
- log2_line_len += 2;
- return 1<< log2_line_len;
+}
void invalidate_dcache_all(void) { v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL); @@ -303,6 +318,11 @@ void flush_cache(unsigned long start, unsigned long size) { flush_dcache_range(start, start + size); }
+int get_dcache_line_size(void) +{
- return v7_dcache_line_size();
+} #else /* #ifndef CONFIG_SYS_DCACHE_OFF */ void invalidate_dcache_all(void) { @@ -327,6 +347,11 @@ void arm_init_before_mmu(void) void flush_cache(unsigned long start, unsigned long size) { }
+int get_dcache_line_size(void) +{
- return 0;
+} #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
#ifndef CONFIG_SYS_ICACHE_OFF diff --git a/include/common.h b/include/common.h index 12a1074..b535300 100644 --- a/include/common.h +++ b/include/common.h @@ -622,6 +622,7 @@ void flush_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_all(void); void invalidate_icache_all(void); +int get_dcache_line_size(void);
/* arch/$(ARCH)/lib/ticks.S */ unsigned long long get_ticks(void);
I like the idea of a global cache line accessor, but:
- Does it have to be a function? I don't know cache implementations
where line size is not a constant, and a function might be overkill.
- If it has to be a function, then I'd rather have the function
introduced in arch/arm/lib/cache.c as a weak function returning 32, with armv7 providing a replacement.
Since this is used from generic drivers I think this should be defined all ARCHs. How about something like this.
int __weak get_dcache_line_size(void) { #if defined(CONFIG_SYS_CACHE_LINE_SIZE) && !defined(CONFIG_SYS_DCACHE_OFF) return CONFIG_SYS_CACHE_LINE_SIZE; #else return sizeof(int); /* or 0 - whatever is appropriate for memalign() */ #endif }
Then over-ride this from the respective ARCH implementation if there is a cache-type registers. I see that armv5/6/7 all can find this at run-time from CP15 registers.
Aneesh, that patch could affect your patch series as the magic 32 could then come from this weak function rather than be hard-coded.
I think you are referring to Hong's series. In armv7 series we are getting the size by reading ccsidr register just like Lukasz is doing here - no magic values. I think in Hong's series also this can be found from the cache type CP15 register.
Correct, I misattributed the patch.
As for the cache line size, I see one reason for using a constant rather than dynamically finding it: aligning non-dynamic (either static local or global) buffers. If there are any in the code, they'll need an __attribute__((aligned())) directive, which can only take a constant.
OTOH, maybe they could be changed to dynamic buffers allocated at init time, which would make the handling of cache_aligned buffers homogeneous.
Amicalement,

On Fri, Aug 12, 2011 at 2:16 AM, Aneesh V aneesh@ti.com wrote:
Hi Albert, Lukasz,
On Friday 12 August 2011 02:28 PM, Albert ARIBAUD wrote:
Hi Lukasz,
On 12/08/2011 10:24, Lukasz Majewski wrote:
This commit adds support for reading the D cache line size for armv7 architecture.
The get_dcache_line_size() function is supposed to work in conjunction with memalign call to provide D cache aligned DMA buffers.
Signed-off-by: Lukasz Majewskil.majewski@samsung.com Signed-off-by: Kyungmin Parkkyungmin.park@samsung.com CC: Aneesh Vaneesh@ti.com CC: Albert ARIBAUDalbert.u.boot@aribaud.net
arch/arm/cpu/armv7/cache_v7.c | 25 +++++++++++++++++++++++++ include/common.h | 1 + 2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 3e1e1bf..bd0b1a8 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -246,6 +246,21 @@ static void v7_inval_tlb(void) CP15ISB; }
+/* Read the cache line size (bytes) */ +static int v7_dcache_line_size(void) +{
- u32 ccsidr, log2_line_len;
- ccsidr = get_ccsidr();
- log2_line_len = ((ccsidr& CCSIDR_LINE_SIZE_MASK)>>
- CCSIDR_LINE_SIZE_OFFSET) + 2;
- /* Converting from words to bytes */
- log2_line_len += 2;
- return 1<< log2_line_len;
+}
void invalidate_dcache_all(void) { v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL); @@ -303,6 +318,11 @@ void flush_cache(unsigned long start, unsigned long size) { flush_dcache_range(start, start + size); }
+int get_dcache_line_size(void) +{
- return v7_dcache_line_size();
+} #else /* #ifndef CONFIG_SYS_DCACHE_OFF */ void invalidate_dcache_all(void) { @@ -327,6 +347,11 @@ void arm_init_before_mmu(void) void flush_cache(unsigned long start, unsigned long size) { }
+int get_dcache_line_size(void) +{
- return 0;
+} #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
#ifndef CONFIG_SYS_ICACHE_OFF diff --git a/include/common.h b/include/common.h index 12a1074..b535300 100644 --- a/include/common.h +++ b/include/common.h @@ -622,6 +622,7 @@ void flush_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_all(void); void invalidate_icache_all(void); +int get_dcache_line_size(void);
/* arch/$(ARCH)/lib/ticks.S */ unsigned long long get_ticks(void);
I like the idea of a global cache line accessor, but:
- Does it have to be a function? I don't know cache implementations
where line size is not a constant, and a function might be overkill.
- If it has to be a function, then I'd rather have the function
introduced in arch/arm/lib/cache.c as a weak function returning 32, with armv7 providing a replacement.
Since this is used from generic drivers I think this should be defined all ARCHs. How about something like this.
int __weak get_dcache_line_size(void) { #if defined(CONFIG_SYS_CACHE_LINE_SIZE) && !defined(CONFIG_SYS_DCACHE_OFF) return CONFIG_SYS_CACHE_LINE_SIZE; #else return sizeof(int); /* or 0 - whatever is appropriate for memalign() */
It might be better here to return __BIGGEST_ALIGNMENT__ which will always be defined by GCC to be the largest alignment requirement for any data type on the current machine.
-Anton
#endif }
Then over-ride this from the respective ARCH implementation if there is a cache-type registers. I see that armv5/6/7 all can find this at run-time from CP15 registers.
Aneesh, that patch could affect your patch series as the magic 32 could then come from this weak function rather than be hard-coded.
I think you are referring to Hong's series. In armv7 series we are getting the size by reading ccsidr register just like Lukasz is doing here - no magic values. I think in Hong's series also this can be found from the cache type CP15 register.
br, Aneesh _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On Friday 12 August 2011 01:54 PM, Lukasz Majewski wrote:
This commit adds support for reading the D cache line size for armv7 architecture.
The get_dcache_line_size() function is supposed to work in conjunction with memalign call to provide D cache aligned DMA buffers.
Signed-off-by: Lukasz Majewskil.majewski@samsung.com Signed-off-by: Kyungmin Parkkyungmin.park@samsung.com CC: Aneesh Vaneesh@ti.com CC: Albert ARIBAUDalbert.u.boot@aribaud.net
arch/arm/cpu/armv7/cache_v7.c | 25 +++++++++++++++++++++++++ include/common.h | 1 + 2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 3e1e1bf..bd0b1a8 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -246,6 +246,21 @@ static void v7_inval_tlb(void) CP15ISB; }
+/* Read the cache line size (bytes) */ +static int v7_dcache_line_size(void) +{
- u32 ccsidr, log2_line_len;
- ccsidr = get_ccsidr();
- log2_line_len = ((ccsidr& CCSIDR_LINE_SIZE_MASK)>>
CCSIDR_LINE_SIZE_OFFSET) + 2;
- /* Converting from words to bytes */
- log2_line_len += 2;
- return 1<< log2_line_len;
+}
- void invalidate_dcache_all(void) { v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL);
@@ -303,6 +318,11 @@ void flush_cache(unsigned long start, unsigned long size) { flush_dcache_range(start, start + size); }
+int get_dcache_line_size(void) +{
- return v7_dcache_line_size();
+} #else /* #ifndef CONFIG_SYS_DCACHE_OFF */ void invalidate_dcache_all(void) { @@ -327,6 +347,11 @@ void arm_init_before_mmu(void) void flush_cache(unsigned long start, unsigned long size) { }
+int get_dcache_line_size(void) +{
- return 0;
+}
Does memalign() take 0 as input and if so what is the output. The GNU C library seems to mandate only that it's a power of 2. But the following man page seems to says that "The value of alignment must be a power of two and must be greater than or equal to the size of a word."
http://www.s-gms.ms.edus.si/cgi-bin/man-cgi?memalign+3C
Also, you seem to be using get_dcache_line_size() in MMC driver. Is this function defined for all platforms. Maybe, you must implement a weakly linked default function for all platforms?
best regards, Aneesh

Hi Anessh,
On Fri, 12 Aug 2011 14:32:52 +0530 Aneesh V aneesh@ti.com wrote:
+int get_dcache_line_size(void) +{
- return 0;
+}
Does memalign() take 0 as input and if so what is the output. The GNU C library seems to mandate only that it's a power of 2. But the following man page seems to says that "The value of alignment must be a power of two and must be greater than or equal to the size of a word."
Documentation is one thing, and I was initially planning to return 8 when the CONFIG_DCACHE_OFF is defined (when dcache is disabled).
But then I've looked in the implementation of this function (common/dlmalloc.c) and discover, that it's smallest alignment is 8 bytes. When number passed to memalign is smaller than 8, then anyway the alignment is set to this default value.
On the other hand I've realized than it is more natural to return 0 than 8, and assumed that this will not harm the current implementation.
For the sake of documentation conformance, the value of 8 shall be returned in this case.
Also, you seem to be using get_dcache_line_size() in MMC driver. Is this function defined for all platforms. Maybe, you must implement a weakly linked default function for all platforms?
best regards, Aneesh
Yes, you are right, now the get_dcache_line_size() is defined in the arch/arm/cpu/armv7/cache_v7.c, so other boards will be broken.
Next version will use the weakly linked default function.

This commit adds support for reading the D cache line size for armv7 architecture.
The get_dcache_line_size() function is supposed to work in conjunction with memalign call to provide D cache aligned DMA buffers.
Signed-off-by: Lukasz Majewski l.majewski@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Aneesh V aneesh@ti.com CC: Albert ARIBAUD albert.u.boot@aribaud.net --- Changes for v2: - Weak function get_dcache_line_size added to lib/cache.c for non armv7 architectures --- arch/arm/cpu/armv7/cache_v7.c | 15 +++++++++++++++ arch/arm/lib/cache.c | 11 +++++++++++ include/common.h | 1 + 3 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 3e1e1bf..0ff9a97 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -246,6 +246,21 @@ static void v7_inval_tlb(void) CP15ISB; }
+/* Read the cache line size (in bytes) */ +int get_dcache_line_size(void) +{ + u32 ccsidr, log2_line_len; + puts("222\n"); + ccsidr = get_ccsidr(); + + log2_line_len = ((ccsidr & CCSIDR_LINE_SIZE_MASK) >> + CCSIDR_LINE_SIZE_OFFSET) + 2; + /* Converting from words to bytes */ + log2_line_len += 2; + + return 1 << log2_line_len; +} + void invalidate_dcache_all(void) { v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL); diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c index 92b61a2..5ebf551 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -53,3 +53,14 @@ void __flush_dcache_all(void) } void flush_dcache_all(void) __attribute__((weak, alias("__flush_dcache_all"))); + +/* Default implementation: */ +/* Read the default D CACHE LINE size */ +int __attribute__((weak)) get_dcache_line_size(void) +{ +#if defined(CONFIG_SYS_CACHE_LINE_SIZE) && !defined(CONFIG_SYS_DCACHE_OFF) + return CONFIG_SYS_CACHE_LINE_SIZE; +#else + return 8; /* Default alignment for memalign() */ +#endif +} diff --git a/include/common.h b/include/common.h index 12a1074..b535300 100644 --- a/include/common.h +++ b/include/common.h @@ -622,6 +622,7 @@ void flush_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_all(void); void invalidate_icache_all(void); +int get_dcache_line_size(void);
/* arch/$(ARCH)/lib/ticks.S */ unsigned long long get_ticks(void);

Hello.
On 16-08-2011 14:31, Lukasz Majewski wrote:
This commit adds support for reading the D cache line size for armv7 architecture.
The get_dcache_line_size() function is supposed to work in conjunction with memalign call to provide D cache aligned DMA buffers.
Signed-off-by: Lukasz Majewskil.majewski@samsung.com Signed-off-by: Kyungmin Parkkyungmin.park@samsung.com CC: Aneesh Vaneesh@ti.com CC: Albert ARIBAUDalbert.u.boot@aribaud.net
Changes for v2:
- Weak function get_dcache_line_size added to lib/cache.c for non armv7
architectures
arch/arm/cpu/armv7/cache_v7.c | 15 +++++++++++++++ arch/arm/lib/cache.c | 11 +++++++++++ include/common.h | 1 + 3 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 3e1e1bf..0ff9a97 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -246,6 +246,21 @@ static void v7_inval_tlb(void) CP15ISB; }
+/* Read the cache line size (in bytes) */ +int get_dcache_line_size(void) +{
- u32 ccsidr, log2_line_len;
An empty line wounldn't hurt here.
- puts("222\n");
Shouldn't that have been deleted?
WBR, Sergei

This commit adds support for reading the D cache line size for armv7 architecture.
The get_dcache_line_size() function is supposed to work in conjunction with memalign call to provide D cache aligned DMA buffers.
Signed-off-by: Lukasz Majewski l.majewski@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Aneesh V aneesh@ti.com CC: Albert ARIBAUD albert.u.boot@aribaud.net --- Changes for v2: - Weak function get_dcache_line_size added to lib/cache.c for non armv7 architectures --- arch/arm/cpu/armv7/cache_v7.c | 14 ++++++++++++++ arch/arm/lib/cache.c | 11 +++++++++++ include/common.h | 1 + 3 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 3e1e1bf..ea5a3e4 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -246,6 +246,20 @@ static void v7_inval_tlb(void) CP15ISB; }
+/* Read the cache line size (in bytes) */ +int get_dcache_line_size(void) +{ + u32 ccsidr, log2_line_len; + + ccsidr = get_ccsidr(); + log2_line_len = ((ccsidr & CCSIDR_LINE_SIZE_MASK) >> + CCSIDR_LINE_SIZE_OFFSET) + 2; + /* Converting from words to bytes */ + log2_line_len += 2; + + return 1 << log2_line_len; +} + void invalidate_dcache_all(void) { v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL); diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c index 92b61a2..5ebf551 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -53,3 +53,14 @@ void __flush_dcache_all(void) } void flush_dcache_all(void) __attribute__((weak, alias("__flush_dcache_all"))); + +/* Default implementation: */ +/* Read the default D CACHE LINE size */ +int __attribute__((weak)) get_dcache_line_size(void) +{ +#if defined(CONFIG_SYS_CACHE_LINE_SIZE) && !defined(CONFIG_SYS_DCACHE_OFF) + return CONFIG_SYS_CACHE_LINE_SIZE; +#else + return 8; /* Default alignment for memalign() */ +#endif +} diff --git a/include/common.h b/include/common.h index 12a1074..b535300 100644 --- a/include/common.h +++ b/include/common.h @@ -622,6 +622,7 @@ void flush_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_all(void); void invalidate_icache_all(void); +int get_dcache_line_size(void);
/* arch/$(ARCH)/lib/ticks.S */ unsigned long long get_ticks(void);

This commit adds support for reading the D cache line size for armv7 architecture.
The get_dcache_line_size() function is supposed to work in conjunction with memalign call to provide D cache aligned DMA buffers.
Signed-off-by: Lukasz Majewski l.majewski@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Aneesh V aneesh@ti.com CC: Albert ARIBAUD albert.u.boot@aribaud.net --- Changes for v2: - Weak function get_dcache_line_size added to lib/cache.c for non armv7 architectures Changes for v3: - __BIGGEST_ALIGNMENT__ GCC constant added --- arch/arm/cpu/armv7/cache_v7.c | 14 ++++++++++++++ arch/arm/lib/cache.c | 13 +++++++++++++ include/common.h | 1 + 3 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 3e1e1bf..ea5a3e4 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -246,6 +246,20 @@ static void v7_inval_tlb(void) CP15ISB; }
+/* Read the cache line size (in bytes) */ +int get_dcache_line_size(void) +{ + u32 ccsidr, log2_line_len; + + ccsidr = get_ccsidr(); + log2_line_len = ((ccsidr & CCSIDR_LINE_SIZE_MASK) >> + CCSIDR_LINE_SIZE_OFFSET) + 2; + /* Converting from words to bytes */ + log2_line_len += 2; + + return 1 << log2_line_len; +} + void invalidate_dcache_all(void) { v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL); diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c index 92b61a2..305f070 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -53,3 +53,16 @@ void __flush_dcache_all(void) } void flush_dcache_all(void) __attribute__((weak, alias("__flush_dcache_all"))); + +/* Default implementation: */ +/* Read the default D CACHE LINE size */ +int __attribute__((weak)) get_dcache_line_size(void) +{ +#if defined(CONFIG_SYS_CACHE_LINE_SIZE) && !defined(CONFIG_SYS_DCACHE_OFF) + return CONFIG_SYS_CACHE_LINE_SIZE; +#else + /* The smallest alignment */ + /* for memalign() is 8 Bytes. */ + return __BIGGEST_ALIGNMENT__; /* Constant defined by GCC compiler */ +#endif +} diff --git a/include/common.h b/include/common.h index 12a1074..b535300 100644 --- a/include/common.h +++ b/include/common.h @@ -622,6 +622,7 @@ void flush_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_all(void); void invalidate_icache_all(void); +int get_dcache_line_size(void);
/* arch/$(ARCH)/lib/ticks.S */ unsigned long long get_ticks(void);

Hi Lukasz,
Le 17/08/2011 10:51, Lukasz Majewski a écrit :
This commit adds support for reading the D cache line size for armv7 architecture.
The get_dcache_line_size() function is supposed to work in conjunction with memalign call to provide D cache aligned DMA buffers.
Signed-off-by: Lukasz Majewskil.majewski@samsung.com Signed-off-by: Kyungmin Parkkyungmin.park@samsung.com CC: Aneesh Vaneesh@ti.com CC: Albert ARIBAUDalbert.u.boot@aribaud.net
Changes for v2:
- Weak function get_dcache_line_size added to lib/cache.c for non armv7
architectures Changes for v3:
- __BIGGEST_ALIGNMENT__ GCC constant added
arch/arm/cpu/armv7/cache_v7.c | 14 ++++++++++++++ arch/arm/lib/cache.c | 13 +++++++++++++ include/common.h | 1 + 3 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 3e1e1bf..ea5a3e4 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -246,6 +246,20 @@ static void v7_inval_tlb(void) CP15ISB; }
+/* Read the cache line size (in bytes) */ +int get_dcache_line_size(void) +{
- u32 ccsidr, log2_line_len;
- ccsidr = get_ccsidr();
- log2_line_len = ((ccsidr& CCSIDR_LINE_SIZE_MASK)>>
CCSIDR_LINE_SIZE_OFFSET) + 2;
- /* Converting from words to bytes */
- log2_line_len += 2;
- return 1<< log2_line_len;
+}
- void invalidate_dcache_all(void) { v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL);
diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c index 92b61a2..305f070 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -53,3 +53,16 @@ void __flush_dcache_all(void) } void flush_dcache_all(void) __attribute__((weak, alias("__flush_dcache_all")));
+/* Default implementation: */ +/* Read the default D CACHE LINE size */ +int __attribute__((weak)) get_dcache_line_size(void) +{ +#if defined(CONFIG_SYS_CACHE_LINE_SIZE)&& !defined(CONFIG_SYS_DCACHE_OFF)
- return CONFIG_SYS_CACHE_LINE_SIZE;
+#else
- /* The smallest alignment */
- /* for memalign() is 8 Bytes. */
- return __BIGGEST_ALIGNMENT__; /* Constant defined by GCC compiler */
Fix the comment (still says 8 bytes, but that does not fit any more with the use of __BIGGEST_ALIGNMENT__).
+#endif +} diff --git a/include/common.h b/include/common.h index 12a1074..b535300 100644 --- a/include/common.h +++ b/include/common.h @@ -622,6 +622,7 @@ void flush_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_all(void); void invalidate_icache_all(void); +int get_dcache_line_size(void);
/* arch/$(ARCH)/lib/ticks.S */ unsigned long long get_ticks(void);
Amicalement,

This commit adds support for reading the D cache line size for armv7 architecture.
The get_dcache_line_size() function is supposed to work in conjunction with memalign call to provide D cache aligned DMA buffers.
Signed-off-by: Lukasz Majewski l.majewski@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Aneesh V aneesh@ti.com CC: Albert ARIBAUD albert.u.boot@aribaud.net --- Changes for v2: - Weak function get_dcache_line_size added to lib/cache.c for non armv7 architectures Changes for v3: - __BIGGEST_ALIGNMENT__ GCC constant added --- arch/arm/cpu/armv7/cache_v7.c | 14 ++++++++++++++ arch/arm/lib/cache.c | 11 +++++++++++ include/common.h | 1 + 3 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 3e1e1bf..ea5a3e4 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -246,6 +246,20 @@ static void v7_inval_tlb(void) CP15ISB; }
+/* Read the cache line size (in bytes) */ +int get_dcache_line_size(void) +{ + u32 ccsidr, log2_line_len; + + ccsidr = get_ccsidr(); + log2_line_len = ((ccsidr & CCSIDR_LINE_SIZE_MASK) >> + CCSIDR_LINE_SIZE_OFFSET) + 2; + /* Converting from words to bytes */ + log2_line_len += 2; + + return 1 << log2_line_len; +} + void invalidate_dcache_all(void) { v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL); diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c index 92b61a2..5e699cc 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -53,3 +53,14 @@ void __flush_dcache_all(void) } void flush_dcache_all(void) __attribute__((weak, alias("__flush_dcache_all"))); + +/* Default implementation: */ +/* Read the default D CACHE LINE size */ +int __attribute__((weak)) get_dcache_line_size(void) +{ +#if defined(CONFIG_SYS_CACHE_LINE_SIZE) && !defined(CONFIG_SYS_DCACHE_OFF) + return CONFIG_SYS_CACHE_LINE_SIZE; +#else + return __BIGGEST_ALIGNMENT__; /* Constant defined by GCC compiler */ +#endif +} diff --git a/include/common.h b/include/common.h index 12a1074..b535300 100644 --- a/include/common.h +++ b/include/common.h @@ -622,6 +622,7 @@ void flush_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_all(void); void invalidate_icache_all(void); +int get_dcache_line_size(void);
/* arch/$(ARCH)/lib/ticks.S */ unsigned long long get_ticks(void);

The get_dcache_line_size() function is supposed to work in conjunction with memalign call to provide D cache aligned DMA buffers.
This commit adds support for reading the D cache line size for armv7 architecture. Moreover a default implementation of get_dcache_line_size() is provided.
Signed-off-by: Lukasz Majewski l.majewski@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Aneesh V aneesh@ti.com CC: Albert ARIBAUD albert.u.boot@aribaud.net --- Changes for v2: - Weak function get_dcache_line_size added to arch/arm/lib/cache.c Changes for v3: - __BIGGEST_ALIGNMENT__ GCC constant added Changes for v4: - Weak function get_dcache_line_size added to arch/arm/lib/cache.c for non armv7 architectures --- arch/arm/cpu/armv7/cache_v7.c | 14 ++++++++++++++ include/common.h | 1 + lib/Makefile | 1 + lib/cache.c | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 0 deletions(-) create mode 100644 lib/cache.c
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 3e1e1bf..ea5a3e4 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -246,6 +246,20 @@ static void v7_inval_tlb(void) CP15ISB; }
+/* Read the cache line size (in bytes) */ +int get_dcache_line_size(void) +{ + u32 ccsidr, log2_line_len; + + ccsidr = get_ccsidr(); + log2_line_len = ((ccsidr & CCSIDR_LINE_SIZE_MASK) >> + CCSIDR_LINE_SIZE_OFFSET) + 2; + /* Converting from words to bytes */ + log2_line_len += 2; + + return 1 << log2_line_len; +} + void invalidate_dcache_all(void) { v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL); diff --git a/include/common.h b/include/common.h index 12a1074..b535300 100644 --- a/include/common.h +++ b/include/common.h @@ -622,6 +622,7 @@ void flush_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_range(unsigned long start, unsigned long stop); void invalidate_dcache_all(void); void invalidate_icache_all(void); +int get_dcache_line_size(void);
/* arch/$(ARCH)/lib/ticks.S */ unsigned long long get_ticks(void); diff --git a/lib/Makefile b/lib/Makefile index 884f64c..c0070c2 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -49,6 +49,7 @@ COBJS-$(CONFIG_SHA1) += sha1.o COBJS-$(CONFIG_SHA256) += sha256.o COBJS-y += strmhz.o COBJS-$(CONFIG_RBTREE) += rbtree.o +COBJS-y += cache.o endif
COBJS-y += ctype.o diff --git a/lib/cache.c b/lib/cache.c new file mode 100644 index 0000000..b8f49ce --- /dev/null +++ b/lib/cache.c @@ -0,0 +1,34 @@ +/* + * (C) Copyright 2011 SAMSUNG Electronics + * Łukasz Majewski l.majewski@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> + +/* Read the default Data CACHE LINE size */ +int __attribute__((weak)) get_dcache_line_size(void) +{ +#if defined(CONFIG_SYS_CACHE_LINE_SIZE) && !defined(CONFIG_SYS_DCACHE_OFF) + return CONFIG_SYS_CACHE_LINE_SIZE; +#else + return __BIGGEST_ALIGNMENT__; /* Constant defined by GCC compiler */ +#endif +}
participants (5)
-
Albert ARIBAUD
-
Aneesh V
-
Anton Staaf
-
Lukasz Majewski
-
Sergei Shtylyov