Skip to contentSkip to conversation

armv7: cache maintenance operations

PATCH Superseded Aneesh V 6 participants 50 messages Dec 22, 2010 – Mar 1, 2011

Subsystems (2)

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Aneesh V

author
#0 lore raw

cover armv7: cache maintenance operations

With D-cache and MMU enabled for ARM in u-boot it becomes imperative to support a minimal set of cache maintenance operations and necessary initializations before enabling MMU.

This series of patches attempt to do the following for armv7:
* Necessary initialization sequence before enabling MMU that includes invalidation of TLB, data caches, branch predictor array etc.
* Framework for supporting SOC specific outer caches in a generic manner (using a structure of function pointers - inspired by the Linux implementation)
* Generic armv7 cache maintenance operations for caches known to the CPU
* Support for ARM PL310 L2 cache controller used in OMAP4
* Cleanup of the cleanup_before_linux() function
* Adapting all armv7 SOCs to use the new framework and removing duplicated code

Testing:
* Extensive testing on OMAP4430SDP and OMAP3430SDP by creating coherency issues and solving them using the maintenance routines
- Eg: memfill a region of memory with a known pattern
- Invalidate the region
- Read back and compare the region with the original pattern
- If match fails it means that invalidate is successful
- Now add a flush call just before the invalidate
- If match succeeds it means that flush was successful
- Outer caches were tested with experiments involving making the function pointers NULL
* Kernel booting on OMAP4430SDP and OMAP3430SDP

Aneesh V (8):
arm: make default implementation of cache_flush() weakly linked
armv7: cache maintenance operations for armv7
armv7: integrate cache maintenance support
arm: minor fixes for cache and mmu handling
armv7: add PL310 support to u-boot
armv7: adapt omap4 to the new cache maintenance framework
armv7: adapt omap3 to the new cache maintenance framework
armv7: adapt s5pc1xx to the new cache maintenance framework

 arch/arm/cpu/armv7/Makefile                   |    2 +-
 arch/arm/cpu/armv7/cache_v7.c                 |  359 +++++++++++++++++++++++++
 arch/arm/cpu/armv7/config.mk                  |    2 +-
 arch/arm/cpu/armv7/cpu.c                      |   47 ++--
 arch/arm/cpu/armv7/omap3/Makefile             |    1 -
 arch/arm/cpu/armv7/omap3/board.c              |  151 +++++++++--
 arch/arm/cpu/armv7/omap3/cache.S              |  263 ------------------
 arch/arm/cpu/armv7/omap3/lowlevel_init.S      |   30 ++
 arch/arm/cpu/armv7/omap4/board.c              |   25 ++-
 arch/arm/cpu/armv7/omap4/lowlevel_init.S      |   17 ++
 arch/arm/cpu/armv7/s5pc1xx/cache.S            |   86 +------
 arch/arm/cpu/armv7/s5pc1xx/clock.c            |   12 +
 arch/arm/cpu/armv7/start.S                    |   18 ++-
 arch/arm/include/asm/arch-omap3/omap3.h       |   20 ++
 arch/arm/include/asm/arch-omap3/sys_proto.h   |   10 +-
 arch/arm/include/asm/arch-omap4/omap4.h       |    6 +
 arch/arm/include/asm/arch-omap4/sys_proto.h   |    3 +-
 arch/arm/include/asm/arch-s5pc1xx/sys_proto.h |    4 +-
 arch/arm/include/asm/armv7.h                  |   63 +++++
 arch/arm/include/asm/pl310.h                  |   49 ++++
 arch/arm/lib/Makefile                         |    1 +
 arch/arm/lib/board.c                          |    6 +
 arch/arm/lib/cache-cp15.c                     |   18 ++-
 arch/arm/lib/cache-pl310.c                    |  114 ++++++++
 arch/arm/lib/cache.c                          |   20 +-
 include/common.h                              |    5 +-
 include/configs/omap4_panda.h                 |    6 +-
 include/configs/omap4_sdp4430.h               |    6 +-
 28 files changed, 929 insertions(+), 415 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/cache_v7.c
 delete mode 100644 arch/arm/cpu/armv7/omap3/cache.S
 create mode 100644 arch/arm/include/asm/armv7.h
 create mode 100644 arch/arm/include/asm/pl310.h
 create mode 100644 arch/arm/lib/cache-pl310.c
author
#1 lore raw

PATCH 1/8 arm: make default implementation of cache_flush() weakly linked

make default implementation of cache_flush() weakly linked so that sub-architectures can override it

---
 arch/arm/lib/cache.c |    9 +++------
 1 files changed, 3 insertions(+), 6 deletions(-)
arch/arm/lib/cache.c +3 -6
index 30686fe..275b6e1 100644
@@ -25,7 +25,7 @@
 
 #include <common.h>
 
-void  flush_cache (unsigned long dummy1, unsigned long dummy2)
+void  __flush_cache(unsigned long dummy1, unsigned long dummy2)
 {
 #if defined(CONFIG_OMAP2420) || defined(CONFIG_ARM1136)
 	void arm1136_cache_flush(void);
@@ -38,10 +38,7 @@ void  flush_cache (unsigned long dummy1, unsigned long dummy2)
 	/* disable write buffer as well (page 2-22) */
 	asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
 #endif
-#ifdef CONFIG_OMAP34XX
-	void v7_flush_cache_all(void);
-
-	v7_flush_cache_all();
-#endif
 	return;
 }
+void  flush_cache(unsigned long dummy1, unsigned long dummy2)
+	__attribute__((weak, alias("__flush_cache")));
Signature · 1 line
1.7.0.4
author
#3 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

In reply to Aneesh V

- Add a framework for layered cache maintenance
- separate out SOC specific outer cache maintenance from maintenance of caches known to CPU

- Add generic ARMv7 cache maintenance operations that affect all caches known to ARMv7 CPUs. For instance in Cortex-A8 these opertions will affect both L1 and L2 caches. In Cortex-A9 these will affect only L1 cache

- D-cache operations supported:
- Invalidate entire D-cache
- Invalidate D-cache range
- Flush(clean & invalidate) entire D-cache
- Flush D-cache range
- I-cache operations supported:
- Invalidate entire I-cache

- Add maintenance functions for TLB, branch predictor array etc.

- Enable -march=armv7-a so that armv7 assembly instructions can be used

---
 arch/arm/cpu/armv7/Makefile   |    2 +-
 arch/arm/cpu/armv7/cache_v7.c |  359 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/cpu/armv7/config.mk  |    2 +-
 arch/arm/include/asm/armv7.h  |   63 +++++++
 include/common.h              |    5 +-
 5 files changed, 428 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/cache_v7.c
 create mode 100644 arch/arm/include/asm/armv7.h
arch/arm/cpu/armv7/Makefile +1 -1
index 8c0e915..299792a 100644
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)lib$(CPU).o
 
 START	:= start.o
-COBJS	:= cpu.o
+COBJS	:= cpu.o cache_v7.o
 COBJS  += syslib.o
 
 SRCS	:= $(START:.o=.S) $(COBJS:.o=.c)
arch/arm/cpu/armv7/cache_v7.c new file +359 -0

359 lines not on this page · raw message

arch/arm/cpu/armv7/config.mk +1 -1
index 49ac9c7..7f9b171 100644
@@ -23,7 +23,7 @@
 PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
 
 # Make ARMv5 to allow more compilers to work, even though its v7a.
-PLATFORM_CPPFLAGS += -march=armv5
+PLATFORM_CPPFLAGS += -march=armv7-a
 # =========================================================================
 #
 # Supply options according to compiler version
arch/arm/include/asm/armv7.h new file +63 -0

63 lines not on this page · raw message

include/common.h +4 -1
index 189ad81..d750ff9 100644
@@ -411,6 +411,7 @@ void	icache_disable(void);
 int	dcache_status (void);
 void	dcache_enable (void);
 void	dcache_disable(void);
+void	mmu_disable(void);
 void	relocate_code (ulong, gd_t *, ulong) __attribute__ ((noreturn));
 ulong	get_endaddr   (void);
 void	trap_init     (ulong);
@@ -603,9 +604,11 @@ ulong	video_setmem (ulong);
 
 /* arch/$(ARCH)/lib/cache.c */
 void	flush_cache   (unsigned long, unsigned long);
+void	flush_dcache_all(void);
 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);
 
 /* arch/$(ARCH)/lib/ticks.S */
 unsigned long long get_ticks(void);
Signature · 1 line
1.7.0.4
#4 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

Hi Aneesh,

Le 22/12/2010 12:54, Aneesh V a ?crit :

Quoted 125 lines

- Add a framework for layered cache maintenance
- separate out SOC specific outer cache maintenance from maintenance of caches known to CPU

- Add generic ARMv7 cache maintenance operations that affect all caches known to ARMv7 CPUs. For instance in Cortex-A8 these opertions will affect both L1 and L2 caches. In Cortex-A9 these will affect only L1 cache

- D-cache operations supported:
- Invalidate entire D-cache
- Invalidate D-cache range
- Flush(clean& invalidate) entire D-cache
- Flush D-cache range
- I-cache operations supported:
- Invalidate entire I-cache

- Add maintenance functions for TLB, branch predictor array etc.

- Enable -march=armv7-a so that armv7 assembly instructions can be used

---
  arch/arm/cpu/armv7/Makefile   |    2 +-
  arch/arm/cpu/armv7/cache_v7.c |  359 +++++++++++++++++++++++++++++++++++++++++
  arch/arm/cpu/armv7/config.mk  |    2 +-
  arch/arm/include/asm/armv7.h  |   63 +++++++
  include/common.h              |    5 +-
  5 files changed, 428 insertions(+), 3 deletions(-)

create mode 100644 arch/arm/cpu/armv7/cache_v7.c create mode 100644 arch/arm/include/asm/armv7.h

arch/arm/cpu/armv7/Makefile +1 -1
index 8c0e915..299792a 100644
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
  LIB	= $(obj)lib$(CPU).o
 
  START	:= start.o
-COBJS	:= cpu.o
+COBJS	:= cpu.o cache_v7.o
  COBJS  += syslib.o
 
  SRCS	:= $(START:.o=.S) $(COBJS:.o=.c)
arch/arm/cpu/armv7/cache_v7.c new file +73 -0
new file mode 100644
index 0000000..0521d66
@@ -0,0 +1,359 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments Incorporated - http://www.ti.com/
+ * Aneesh V<[email protected]>
+ *
+ * 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<linux/types.h>
+#include<common.h>
+#include<asm/armv7.h>
+
+#define ARMV7_DCACHE_INVAL_ALL		1
+#define ARMV7_DCACHE_CLEAN_INVAL_ALL	2
+#define ARMV7_DCACHE_INVAL_RANGE	3
+#define ARMV7_DCACHE_CLEAN_INVAL_RANGE	4
+
+struct v7_outer_cache_ops v7_outer_cache;
+
+#ifndef CONFIG_SYS_NO_DCACHE
+/*
+ * Write the level and type you want to Cache Size Selection Register(CSSELR)
+ * to get size details from Current Cache Size ID Register(CCSIDR)
+ */
+static void set_csselr(u32 level, u32 type)
+{	u32 csselr = level<<  1 | type;
+	/* Write to Cache Size Selection Register(CSSELR) */
+	asm volatile ("mcr p15, 2, %0, c0, c0, 0" : : "r" (csselr));
+}
+
+static u32 get_ccsidr(void)
+{
+	u32 ccsidr;
+	/* Read current CP15 Cache Size ID Register */
+	asm volatile ("mrc p15, 1, %0, c0, c0, 0" : "=r" (ccsidr));
+	return ccsidr;
+}
+
+static u32 get_clidr(void)
+{
+	u32 clidr;
+	/* Read current CP15 Cache Level ID Register */
+	asm volatile ("mrc p15,1,%0,c0,c0,1" : "=r" (clidr));
+	return clidr;
+}
+
+/* round up the input number to a power of 2 and get the log2 */
+static inline u32 log_2_round_up(u32 num)
+{
+	/* count leading zeros */
+	asm volatile ("CLZ %0, %0" : "+r" (num));
+
+	/* position of most significant 1 */
+	num = 31 - num;
+
+	return num;
+}
+

arch/arm/cpu/armv7/cache_v7.c line 83

Quoted 10 lines
arch/arm/cpu/armv7/cache_v7.c new file +10 -0
+static void v7_inval_dcache_level_setway(u32 level, u32 num_sets,
+					 u32 num_ways, u32 way_shift,
+					 u32 log2_line_len)
+{
+	int way, set, setway;
+	/*
+	 * For optimal assembly code:
+	 *	a. count down
+	 *	b. have bigger loop inside
+	 */

Out of curiosity, can you elaborate on why the compiler would optimize better in these cases?

arch/arm/cpu/armv7/cache_v7.c line 85

Quoted 2 lines
arch/arm/cpu/armv7/cache_v7.c new file +2 -0
+	for (way = num_ways - 1; way>= 0 ; way--)
+		for (set = num_sets - 1; set>= 0; set--) {

Please fix whitespacing around operators. The best way to ''catch'em all'' is to run Linux' checkpatch.pl (I do this with option --no-tree) on all patches that you submit to u-boot and, fix all warning and errors and if some are left that you think should not be fixed, mention them and explain why they're wrongly emitted.

Quoted 155 lines
arch/arm/cpu/armv7/cache_v7.c new file +155 -0
+			setway = (level<<  1) | (set<<  log2_line_len) |
+				 (way<<  way_shift);
+			/* Invalidate data/unified cache line by set/way */
+			asm volatile ("	mcr p15, 0, %0, c7, c6, 2"
+					: : "r" (setway));
+		}
+	/* Make sure the operation is complete */
+	asm volatile ("DMB");
+}
+
+static void v7_clean_inval_dcache_level_setway(u32 level, u32 num_sets,
+					       u32 num_ways, u32 way_shift,
+					       u32 log2_line_len)
+{
+	int way, set, setway;
+	/*
+	 * For optimal assembly code:
+	 *	a. count down
+	 *	b. have bigger loop inside
+	 */
+	for (way = num_ways - 1; way>= 0 ; way--)
+		for (set = num_sets - 1; set>= 0; set--) {
+			setway = (level<<  1) | (set<<  log2_line_len) |
+				 (way<<  way_shift);
+			/*
+			 * Clean&  Invalidate data/unified
+			 * cache line by set/way
+			 */
+			asm volatile ("	mcr p15, 0, %0, c7, c14, 2"
+					: : "r" (setway));
+		}
+	/* Make sure the operation is complete */
+	asm volatile ("DMB");
+}
+
+static void v7_maint_dcache_level_setway(u32 level, u32 operation)
+{
+	u32 ccsidr;
+	u32 num_sets, num_ways, log2_line_len, log2_num_ways;
+	u32 way_shift;
+	set_csselr(level, ARMV7_CSSELR_IND_DATA_UNIFIED);
+
+	ccsidr = get_ccsidr();
+
+	log2_line_len = mask_n_get(ccsidr, 0, 2) + 2;
+	/* Converting from words to bytes */
+	log2_line_len += 2;
+
+	num_ways  = mask_n_get(ccsidr, 3, 12) + 1;
+	num_sets  = mask_n_get(ccsidr, 13, 27) + 1;
+	/*
+	 * According to ARMv7 ARM number of sets and number of ways need
+	 * not be a power of 2
+	 */
+	log2_num_ways = log_2_round_up(num_ways);
+
+	way_shift = (32 - log2_num_ways);
+	if (operation == ARMV7_DCACHE_INVAL_ALL)
+		v7_inval_dcache_level_setway(level, num_sets, num_ways,
+				      way_shift, log2_line_len);
+	else if (operation == ARMV7_DCACHE_CLEAN_INVAL_ALL)
+		v7_clean_inval_dcache_level_setway(level, num_sets, num_ways,
+						   way_shift, log2_line_len);
+}
+
+static void v7_maint_dcache_all(u32 operation)
+{
+	u32 level, cache_type, level_start_bit = 0;
+
+	u32 clidr = get_clidr();
+
+	for (level = 0; level<  7; level++) {
+		cache_type = mask_n_get(clidr, level_start_bit,
+					level_start_bit + 2);
+		if ((cache_type == ARMV7_CLIDR_CTYPE_DATA_ONLY) ||
+		    (cache_type == ARMV7_CLIDR_CTYPE_INSTRUCTION_DATA) ||
+		    (cache_type == ARMV7_CLIDR_CTYPE_UNIFIED))
+			v7_maint_dcache_level_setway(level, operation);
+		level_start_bit += 3;
+	}
+}
+
+static void v7_dcache_clean_inval_range(u32 start,
+					u32 stop, u32 line_len)
+{
+	u32 mva;
+	/* Align start to cache line boundary */
+	start&= ~(line_len - 1);
+	for (mva = start; mva<  stop; mva = mva + line_len)
+		/* DCCIMVAC - Clean&  Invalidate data cache by MVA to PoC */
+		asm volatile ("mcr p15, 0, %0, c7, c14, 1" : : "r" (mva));
+}
+
+static void v7_dcache_inval_range(u32 start, u32 stop, u32 line_len)
+{
+	u32 mva;
+
+	/*
+	 * If start address is not aligned to cache-line flush the first
+	 * line to prevent affecting somebody else's buffer
+	 */
+	if (start&  (line_len - 1)) {
+		v7_dcache_clean_inval_range(start, start + 1, line_len);
+		/* move to next cache line */
+		start = (start + line_len - 1)&  ~(line_len - 1);
+	}
+
+	/*
+	 * If stop address is not aligned to cache-line flush the last
+	 * line to prevent affecting somebody else's buffer
+	 */
+	if (stop&  (line_len - 1)) {
+		v7_dcache_clean_inval_range(stop, stop + 1, line_len);
+		/* align to the beginning of this cache line */
+		stop&= ~(line_len - 1);
+	}
+
+	for (mva = start; mva<  stop; mva = mva + line_len)
+		/* DCIMVAC - Invalidate data cache by MVA to PoC */
+		asm volatile ("mcr p15, 0, %0, c7, c6, 1" : : "r" (mva));
+}
+
+static void v7_dcache_maint_range(u32 start, u32 stop, u32 range_op)
+{
+	u32 line_len, ccsidr;
+	ccsidr = get_ccsidr();
+	line_len = mask_n_get(ccsidr, 0, 2) + 2;
+	/* Converting from words to bytes */
+	line_len += 2;
+	/* converting from log2(linelen) to linelen */
+	line_len = 1<<  line_len;
+
+	switch (range_op) {
+	case ARMV7_DCACHE_CLEAN_INVAL_RANGE:
+		v7_dcache_clean_inval_range(start, stop, line_len);
+		break;
+	case ARMV7_DCACHE_INVAL_RANGE:
+		v7_dcache_inval_range(start, stop, line_len);
+		break;
+	}
+
+	/* Make sure the operation is complete */
+	asm volatile ("DMB");
+}
+
+/* Invalidate TLB */
+static void v7_inval_tlb(void)
+{
+	/* Invalidate entire unified TLB */
+	asm volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0));
+	/* Invalidate entire data TLB */
+	asm volatile ("mcr p15, 0, %0, c8, c6, 0" : : "r" (0));
+	/* Invalidate entire instruction TLB */
+	asm volatile ("mcr p15, 0, %0, c8, c5, 0" : : "r" (0));
+	/* Full system DSB - make sure that the invalidation is complete */

arch/arm/cpu/armv7/cache_v7.c line 250

Quoted 10 lines
arch/arm/cpu/armv7/cache_v7.c new file +10 -0
+	asm volatile ("DSB");
+	/* Full system ISB - make sure the instruction stream sees it */
+	asm volatile ("ISB");
+}
+
+void invalidate_dcache_all(void)
+{
+	v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL);
+	if (v7_outer_cache.inval_all)
+		v7_outer_cache.inval_all();

Why use pointers here rather than weak functions?

Quoted 99 lines
arch/arm/cpu/armv7/cache_v7.c new file +99 -0
+}
+
+/*
+ * Performs a clean&  invalidation of the entire data cache
+ * at all levels
+ */
+void flush_dcache_all(void)
+{
+	v7_maint_dcache_all(ARMV7_DCACHE_CLEAN_INVAL_ALL);
+	if (v7_outer_cache.flush_all)
+		v7_outer_cache.flush_all();
+}
+
+/*
+ * Invalidates range in all levels of D-cache/unified cache used:
+ * Affects the range [start, stop - 1]
+ */
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+
+	v7_dcache_maint_range(start, stop, ARMV7_DCACHE_INVAL_RANGE);
+	if (v7_outer_cache.inval_range)
+		/* physical address is same as virtual address */
+		v7_outer_cache.inval_range(start, stop);
+}
+
+/*
+ * Flush range(clean&  invalidate) from all levels of D-cache/unified
+ * cache used:
+ * Affects the range [start, stop - 1]
+ */
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+	v7_dcache_maint_range(start, stop, ARMV7_DCACHE_CLEAN_INVAL_RANGE);
+	if (v7_outer_cache.flush_range)
+		/* physical address is same as virtual address */
+		v7_outer_cache.flush_range(start, stop);
+}
+static void __v7_setup_outer_cache_ops(void)
+{
+	puts("v7_setup_outer_cache_ops: dummy implementation! "
+	     "real implementation not available!!\n");
+}
+
+void v7_setup_outer_cache_ops(void)
+	__attribute__((weak, alias("__v7_setup_outer_cache_ops")));
+
+void arm_init_before_mmu(void)
+{
+	v7_setup_outer_cache_ops();
+	if (v7_outer_cache.enable)
+		v7_outer_cache.enable();
+	invalidate_dcache_all();
+	v7_inval_tlb();
+}
+#else
+void invalidate_dcache_all(void)
+{
+}
+
+void flush_dcache_all(void)
+{
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void arm_init_before_mmu(void)
+{
+}
+#endif
+
+#ifndef CONFIG_SYS_NO_ICACHE
+/* Invalidate entire I-cache and branch predictor array */
+void invalidate_icache_all(void)
+{
+	/*
+	 * Invalidate all instruction caches to PoU.
+	 * Also flushes branch target cache.
+	 */
+	asm volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
+
+	/* Invalidate entire branch predictor array */
+	asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0));
+
+	/* Full system DSB - make sure that the invalidation is complete */
+	asm volatile ("DSB");
+	/* Full system ISB - make sure the instruction stream sees it */
+	asm volatile ("ISB");
+}
+#else
+void invalidate_icache_all(void)
+{
+}

arch/arm/cpu/armv7/cache_v7.c line 359

Quoted 10 lines
arch/arm/cpu/armv7/cache_v7.c new file +10 -0
+#endif
+
+/*
+ * Flush range from all levels of d-cache/unified-cache used:
+ * Affects the range [start, start + size - 1]
+ */
+void  flush_cache(unsigned long start, unsigned long size)
+{
+	flush_dcache_range(start, start + size);
+}

This function is the only one which is defined to something non-empty when CONFIG_SYS_NO_DCACHE is defined. Why is it not in the big #ifndef for dcache above ?

arch/arm/cpu/armv7/config.mk line 26

Quoted 10 lines
arch/arm/cpu/armv7/config.mk +1 -1
index 49ac9c7..7f9b171 100644
@@ -23,7 +23,7 @@
  PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
 
  # Make ARMv5 to allow more compilers to work, even though its v7a.
-PLATFORM_CPPFLAGS += -march=armv5
+PLATFORM_CPPFLAGS += -march=armv7-a

Did you check that this does not break any board using armv7?

Quoted 48 lines
arch/arm/cpu/armv7/config.mk +0 -0
  # =========================================================================
  #
  # Supply options according to compiler version
arch/arm/include/asm/armv7.h new file +39 -0
new file mode 100644
index 0000000..57409b6
@@ -0,0 +1,63 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Aneesh V<[email protected]>
+ *
+ * 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
+ */
+#ifndef ARMV7_H
+#define ARMV7_H
+
+#include<linux/types.h>
+
+/*
+ * Values for InD field in CSSELR
+ * Selects the type of cache
+ */
+#define ARMV7_CSSELR_IND_DATA_UNIFIED	0
+#define ARMV7_CSSELR_IND_INSTRUCTION	1
+
+/* Values for Ctype fields in CLIDR */
+#define ARMV7_CLIDR_CTYPE_NO_CACHE		0
+#define ARMV7_CLIDR_CTYPE_INSTRUCTION_ONLY	1

arch/arm/include/asm/armv7.h line 49

Quoted 10 lines
arch/arm/include/asm/armv7.h new file +10 -0
+#define ARMV7_CLIDR_CTYPE_DATA_ONLY		2
+#define ARMV7_CLIDR_CTYPE_INSTRUCTION_DATA	3
+#define ARMV7_CLIDR_CTYPE_UNIFIED		4
+
+/* some utility macros */
+#define mask(start, end) \
+	(((1<<  ((end) - (start) + 1)) - 1)<<  (start))
+
+#define mask_n_get(reg, start, end) \
+	(((reg)&  mask(start, end))>>  (start))

Seeing as these functions are only used in the ARMv7 cache C file, they should be moved there.

Quoted 28 lines
arch/arm/include/asm/armv7.h new file +13 -0
+struct v7_outer_cache_ops {
+	void (*enable)(void);
+	void (*disable)(void);
+	void (*flush_all)(void);
+	void (*inval_all)(void);
+	void (*flush_range)(u32 start, u32 end);
+	void (*inval_range)(u32 start, u32 end);
+};
+
+extern struct v7_outer_cache_ops v7_outer_cache;
+
+void v7_setup_outer_cache_ops(void);
+#endif
include/common.h +1 -0
index 189ad81..d750ff9 100644
@@ -411,6 +411,7 @@ void	icache_disable(void);
  int	dcache_status (void);
  void	dcache_enable (void);
  void	dcache_disable(void);
+void	mmu_disable(void);
  void	relocate_code (ulong, gd_t *, ulong) __attribute__ ((noreturn));
  ulong	get_endaddr   (void);
  void	trap_init     (ulong);
@@ -603,9 +604,11 @@ ulong	video_setmem (ulong);
 
  /* arch/$(ARCH)/lib/cache.c */

include/common.h ulong video_setmem (ulong); · line 614

Quoted 10 lines
include/common.h +3 -1
  void	flush_cache   (unsigned long, unsigned long);
+void	flush_dcache_all(void);
  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);
 
  /* arch/$(ARCH)/lib/ticks.S */
  unsigned long long get_ticks(void);

Amicalement,

Signature · 1 line
Albert.
#5 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

Le 08/01/2011 07:36, Albert ARIBAUD a ?crit :

Quoted 10 lines

arch/arm/cpu/armv7/config.mk line 26

Quoted 8 lines
arch/arm/cpu/armv7/config.mk +1 -1
@@ -23,7 +23,7 @@
   PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
 
   # Make ARMv5 to allow more compilers to work, even though its v7a.
-PLATFORM_CPPFLAGS += -march=armv5
+PLATFORM_CPPFLAGS += -march=armv7-a

Did you check that this does not break any board using armv7?

Actually I should have said "Did you check that it does not break building with any common toolchain", considering the comment above the line. And indeed, it breaks building with ELDK 4.2 toolchain.

Amicalement,

Signature · 1 line
Albert.
author
#6 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

In reply to Albert ARIBAUD

Hi Albert,

Quoted 133 lines · Albert ARIBAUD

Hi Aneesh,

Le 22/12/2010 12:54, Aneesh V a ?crit :

Quoted 130 lines

- Add a framework for layered cache maintenance
- separate out SOC specific outer cache maintenance from maintenance of caches known to CPU

- Add generic ARMv7 cache maintenance operations that affect all caches known to ARMv7 CPUs. For instance in Cortex-A8 these opertions will affect both L1 and L2 caches. In Cortex-A9 these will affect only L1 cache

- D-cache operations supported:
- Invalidate entire D-cache
- Invalidate D-cache range
- Flush(clean& invalidate) entire D-cache
- Flush D-cache range
- I-cache operations supported:
- Invalidate entire I-cache

- Add maintenance functions for TLB, branch predictor array etc.

- Enable -march=armv7-a so that armv7 assembly instructions can be used

---
   arch/arm/cpu/armv7/Makefile   |    2 +-
   arch/arm/cpu/armv7/cache_v7.c |  359 +++++++++++++++++++++++++++++++++++++++++
   arch/arm/cpu/armv7/config.mk  |    2 +-
   arch/arm/include/asm/armv7.h  |   63 +++++++
   include/common.h              |    5 +-
   5 files changed, 428 insertions(+), 3 deletions(-)

create mode 100644 arch/arm/cpu/armv7/cache_v7.c create mode 100644 arch/arm/include/asm/armv7.h

arch/arm/cpu/armv7/Makefile +1 -1
index 8c0e915..299792a 100644
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
   LIB	= $(obj)lib$(CPU).o
 
   START	:= start.o
-COBJS	:= cpu.o
+COBJS	:= cpu.o cache_v7.o
   COBJS  += syslib.o
 
   SRCS	:= $(START:.o=.S) $(COBJS:.o=.c)
arch/arm/cpu/armv7/cache_v7.c new file +78 -0
new file mode 100644
index 0000000..0521d66
@@ -0,0 +1,359 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments Incorporated - http://www.ti.com/
+ * Aneesh V<[email protected]>
+ *
+ * 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<linux/types.h>
+#include<common.h>
+#include<asm/armv7.h>
+
+#define ARMV7_DCACHE_INVAL_ALL		1
+#define ARMV7_DCACHE_CLEAN_INVAL_ALL	2
+#define ARMV7_DCACHE_INVAL_RANGE	3
+#define ARMV7_DCACHE_CLEAN_INVAL_RANGE	4
+
+struct v7_outer_cache_ops v7_outer_cache;
+
+#ifndef CONFIG_SYS_NO_DCACHE
+/*
+ * Write the level and type you want to Cache Size Selection Register(CSSELR)
+ * to get size details from Current Cache Size ID Register(CCSIDR)
+ */
+static void set_csselr(u32 level, u32 type)
+{	u32 csselr = level<<   1 | type;
+	/* Write to Cache Size Selection Register(CSSELR) */
+	asm volatile ("mcr p15, 2, %0, c0, c0, 0" : : "r" (csselr));
+}
+
+static u32 get_ccsidr(void)
+{
+	u32 ccsidr;
+	/* Read current CP15 Cache Size ID Register */
+	asm volatile ("mrc p15, 1, %0, c0, c0, 0" : "=r" (ccsidr));
+	return ccsidr;
+}
+
+static u32 get_clidr(void)
+{
+	u32 clidr;
+	/* Read current CP15 Cache Level ID Register */
+	asm volatile ("mrc p15,1,%0,c0,c0,1" : "=r" (clidr));
+	return clidr;
+}
+
+/* round up the input number to a power of 2 and get the log2 */
+static inline u32 log_2_round_up(u32 num)
+{
+	/* count leading zeros */
+	asm volatile ("CLZ %0, %0" : "+r" (num));
+
+	/* position of most significant 1 */
+	num = 31 - num;
+
+	return num;
+}
+
+static void v7_inval_dcache_level_setway(u32 level, u32 num_sets,
+					 u32 num_ways, u32 way_shift,
+					 u32 log2_line_len)
+{
+	int way, set, setway;
Quoted 8 lines

arch/arm/cpu/armv7/cache_v7.c line 83

Quoted 5 lines
arch/arm/cpu/armv7/cache_v7.c new file +5 -0
+	/*
+	 * For optimal assembly code:
+	 *	a. count down
+	 *	b. have bigger loop inside
+	 */

Out of curiosity, can you elaborate on why the compiler would optimize better in these cases?

While counting down the termination condition check is against 0. So you can just decrement the loop count using a 'subs' and do a 'bne'. When you count up you have to do a comparison with a non-zero value. So you will need one 'cmp' instruction extra:-)

bigger loop inside because that reduces the frequency at which your outer parameter changes and hence the overall number of instructions executed. Consider this:
1. We encode both the loop counts along with other data into a register that is finally written to CP15 register.
2. outer loop has the code for shifting and ORing the outer variable to this register.
3. Inner loop has the code for shifting and ORing the inner variable. Step (3) has to be executed 'way x set' number of times anyways. But having bigger loop inside makes sure that 2 is executed fewer times!

With these tweaks the assembly code generated by this C code is as good as the original hand-written assembly code with my compiler.

Quoted 9 lines

arch/arm/cpu/armv7/cache_v7.c line 85

Quoted 3 lines
arch/arm/cpu/armv7/cache_v7.c new file +2 -0
+	for (way = num_ways - 1; way>= 0 ; way--)
+		for (set = num_sets - 1; set>= 0; set--) {

Please fix whitespacing around operators. The best way to ''catch'em all'' is to run Linux' checkpatch.pl (I do this with option --no-tree) on all patches that you submit to u-boot and, fix all warning and errors and if some are left that you think should not be fixed, mention them and explain why they're wrongly emitted.

I religiously do checkpatch whenever I send out a patch. Please note that my original mail seems to be fine. I saved it and ran checkpatch again. No errors, no warnings! Something amiss?

Best regards,
Aneesh

#7 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

(I realize I did not answer the other ones)

Le 08/01/2011 11:06, Aneesh V a ?crit :

Quoted 7 lines
Quoted 2 lines

Out of curiosity, can you elaborate on why the compiler would optimize better in these cases?

While counting down the termination condition check is against 0. So you can just decrement the loop count using a 'subs' and do a 'bne'. When you count up you have to do a comparison with a non-zero value. So you will need one 'cmp' instruction extra:-)

I would not try to be too smart about what instructions are generated and how by a compiler such as gcc which has rather complex code generation optimizations.

Quoted 10 lines

bigger loop inside because that reduces the frequency at which your outer parameter changes and hence the overall number of instructions executed. Consider this:
1. We encode both the loop counts along with other data into a register that is finally written to CP15 register.
2. outer loop has the code for shifting and ORing the outer variable to this register.
3. Inner loop has the code for shifting and ORing the inner variable. Step (3) has to be executed 'way x set' number of times anyways. But having bigger loop inside makes sure that 2 is executed fewer times!

Here too it seems like you're underestimating the compiler's optimizing capabilities -- your explanation seems to amount to extracting a constant calculation from a loop, something that is rather usual in code optimizing.

Quoted 2 lines

With these tweaks the assembly code generated by this C code is as good as the original hand-written assembly code with my compiler.

How about other compilers?

Quoted 9 lines
Quoted 8 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+	for (way = num_ways - 1; way>= 0 ; way--)
+		for (set = num_sets - 1; set>= 0; set--) {

Please fix whitespacing around operators. The best way to ''catch'em all'' is to run Linux' checkpatch.pl (I do this with option --no-tree) on all patches that you submit to u-boot and, fix all warning and errors and if some are left that you think should not be fixed, mention them and explain why they're wrongly emitted.

Quoted 3 lines

I religiously do checkpatch whenever I send out a patch. Please note that my original mail seems to be fine. I saved it and ran checkpatch again. No errors, no warnings! Something amiss?

Well, something like "set>= 0" is quite surprising as it has inconsistent spacing around a binary operators. But you're right, checkpatch does not detect it. Can you fix them manually?

Quoted 2 lines

Best regards,
Aneesh

Amicalement,

Signature · 1 line
Albert.
author
#8 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

Quoted 7 lines · Albert ARIBAUD

(I realize I did not answer the other ones)

Le 08/01/2011 11:06, Aneesh V a ?crit :

Quoted 3 lines
Quoted 2 lines

Out of curiosity, can you elaborate on why the compiler would optimize better in these cases?

Quoted 8 lines
Quoted 4 lines

While counting down the termination condition check is against 0. So you can just decrement the loop count using a 'subs' and do a 'bne'. When you count up you have to do a comparison with a non-zero value. So you will need one 'cmp' instruction extra:-)

I would not try to be too smart about what instructions are generated and how by a compiler such as gcc which has rather complex code generation optimizations.

IMHO, on ARM comparing with 0 is always going to be efficient than comparing with a non-zero number for a termination condition, assuming a decent compiler.

Quoted 12 lines
Quoted 11 lines

bigger loop inside because that reduces the frequency at which your outer parameter changes and hence the overall number of instructions executed. Consider this:
1. We encode both the loop counts along with other data into a register that is finally written to CP15 register.
2. outer loop has the code for shifting and ORing the outer variable to this register.
3. Inner loop has the code for shifting and ORing the inner variable. Step (3) has to be executed 'way x set' number of times anyways. But having bigger loop inside makes sure that 2 is executed fewer times!

It's not a constant calculation. It's based on loop index. And this optimization is not relying on compiler specifics. This is a logic level optimization. It should generally give good results with all compilers. Perhaps I was wrong in stating that it helps in getting better assembly. It just helps in better run-time efficiency.

Quoted 4 lines

Here too it seems like you're underestimating the compiler's optimizing capabilities -- your explanation seems to amount to extracting a constant calculation from a loop, something that is rather usual in code optimizing.

Actually, in my experience(in this same context) GCC does a terrible job at this! For instance:

+ for (set = num_sets - 1; set >= 0; set--) {
+ setway = (level << 1) | (set << log2_line_len) |
+ (way << way_shift);

Here, way_shift = 32 - log2_num_ways

But if you substitute way_shift with the latter, GCC will put the subtraction instruction inside the loop! - where as it is clearly loop invariant. So, I had to move it explicitly out of the loop! In fact, I was thinking of giving this feedback to GCC.

Quoted 6 lines
Quoted 3 lines

With these tweaks the assembly code generated by this C code is as good as the original hand-written assembly code with my compiler.

How about other compilers?

I haven't tested other compilers. However, as I mentioned above the latter one is a logic optimization. The former hopefully should help all ARM compilers.

As you must be knowing, existing code for cache maintenance was in assembly. When I moved it to C I wanted to make sure that the generated code is as good as the original assembly for this critical piece of code (I expected some criticism about moving it to C :-)). That's why I checked the generated code and did these ,hopefully, minor tweaks to make it better. I hope they don't have any serious drawbacks.

Best regards,
Aneesh

author
#9 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

In reply to Albert ARIBAUD

On Thursday 13 January 2011 12:48 AM, Albert ARIBAUD wrote:
<snip ..>

Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
Quoted 2 lines

+ for (way = num_ways - 1; way>= 0 ; way--)
+ for (set = num_sets - 1; set>= 0; set--) {

Please fix whitespacing around operators. The best way to ''catch'em all'' is to run Linux' checkpatch.pl (I do this with option --no-tree) on all patches that you submit to u-boot and, fix all warning and errors and if some are left that you think should not be fixed, mention them and explain why they're wrongly emitted.

Quoted 7 lines
Quoted 3 lines

I religiously do checkpatch whenever I send out a patch. Please note that my original mail seems to be fine. I saved it and ran checkpatch again. No errors, no warnings! Something amiss?

Well, something like "set>= 0" is quite surprising as it has inconsistent spacing around a binary operators. But you're right, checkpatch does not detect it. Can you fix them manually?

Checkpatch does find such issues. I was trying to say that my original mail doesn't have any spacing issues. The problem seems to have appeared in your reply. Is your mail client doing something funny?

Quoted 5 lines
Quoted 3 lines

Best regards,
Aneesh

Amicalement,

#10 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

Le 13/01/2011 13:14, Aneesh V a ?crit :

Quoted 17 lines · Albert ARIBAUD

<snip ..>

Quoted 14 lines
Quoted 13 lines
Quoted 9 lines
Quoted 2 lines

+ for (way = num_ways - 1; way>= 0 ; way--)
+ for (set = num_sets - 1; set>= 0; set--) {

Please fix whitespacing around operators. The best way to ''catch'em all'' is to run Linux' checkpatch.pl (I do this with option --no-tree) on all patches that you submit to u-boot and, fix all warning and errors
and if some are left that you think should not be fixed, mention them and explain why they're wrongly emitted.

I religiously do checkpatch whenever I send out a patch. Please note that my original mail seems to be fine. I saved it and ran checkpatch again. No errors, no warnings! Something amiss?

Quoted 7 lines
Quoted 3 lines

Well, something like "set>= 0" is quite surprising as it has inconsistent spacing around a binary operators. But you're right, checkpatch does not detect it. Can you fix them manually?

Checkpatch does find such issues. I was trying to say that my original mail doesn't have any spacing issues. The problem seems to have appeared in your reply. Is your mail client doing something funny?

You're right. The issue appears when doing a "reply" with Thunderbird. Seems to me like a recent change in behavior, as I recall having replied to mails with this kind of spacing preserved. Sorry for the noise.

Amicalement,

Signature · 1 line
Albert.
author
#11 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

In reply to Albert ARIBAUD
Quoted 1 line · Albert ARIBAUD

Hi Aneesh,

Pressed the Send button too fast last time. Missed answering the last few questions.

<snip..>

Quoted 8 lines

arch/arm/cpu/armv7/cache_v7.c line 250

Quoted 6 lines
arch/arm/cpu/armv7/cache_v7.c new file +6 -0
+
+void invalidate_dcache_all(void)
+{
+	v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL);
+	if (v7_outer_cache.inval_all)
+		v7_outer_cache.inval_all();

Why use pointers here rather than weak functions?

In fact, I hadn't thought about it. Maybe I was biased by the Linux implementation.The only reason I can think of is that pointer gives the flexibility of doing this assignment at run-time. Let's say we had a multi-platform u-boot that detects the SOC at run-time?

Quoted 106 lines
Quoted 106 lines
arch/arm/cpu/armv7/cache_v7.c new file +105 -0
+}
+
+/*
+ * Performs a clean&   invalidation of the entire data cache
+ * at all levels
+ */
+void flush_dcache_all(void)
+{
+	v7_maint_dcache_all(ARMV7_DCACHE_CLEAN_INVAL_ALL);
+	if (v7_outer_cache.flush_all)
+		v7_outer_cache.flush_all();
+}
+
+/*
+ * Invalidates range in all levels of D-cache/unified cache used:
+ * Affects the range [start, stop - 1]
+ */
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+
+	v7_dcache_maint_range(start, stop, ARMV7_DCACHE_INVAL_RANGE);
+	if (v7_outer_cache.inval_range)
+		/* physical address is same as virtual address */
+		v7_outer_cache.inval_range(start, stop);
+}
+
+/*
+ * Flush range(clean&   invalidate) from all levels of D-cache/unified
+ * cache used:
+ * Affects the range [start, stop - 1]
+ */
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+	v7_dcache_maint_range(start, stop, ARMV7_DCACHE_CLEAN_INVAL_RANGE);
+	if (v7_outer_cache.flush_range)
+		/* physical address is same as virtual address */
+		v7_outer_cache.flush_range(start, stop);
+}
+static void __v7_setup_outer_cache_ops(void)
+{
+	puts("v7_setup_outer_cache_ops: dummy implementation! "
+	     "real implementation not available!!\n");
+}
+
+void v7_setup_outer_cache_ops(void)
+	__attribute__((weak, alias("__v7_setup_outer_cache_ops")));
+
+void arm_init_before_mmu(void)
+{
+	v7_setup_outer_cache_ops();
+	if (v7_outer_cache.enable)
+		v7_outer_cache.enable();
+	invalidate_dcache_all();
+	v7_inval_tlb();
+}
+#else
+void invalidate_dcache_all(void)
+{
+}
+
+void flush_dcache_all(void)
+{
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void arm_init_before_mmu(void)
+{
+}
+#endif
+
+#ifndef CONFIG_SYS_NO_ICACHE
+/* Invalidate entire I-cache and branch predictor array */
+void invalidate_icache_all(void)
+{
+	/*
+	 * Invalidate all instruction caches to PoU.
+	 * Also flushes branch target cache.
+	 */
+	asm volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
+
+	/* Invalidate entire branch predictor array */
+	asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0));
+
+	/* Full system DSB - make sure that the invalidation is complete */
+	asm volatile ("DSB");
+	/* Full system ISB - make sure the instruction stream sees it */
+	asm volatile ("ISB");
+}
+#else
+void invalidate_icache_all(void)
+{
+}
+#endif
+
+/*
+ * Flush range from all levels of d-cache/unified-cache used:
+ * Affects the range [start, start + size - 1]
+ */
Quoted 8 lines

arch/arm/cpu/armv7/cache_v7.c line 359

Quoted 4 lines
arch/arm/cpu/armv7/cache_v7.c new file +4 -0
+void  flush_cache(unsigned long start, unsigned long size)
+{
+	flush_dcache_range(start, start + size);
+}

This function is the only one which is defined to something non-empty when CONFIG_SYS_NO_DCACHE is defined. Why is it not in the big #ifndef for dcache above ?

Although this function is non-empty, flush_dcache_range() is in turn empty. Effect will be the same, right?

Quoted 8 lines
Quoted 8 lines
arch/arm/cpu/armv7/config.mk +0 -0
index 49ac9c7..7f9b171 100644
@@ -23,7 +23,7 @@
   PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
 
Quoted 5 lines

arch/arm/cpu/armv7/config.mk line 26

Quoted 3 lines
arch/arm/cpu/armv7/config.mk +1 -1
   # Make ARMv5 to allow more compilers to work, even though its v7a.
-PLATFORM_CPPFLAGS += -march=armv5
+PLATFORM_CPPFLAGS += -march=armv7-a

Did you check that this does not break any board using armv7?

I checked only Codesourcery tool chain.
Linux kernel build for a v7 architecture processor uses armv7-a. Is it not fair to assume that the toolchain used for bootloader also supports it? Do we have to support those out-dated compilers?

Quoted 53 lines
Quoted 53 lines
arch/arm/cpu/armv7/config.mk +0 -0
   # =========================================================================
   #
   # Supply options according to compiler version
arch/arm/include/asm/armv7.h new file +44 -0
new file mode 100644
index 0000000..57409b6
@@ -0,0 +1,63 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Aneesh V<[email protected]>
+ *
+ * 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
+ */
+#ifndef ARMV7_H
+#define ARMV7_H
+
+#include<linux/types.h>
+
+/*
+ * Values for InD field in CSSELR
+ * Selects the type of cache
+ */
+#define ARMV7_CSSELR_IND_DATA_UNIFIED	0
+#define ARMV7_CSSELR_IND_INSTRUCTION	1
+
+/* Values for Ctype fields in CLIDR */
+#define ARMV7_CLIDR_CTYPE_NO_CACHE		0
+#define ARMV7_CLIDR_CTYPE_INSTRUCTION_ONLY	1
+#define ARMV7_CLIDR_CTYPE_DATA_ONLY		2
+#define ARMV7_CLIDR_CTYPE_INSTRUCTION_DATA	3
+#define ARMV7_CLIDR_CTYPE_UNIFIED		4
+
+/* some utility macros */
Quoted 8 lines

arch/arm/include/asm/armv7.h

Quoted 5 lines
arch/arm/include/asm/armv7.h new file +5 -0
+#define mask(start, end) \
+	(((1<<   ((end) - (start) + 1)) - 1)<<   (start))
+
+#define mask_n_get(reg, start, end) \
+	(((reg)&   mask(start, end))>>   (start))

Seeing as these functions are only used in the ARMv7 cache C file, they should be moved there.

I plan to use a modified version of mask_n_get() and its set couterpart mask_n_set() in my subsequent works in more files.

Can I keep it here itself or should I move it to an OMAP specific header file or can I move it to a more generic header file? Please suggest.

Best regards,
Aneesh

#12 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

Le 08/01/2011 14:17, Aneesh V a ?crit :

Quoted 6 lines
Quoted 1 line

Why use pointers here rather than weak functions?

In fact, I hadn't thought about it. Maybe I was biased by the Linux implementation.The only reason I can think of is that pointer gives the flexibility of doing this assignment at run-time. Let's say we had a multi-platform u-boot that detects the SOC at run-time?

I know we consider multi-board u-boot binaries when boards are variant of a given SoC, that's one reason why we wanted relocation. I'm not sure about multi-SoC when SoC is a variant of a given cpu, though. Wolfgang, your opinion?

Quoted 11 lines
Quoted 8 lines

arch/arm/cpu/armv7/cache_v7.c line 359

Quoted 4 lines
arch/arm/cpu/armv7/cache_v7.c new file +4 -0
+void flush_cache(unsigned long start, unsigned long size)
+{
+ flush_dcache_range(start, start + size);
+}

This function is the only one which is defined to something non-empty when CONFIG_SYS_NO_DCACHE is defined. Why is it not in the big #ifndef for dcache above ?

Although this function is non-empty, flush_dcache_range() is in turn empty. Effect will be the same, right?

Yes the effect is the same, but your patch results in a non-trivially empty function; I'd prefer it to be visibly empty when we compile without cache support.

Quoted 13 lines
Quoted 7 lines
Quoted 7 lines
arch/arm/cpu/armv7/config.mk +0 -0
index 49ac9c7..7f9b171 100644
@@ -23,7 +23,7 @@

PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float

Quoted 5 lines

arch/arm/cpu/armv7/config.mk line 26

Quoted 3 lines

# Make ARMv5 to allow more compilers to work, even though its v7a.

arch/arm/cpu/armv7/config.mk +1 -1
-PLATFORM_CPPFLAGS += -march=armv5
+PLATFORM_CPPFLAGS += -march=armv7-a

Did you check that this does not break any board using armv7?

Quoted 4 lines

I checked only Codesourcery tool chain.
Linux kernel build for a v7 architecture processor uses armv7-a. Is it not fair to assume that the toolchain used for bootloader also supports it? Do we have to support those out-dated compilers?

Just because Linux uses armv7-a for a v7 arch does not mean we must have it for u-boot. For starters, U-boot does not always boot Linux. :)

As for out-dated compilers, that's the question I'm asking: do we consider e.g. ELDK 4.2 as outdated or not? It won't accept armv7-a.

Quoted 10 lines
Quoted 9 lines

arch/arm/cpu/armv7/config.mk

Quoted 6 lines
arch/arm/cpu/armv7/config.mk +6 -0
+/* some utility macros */
+#define mask(start, end) \
+ (((1<< ((end) - (start) + 1)) - 1)<< (start))
+
+#define mask_n_get(reg, start, end) \
+ (((reg)& mask(start, end))>> (start))

Seeing as these functions are only used in the ARMv7 cache C file, they should be moved there.

Quoted 6 lines

I plan to use a modified version of mask_n_get() and its set couterpart mask_n_set() in my subsequent works in more files.

Can I keep it here itself or should I move it to an OMAP specific header file or can I move it to a more generic header file? Please suggest.

They're very generic actually. I think they should go to a gereric bit manipulation header, and be named a... bit... more explicitly. For instance, the name 'mask' does not show that the macro creates a range of 'one' bits from start to end.

Quoted 2 lines

Best regards,
Aneesh

Amicalement,

Signature · 1 line
Albert.
#13 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

Dear Albert ARIBAUD,

Quoted 5 lines · In message <[email protected]> you wrote:

I know we consider multi-board u-boot binaries when boards are variant of a given SoC, that's one reason why we wanted relocation. I'm not sure about multi-SoC when SoC is a variant of a given cpu, though. Wolfgang, your opinion?

Unless we see a specific example which uses this feature, we should not add provisions that make the code more complicated than needed.

And when we start supporting such a feature, we should probably do this based on a device tree approach.

Quoted 6 lines
Quoted 2 lines

Although this function is non-empty, flush_dcache_range() is in turn empty. Effect will be the same, right?

Yes the effect is the same, but your patch results in a non-trivially empty function; I'd prefer it to be visibly empty when we compile without cache support.

Yes, that's my opinion, too.

Quoted 5 lines

Just because Linux uses armv7-a for a v7 arch does not mean we must have it for u-boot. For starters, U-boot does not always boot Linux. :)

As for out-dated compilers, that's the question I'm asking: do we consider e.g. ELDK 4.2 as outdated or not? It won't accept armv7-a.

That's a catch question.

Yes, ELDK 4.2 is outdated. But it is still one of the most stable versions of a tool chain known to me, especially when it comes to using the very same tool versions across several architectures.

I cannot see any benefits of this code change that would justiify such a breakage.

Best regards,

Wolfgang Denk

Signature · 6 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"The bad reputation UNIX has gotten is totally undeserved, laid on by
people who don't understand, who have not gotten in there  and  tried
anything."          -- Jim Joyce, owner of Jim Joyce's UNIX Bookstore
author
#14 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

Dear Wolfgang,

Quoted 11 lines · Wolfgang Denk

Dear Albert ARIBAUD,

Quoted 5 lines · In message<[email protected]> you wrote:

I know we consider multi-board u-boot binaries when boards are variant of a given SoC, that's one reason why we wanted relocation. I'm not sure about multi-SoC when SoC is a variant of a given cpu, though. Wolfgang, your opinion?

Unless we see a specific example which uses this feature, we should not add provisions that make the code more complicated than needed.

Agree. But do you think the pointer based approach makes it overly complex?

Quoted 4 lines

And when we start supporting such a feature, we should probably do this based on a device tree approach.

Quoted 8 lines
Quoted 6 lines
Quoted 2 lines

Although this function is non-empty, flush_dcache_range() is in turn empty. Effect will be the same, right?

Yes the effect is the same, but your patch results in a non-trivially empty function; I'd prefer it to be visibly empty when we compile without cache support.

Yes, that's my opinion, too.

Agree.

Quoted 8 lines
Quoted 7 lines

Just because Linux uses armv7-a for a v7 arch does not mean we must have it for u-boot. For starters, U-boot does not always boot Linux. :)

As for out-dated compilers, that's the question I'm asking: do we consider e.g. ELDK 4.2 as outdated or not? It won't accept armv7-a.

Quoted 8 lines

That's a catch question.

Yes, ELDK 4.2 is outdated. But it is still one of the most stable versions of a tool chain known to me, especially when it comes to using the very same tool versions across several architectures.

I cannot see any benefits of this code change that would justiify such a breakage.

Agree. The only benefit is that I can use some memory barrier instructions without hand-coding the respective machine instructions. But that can be done if it helps avoiding compiler breakage.

Quoted 6 lines

Best regards,

Wolfgang Denk

#15 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

Dear Aneesh V,

Quoted 6 lines · In message <[email protected]> you wrote:
Quoted 3 lines

Unless we see a specific example which uses this feature, we should not add provisions that make the code more complicated than needed.

Agree. But do you think the pointer based approach makes it overly complex?

Not overly complex, but more complex than needed.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
A consultant is a person who borrows your watch, tells you what  time
it is, pockets the watch, and sends you a bill for it.
author
#16 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

In reply to Albert ARIBAUD
Quoted 2 lines · Albert ARIBAUD

Le 08/01/2011 14:17, Aneesh V a ?crit :

<snip..>

Quoted 13 lines
Quoted 13 lines
Quoted 9 lines

arch/arm/include/asm/armv7.h

Quoted 6 lines
arch/arm/include/asm/armv7.h new file +6 -0
+/* some utility macros */
+#define mask(start, end) \
+ (((1<< ((end) - (start) + 1)) - 1)<< (start))
+
+#define mask_n_get(reg, start, end) \
+ (((reg)& mask(start, end))>> (start))

Seeing as these functions are only used in the ARMv7 cache C file, they should be moved there.

I plan to use a modified version of mask_n_get() and its set couterpart mask_n_set() in my subsequent works in more files.

Quoted 9 lines
Quoted 3 lines

Can I keep it here itself or should I move it to an OMAP specific header file or can I move it to a more generic header file? Please suggest.

They're very generic actually. I think they should go to a gereric bit manipulation header, and be named a... bit... more explicitly. For instance, the name 'mask' does not show that the macro creates a range of 'one' bits from start to end.

What I need is something like below:

#define get_bit_field(nr, start, mask)\
	(((nr) & (mask)) >> (start))
#define set_bit_field(nr, start, mask, val)\
	(nr) = ((nr) & ~(mask)) | (((val) << (start)) & (mask))

Can these go in a generic header? If so, can I add them to "include/linux/bitops.h"

Best regards,
Aneesh

#17 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

Le 12/01/2011 10:08, Aneesh V a ?crit :

Quoted 29 lines · Albert ARIBAUD
Quoted 2 lines

Le 08/01/2011 14:17, Aneesh V a ?crit :

<snip..>

Quoted 13 lines
Quoted 13 lines
Quoted 9 lines

arch/arm/include/asm/armv7.h

Quoted 6 lines
arch/arm/include/asm/armv7.h new file +6 -0
+/* some utility macros */
+#define mask(start, end) \
+ (((1<< ((end) - (start) + 1)) - 1)<< (start))
+
+#define mask_n_get(reg, start, end) \
+ (((reg)& mask(start, end))>> (start))

Seeing as these functions are only used in the ARMv7 cache C file, they should be moved there.

I plan to use a modified version of mask_n_get() and its set couterpart mask_n_set() in my subsequent works in more files.

Quoted 8 lines
Quoted 3 lines

Can I keep it here itself or should I move it to an OMAP specific header file or can I move it to a more generic header file? Please suggest.

They're very generic actually. I think they should go to a gereric bit manipulation header, and be named a... bit... more explicitly. For instance, the name 'mask' does not show that the macro creates a range of 'one' bits from start to end.

What I need is something like below:

Quoted 8 lines

#define get_bit_field(nr, start, mask)\
(((nr) & (mask)) >> (start))

#define set_bit_field(nr, start, mask, val)\
(nr) = ((nr) & ~(mask)) | (((val) << (start)) & (mask))

Can these go in a generic header? If so, can I add them to "include/linux/bitops.h"

After some more thought, I am wondering if a *generic* field setting and getting macro is really useful. So far everyone is fine with at most defining field-specific macros.

Quoted 2 lines

Best regards,
Aneesh

Amicalement,

Signature · 1 line
Albert.
author
#18 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

Quoted 37 lines · Albert ARIBAUD

Le 12/01/2011 10:08, Aneesh V a ?crit :

Quoted 36 lines · Albert ARIBAUD
Quoted 2 lines

Le 08/01/2011 14:17, Aneesh V a ?crit :

<snip..>

Quoted 14 lines
Quoted 14 lines
Quoted 10 lines

arch/arm/include/asm/armv7.h

Quoted 6 lines
arch/arm/include/asm/armv7.h new file +6 -0
+/* some utility macros */
+#define mask(start, end) \
+ (((1<< ((end) - (start) + 1)) - 1)<< (start))
+
+#define mask_n_get(reg, start, end) \
+ (((reg)& mask(start, end))>> (start))

Seeing as these functions are only used in the ARMv7 cache C file, they
should be moved there.

I plan to use a modified version of mask_n_get() and its set couterpart mask_n_set() in my subsequent works in more files.

Quoted 8 lines
Quoted 3 lines

Can I keep it here itself or should I move it to an OMAP specific header file or can I move it to a more generic header file? Please suggest.

They're very generic actually. I think they should go to a gereric bit manipulation header, and be named a... bit... more explicitly. For instance, the name 'mask' does not show that the macro creates a range of 'one' bits from start to end.

What I need is something like below:

#define get_bit_field(nr, start, mask)\
(((nr) & (mask)) >> (start))

#define set_bit_field(nr, start, mask, val)\
(nr) = ((nr) & ~(mask)) | (((val) << (start)) & (mask))

Quoted 6 lines
Quoted 2 lines

Can these go in a generic header? If so, can I add them to "include/linux/bitops.h"

After some more thought, I am wondering if a *generic* field setting and getting macro is really useful. So far everyone is fine with at most defining field-specific macros.

Is it going to be easy if you have many fields to deal with?

However, I agree that the above may be specific to our needs.

What may be of more generic interest may be something like this with the mask automatically generated:
#define get_bit_field(nr, start, end)
#define set_bit_field(nr, start, end, val)

However, in our case I am already given the mask and start position for each field (automatically generated from hw database). So, I prefer the former versions.

If that doesn't look useful for generic use I will put them in OMAP specific headers.

Best regards,
Aneesh

#19 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

Le 13/01/2011 13:05, Aneesh V a ?crit :

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

What I need is something like below:

#define get_bit_field(nr, start, mask)\
(((nr) & (mask)) >> (start))

#define set_bit_field(nr, start, mask, val)\
(nr) = ((nr) & ~(mask)) | (((val) << (start)) & (mask))

Quoted 8 lines
Quoted 6 lines
Quoted 2 lines

Can these go in a generic header? If so, can I add them to "include/linux/bitops.h"

After some more thought, I am wondering if a *generic* field setting and getting macro is really useful. So far everyone is fine with at most defining field-specific macros.

Is it going to be easy if you have many fields to deal with?

I don't see how the generic macros ease anything. Instead of defining say

#define get_field_F(x) ((x >> F_start) & F_mask) #define set_field_F(x,v) { x = (x ~ F_mask ) | (v << F_start) }

You'd have

#define get_field_F(x) get_bit_field(x, F_start, F_mask) #define set_field_F(x,v) set_bit_field(x, F_start, F_mask, v);

Which does not seem to bring any simplicity to me.

Quoted 11 lines

However, I agree that the above may be specific to our needs.

What may be of more generic interest may be something like this with the mask automatically generated:
#define get_bit_field(nr, start, end)
#define set_bit_field(nr, start, end, val)

However, in our case I am already given the mask and start position for each field (automatically generated from hw database). So, I prefer the former versions.

Quoted 5 lines

If that doesn't look useful for generic use I will put them in OMAP specific headers.

Best regards,
Aneesh

Amicalement,

Signature · 1 line
Albert.
author
#20 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

Quoted 24 lines · Albert ARIBAUD

Le 13/01/2011 13:05, Aneesh V a ?crit :

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

What I need is something like below:

#define get_bit_field(nr, start, mask)\
(((nr) & (mask)) >> (start))

#define set_bit_field(nr, start, mask, val)\
(nr) = ((nr) & ~(mask)) | (((val) << (start)) & (mask))

Quoted 8 lines
Quoted 6 lines
Quoted 2 lines

Can these go in a generic header? If so, can I add them to "include/linux/bitops.h"

After some more thought, I am wondering if a *generic* field setting and getting macro is really useful. So far everyone is fine with at most defining field-specific macros.

Is it going to be easy if you have many fields to deal with?

I don't see how the generic macros ease anything. Instead of defining say

#define get_field_F(x) ((x >> F_start) & F_mask) #define set_field_F(x,v) { x = (x ~ F_mask ) | (v << F_start) }

Quoted 6 lines

You'd have

#define get_field_F(x) get_bit_field(x, F_start, F_mask) #define set_field_F(x,v) set_bit_field(x, F_start, F_mask, v);

Which does not seem to bring any simplicity to me.

I wouldn't define get_field_F.
Instead I would just use set_bit_field(x, F_start, F_mask, v) directly in the code and I have F_start and F_mask defined in the header files (automatically generated)

Even if it was manual isn't it easier to define just F_start and F_mask per field than defining a get_field_F per field?

Perhaps my requirement is different. If this scheme is not used by many, I shall put these macros in OMAP specific headers.

best regards,
Aneesh

#21 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

Le 13/01/2011 15:30, Aneesh V a ?crit :

Quoted 2 lines

Perhaps my requirement is different. If this scheme is not used by many, I shall put these macros in OMAP specific headers.

Yes, I'd prefer that, finally.

Quoted 2 lines

best regards,
Aneesh

Amicalement,

Signature · 1 line
Albert.
author
#22 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

In reply to Albert ARIBAUD

Hi Albert,

Quoted 1 line · Albert ARIBAUD

Hi Aneesh,

[snip ..]

Quoted 10 lines

arch/arm/include/asm/armv7.h

Quoted 6 lines
arch/arm/include/asm/armv7.h new file +6 -0
+/* some utility macros */
+#define mask(start, end) \
+	(((1<<   ((end) - (start) + 1)) - 1)<<   (start))
+
+#define mask_n_get(reg, start, end) \
+	(((reg)&   mask(start, end))>>   (start))

Seeing as these functions are only used in the ARMv7 cache C file, they should be moved there.

I am working on v2 of this series.

We had aligned on moving these macros to omap specific headers. But I now realize that I want to use them from cache_v7.c, so it can not be in omap header. I have used them in other places too in my recent work so it needs to be in a header file. I am putting these functions and some other utils I need in a new file "arch/arm/include/asm/utils.h" Is that fine?

Best regards,
Aneesh

#23 lore raw

PATCH 2/8 armv7: cache maintenance operations for armv7

Le 01/03/2011 12:54, Aneesh V a ?crit :

Quoted 16 lines

Hi Albert,

Quoted 1 line · Albert ARIBAUD

Hi Aneesh,

[snip ..]

Quoted 10 lines

arch/arm/include/asm/armv7.h

Quoted 6 lines
arch/arm/include/asm/armv7.h new file +6 -0
+/* some utility macros */
+#define mask(start, end) \
+ (((1<< ((end) - (start) + 1)) - 1)<< (start))
+
+#define mask_n_get(reg, start, end) \
+ (((reg)& mask(start, end))>> (start))

Seeing as these functions are only used in the ARMv7 cache C file, they should be moved there.

Quoted 8 lines

I am working on v2 of this series.

We had aligned on moving these macros to omap specific headers. But I now realize that I want to use them from cache_v7.c, so it can not be in omap header. I have used them in other places too in my recent work so it needs to be in a header file. I am putting these functions and some other utils I need in a new file "arch/arm/include/asm/utils.h" Is that fine?

I need to look at the code that uses these macros again. I'll do that tonight.

Quoted 2 lines

Best regards,
Aneesh

Amicalement,

Signature · 1 line
Albert.
author
#24 lore raw

PATCH 3/8 armv7: integrate cache maintenance support

In reply to Aneesh V

- Enable I-cache on bootup
- Enable MMU and D-cache immediately after relocation
- Do necessary initialization before enabling d-cache and MMU
- Changes to cleanup_before_linux()
- Make changes according to the new framework

---
 arch/arm/cpu/armv7/cpu.c   |   47 +++++++++++++++++++------------------------
 arch/arm/cpu/armv7/start.S |   18 +++++++++++++++-
 arch/arm/lib/board.c       |    6 +++++
 arch/arm/lib/cache-cp15.c  |    9 ++++++++
 4 files changed, 53 insertions(+), 27 deletions(-)
arch/arm/cpu/armv7/cpu.c +21 -26
index a01e0d6..b418304 100644
@@ -38,13 +38,10 @@
 #ifndef CONFIG_L2_OFF
 #include <asm/arch/sys_proto.h>
 #endif
-
-static void cache_flush(void);
+#include <asm/armv7.h>
 
 int cleanup_before_linux(void)
 {
-	unsigned int i;
-
 	/*
 	 * this function is called just before we call linux
 	 * it prepares the processor for linux
@@ -53,31 +50,29 @@ int cleanup_before_linux(void)
 	 */
 	disable_interrupts();
 
-	/* turn off I/D-cache */
+	/*
+	 * Turn off I-cache and invalidate it
+	 */
 	icache_disable();
-	dcache_disable();
+	invalidate_icache_all();
 
-	/* invalidate I-cache */
-	cache_flush();
-
-#ifndef CONFIG_L2_OFF
-	/* turn off L2 cache */
-	l2_cache_disable();
-	/* invalidate L2 cache also */
-	invalidate_dcache(get_device_type());
-#endif
-	i = 0;
-	/* mem barrier to sync up things */
-	asm("mcr p15, 0, %0, c7, c10, 4": :"r"(i));
+	/*
+	 * turn off D-cache
+	 * dcache_disable() in turn flushes the d-cache and disables MMU
+	 */
+	dcache_disable();
 
-#ifndef CONFIG_L2_OFF
-	l2_cache_enable();
-#endif
+	/*
+	 * After D-cache is flushed and before it is disabled there may
+	 * be some new valid entries brought into the cache. We are sure
+	 * that these lines are not dirty and will not affect our execution.
+	 * (because unwinding the call-stack and setting a bit in CP15 SCTRL
+	 * is all we did during this. We have not pushed anything on to the
+	 * stack. Neither have we affected any static data) 
+	 * So just invalidate the entire d-cache again to avoid coherency
+	 * problems for kernel
+	 */
+	invalidate_dcache_all();
 
 	return 0;
 }
-
-static void cache_flush(void)
-{
-	asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
-}
arch/arm/cpu/armv7/start.S +17 -1
index 684f2d2..7d17f1e 100644
@@ -241,6 +241,14 @@ clbss_l:str	r2, [r0]		/* clear loop...		    */
  * initialization, now running from RAM.
  */
 jump_2_ram:
+/*
+ * If I-cache is enabled invalidate it
+ */
+#ifndef CONFIG_SYS_NO_ICACHE
+	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
+	dsb
+	isb
+#endif
 	ldr	r0, _board_init_r_ofs
 	adr	r1, _start
 	add	lr, r0, r1
@@ -276,6 +284,9 @@ cpu_init_crit:
 	mov	r0, #0			@ set up for MCR
 	mcr	p15, 0, r0, c8, c7, 0	@ invalidate TLBs
 	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
+	mcr	p15, 0, r0, c7, c5, 6  /* invalidate BP array */
+	dsb
+	isb
 
 	/*
 	 * disable MMU stuff and caches
@@ -284,7 +295,12 @@ cpu_init_crit:
 	bic	r0, r0, #0x00002000	@ clear bits 13 (--V-)
 	bic	r0, r0, #0x00000007	@ clear bits 2:0 (-CAM)
 	orr	r0, r0, #0x00000002	@ set bit 1 (--A-) Align
-	orr	r0, r0, #0x00000800	@ set bit 12 (Z---) BTB
+	orr	r0, r0, #0x00000800	@ set bit 11 (Z---) BTB
+#ifdef CONFIG_SYS_NO_ICACHE
+	bic	r0, r0, #0x00001000	@ clear bit 12 (I) I-cache
+#else
+	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-cache
+#endif
 	mcr	p15, 0, r0, c1, c0, 0
 
 	/*
arch/arm/lib/board.c +6 -0
index 7266381..bef32a6 100644
@@ -459,6 +459,12 @@ void board_init_r (gd_t *id, ulong dest_addr)
 
 	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */
 
+	/*
+	 * Enable D$:
+	 * I$, if needed, must be already enabled in start.S
+	 */
+	dcache_enable();
+
 	monitor_flash_len = _bss_start_ofs;
 	debug ("monitor flash len: %08lX\n", monitor_flash_len);
 	board_init();	/* Setup chipselects */
arch/arm/lib/cache-cp15.c +9 -0
index d9175f0..ca526fb 100644
@@ -34,6 +34,14 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+void __arm_init_before_mmu(void)
+{
+	puts("__arm_init_before_mmu: dummy implementation! "
+	     "real implementation missing!!\n");
+}
+void arm_init_before_mmu(void)
+	__attribute__((weak, alias("__arm_init_before_mmu")));
+
 static void cp_delay (void)
 {
 	volatile int i;
@@ -65,6 +73,7 @@ static inline void mmu_setup(void)
 	int i;
 	u32 reg;
 
+	arm_init_before_mmu();
 	/* Set up an identity-mapping for all 4GB, rw for everyone */
 	for (i = 0; i < 4096; i++)
 		page_table[i] = i << 20 | (3 << 10) | 0x12;
Signature · 1 line
1.7.0.4
#25 lore raw

PATCH 3/8 armv7: integrate cache maintenance support

Hi Aneesh,

Le 22/12/2010 12:54, Aneesh V a ?crit :

Quoted 34 lines

- Enable I-cache on bootup
- Enable MMU and D-cache immediately after relocation
- Do necessary initialization before enabling d-cache and MMU
- Changes to cleanup_before_linux()
- Make changes according to the new framework

---
  arch/arm/cpu/armv7/cpu.c   |   47 +++++++++++++++++++------------------------
  arch/arm/cpu/armv7/start.S |   18 +++++++++++++++-
  arch/arm/lib/board.c       |    6 +++++
  arch/arm/lib/cache-cp15.c  |    9 ++++++++
  4 files changed, 53 insertions(+), 27 deletions(-)
arch/arm/cpu/armv7/cpu.c +1 -4
index a01e0d6..b418304 100644
@@ -38,13 +38,10 @@
  #ifndef CONFIG_L2_OFF
  #include<asm/arch/sys_proto.h>
  #endif
-
-static void cache_flush(void);
+#include<asm/armv7.h>
 
  int cleanup_before_linux(void)
  {
-	unsigned int i;
-
  	/*
  	 * this function is called just before we call linux
  	 * it prepares the processor for linux

arch/arm/cpu/armv7/cpu.c int cleanup_before_linux(void) · line 58

Quoted 9 lines
arch/arm/cpu/armv7/cpu.c +3 -2
@@ -53,31 +50,29 @@ int cleanup_before_linux(void)
  	 */
  	disable_interrupts();
 
-	/* turn off I/D-cache */
+	/*
+	 * Turn off I-cache and invalidate it
+	 */
  	icache_disable();
-	dcache_disable();

(1) -- see below

arch/arm/cpu/armv7/cpu.c int cleanup_before_linux(void) · line 61

Quoted 4 lines
arch/arm/cpu/armv7/cpu.c +1 -2
+	invalidate_icache_all();
 
-	/* invalidate I-cache */
-	cache_flush();

(2) -- see below

Quoted 5 lines
arch/arm/cpu/armv7/cpu.c +0 -5
-
-#ifndef CONFIG_L2_OFF
-	/* turn off L2 cache */
-	l2_cache_disable();
-	/* invalidate L2 cache also */

arch/arm/cpu/armv7/cpu.c int cleanup_before_linux(void) · line 63

Quoted 10 lines
arch/arm/cpu/armv7/cpu.c +5 -5
-	invalidate_dcache(get_device_type());
-#endif
-	i = 0;
-	/* mem barrier to sync up things */
-	asm("mcr p15, 0, %0, c7, c10, 4": :"r"(i));
+	/*
+	 * turn off D-cache
+	 * dcache_disable() in turn flushes the d-cache and disables MMU
+	 */
+	dcache_disable();

(3) -- see below

Quoted 4 lines
arch/arm/cpu/armv7/cpu.c +1 -3
-#ifndef CONFIG_L2_OFF
-	l2_cache_enable();
-#endif
+	/*

arch/arm/cpu/armv7/cpu.c int cleanup_before_linux(void) · line 75

Quoted 10 lines
arch/arm/cpu/armv7/cpu.c +10 -0
+	 * After D-cache is flushed and before it is disabled there may
+	 * be some new valid entries brought into the cache. We are sure
+	 * that these lines are not dirty and will not affect our execution.
+	 * (because unwinding the call-stack and setting a bit in CP15 SCTRL
+	 * is all we did during this. We have not pushed anything on to the
+	 * stack. Neither have we affected any static data)
+	 * So just invalidate the entire d-cache again to avoid coherency
+	 * problems for kernel
+	 */
+	invalidate_dcache_all();

I'm not sure about the logic here, but I am no cache guru, so don't hesitate to make me... flush... with shame. If dcache_disable stayed in
(1) instead of being moved to (3), wouldn't the cache_flush in (2) ensure the no new valid entries would appear in the dcache? Put another way, I'd have naively thought the sequence would be:

- disable L2 cache
- disable L1 I and D cache
- invalidate L1 I cache and flush L1 D cache
- flush L2 D cache

Quoted 72 lines
arch/arm/cpu/armv7/cpu.c +0 -5
  	return 0;
  }
-
-static void cache_flush(void)
-{
-	asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
-}
arch/arm/cpu/armv7/start.S +17 -1
index 684f2d2..7d17f1e 100644
@@ -241,6 +241,14 @@ clbss_l:str	r2, [r0]		/* clear loop...		    */
   * initialization, now running from RAM.
   */
  jump_2_ram:
+/*
+ * If I-cache is enabled invalidate it
+ */
+#ifndef CONFIG_SYS_NO_ICACHE
+	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
+	dsb
+	isb
+#endif
  	ldr	r0, _board_init_r_ofs
  	adr	r1, _start
  	add	lr, r0, r1
@@ -276,6 +284,9 @@ cpu_init_crit:
  	mov	r0, #0			@ set up for MCR
  	mcr	p15, 0, r0, c8, c7, 0	@ invalidate TLBs
  	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
+	mcr	p15, 0, r0, c7, c5, 6  /* invalidate BP array */
+	dsb
+	isb
 
  	/*
  	 * disable MMU stuff and caches
@@ -284,7 +295,12 @@ cpu_init_crit:
  	bic	r0, r0, #0x00002000	@ clear bits 13 (--V-)
  	bic	r0, r0, #0x00000007	@ clear bits 2:0 (-CAM)
  	orr	r0, r0, #0x00000002	@ set bit 1 (--A-) Align
-	orr	r0, r0, #0x00000800	@ set bit 12 (Z---) BTB
+	orr	r0, r0, #0x00000800	@ set bit 11 (Z---) BTB
+#ifdef CONFIG_SYS_NO_ICACHE
+	bic	r0, r0, #0x00001000	@ clear bit 12 (I) I-cache
+#else
+	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-cache
+#endif
  	mcr	p15, 0, r0, c1, c0, 0
 
  	/*
arch/arm/lib/board.c +6 -0
index 7266381..bef32a6 100644
@@ -459,6 +459,12 @@ void board_init_r (gd_t *id, ulong dest_addr)
 
  	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */
 
+	/*
+	 * Enable D$:
+	 * I$, if needed, must be already enabled in start.S
+	 */
+	dcache_enable();
+
  	monitor_flash_len = _bss_start_ofs;
  	debug ("monitor flash len: %08lX\n", monitor_flash_len);
  	board_init();	/* Setup chipselects */
arch/arm/lib/cache-cp15.c +0 -0
index d9175f0..ca526fb 100644

arch/arm/lib/cache-cp15.c line 41

Quoted 8 lines
arch/arm/lib/cache-cp15.c +5 -0
@@ -34,6 +34,14 @@
 
  DECLARE_GLOBAL_DATA_PTR;
 
+void __arm_init_before_mmu(void)
+{
+	puts("__arm_init_before_mmu: dummy implementation! "
+	     "real implementation missing!!\n");
+}

If the function is absolutely needed, please make sure booting does not continue. If the function is not absolutely needed, please rewrite message since nothing would actually be 'missing', but rather 'could be added'.

Quoted 7 lines
arch/arm/lib/cache-cp15.c +3 -0
+void arm_init_before_mmu(void)
+	__attribute__((weak, alias("__arm_init_before_mmu")));
+
  static void cp_delay (void)
  {
  	volatile int i;

arch/arm/lib/cache-cp15.c static inline void mmu_setup(void) · line 79

Quoted 7 lines
arch/arm/lib/cache-cp15.c +1 -0
@@ -65,6 +73,7 @@ static inline void mmu_setup(void)
  	int i;
  	u32 reg;
 
+	arm_init_before_mmu();
  	/* Set up an identity-mapping for all 4GB, rw for everyone */
  	for (i = 0; i<  4096; i++)
  		page_table[i] = i<<  20 | (3<<  10) | 0x12;

Amicalement,

Signature · 1 line
Albert.
author
#26 lore raw

PATCH 3/8 armv7: integrate cache maintenance support

Hi Albert,

Quoted 95 lines · Albert ARIBAUD

Hi Aneesh,

Le 22/12/2010 12:54, Aneesh V a ?crit :

Quoted 34 lines

- Enable I-cache on bootup
- Enable MMU and D-cache immediately after relocation
- Do necessary initialization before enabling d-cache and MMU
- Changes to cleanup_before_linux()
- Make changes according to the new framework

---
   arch/arm/cpu/armv7/cpu.c   |   47 +++++++++++++++++++------------------------
   arch/arm/cpu/armv7/start.S |   18 +++++++++++++++-
   arch/arm/lib/board.c       |    6 +++++
   arch/arm/lib/cache-cp15.c  |    9 ++++++++
   4 files changed, 53 insertions(+), 27 deletions(-)
arch/arm/cpu/armv7/cpu.c +1 -4
index a01e0d6..b418304 100644
@@ -38,13 +38,10 @@
   #ifndef CONFIG_L2_OFF
   #include<asm/arch/sys_proto.h>
   #endif
-
-static void cache_flush(void);
+#include<asm/armv7.h>
 
   int cleanup_before_linux(void)
   {
-	unsigned int i;
-
   	/*
   	 * this function is called just before we call linux
   	 * it prepares the processor for linux

arch/arm/cpu/armv7/cpu.c int cleanup_before_linux(void) · line 58

Quoted 9 lines
arch/arm/cpu/armv7/cpu.c +3 -2
@@ -53,31 +50,29 @@ int cleanup_before_linux(void)
   	 */
   	disable_interrupts();
 
-	/* turn off I/D-cache */
+	/*
+	 * Turn off I-cache and invalidate it
+	 */
   	icache_disable();
-	dcache_disable();

(1) -- see below

arch/arm/cpu/armv7/cpu.c int cleanup_before_linux(void) · line 61

Quoted 4 lines
arch/arm/cpu/armv7/cpu.c +1 -2
+	invalidate_icache_all();
 
-	/* invalidate I-cache */
-	cache_flush();

(2) -- see below

Quoted 5 lines
arch/arm/cpu/armv7/cpu.c +0 -5
-
-#ifndef CONFIG_L2_OFF
-	/* turn off L2 cache */
-	l2_cache_disable();
-	/* invalidate L2 cache also */

arch/arm/cpu/armv7/cpu.c int cleanup_before_linux(void) · line 63

Quoted 10 lines
arch/arm/cpu/armv7/cpu.c +5 -5
-	invalidate_dcache(get_device_type());
-#endif
-	i = 0;
-	/* mem barrier to sync up things */
-	asm("mcr p15, 0, %0, c7, c10, 4": :"r"(i));
+	/*
+	 * turn off D-cache
+	 * dcache_disable() in turn flushes the d-cache and disables MMU
+	 */
+	dcache_disable();

(3) -- see below

Quoted 4 lines
arch/arm/cpu/armv7/cpu.c +1 -3
-#ifndef CONFIG_L2_OFF
-	l2_cache_enable();
-#endif
+	/*

arch/arm/cpu/armv7/cpu.c int cleanup_before_linux(void) · line 75

Quoted 10 lines
arch/arm/cpu/armv7/cpu.c +10 -0
+	 * After D-cache is flushed and before it is disabled there may
+	 * be some new valid entries brought into the cache. We are sure
+	 * that these lines are not dirty and will not affect our execution.
+	 * (because unwinding the call-stack and setting a bit in CP15 SCTRL
+	 * is all we did during this. We have not pushed anything on to the
+	 * stack. Neither have we affected any static data)
+	 * So just invalidate the entire d-cache again to avoid coherency
+	 * problems for kernel
+	 */
+	invalidate_dcache_all();

I'm not sure about the logic here, but I am no cache guru, so don't hesitate to make me... flush... with shame. If dcache_disable stayed in
(1) instead of being moved to (3), wouldn't the cache_flush in (2) ensure the no new valid entries would appear in the dcache? Put another way, I'd have naively thought the sequence would be:

Quoted 4 lines

- disable L2 cache
- disable L1 I and D cache
- invalidate L1 I cache and flush L1 D cache
- flush L2 D cache

This is what I did too in the beginning. But I ran into problems with it. Here is how:

1 - disable L2 cache
2 - disable L1 I and D cache
3 - invalidate L1 I cache and flush L1 D cache
4 - flush L2 D cache

- At step 3 and 4 we call the functions to flush the call. These functions in their prologue push some registers(including r14) to the stack.
- Please note that the cache is disabled at this point in time. So the new stack contents go directly into the memory.
- Also, note that the stack may be already cached in L1 or L2(before the caches were disabled). So we have a coherency issue here.
- Now when the caches are flushed the stack in the cache over-writes the stack in memory thus losing the latest stack contents.
- When we try to return from the function there is a crash!

Conclusion:
1. If you disable first and then flush you have to be careful about memory coherency in the period between disable and flush. You must not write anything to the memory and you must be sure about what you read from memory. This is difficult unless you program the entire thing in assembly.
2. If you flush first and then disable you have to take care of the new entries coming to the cache after the flush and before disabling. This is what we are doing.

Quoted 76 lines
Quoted 76 lines
arch/arm/cpu/armv7/cpu.c +0 -5
   	return 0;
   }
-
-static void cache_flush(void)
-{
-	asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
-}
arch/arm/cpu/armv7/start.S +17 -1
index 684f2d2..7d17f1e 100644
@@ -241,6 +241,14 @@ clbss_l:str	r2, [r0]		/* clear loop...		    */
    * initialization, now running from RAM.
    */
   jump_2_ram:
+/*
+ * If I-cache is enabled invalidate it
+ */
+#ifndef CONFIG_SYS_NO_ICACHE
+	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
+	dsb
+	isb
+#endif
   	ldr	r0, _board_init_r_ofs
   	adr	r1, _start
   	add	lr, r0, r1
@@ -276,6 +284,9 @@ cpu_init_crit:
   	mov	r0, #0			@ set up for MCR
   	mcr	p15, 0, r0, c8, c7, 0	@ invalidate TLBs
   	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
+	mcr	p15, 0, r0, c7, c5, 6  /* invalidate BP array */
+	dsb
+	isb
 
   	/*
   	 * disable MMU stuff and caches
@@ -284,7 +295,12 @@ cpu_init_crit:
   	bic	r0, r0, #0x00002000	@ clear bits 13 (--V-)
   	bic	r0, r0, #0x00000007	@ clear bits 2:0 (-CAM)
   	orr	r0, r0, #0x00000002	@ set bit 1 (--A-) Align
-	orr	r0, r0, #0x00000800	@ set bit 12 (Z---) BTB
+	orr	r0, r0, #0x00000800	@ set bit 11 (Z---) BTB
+#ifdef CONFIG_SYS_NO_ICACHE
+	bic	r0, r0, #0x00001000	@ clear bit 12 (I) I-cache
+#else
+	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-cache
+#endif
   	mcr	p15, 0, r0, c1, c0, 0
 
   	/*
arch/arm/lib/board.c +6 -0
index 7266381..bef32a6 100644
@@ -459,6 +459,12 @@ void board_init_r (gd_t *id, ulong dest_addr)
 
   	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */
 
+	/*
+	 * Enable D$:
+	 * I$, if needed, must be already enabled in start.S
+	 */
+	dcache_enable();
+
   	monitor_flash_len = _bss_start_ofs;
   	debug ("monitor flash len: %08lX\n", monitor_flash_len);
   	board_init();	/* Setup chipselects */
arch/arm/lib/cache-cp15.c +0 -0
index d9175f0..ca526fb 100644
@@ -34,6 +34,14 @@
 
   DECLARE_GLOBAL_DATA_PTR;
 
Quoted 11 lines

arch/arm/lib/cache-cp15.c line 41

Quoted 5 lines
arch/arm/lib/cache-cp15.c +5 -0
+void __arm_init_before_mmu(void)
+{
+	puts("__arm_init_before_mmu: dummy implementation! "
+	     "real implementation missing!!\n");
+}

If the function is absolutely needed, please make sure booting does not continue. If the function is not absolutely needed, please rewrite message since nothing would actually be 'missing', but rather 'could be added'.

Before ARMv7 caches are guaranteed to be invalidated at reset. But I couldn't find conclusive information about TLB. So I am not sure, it may or may not be absolutely necessary.

I shall just remove that message!

Quoted 16 lines
Quoted 7 lines
arch/arm/lib/cache-cp15.c +3 -0
+void arm_init_before_mmu(void)
+	__attribute__((weak, alias("__arm_init_before_mmu")));
+
   static void cp_delay (void)
   {
   	volatile int i;

arch/arm/lib/cache-cp15.c static inline void mmu_setup(void) · line 79

Quoted 7 lines
arch/arm/lib/cache-cp15.c +1 -0
@@ -65,6 +73,7 @@ static inline void mmu_setup(void)
   	int i;
   	u32 reg;
 
+	arm_init_before_mmu();
   	/* Set up an identity-mapping for all 4GB, rw for everyone */
   	for (i = 0; i<   4096; i++)
   		page_table[i] = i<<   20 | (3<<   10) | 0x12;

Amicalement,

author
#27 lore raw

PATCH 4/8 arm: minor fixes for cache and mmu handling

In reply to Aneesh V

1. make sure that page table setup is not done multiple times
2. flush_dcache_all() is more appropriate while disabling cache than a range flush on the entire memory(flush_cache())

Provide a default implementation for flush_dcache_all() for backward compatibility and to avoid build issues.

---
 arch/arm/lib/cache-cp15.c |    9 +++++++--
 arch/arm/lib/cache.c      |   13 ++++++++++++-
 2 files changed, 19 insertions(+), 3 deletions(-)
arch/arm/lib/cache-cp15.c +7 -2
index ca526fb..20aa993 100644
@@ -94,13 +94,18 @@ static inline void mmu_setup(void)
 	set_cr(reg | CR_M);
 }
 
+static int mmu_enabled(void)
+{
+	return get_cr() & CR_M;
+}
+
 /* cache_bit must be either CR_I or CR_C */
 static void cache_enable(uint32_t cache_bit)
 {
 	uint32_t reg;
 
 	/* The data cache is not active unless the mmu is enabled too */
-	if (cache_bit == CR_C)
+	if ((cache_bit == CR_C) && !mmu_enabled())
 		mmu_setup();
 	reg = get_cr();	/* get control reg. */
 	cp_delay();
@@ -119,7 +124,7 @@ static void cache_disable(uint32_t cache_bit)
 			return;
 		/* if disabling data cache, disable mmu too */
 		cache_bit |= CR_M;
-		flush_cache(0, ~0);
+		flush_dcache_all();
 	}
 	reg = get_cr();
 	cp_delay();
arch/arm/lib/cache.c +12 -1
index 275b6e1..363609a 100644
@@ -25,7 +25,7 @@
 
 #include <common.h>
 
-void  __flush_cache(unsigned long dummy1, unsigned long dummy2)
+void  __flush_cache(unsigned long start, unsigned long size)
 {
 #if defined(CONFIG_OMAP2420) || defined(CONFIG_ARM1136)
 	void arm1136_cache_flush(void);
@@ -42,3 +42,14 @@ void  __flush_cache(unsigned long dummy1, unsigned long dummy2)
 }
 void  flush_cache(unsigned long dummy1, unsigned long dummy2)
 	__attribute__((weak, alias("__flush_cache")));
+
+/*
+ * Default implementation:
+ * do a range flush for the entire range
+ */
+void	__flush_dcache_all(void)
+{
+	flush_cache(0, ~0);
+}
+void	flush_dcache_all(void)
+	__attribute__((weak, alias("__flush_dcache_all")));
Signature · 1 line
1.7.0.4
#28 lore raw

PATCH 4/8 arm: minor fixes for cache and mmu handling

Hi Aneesh,

Le 22/12/2010 12:54, Aneesh V a ?crit :

Quoted 27 lines

1. make sure that page table setup is not done multiple times
2. flush_dcache_all() is more appropriate while disabling cache than a range flush on the entire memory(flush_cache())

Provide a default implementation for flush_dcache_all() for backward compatibility and to avoid build issues.

---
  arch/arm/lib/cache-cp15.c |    9 +++++++--
  arch/arm/lib/cache.c      |   13 ++++++++++++-
  2 files changed, 19 insertions(+), 3 deletions(-)
arch/arm/lib/cache-cp15.c +5 -0
index ca526fb..20aa993 100644
@@ -94,13 +94,18 @@ static inline void mmu_setup(void)
  	set_cr(reg | CR_M);
  }
 
+static int mmu_enabled(void)
+{
+	return get_cr()&  CR_M;
+}
+
  /* cache_bit must be either CR_I or CR_C */

arch/arm/lib/cache-cp15.c static inline void mmu_setup(void) · line 111

Quoted 10 lines
arch/arm/lib/cache-cp15.c +1 -1
  static void cache_enable(uint32_t cache_bit)
  {
  	uint32_t reg;
 
  	/* The data cache is not active unless the mmu is enabled too */
-	if (cache_bit == CR_C)
+	if ((cache_bit == CR_C)&&  !mmu_enabled())
  		mmu_setup();
  	reg = get_cr();	/* get control reg. */
  	cp_delay();

Do you know why double MMU setups happen? Can we not fix the execution path and remove the second MMU setup call there, rather that catching t on the fly to ignore it?

Quoted 23 lines
arch/arm/lib/cache-cp15.c +1 -1
@@ -119,7 +124,7 @@ static void cache_disable(uint32_t cache_bit)
  			return;
  		/* if disabling data cache, disable mmu too */
  		cache_bit |= CR_M;
-		flush_cache(0, ~0);
+		flush_dcache_all();
  	}
  	reg = get_cr();
  	cp_delay();
arch/arm/lib/cache.c +1 -1
index 275b6e1..363609a 100644
@@ -25,7 +25,7 @@
 
  #include<common.h>
 
-void  __flush_cache(unsigned long dummy1, unsigned long dummy2)
+void  __flush_cache(unsigned long start, unsigned long size)
  {
  #if defined(CONFIG_OMAP2420) || defined(CONFIG_ARM1136)
  	void arm1136_cache_flush(void);

arch/arm/lib/cache.c void __flush_cache(unsigned long dummy1, unsigned long dummy2) · line 43

Quoted 2 lines
arch/arm/lib/cache.c +0 -0
@@ -42,3 +42,14 @@ void  __flush_cache(unsigned long dummy1, unsigned long dummy2)
  }
  void  flush_cache(unsigned long dummy1, unsigned long dummy2)

Please fix also parameters in this declaration.

arch/arm/lib/cache.c void __flush_cache(unsigned long dummy1, unsigned long dummy2) · line 55

Quoted 12 lines
arch/arm/lib/cache.c +11 -0
  	__attribute__((weak, alias("__flush_cache")));
+
+/*
+ * Default implementation:
+ * do a range flush for the entire range
+ */
+void	__flush_dcache_all(void)
+{
+	flush_cache(0, ~0);
+}
+void	flush_dcache_all(void)
+	__attribute__((weak, alias("__flush_dcache_all")));

Amicalement,

Signature · 1 line
Albert.
author
#29 lore raw

PATCH 4/8 arm: minor fixes for cache and mmu handling

Hi Albert,

Quoted 34 lines · Albert ARIBAUD

Hi Aneesh,

Le 22/12/2010 12:54, Aneesh V a ?crit :

Quoted 31 lines

1. make sure that page table setup is not done multiple times
2. flush_dcache_all() is more appropriate while disabling cache than a range flush on the entire memory(flush_cache())

Provide a default implementation for flush_dcache_all() for backward compatibility and to avoid build issues.

---
   arch/arm/lib/cache-cp15.c |    9 +++++++--
   arch/arm/lib/cache.c      |   13 ++++++++++++-
   2 files changed, 19 insertions(+), 3 deletions(-)
arch/arm/lib/cache-cp15.c +5 -0
index ca526fb..20aa993 100644
@@ -94,13 +94,18 @@ static inline void mmu_setup(void)
   	set_cr(reg | CR_M);
   }
 
+static int mmu_enabled(void)
+{
+	return get_cr()&   CR_M;
+}
+
   /* cache_bit must be either CR_I or CR_C */
   static void cache_enable(uint32_t cache_bit)
   {
   	uint32_t reg;
 
Quoted 10 lines

arch/arm/lib/cache-cp15.c static inline void mmu_setup(void) · line 111

Quoted 6 lines
arch/arm/lib/cache-cp15.c +1 -1
   	/* The data cache is not active unless the mmu is enabled too */
-	if (cache_bit == CR_C)
+	if ((cache_bit == CR_C)&&   !mmu_enabled())
   		mmu_setup();
   	reg = get_cr();	/* get control reg. */
   	cp_delay();

Do you know why double MMU setups happen? Can we not fix the execution path and remove the second MMU setup call there, rather that catching t on the fly to ignore it?

Please note that mmu_setup() was getting called unconditionally from dcache_enable(). I see that some drivers are calling dcache_enable() and there are u-boot commands for enabling disabling cache. Consequently mmu_setup() may get called multiple times.
Do we want to prevent dcache_enable() from being called multiple times?

Best regards,
Aneesh

author
#30 lore raw

PATCH 5/8 armv7: add PL310 support to u-boot

In reply to Aneesh V

Add support for some of the key maintenance operations
- Invalidate all
- Invalidate range
- Flush(clean & invalidate) all
- Flush range

---
 arch/arm/include/asm/pl310.h |   49 ++++++++++++++++++
 arch/arm/lib/Makefile        |    1 +
 arch/arm/lib/cache-pl310.c   |  114 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 164 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/pl310.h
 create mode 100644 arch/arm/lib/cache-pl310.c
arch/arm/include/asm/pl310.h new file +49 -0
new file mode 100644
index 0000000..8f5b33e
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Aneesh V <[email protected]>
+ *
+ * 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
+ */
+#ifndef PL310_H
+#define PL310_H
+
+#include <linux/types.h>
+
+/* Register offsets */
+#define PL310_CACHE_TYPE		0x004
+#define PL310_AUX_CTRL			0x104
+
+#define PL310_CACHE_SYNC		0x730
+#define PL310_INVAL_LINE_PA		0x770
+#define PL310_INVAL_WAY			0x77C
+#define PL310_CLEAN_LINE_PA		0x7B0
+#define PL310_CLEAN_INVAL_WAY		0x7FC
+#define PL310_CLEAN_INVAL_LINE_PA	0x7F0
+
+/* Register bit fields */
+#define PL310_AUX_CTRL_ASSOCIATIVITY_MASK	(1 << 16)
+
+void pl310_inval_all(void);
+void pl310_clean_inval_all(void);
+void pl310_inval_range(u32 start, u32 end);
+void pl310_clean_inval_range(u32 start, u32 end);
+
+#endif
arch/arm/lib/Makefile +1 -0
index 454440c..dc108a6 100644
@@ -42,6 +42,7 @@ COBJS-y	+= cache.o
 ifndef CONFIG_SYS_NO_CP15_CACHE
 COBJS-y	+= cache-cp15.o
 endif
+COBJS-$(CONFIG_SYS_USE_PL310) += cache-pl310.o
 COBJS-y	+= interrupts.o
 COBJS-y	+= reset.o
 
arch/arm/lib/cache-pl310.c new file +114 -0

114 lines not on this page · raw message

Signature · 1 line
1.7.0.4
#31 lore raw

PATCH 5/8 armv7: add PL310 support to u-boot

Dear Aneesh V,

Quoted 5 lines · In message <[email protected]> you wrote:

Add support for some of the key maintenance operations
- Invalidate all
- Invalidate range
- Flush(clean & invalidate) all
- Flush range

Can you please use a more descriptive subject, and commit message?

I have no idea what a "PL310" might be - is this a new board? Or a new SoC? or a new Ethernet controller?

And what exactly are "key maintenance operations"? Looks as if you were talking about basic cache operations?

Quoted 2 lines
arch/arm/include/asm/pl310.h new file +0 -0

...

arch/arm/include/asm/pl310.h line 39

Quoted 10 lines
arch/arm/include/asm/pl310.h new file +10 -0
+/* Register offsets */
+#define PL310_CACHE_TYPE		0x004
+#define PL310_AUX_CTRL			0x104
+
+#define PL310_CACHE_SYNC		0x730
+#define PL310_INVAL_LINE_PA		0x770
+#define PL310_INVAL_WAY			0x77C
+#define PL310_CLEAN_LINE_PA		0x7B0
+#define PL310_CLEAN_INVAL_WAY		0x7FC
+#define PL310_CLEAN_INVAL_LINE_PA	0x7F0

NAK. Please use a C struct instead.

arch/arm/lib/Makefile COBJS-y += cache.o · line 47

Quoted 9 lines
arch/arm/lib/Makefile +1 -0
@@ -42,6 +42,7 @@ COBJS-y	+= cache.o
 ifndef CONFIG_SYS_NO_CP15_CACHE
 COBJS-y	+= cache-cp15.o
 endif
+COBJS-$(CONFIG_SYS_USE_PL310) += cache-pl310.o
 COBJS-y	+= interrupts.o
 COBJS-y	+= reset.o

There is no documentation for CONFIG_SYS_USE_PL310, and there is no use of this variable.

Also, it seems CONFIG_SYS_PL310 would be more appropriate.

...

arch/arm/lib/Makefile COBJS-y += cache.o

Quoted 4 lines
arch/arm/lib/Makefile +4 -0
+static void pl310_cache_sync(void)
+{
+	__raw_writel(0, CONFIG_SYS_PL310_BASE + PL310_CACHE_SYNC);
+}

Please use a proper C struct instead of base address plus offset. Please fix globally.

...

arch/arm/lib/Makefile

Quoted 3 lines
arch/arm/lib/Makefile +3 -0
+	for (pa = start; pa < stop; pa = pa + line_size)
+		__raw_writel(pa, CONFIG_SYS_PL310_BASE +
+			     PL310_CLEAN_INVAL_LINE_PA);

Please use braces for multiline statements.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
No one can guarantee the actions of another.
	-- Spock, "Day of the Dove", stardate unknown
author
#32 lore raw

PATCH 5/8 armv7: add PL310 support to u-boot

Dear Wolfgang,

Quoted 9 lines · Wolfgang Denk

Dear Aneesh V,

Quoted 5 lines · In message<[email protected]> you wrote:

Add support for some of the key maintenance operations
- Invalidate all
- Invalidate range
- Flush(clean& invalidate) all
- Flush range

Quoted 4 lines

Can you please use a more descriptive subject, and commit message?

I have no idea what a "PL310" might be - is this a new board? Or a new SoC? or a new Ethernet controller?

Sure. I will add a more descriptive message.
PL310 is an L2 cache controller from ARM.

Quoted 4 lines

And what exactly are "key maintenance operations"? Looks as if you were talking about basic cache operations?

Yes. I was talking about basic cache operations. In ARM terminology the cache operations are called "cache maintenance operations".

Quoted 4 lines
Quoted 3 lines
arch/arm/include/asm/pl310.h new file +0 -0

...

Quoted 12 lines

arch/arm/include/asm/pl310.h line 39

Quoted 10 lines
arch/arm/include/asm/pl310.h new file +10 -0
+/* Register offsets */
+#define PL310_CACHE_TYPE		0x004
+#define PL310_AUX_CTRL			0x104
+
+#define PL310_CACHE_SYNC		0x730
+#define PL310_INVAL_LINE_PA		0x770
+#define PL310_INVAL_WAY			0x77C
+#define PL310_CLEAN_LINE_PA		0x7B0
+#define PL310_CLEAN_INVAL_WAY		0x7FC
+#define PL310_CLEAN_INVAL_LINE_PA	0x7F0

NAK. Please use a C struct instead.

Ok.

Quoted 15 lines

arch/arm/lib/Makefile COBJS-y += cache.o · line 47

Quoted 11 lines
arch/arm/lib/Makefile +1 -0
@@ -42,6 +42,7 @@ COBJS-y	+= cache.o
  ifndef CONFIG_SYS_NO_CP15_CACHE
  COBJS-y	+= cache-cp15.o
  endif
+COBJS-$(CONFIG_SYS_USE_PL310) += cache-pl310.o
  COBJS-y	+= interrupts.o
  COBJS-y	+= reset.o

There is no documentation for CONFIG_SYS_USE_PL310, and there is no use of this variable.

Quoted 1 line

Also, it seems CONFIG_SYS_PL310 would be more appropriate.

I shall make it CONFIG_SYS_PL310 and add documentation.

Quoted 10 lines

...

arch/arm/lib/Makefile

Quoted 4 lines
arch/arm/lib/Makefile +4 -0
+static void pl310_cache_sync(void)
+{
+	__raw_writel(0, CONFIG_SYS_PL310_BASE + PL310_CACHE_SYNC);
+}

Please use a proper C struct instead of base address plus offset. Please fix globally.

Quoted 6 lines

...

arch/arm/lib/Makefile

Quoted 3 lines
arch/arm/lib/Makefile +3 -0
+	for (pa = start; pa<  stop; pa = pa + line_size)
+		__raw_writel(pa, CONFIG_SYS_PL310_BASE +
+			     PL310_CLEAN_INVAL_LINE_PA);

Please use braces for multiline statements.

ok.

Quoted 6 lines

Best regards,

Wolfgang Denk

Best regards,
Aneesh

author
#33 lore raw

PATCH 6/8 armv7: adapt omap4 to the new cache maintenance framework

In reply to Aneesh V

adapt omap4 to the new layered cache maintenance framework

---
 arch/arm/cpu/armv7/omap4/board.c            |   25 ++++++++++++++++++++++++-
 arch/arm/cpu/armv7/omap4/lowlevel_init.S    |   17 +++++++++++++++++
 arch/arm/include/asm/arch-omap4/omap4.h     |    6 ++++++
 arch/arm/include/asm/arch-omap4/sys_proto.h |    3 ++-
 include/configs/omap4_panda.h               |    6 +++---
 include/configs/omap4_sdp4430.h             |    6 +++---
 6 files changed, 55 insertions(+), 8 deletions(-)
arch/arm/cpu/armv7/omap4/board.c +24 -1
index fcd29a7..09612e5 100644
@@ -31,7 +31,8 @@
 #include <asm/arch/cpu.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/sizes.h>
-
+#include <asm/armv7.h>
+#include <asm/pl310.h>
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -127,3 +128,25 @@ int arch_cpu_init(void)
 	set_muxconf_regs();
 	return 0;
 }
+
+/*
+ * Outer cache related functions
+ */
+#ifndef CONFIG_SYS_NO_DCACHE
+void v7_setup_outer_cache_ops(void)
+{
+#ifndef CONFIG_L2_OFF
+	v7_outer_cache.enable = omap4_enable_pl310;
+	v7_outer_cache.disable = omap4_disable_pl310;
+	v7_outer_cache.flush_all = pl310_clean_inval_all;
+	v7_outer_cache.flush_range = pl310_clean_inval_range;
+	v7_outer_cache.inval_range = pl310_inval_range;
+	/*
+	 * Do not setup v7_outer_cache.inval_all
+	 * Not needed in OMAP4 because ROM code invalidates entire L2$ at
+	 * bootup.
+	 */
+	v7_outer_cache.inval_all = NULL;
+#endif
+}
+#endif
arch/arm/cpu/armv7/omap4/lowlevel_init.S +17 -0
index 026dfa4..4beed53 100644
@@ -29,6 +29,8 @@
 #include <asm/arch/omap4.h>
 
 .globl lowlevel_init
+.globl omap4_enable_pl310
+.globl omap4_disable_pl310
 lowlevel_init:
 	/*
 	 * Setup a temporary stack
@@ -45,3 +47,18 @@ lowlevel_init:
 	 */
 	bl	s_init
 	pop	{ip, pc}
+
+set_pl310_ctrl_reg:
+        PUSH	{r4-r11, lr}	@ save registers - ROM code may pollute
+				@ our registers
+        LDR	r12, =0x102	@ Set PL310 control register - value in R0
+        SMC	#0		@ call ROM Code API to set control register
+        POP	{r4-r11, pc}
+
+omap4_enable_pl310:
+	MOV	r0, #1
+	B	set_pl310_ctrl_reg
+
+omap4_disable_pl310:
+	MOV	r0, #0
+	B	set_pl310_ctrl_reg
arch/arm/include/asm/arch-omap4/omap4.h +6 -0
index a30bb33..9c6ec6f 100644
@@ -100,6 +100,12 @@
 #define PRM_RSTCTRL		PRM_DEVICE_BASE
 #define PRM_RSTCTRL_RESET	0x01
 
+/* PL310 base */
+#define CONFIG_SYS_PL310_BASE	0x48242000
+
+/* PL310 associativity */
+#define OMAP44XX_PL310_ASSOCIATIVITY	16
+
 #ifndef __ASSEMBLY__
 
 struct s32ktimer {
arch/arm/include/asm/arch-omap4/sys_proto.h +2 -1
index 4813e9e..79c373d 100644
@@ -31,7 +31,8 @@ struct omap_sysinfo {
 void gpmc_init(void);
 void watchdog_init(void);
 u32 get_device_type(void);
-void invalidate_dcache(u32);
+void omap4_enable_pl310(void);
+void omap4_disable_pl310(void);
 void set_muxconf_regs(void);
 void sr32(void *, u32, u32, u32);
 u32 wait_on_value(u32, u32, void *, u32);
include/configs/omap4_panda.h +3 -3
index 2b03b0f..0ec306a 100644
@@ -45,9 +45,6 @@
 #define CONFIG_DISPLAY_CPUINFO		1
 #define CONFIG_DISPLAY_BOARDINFO	1
 
-/* Keep L2 Cache Disabled */
-#define CONFIG_L2_OFF			1
-
 /* Clock Defines */
 #define V_OSCK			38400000	/* Clock output from T2 */
 #define V_SCLK                   V_OSCK
@@ -234,4 +231,7 @@
 					 CONFIG_SYS_INIT_RAM_SIZE - \
 					 GENERATED_GBL_DATA_SIZE)
 
+#ifndef CONFIG_L2_OFF
+#define CONFIG_SYS_USE_PL310		1
+#endif
 #endif /* __CONFIG_H */
include/configs/omap4_sdp4430.h +3 -3
index d288333..0e5840e 100644
@@ -46,9 +46,6 @@
 #define CONFIG_DISPLAY_CPUINFO		1
 #define CONFIG_DISPLAY_BOARDINFO	1
 
-/* Keep L2 Cache Disabled */
-#define CONFIG_L2_OFF			1
-
 /* Clock Defines */
 #define V_OSCK			38400000	/* Clock output from T2 */
 #define V_SCLK                   V_OSCK
@@ -239,4 +236,7 @@
 					 CONFIG_SYS_INIT_RAM_SIZE - \
 					 GENERATED_GBL_DATA_SIZE)
 
+#ifndef CONFIG_L2_OFF
+#define CONFIG_SYS_USE_PL310		1
+#endif
 #endif /* __CONFIG_H */
Signature · 1 line
1.7.0.4
#34 lore raw

PATCH 6/8 armv7: adapt omap4 to the new cache maintenance framework

Dear Aneesh V,

arch/arm/cpu/armv7/omap4/board.c int arch_cpu_init(void) · line 135

Quoted 8 lines · In message <[email protected]> you wrote:

adapt omap4 to the new layered cache maintenance framework

arch/arm/cpu/armv7/omap4/board.c +4 -0
+/*
+ * Outer cache related functions
+ */
+#ifndef CONFIG_SYS_NO_DCACHE

Do we really need such a #define? Where is CONFIG_SYS_NO_DCACHE documented?

arch/arm/cpu/armv7/omap4/board.c int arch_cpu_init(void) · line 138

Quoted 3 lines
arch/arm/cpu/armv7/omap4/board.c +3 -0
+void v7_setup_outer_cache_ops(void)
+{
+#ifndef CONFIG_L2_OFF

Should this be CONFIG_L2_OFF or CONFIG_SYS_L2_OFF? Where is CONFIG_SYS_L2_OFF documented?

arch/arm/cpu/armv7/omap4/lowlevel_init.S lowlevel_init: · line 56

Quoted 11 lines
arch/arm/cpu/armv7/omap4/lowlevel_init.S +7 -0
@@ -45,3 +47,18 @@ lowlevel_init:
 	 */
 	bl	s_init
 	pop	{ip, pc}
+
+set_pl310_ctrl_reg:
+        PUSH	{r4-r11, lr}	@ save registers - ROM code may pollute
+				@ our registers
+        LDR	r12, =0x102	@ Set PL310 control register - value in R0
+        SMC	#0		@ call ROM Code API to set control register
+        POP	{r4-r11, pc}

Indentation by TAB, please.

Best regards,

Wolfgang Denk

Signature · 4 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
It's not an optical illusion, it just looks like one.   -- Phil White
author
#35 lore raw

PATCH 6/8 armv7: adapt omap4 to the new cache maintenance framework

Dear Wolfgang,

Quoted 7 lines · Wolfgang Denk

Dear Aneesh V,

Quoted 3 lines · In message<[email protected]> you wrote:

adapt omap4 to the new layered cache maintenance framework

Quoted 7 lines

arch/arm/cpu/armv7/omap4/board.c int arch_cpu_init(void) · line 135

Quoted 4 lines
arch/arm/cpu/armv7/omap4/board.c +4 -0
+/*
+ * Outer cache related functions
+ */
+#ifndef CONFIG_SYS_NO_DCACHE

Do we really need such a #define? Where is CONFIG_SYS_NO_DCACHE documented?

I shall add documentation if it doesn't exist. But I see that it's already being used.
IMO, it's good to have this option:
1. Not all boards may like to enable data cache.
2. Disabling caches may be one thing you might want to try while debugging issues.
3. CPUs that do not have cache operations and initialization defined yet might want to keep it disabled.

Quoted 7 lines

arch/arm/cpu/armv7/omap4/board.c int arch_cpu_init(void) · line 138

Quoted 4 lines
arch/arm/cpu/armv7/omap4/board.c +3 -0
+void v7_setup_outer_cache_ops(void)
+{
+#ifndef CONFIG_L2_OFF

Should this be CONFIG_L2_OFF or CONFIG_SYS_L2_OFF? Where is CONFIG_SYS_L2_OFF documented?

CONFIG_L2_OFF is also aready being used. That's why I used it.

A handful of board config files are using it, but in actual code it's only referenced by armv7 code.

Shall I change them all to CONFIG_SYS_L2_OFF
I shall add documentation.

Quoted 15 lines

arch/arm/cpu/armv7/omap4/lowlevel_init.S lowlevel_init: · line 56

Quoted 13 lines
arch/arm/cpu/armv7/omap4/lowlevel_init.S +7 -0
@@ -45,3 +47,18 @@ lowlevel_init:
  	 */
  	bl	s_init
  	pop	{ip, pc}
+
+set_pl310_ctrl_reg:
+        PUSH	{r4-r11, lr}	@ save registers - ROM code may pollute
+				@ our registers
+        LDR	r12, =0x102	@ Set PL310 control register - value in R0
+        SMC	#0		@ call ROM Code API to set control register
+        POP	{r4-r11, pc}

Indentation by TAB, please.

Sure. I will take care in future. BTW, that was not caught by checkpatch.pl. Is there anyway to catch such errors using some tool?

Quoted 6 lines

Best regards,

Wolfgang Denk

Best regards,
Aneesh

#36 lore raw

PATCH 6/8 armv7: adapt omap4 to the new cache maintenance framework

Dear Aneesh V,

Quoted 5 lines · In message <[email protected]> you wrote:

A handful of board config files are using it, but in actual code it's only referenced by armv7 code.

Shall I change them all to CONFIG_SYS_L2_OFF

Yes, please do (in a separate patch). Thanks.

Quoted 1 line

I shall add documentation.

Thanks.

Quoted 2 lines

Sure. I will take care in future. BTW, that was not caught by checkpatch.pl. Is there anyway to catch such errors using some tool?

I use just visual inspection, and vi when in doubt.

Best regards,

Wolfgang Denk

Signature · 4 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Sorry, but my karma just ran over your dogma.
author
#37 lore raw

PATCH 7/8 armv7: adapt omap3 to the new cache maintenance framework

In reply to Aneesh V

adapt omap3 to the new layered cache maintenance framework

---
 arch/arm/cpu/armv7/omap3/Makefile           |    1 -
 arch/arm/cpu/armv7/omap3/board.c            |  151 ++++++++++++++--
 arch/arm/cpu/armv7/omap3/cache.S            |  263 ---------------------------
 arch/arm/cpu/armv7/omap3/lowlevel_init.S    |   30 +++
 arch/arm/include/asm/arch-omap3/omap3.h     |   20 ++
 arch/arm/include/asm/arch-omap3/sys_proto.h |   10 +-
 6 files changed, 190 insertions(+), 285 deletions(-)
 delete mode 100644 arch/arm/cpu/armv7/omap3/cache.S
arch/arm/cpu/armv7/omap3/Makefile +0 -1
index 7164d50..522bcd2 100644
@@ -26,7 +26,6 @@ include $(TOPDIR)/config.mk
 LIB	=  $(obj)lib$(SOC).o
 
 SOBJS	:= lowlevel_init.o
-SOBJS	+= cache.o
 
 COBJS	+= board.o
 COBJS	+= clock.o
arch/arm/cpu/armv7/omap3/board.c +133 -18

171 lines not on this page · raw message

arch/arm/cpu/armv7/omap3/cache.S deleted +0 -263

263 lines not on this page · raw message

arch/arm/cpu/armv7/omap3/lowlevel_init.S +30 -0
index 109481e..c2feeff 100644
@@ -35,6 +35,36 @@
 _TEXT_BASE:
 	.word	CONFIG_SYS_TEXT_BASE	/* sdram load addr from config.mk */
 
+.global omap3_gp_romcode_call
+omap3_gp_romcode_call:
+	PUSH {r4-r12, lr} @ Save all registers from ROM code!
+	MOV r12, r0	@ Copy the Service ID in R12
+	MOV r0, r1	@ Copy parameter to R0
+	DSB
+	DMB
+	SMC #0		@ Use the SMI #1 to enter Monitor
+	POP {r4-r12, pc}
+
+/*
+ * Funtion for making PPA HAL API calls in secure devices
+ * Input:
+ *	R0 - Service ID
+ *	R1 - paramer list
+ */
+.global do_omap3_emu_romcode_call
+do_omap3_emu_romcode_call:
+	PUSH {r4-r12, lr} @ Save all registers from ROM code!
+	MOV r12, r0	@ Copy the Secure Service ID in R12
+	MOV r3, r1	@ Copy the pointer to va_list in R3
+	MOV r1, #0	@ Process ID - 0
+	MOV r2, #OMAP3_EMU_HAL_START_HAL_CRITICAL	@ Copy the pointer
+							@ to va_list in R3
+	MOV r6, #0xFF	@ Indicate new Task call
+	DSB
+	DMB
+	SMC #1		@ Use the SMI #1 to enter Monitor
+	POP {r4-r12, pc}
+
 #if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_NAND_BOOT)
 /**************************************************************************
  * cpy_clk_code: relocates clock code into SRAM where its safer to execute
arch/arm/include/asm/arch-omap3/omap3.h +20 -0
index 3957c79..7b861a3 100644
@@ -145,8 +145,14 @@ struct gpio {
 #define SRAM_VECT_CODE			(SRAM_OFFSET0 | SRAM_OFFSET1 | \
 					 SRAM_OFFSET2)
 
+#define OMAP3_PUBLIC_SRAM_BASE		0x40208000 /* Works for GP & EMU */
+#define OMAP3_PUBLIC_SRAM_END		0x40210000
+
 #define LOW_LEVEL_SRAM_STACK		0x4020FFFC
 
+/* scratch area - accessible on both EMU and GP */
+#define OMAP3_PUBLIC_SRAM_SCRATCH_AREA	OMAP3_PUBLIC_SRAM_BASE
+
 #define DEBUG_LED1			149	/* gpio */
 #define DEBUG_LED2			150	/* gpio */
 
@@ -213,4 +219,18 @@ struct gpio {
 
 #define OMAP3730		0x0c00
 
+/*
+ * ROM code API related flags
+ */
+#define OMAP3_GP_ROMCODE_API_L2_INVAL		1
+#define OMAP3_GP_ROMCODE_API_WRITE_ACR		3
+
+/*
+ * EMU device PPA HAL related flags
+ */
+#define OMAP3_EMU_HAL_API_L2_INVAL		40
+#define OMAP3_EMU_HAL_API_WRITE_ACR		42
+
+#define OMAP3_EMU_HAL_START_HAL_CRITICAL	4
+
 #endif
arch/arm/include/asm/arch-omap3/sys_proto.h +7 -3
index 4a28ba1..25f54ea 100644
@@ -27,6 +27,11 @@ typedef struct {
 	char *nand_string;
 } omap3_sysinfo;
 
+struct __attribute__ ((__packed__)) emu_hal_params {
+	u32 num_params;
+	u32 param1;
+};
+
 void prcm_init(void);
 void per_clocks_enable(void);
 
@@ -53,9 +58,7 @@ u32 is_running_in_sdram(void);
 u32 is_running_in_sram(void);
 u32 is_running_in_flash(void);
 u32 get_device_type(void);
-void l2cache_enable(void);
 void secureworld_exit(void);
-void setup_auxcr(void);
 void try_unlock_memory(void);
 u32 get_boot_type(void);
 void invalidate_dcache(u32);
@@ -66,5 +69,6 @@ void make_cs1_contiguous(void);
 void omap_nand_switch_ecc(int);
 void power_init_r(void);
 void dieid_num_r(void);
-
+void do_omap3_emu_romcode_call(u32 service_id, u32 parameters);
+void omap3_gp_romcode_call(u32 service_id, u32 parameter);
 #endif
Signature · 1 line
1.7.0.4
#38 lore raw

PATCH 7/8 armv7: adapt omap3 to the new cache maintenance framework

Dear Aneesh V,

Quoted 1 line · In message <[email protected]> you wrote:

adapt omap3 to the new layered cache maintenance framework

...

Quoted 1 line

+/* Declarations */

Please drop this comment. Everybody sees what this is.

arch/arm/cpu/armv7/omap3/board.c void s_init(void) · line 179

Quoted 7 lines
arch/arm/cpu/armv7/omap3/board.c +2 -3
+#ifndef CONFIG_L2_OFF
 	/*
-	 * Writing to AuxCR in U-boot using SMI for GP DEV
-	 * Currently SMI in Kernel on ES2 devices seems to have an issue
-	 * Once that is resolved, we can postpone this config to kernel
+	 * Invalidate L2-cache from secure mode
 	 */

Why not change this into simple

	/* Invalidate L2-cache from secure mode */

?

...

arch/arm/cpu/armv7/omap3/board.c int checkboard (void) · line 300

Quoted 13 lines
arch/arm/cpu/armv7/omap3/board.c +13 -0
+static void omap3_emu_romcode_call(u32 service_id, u32 *parameters)
+{
+	u32 i, num_params = *parameters;
+	u32 *sram_scratch_space = (u32 *)OMAP3_PUBLIC_SRAM_SCRATCH_AREA;
+	/*
+	 * copy the parameters to an un-cached area to avoid coherency
+	 * issues
+	 */
+	for (i = 0; i < num_params; i++) {
+		__raw_writel(*parameters, sram_scratch_space);
+		parameters++;
+		sram_scratch_space++;
+	}

Do you have unlimited storage there? Or should you add some check not to exceed some maximum size?

arch/arm/cpu/armv7/omap3/board.c int checkboard (void) · line 321

Quoted 6 lines
arch/arm/cpu/armv7/omap3/board.c +6 -0
+	} else {
+		struct emu_hal_params emu_romcode_params;
+		emu_romcode_params.num_params = 1;
+		emu_romcode_params.param1 = acr;
+		omap3_emu_romcode_call(OMAP3_EMU_HAL_API_WRITE_ACR,
+				       (u32 *)&emu_romcode_params);

Please add a blank line between declarations and code (fix globally).

arch/arm/cpu/armv7/omap3/board.c int checkboard (void) · line 339

Quoted 4 lines
arch/arm/cpu/armv7/omap3/board.c +4 -0
+static void omap3_setup_aux_cr(void)
+{
+	/* Workaround for Cortex-A8 errata: #454179 #430973
+	 *	Set "IBE" bit

...
Incorrect multiline comment style.

...

arch/arm/include/asm/arch-omap3/sys_proto.h typedef struct { · line 33

Quoted 12 lines
arch/arm/include/asm/arch-omap3/sys_proto.h +4 -0
index 4a28ba1..25f54ea 100644
@@ -27,6 +27,11 @@ typedef struct {
 	char *nand_string;
 } omap3_sysinfo;
 
+struct __attribute__ ((__packed__)) emu_hal_params {
+	u32 num_params;
+	u32 param1;
+};

Why exactly do we need the "__attribute__ ((__packed__))" here?

Best regards,

Wolfgang Denk

Signature · 6 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
The years of peak mental activity are undoubtedly between the ages of
four and eighteen. At four we know all the questions, at eighteen all
the answers.
author
#39 lore raw

PATCH 7/8 armv7: adapt omap3 to the new cache maintenance framework

Dear Wolfgang,

Quoted 9 lines · Wolfgang Denk

Dear Aneesh V,

Quoted 1 line · In message<[email protected]> you wrote:

adapt omap3 to the new layered cache maintenance framework

...

Quoted 1 line

+/* Declarations */

Please drop this comment. Everybody sees what this is.

ok.

Quoted 11 lines

arch/arm/cpu/armv7/omap3/board.c void s_init(void) · line 179

Quoted 8 lines
arch/arm/cpu/armv7/omap3/board.c +2 -3
+#ifndef CONFIG_L2_OFF
  	/*
-	 * Writing to AuxCR in U-boot using SMI for GP DEV
-	 * Currently SMI in Kernel on ES2 devices seems to have an issue
-	 * Once that is resolved, we can postpone this config to kernel
+	 * Invalidate L2-cache from secure mode
  	 */

Why not change this into simple

Quoted 3 lines
	/* Invalidate L2-cache from secure mode */

?

ok.

Quoted 18 lines

...

arch/arm/cpu/armv7/omap3/board.c int checkboard (void) · line 300

Quoted 13 lines
arch/arm/cpu/armv7/omap3/board.c +13 -0
+static void omap3_emu_romcode_call(u32 service_id, u32 *parameters)
+{
+	u32 i, num_params = *parameters;
+	u32 *sram_scratch_space = (u32 *)OMAP3_PUBLIC_SRAM_SCRATCH_AREA;
+	/*
+	 * copy the parameters to an un-cached area to avoid coherency
+	 * issues
+	 */
+	for (i = 0; i<  num_params; i++) {
+		__raw_writel(*parameters, sram_scratch_space);
+		parameters++;
+		sram_scratch_space++;
+	}

Do you have unlimited storage there? Or should you add some check not to exceed some maximum size?

Number of params is typically 1 or 2. We should have enough space unless the usage is wrong.

Quoted 9 lines

arch/arm/cpu/armv7/omap3/board.c int checkboard (void) · line 321

Quoted 7 lines
arch/arm/cpu/armv7/omap3/board.c +6 -0
+	} else {
+		struct emu_hal_params emu_romcode_params;
+		emu_romcode_params.num_params = 1;
+		emu_romcode_params.param1 = acr;
+		omap3_emu_romcode_call(OMAP3_EMU_HAL_API_WRITE_ACR,
+				       (u32 *)&emu_romcode_params);

Please add a blank line between declarations and code (fix globally).

ok.

Quoted 7 lines

arch/arm/cpu/armv7/omap3/board.c int checkboard (void) · line 339

Quoted 5 lines
arch/arm/cpu/armv7/omap3/board.c +4 -0
+static void omap3_setup_aux_cr(void)
+{
+	/* Workaround for Cortex-A8 errata: #454179 #430973
+	 *	Set "IBE" bit

...
Incorrect multiline comment style.

Will correct it.

Quoted 10 lines

...

Quoted 8 lines
arch/arm/include/asm/arch-omap3/sys_proto.h +0 -0
index 4a28ba1..25f54ea 100644
@@ -27,6 +27,11 @@ typedef struct {
  	char *nand_string;
  } omap3_sysinfo;
 
Quoted 6 lines

arch/arm/include/asm/arch-omap3/sys_proto.h typedef struct { · line 33

Quoted 4 lines
arch/arm/include/asm/arch-omap3/sys_proto.h +4 -0
+struct __attribute__ ((__packed__)) emu_hal_params {
+	u32 num_params;
+	u32 param1;
+};

Why exactly do we need the "__attribute__ ((__packed__))" here?

Because a pointer to it has to be passed to ROM code and ROM code wouldn't expect any padding.

Quoted 6 lines

Best regards,

Wolfgang Denk

Best regards,
Aneesh

#40 lore raw

PATCH 7/8 armv7: adapt omap3 to the new cache maintenance framework

Dear Aneesh V,

Quoted 10 lines · In message <[email protected]> you wrote:
Quoted 7 lines

arch/arm/include/asm/arch-omap3/sys_proto.h typedef struct { · line 33

Quoted 5 lines
arch/arm/include/asm/arch-omap3/sys_proto.h +4 -0
+struct __attribute__ ((__packed__)) emu_hal_params {
+	u32 num_params;
+	u32 param1;
+};

Why exactly do we need the "__attribute__ ((__packed__))" here?

Because a pointer to it has to be passed to ROM code and ROM code wouldn't expect any padding.

But padding would only be needed if there were any alignment requirements requiring it. There are none here.

Best regards,

Wolfgang Denk

Signature · 6 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"The combination of a number of things to make existence worthwhile."
"Yes, the philosophy of 'none,' meaning 'all.'"
	-- Spock and Lincoln, "The Savage Curtain", stardate 5906.4
author
#41 lore raw

PATCH 7/8 armv7: adapt omap3 to the new cache maintenance framework

Dear Wolfgang,

Quoted 11 lines · Wolfgang Denk

Dear Aneesh V,

Quoted 8 lines · In message<[email protected]> you wrote:
Quoted 7 lines

arch/arm/include/asm/arch-omap3/sys_proto.h typedef struct { · line 33

Quoted 5 lines
arch/arm/include/asm/arch-omap3/sys_proto.h +4 -0
+struct __attribute__ ((__packed__)) emu_hal_params {
+	u32 num_params;
+	u32 param1;
+};

Why exactly do we need the "__attribute__ ((__packed__))" here?

Quoted 5 lines
Quoted 2 lines

Because a pointer to it has to be passed to ROM code and ROM code wouldn't expect any padding.

But padding would only be needed if there were any alignment requirements requiring it. There are none here.

Yes. But, is that guaranteed? I didn't want to make it compiler dependent. Isn't it safer to use '__attribute__ ((__packed__))'

Best regards,
Aneesh

#42 lore raw

PATCH 7/8 armv7: adapt omap3 to the new cache maintenance framework

Dear Aneesh V,

Quoted 8 lines · In message <[email protected]> you wrote:
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines

arch/arm/include/asm/arch-omap3/sys_proto.h typedef struct { · line 33

Quoted 5 lines
arch/arm/include/asm/arch-omap3/sys_proto.h +4 -0
+struct __attribute__ ((__packed__)) emu_hal_params {
+	u32 num_params;
+	u32 param1;
+};

Why exactly do we need the "__attribute__ ((__packed__))" here?

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

Because a pointer to it has to be passed to ROM code and ROM code wouldn't expect any padding.

But padding would only be needed if there were any alignment requirements requiring it. There are none here.

Yes. But, is that guaranteed? I didn't want to make it compiler

Well, there has never been a guarantee agains broken tools doing stupid or plain wrong things.

Quoted 1 line

dependent. Isn't it safer to use '__attribute__ ((__packed__))'

'__attribute__ ((__packed__))' has (especially on ARM) certain side-effects that are neither needed nor wanted here, I think.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Knowledge, sir, should be free to all!
	-- Harry Mudd, "I, Mudd", stardate 4513.3
author
#43 lore raw

PATCH 8/8 armv7: adapt s5pc1xx to the new cache maintenance framework

In reply to Aneesh V

adapt s5pc1xx to the new layered cache maintenance framework

---
 arch/arm/cpu/armv7/s5pc1xx/cache.S            |   86 +-----------------------
 arch/arm/cpu/armv7/s5pc1xx/clock.c            |   12 ++++
 arch/arm/include/asm/arch-s5pc1xx/sys_proto.h |    4 +-
 3 files changed, 18 insertions(+), 84 deletions(-)
arch/arm/cpu/armv7/s5pc1xx/cache.S +4 -82
index 7734b32..e62ad75 100644
@@ -23,96 +23,18 @@
  * MA 02111-1307 USA
  */
 
-#include <asm/arch/cpu.h>
-
 .align 5
-.global invalidate_dcache
-.global l2_cache_enable
-.global l2_cache_disable
-
-/*
- * invalidate_dcache()
- * Invalidate the whole D-cache.
- *
- * Corrupted registers: r0-r5, r7, r9-r11
- */
-invalidate_dcache:
-	stmfd	r13!, {r0 - r5, r7, r9 - r12, r14}
-
-	cmp	r0, #0xC100			@ check if the cpu is s5pc100
-
-	beq	finished_inval			@ s5pc100 doesn't need this
-						@ routine
-	mrc	p15, 1, r0, c0, c0, 1		@ read clidr
-	ands	r3, r0, #0x7000000		@ extract loc from clidr
-	mov	r3, r3, lsr #23			@ left align loc bit field
-	beq	finished_inval			@ if loc is 0, then no need to
-						@ clean
-	mov	r10, #0				@ start clean at cache level 0
-inval_loop1:
-	add	r2, r10, r10, lsr #1		@ work out 3x current cache
-						@ level
-	mov	r1, r0, lsr r2			@ extract cache type bits from
-						@ clidr
-	and	r1, r1, #7			@ mask of the bits for current
-						@ cache only
-	cmp	r1, #2				@ see what cache we have at
-						@ this level
-	blt	skip_inval			@ skip if no cache, or just
-						@ i-cache
-	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level
-						@ in cssr
-	mov	r2, #0				@ operand for mcr SBZ
-	mcr	p15, 0, r2, c7, c5, 4		@ flush prefetch buffer to
-						@ sych the new cssr&csidr,
-						@ with armv7 this is 'isb',
-						@ but we compile with armv5
-	mrc	p15, 1, r1, c0, c0, 0		@ read the new csidr
-	and	r2, r1, #7			@ extract the length of the
-						@ cache lines
-	add	r2, r2, #4			@ add 4 (line length offset)
-	ldr	r4, =0x3ff
-	ands	r4, r4, r1, lsr #3		@ find maximum number on the
-						@ way size
-	clz	r5, r4				@ find bit position of way
-						@ size increment
-	ldr	r7, =0x7fff
-	ands	r7, r7, r1, lsr #13		@ extract max number of the
-						@ index size
-inval_loop2:
-	mov	r9, r4				@ create working copy of max
-						@ way size
-inval_loop3:
-	orr	r11, r10, r9, lsl r5		@ factor way and cache number
-						@ into r11
-	orr	r11, r11, r7, lsl r2		@ factor index number into r11
-	mcr	p15, 0, r11, c7, c6, 2		@ invalidate by set/way
-	subs	r9, r9, #1			@ decrement the way
-	bge	inval_loop3
-	subs	r7, r7, #1			@ decrement the index
-	bge	inval_loop2
-skip_inval:
-	add	r10, r10, #2			@ increment cache number
-	cmp	r3, r10
-	bgt	inval_loop1
-finished_inval:
-	mov	r10, #0				@ swith back to cache level 0
-	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level
-						@ in cssr
-	mcr	p15, 0, r10, c7, c5, 4		@ flush prefetch buffer,
-						@ with armv7 this is 'isb',
-						@ but we compile with armv5
-
-	ldmfd	r13!, {r0 - r5, r7, r9 - r12, pc}
+.global ca8_l2_cache_enable
+.global ca8_l2_cache_disable
 
-l2_cache_enable:
+ca8_l2_cache_enable:
 	push	{r0, r1, r2, lr}
 	mrc	15, 0, r3, cr1, cr0, 1
 	orr	r3, r3, #2
 	mcr	15, 0, r3, cr1, cr0, 1
 	pop	{r1, r2, r3, pc}
 
-l2_cache_disable:
+ca8_l2_cache_disable:
 	push	{r0, r1, r2, lr}
 	mrc	15, 0, r3, cr1, cr0, 1
 	bic	r3, r3, #2
arch/arm/cpu/armv7/s5pc1xx/clock.c +12 -0
index 98a27e5..da8b2d7 100644
@@ -26,6 +26,8 @@
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/clk.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/armv7.h>
 
 #define CLK_M	0
 #define CLK_D	1
@@ -328,3 +330,13 @@ void s5p_clock_init(void)
 	get_uart_clk = s5pc1xx_get_uart_clk;
 	get_pwm_clk = s5pc1xx_get_pwm_clk;
 }
+
+#ifndef CONFIG_SYS_NO_DCACHE
+void v7_setup_outer_cache_ops(void)
+{
+#ifndef CONFIG_L2_OFF
+	v7_outer_cache.enable = ca8_l2_cache_enable;
+	v7_outer_cache.disable = ca8_l2_cache_disable;
+#endif
+}
+#endif
arch/arm/include/asm/arch-s5pc1xx/sys_proto.h +2 -2
index 3078aaf..23144da 100644
@@ -26,7 +26,7 @@
 
 u32 get_device_type(void);
 void invalidate_dcache(u32);
-void l2_cache_disable(void);
-void l2_cache_enable(void);
+void ca8_l2_cache_disable(void);
+void ca8_l2_cache_enable(void);
 
 #endif
Signature · 1 line
1.7.0.4
#44 lore raw

PATCH 8/8 armv7: adapt s5pc1xx to the new cache maintenance framework

Dear Aneesh V,

Quoted 26 lines · Aneesh V

adapt s5pc1xx to the new layered cache maintenance framework

---

?arch/arm/cpu/armv7/s5pc1xx/cache.S ? ? ? ? ? ?| ? 86 +-----------------------
?arch/arm/cpu/armv7/s5pc1xx/clock.c ? ? ? ? ? ?| ? 12 ++++
?arch/arm/include/asm/arch-s5pc1xx/sys_proto.h | ? ?4 +-

?3 files changed, 18 insertions(+), 84 deletions(-)

arch/arm/cpu/armv7/s5pc1xx/clock.c +0 -0
index 98a27e5..da8b2d7 100644
@@ -26,6 +26,8 @@

?#include <asm/io.h>
?#include <asm/arch/clock.h>
?#include <asm/arch/clk.h>

arch/arm/cpu/armv7/s5pc1xx/clock.c +2 -0
+#include <asm/arch/sys_proto.h>
+#include <asm/armv7.h>

?#define CLK_M ?0
?#define CLK_D ?1

arch/arm/cpu/armv7/s5pc1xx/clock.c +0 -0
@@ -328,3 +330,13 @@ void s5p_clock_init(void)
 ? ? ? ?get_uart_clk = s5pc1xx_get_uart_clk;
 ? ? ? ?get_pwm_clk = s5pc1xx_get_pwm_clk;
 ?}

arch/arm/cpu/armv7/s5pc1xx/clock.c void s5p_clock_init(void) · line 342

Quoted 10 lines
arch/arm/cpu/armv7/s5pc1xx/clock.c +10 -0
+
+#ifndef CONFIG_SYS_NO_DCACHE
+void v7_setup_outer_cache_ops(void)
+{
+#ifndef CONFIG_L2_OFF
+ ? ? ? v7_outer_cache.enable = ca8_l2_cache_enable;
+ ? ? ? v7_outer_cache.disable = ca8_l2_cache_disable;
+#endif
+}
+#endif

I don't agree with add this function at clock.c.
If need we can make new file as omap3/4 case.

Thanks
Minkyu Kang

Signature · 2 lines
from. prom.
www.promsoft.net
author
#45 lore raw

PATCH 8/8 armv7: adapt s5pc1xx to the new cache maintenance framework

Dear Minkyu Kang,

On Monday 27 December 2010 12:55 PM, Minkyu Kang wrote:
< snip >

Quoted 5 lines
Quoted 5 lines
arch/arm/cpu/armv7/s5pc1xx/clock.c +5 -0
+
+#ifndef CONFIG_SYS_NO_DCACHE
+void v7_setup_outer_cache_ops(void)
+{
+#ifndef CONFIG_L2_OFF
Quoted 8 lines

arch/arm/cpu/armv7/s5pc1xx/clock.c void s5p_clock_init(void) · line 342

Quoted 5 lines
arch/arm/cpu/armv7/s5pc1xx/clock.c +5 -0
+       v7_outer_cache.enable = ca8_l2_cache_enable;
+       v7_outer_cache.disable = ca8_l2_cache_disable;
+#endif
+}
+#endif

I don't agree with add this function at clock.c.
If need we can make new file as omap3/4 case.

I didn't want to add a new file just for this small function. But no problem, I will do that in the next revision.

Best regards,
Aneesh

#46 lore raw

PATCH 8/8 armv7: adapt s5pc1xx to the new cache maintenance framework

Dear Aneesh V,

Quoted 19 lines · Aneesh V

Dear Minkyu Kang,

On Monday 27 December 2010 12:55 PM, Minkyu Kang wrote:
< snip >

Quoted 14 lines

arch/arm/cpu/armv7/s5pc1xx/clock.c void s5p_clock_init(void) · line 342

Quoted 11 lines
arch/arm/cpu/armv7/s5pc1xx/clock.c +10 -0
+
+#ifndef CONFIG_SYS_NO_DCACHE
+void v7_setup_outer_cache_ops(void)
+{
+#ifndef CONFIG_L2_OFF
+ ? ? ? v7_outer_cache.enable = ca8_l2_cache_enable;
+ ? ? ? v7_outer_cache.disable = ca8_l2_cache_disable;
+#endif
+}
+#endif

I don't agree with add this function at clock.c.
If need we can make new file as omap3/4 case.

Quoted 3 lines

I didn't want to add a new file just for this small function. But no problem, I will do that in the next revision.

OK, please make soc.c.
I have plan to move reset.S to this file.

Thanks.
Minkyu Kang

Signature · 2 lines
from. prom.
www.promsoft.net
#47 lore raw

cover armv7: cache maintenance operations

In reply to Aneesh V
Quoted 16 lines · Aneesh V

With D-cache and MMU enabled for ARM in u-boot it becomes imperative to support a minimal set of cache maintenance operations and necessary initializations before enabling MMU.

This series of patches attempt to do the following for armv7:
* Necessary initialization sequence before enabling MMU that includes ?invalidation of TLB, data caches, branch predictor array etc.
* Framework for supporting SOC specific outer caches in a generic manner ?(using a structure of function pointers - inspired by the Linux ?implementation)
* Generic armv7 cache maintenance operations for caches known to the CPU
* Support for ARM PL310 L2 cache controller used in OMAP4
* Cleanup of the cleanup_before_linux() function
* Adapting all armv7 SOCs to use the new framework and removing ?duplicated code

Quoted 12 lines

Testing:
* Extensive testing on OMAP4430SDP and OMAP3430SDP by creating coherency ?issues and solving them using the maintenance routines
? ? ? ?- Eg: memfill a region of memory with a known pattern ? ? ? ?- Invalidate the region
? ? ? ?- Read back and compare the region with the original pattern ? ? ? ?- If match fails it means that invalidate is successful ? ? ? ?- Now add a flush call just before the invalidate
? ? ? ?- If match succeeds it means that flush was successful ? ? ? ?- Outer caches were tested with experiments involving making the ? ? ? ? ?function pointers NULL
* Kernel booting on OMAP4430SDP and OMAP3430SDP

I build tested for Beagle, Overo, Panda, and OMAP4430SDP - no issues.

I run tested on Overo and Panda to evaluate the changes on both OMAP3 and OMAP4 - no issues.

Steve

#48 lore raw

cover armv7: cache maintenance operations

In reply to Aneesh V
Quoted 34 lines

Subject: [U-Boot] [PATCH 0/8] armv7: cache maintenance operations

With D-cache and MMU enabled for ARM in u-boot it becomes imperative to support a minimal set of cache maintenance operations and necessary initializations before enabling MMU.

This series of patches attempt to do the following for armv7:
* Necessary initialization sequence before enabling MMU that includes invalidation of TLB, data caches, branch predictor array etc.
* Framework for supporting SOC specific outer caches in a generic manner (using a structure of function pointers - inspired by the Linux implementation)
* Generic armv7 cache maintenance operations for caches known to the CPU
* Support for ARM PL310 L2 cache controller used in OMAP4
* Cleanup of the cleanup_before_linux() function
* Adapting all armv7 SOCs to use the new framework and removing duplicated code

Testing:
* Extensive testing on OMAP4430SDP and OMAP3430SDP by creating coherency issues and solving them using the maintenance routines
- Eg: memfill a region of memory with a known pattern
- Invalidate the region
- Read back and compare the region with the original pattern
- If match fails it means that invalidate is successful
- Now add a flush call just before the invalidate
- If match succeeds it means that flush was successful
- Outer caches were tested with experiments involving making the function pointers NULL
* Kernel booting on OMAP4430SDP and OMAP3430SDP

Quoted 9 lines

Aneesh V (8):
arm: make default implementation of cache_flush() weakly linked
armv7: cache maintenance operations for armv7
armv7: integrate cache maintenance support
arm: minor fixes for cache and mmu handling
armv7: add PL310 support to u-boot
armv7: adapt omap4 to the new cache maintenance framework
armv7: adapt omap3 to the new cache maintenance framework
armv7: adapt s5pc1xx to the new cache maintenance framework

As I mentioned to John Rigby in anoterh e-mail, I will be on vacation till the 20th of January. So there might be a little delay in merging this patch series after due review by the community.

Regards,
Sandeep

#49 lore raw

cover armv7: cache maintenance operations

Le 28/12/2010 20:51, Paulraj, Sandeep a ?crit :

Quoted 45 lines
Quoted 34 lines

Subject: [U-Boot] [PATCH 0/8] armv7: cache maintenance operations

With D-cache and MMU enabled for ARM in u-boot it becomes imperative to support a minimal set of cache maintenance operations and necessary initializations before enabling MMU.

This series of patches attempt to do the following for armv7:
* Necessary initialization sequence before enabling MMU that includes invalidation of TLB, data caches, branch predictor array etc.
* Framework for supporting SOC specific outer caches in a generic manner (using a structure of function pointers - inspired by the Linux implementation)
* Generic armv7 cache maintenance operations for caches known to the CPU
* Support for ARM PL310 L2 cache controller used in OMAP4
* Cleanup of the cleanup_before_linux() function
* Adapting all armv7 SOCs to use the new framework and removing duplicated code

Testing:
* Extensive testing on OMAP4430SDP and OMAP3430SDP by creating coherency issues and solving them using the maintenance routines
- Eg: memfill a region of memory with a known pattern
- Invalidate the region
- Read back and compare the region with the original pattern
- If match fails it means that invalidate is successful
- Now add a flush call just before the invalidate
- If match succeeds it means that flush was successful
- Outer caches were tested with experiments involving making the function pointers NULL
* Kernel booting on OMAP4430SDP and OMAP3430SDP

Quoted 9 lines

Aneesh V (8):
arm: make default implementation of cache_flush() weakly linked
armv7: cache maintenance operations for armv7
armv7: integrate cache maintenance support
arm: minor fixes for cache and mmu handling
armv7: add PL310 support to u-boot
armv7: adapt omap4 to the new cache maintenance framework
armv7: adapt omap3 to the new cache maintenance framework
armv7: adapt s5pc1xx to the new cache maintenance framework

Quoted 4 lines

As I mentioned to John Rigby in anoterh e-mail, I will be on vacation till the 20th of January. So there might be a little delay in merging this patch series after due review by the community.

Regards,
Sandeep

Hi Sandeep,

I have assigned these to me in patchwork but feel free to reclaim them if you prefer.

Amicalement,

Signature · 1 line
Albert.