From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 5 Apr 2009 11:06:31 +0000 (+0200) Subject: arm: clean cache management X-Git-Tag: v2009.06-rc1~47^2~3 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=b3acb6cd4059dfb29a5e99095d802717f53ff784;p=u-boot arm: clean cache management unify arm cache management except for non standard cache as ARM7TDMI Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- diff --git a/board/armltd/integratorap/split_by_variant.sh b/board/armltd/integratorap/split_by_variant.sh index 51dc53f1bd..2c9fe2e519 100755 --- a/board/armltd/integratorap/split_by_variant.sh +++ b/board/armltd/integratorap/split_by_variant.sh @@ -84,8 +84,8 @@ else esac fi -if [ "$cpu" = "arm_intcm" ] -then +case "$cpu" in + arm_intcm) echo "/* Core module undefined/not ported */" >> tmp.fil echo "#define CONFIG_ARM_INTCM 1" >> tmp.fil echo -n "#undef CONFIG_CM_MULTIPLE_SSRAM" >> tmp.fil @@ -102,7 +102,19 @@ then echo "initialization reg */" >> tmp.fil echo -n "#undef CONFIG_CM_TCRAM " >> tmp.fil echo " /* CM may not have TCRAM */" >> tmp.fil -fi + echo -n " /* May not be processor " >> tmp.fil + echo "without cache support */" >> tmp.fil + echo "#define CONFIG_SYS_NO_ICACHE 1" >> tmp.fil + echo "#define CONFIG_SYS_NO_DCACHE 1" >> tmp.fil + ;; + + arm720t) + echo -n " /* May not be processor " >> tmp.fil + echo "without cache support */" >> tmp.fil + echo "#define CONFIG_SYS_NO_ICACHE 1" >> tmp.fil + echo "#define CONFIG_SYS_NO_DCACHE 1" >> tmp.fil + ;; +esac mkdir -p ${obj}include mkdir -p ${obj}board/armltd/integratorap diff --git a/cpu/arm1136/cpu.c b/cpu/arm1136/cpu.c index 0abe307bb2..78f6e928f9 100644 --- a/cpu/arm1136/cpu.c +++ b/cpu/arm1136/cpu.c @@ -39,13 +39,7 @@ DECLARE_GLOBAL_DATA_PTR; #endif -static void cp_delay (void) -{ - volatile int i; - - /* Many OMAP regs need at least 2 nops */ - for (i = 0; i < 100; i++); -} +static void cache_flush(void); int cpu_init (void) { @@ -68,8 +62,6 @@ int cleanup_before_linux (void) * we turn off caches etc ... */ - unsigned long i; - disable_interrupts (); #ifdef CONFIG_LCD @@ -83,15 +75,12 @@ int cleanup_before_linux (void) #endif /* turn off I/D-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~(CR_C | CR_I); - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); - + icache_disable(); + dcache_disable(); /* flush I/D-cache */ - i = 0; - asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); /* invalidate both caches and flush btb */ - asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i)); /* mem barrier to sync things */ - return(0); + cache_flush(); + + return 0; } int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) @@ -102,25 +91,10 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return(0); } -void icache_enable (void) +static void cache_flush(void) { - ulong reg; + unsigned long i = 0; - reg = get_cr (); /* get control reg. */ - cp_delay (); - set_cr (reg | CR_I); -} - -void icache_disable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - set_cr (reg & ~CR_I); -} - -int icache_status (void) -{ - return(get_cr () & CR_I) != 0; + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); /* invalidate both caches and flush btb */ + asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i)); /* mem barrier to sync things */ } diff --git a/cpu/arm1176/cpu.c b/cpu/arm1176/cpu.c index ef78bd965e..8aefbe37c8 100644 --- a/cpu/arm1176/cpu.c +++ b/cpu/arm1176/cpu.c @@ -38,15 +38,6 @@ static void cache_flush (void); -static void cp_delay (void) -{ - volatile int i; - - /* Many OMAP regs need at least 2 nops */ - for (i = 0; i < 100; i++) - __asm__ __volatile__("nop\n"); -} - int cpu_init (void) { return 0; @@ -66,6 +57,7 @@ int cleanup_before_linux (void) /* turn off I/D-cache */ icache_disable(); dcache_disable(); + /* flush I/D-cache */ cache_flush(); return 0; @@ -95,53 +87,6 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -void icache_enable (void) -{ - ulong reg; - - reg = get_cr (); /* get control reg. */ - cp_delay (); - set_cr (reg | CR_I); -} - -void icache_disable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - set_cr (reg & ~CR_I); -} - -int icache_status (void) -{ - return (get_cr () & CR_I) != 0; -} - -/* It makes no sense to use the dcache if the MMU is not enabled */ -void dcache_enable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - set_cr (reg | CR_C); -} - -void dcache_disable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - set_cr (reg & ~CR_C); -} - -int dcache_status (void) -{ - return (get_cr () & CR_C) != 0; -} - /* flush I/D-cache */ static void cache_flush (void) { diff --git a/cpu/arm720t/cpu.c b/cpu/arm720t/cpu.c index d178e4140b..a6f5c4d8bb 100644 --- a/cpu/arm720t/cpu.c +++ b/cpu/arm720t/cpu.c @@ -36,6 +36,10 @@ #include #include +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) +static void cache_flush(void); +#endif + int cpu_init (void) { /* @@ -59,17 +63,14 @@ int cleanup_before_linux (void) */ #if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) - unsigned long i; - disable_interrupts (); /* turn off I-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~0x1000; - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + icache_disable(); + dcache_disable(); /* flush I-cache */ - asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); + cache_flush(); #ifdef CONFIG_ARM7_REVD /* go to high speed */ IO_SYSCON3 = (IO_SYSCON3 & ~CLKCTL) | CLKCTL_73; @@ -93,64 +94,13 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return (0); } -/* - * Instruction and Data cache enable and disable functions - * - */ - -#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) || defined(CONFIG_ARMADILLO) -static void cp_delay (void) -{ - volatile int i; - - /* copro seems to need some delay between reading and writing */ - for (i = 0; i < 100; i++); -} - -void icache_enable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - set_cr (reg | CR_C); -} - -void icache_disable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - set_cr (reg & ~CR_C); -} - -int icache_status (void) -{ - return (get_cr () & CR_C) != 0; -} - -void dcache_enable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - set_cr (reg | CR_C); -} - -void dcache_disable (void) +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) +/* flush I/D-cache */ +static void cache_flush (void) { - ulong reg; + unsigned long i = 0; - reg = get_cr (); - cp_delay (); - set_cr (reg & ~CR_C); -} - -int dcache_status (void) -{ - return (get_cr () & CR_C) != 0; + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); } #elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) /* No specific cache setup for IntegratorAP/CM720T as yet */ diff --git a/cpu/arm920t/cpu.c b/cpu/arm920t/cpu.c index 83ee3f37f2..08c9339a35 100644 --- a/cpu/arm920t/cpu.c +++ b/cpu/arm920t/cpu.c @@ -38,13 +38,7 @@ DECLARE_GLOBAL_DATA_PTR; #endif -static void cp_delay (void) -{ - volatile int i; - - /* copro seems to need some delay between reading and writing */ - for (i = 0; i < 100; i++); -} +static void cache_flush(void); int cpu_init (void) { @@ -67,20 +61,15 @@ int cleanup_before_linux (void) * we turn off caches etc ... */ - unsigned long i; - disable_interrupts (); /* turn off I/D-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~(CR_C | CR_I); - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); - + icache_disable(); + dcache_disable(); /* flush I/D-cache */ - i = 0; - asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); + cache_flush(); - return (0); + return 0; } int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) @@ -88,55 +77,13 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) disable_interrupts (); reset_cpu (0); /*NOTREACHED*/ - return (0); -} - -void icache_enable (void) -{ - ulong reg; - - reg = get_cr (); /* get control reg. */ - cp_delay (); - set_cr (reg | CR_I); -} - -void icache_disable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - set_cr (reg & ~CR_I); -} - -int icache_status (void) -{ - return (get_cr () & CR_I) != 0; -} - -#ifdef USE_920T_MMU -/* It makes no sense to use the dcache if the MMU is not enabled */ -void dcache_enable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - set_cr (reg | CR_C); + return 0; } -void dcache_disable (void) +/* flush I/D-cache */ +static void cache_flush (void) { - ulong reg; - - reg = get_cr (); - cp_delay (); - reg &= ~CR_C; - set_cr (reg); -} + unsigned long i = 0; -int dcache_status (void) -{ - return (get_cr () & CR_C) != 0; + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); } -#endif diff --git a/cpu/arm925t/cpu.c b/cpu/arm925t/cpu.c index 8d1b562dca..eb6364d694 100644 --- a/cpu/arm925t/cpu.c +++ b/cpu/arm925t/cpu.c @@ -38,13 +38,7 @@ DECLARE_GLOBAL_DATA_PTR; #endif -static void cp_delay (void) -{ - volatile int i; - - /* Many OMAP regs need at least 2 nops */ - for (i = 0; i < 100; i++); -} +static void cache_flush(void); int cpu_init (void) { @@ -67,19 +61,16 @@ int cleanup_before_linux (void) * we turn off caches etc ... */ - unsigned long i; - disable_interrupts (); - /* turn off I/D-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~(CR_C | CR_I); - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); /* flush I/D-cache */ - i = 0; - asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); - return (0); + cache_flush(); + + return 0; } int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) @@ -90,25 +81,11 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return (0); } -void icache_enable (void) -{ - ulong reg; - - reg = get_cr (); /* get control reg. */ - cp_delay (); - set_cr (reg | CR_I); -} - -void icache_disable (void) +/* flush I/D-cache */ +static void cache_flush (void) { - ulong reg; + unsigned long i = 0; - reg = get_cr (); - cp_delay (); - set_cr (reg & ~CR_I); + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); } -int icache_status (void) -{ - return (get_cr () & CR_I) != 0; -} diff --git a/cpu/arm926ejs/cpu.c b/cpu/arm926ejs/cpu.c index d1748c9c6d..84c169e9b1 100644 --- a/cpu/arm926ejs/cpu.c +++ b/cpu/arm926ejs/cpu.c @@ -38,13 +38,7 @@ DECLARE_GLOBAL_DATA_PTR; #endif -static void cp_delay (void) -{ - volatile int i; - - /* copro seems to need some delay between reading and writing */ - for (i = 0; i < 100; i++); -} +static void cache_flush(void); int cpu_init (void) { @@ -67,20 +61,16 @@ int cleanup_before_linux (void) * we turn off caches etc ... */ - unsigned long i; - disable_interrupts (); - /* turn off I/D-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~(CR_C | CR_I); - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); /* flush I/D-cache */ - i = 0; - asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); + cache_flush(); - return (0); + return 0; } int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) @@ -91,52 +81,10 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return (0); } -/* cache_bit must be either CR_I or CR_C */ -static void cache_enable(uint32_t cache_bit) -{ - uint32_t reg; - - reg = get_cr(); /* get control reg. */ - cp_delay(); - set_cr(reg | cache_bit); -} - -/* cache_bit must be either CR_I or CR_C */ -static void cache_disable(uint32_t cache_bit) -{ - uint32_t reg; - - reg = get_cr(); - cp_delay(); - set_cr(reg & ~cache_bit); -} - -void icache_enable(void) -{ - cache_enable(CR_I); -} - -void icache_disable(void) -{ - cache_disable(CR_I); -} - -int icache_status(void) -{ - return (get_cr() & CR_I) != 0; -} - -void dcache_enable(void) -{ - cache_enable(CR_C); -} - -void dcache_disable(void) +/* flush I/D-cache */ +static void cache_flush (void) { - cache_disable(CR_C); -} + unsigned long i = 0; -int dcache_status(void) -{ - return (get_cr() & CR_C) != 0; + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); } diff --git a/cpu/arm946es/cpu.c b/cpu/arm946es/cpu.c index 25684f2018..8d0c53343a 100644 --- a/cpu/arm946es/cpu.c +++ b/cpu/arm946es/cpu.c @@ -38,13 +38,7 @@ DECLARE_GLOBAL_DATA_PTR; #endif -static void cp_delay (void) -{ - volatile int i; - - /* copro seems to need some delay between reading and writing */ - for (i = 0; i < 100; i++); -} +static void cache_flush(void); int cpu_init (void) { @@ -67,8 +61,6 @@ int cleanup_before_linux (void) * we turn off caches etc ... */ - unsigned long i; - disable_interrupts (); /* ARM926E-S needs the protection unit enabled for the icache to have @@ -76,15 +68,12 @@ int cleanup_before_linux (void) * should turn off the protection unit as well.... */ /* turn off I/D-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~(CR_C | CR_I); - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); - + icache_disable(); + dcache_disable(); /* flush I/D-cache */ - i = 0; - asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); - asm ("mcr p15, 0, %0, c7, c6, 0": :"r" (i)); - return (0); + cache_flush(); + + return 0; } int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) @@ -96,27 +85,12 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /*NOTREACHED*/ return (0); } -/* ARM926E-S needs the protection unit enabled for this to have any effect - - left for possible later use */ -void icache_enable (void) -{ - ulong reg; - reg = get_cr (); /* get control reg. */ - cp_delay (); - set_cr (reg | CR_I); -} - -void icache_disable (void) +/* flush I/D-cache */ +static void cache_flush (void) { - ulong reg; + unsigned long i = 0; - reg = get_cr (); - cp_delay (); - set_cr (reg & ~CR_I); -} - -int icache_status (void) -{ - return (get_cr () & CR_I) != 0; + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); + asm ("mcr p15, 0, %0, c7, c6, 0": :"r" (i)); } diff --git a/cpu/arm_cortexa8/cpu.c b/cpu/arm_cortexa8/cpu.c index 506dbec173..64ee972325 100644 --- a/cpu/arm_cortexa8/cpu.c +++ b/cpu/arm_cortexa8/cpu.c @@ -46,13 +46,6 @@ void l2cache_disable(void); static void cache_flush(void); -static void cp_delay(void) -{ - /* Many OMAP regs need at least 2 nops */ - asm("nop"); - asm("nop"); -} - int cpu_init(void) { /* @@ -111,33 +104,6 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -void icache_enable(void) -{ - ulong reg; - - reg = get_cr(); /* get control reg. */ - cp_delay(); - set_cr(reg | CR_I); -} - -void icache_disable(void) -{ - ulong reg; - - reg = get_cr(); - cp_delay(); - set_cr(reg & ~CR_I); -} - -void dcache_disable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - set_cr (reg & ~CR_C); -} - void l2cache_enable() { unsigned long i; @@ -197,11 +163,6 @@ void l2cache_disable() } } -int icache_status(void) -{ - return (get_cr() & CR_I) != 0; -} - static void cache_flush(void) { asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0)); diff --git a/cpu/arm_intcm/cpu.c b/cpu/arm_intcm/cpu.c index ccf7fd5b64..ea6747ae96 100644 --- a/cpu/arm_intcm/cpu.c +++ b/cpu/arm_intcm/cpu.c @@ -76,18 +76,3 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /*NOTREACHED*/ return (0); } - -/* May not be cahed processor on the CM - do nothing */ -void icache_enable (void) -{ -} - -void icache_disable (void) -{ -} - -/* return "disabled" */ -int icache_status (void) -{ - return 0; -} diff --git a/cpu/ixp/cpu.c b/cpu/ixp/cpu.c index 265c82088c..d9cfbabc16 100644 --- a/cpu/ixp/cpu.c +++ b/cpu/ixp/cpu.c @@ -42,6 +42,8 @@ ulong loops_per_jiffy; DECLARE_GLOBAL_DATA_PTR; #endif +static void cache_flush(void); + #if defined(CONFIG_DISPLAY_CPUINFO) int print_cpuinfo (void) { @@ -99,19 +101,16 @@ int cleanup_before_linux (void) * just disable everything that can disturb booting linux */ - unsigned long i; - disable_interrupts (); /* turn off I-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~0x1000; - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + icache_disable(); + dcache_disable(); /* flush I-cache */ - asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); + cache_flush(); - return (0); + return 0; } int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) @@ -126,55 +125,12 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return (0); } -/* cache_bit must be either CR_I or CR_C */ -static void cache_enable(uint32_t cache_bit) -{ - uint32_t reg; - - reg = get_cr(); /* get control reg. */ - cp_delay(); - set_cr(reg | cache_bit); -} - -/* cache_bit must be either CR_I or CR_C */ -static void cache_disable(uint32_t cache_bit) -{ - uint32_t reg; - - reg = get_cr(); - cp_delay(); - set_cr(reg & ~cache_bit); -} - -void icache_enable(void) -{ - cache_enable(CR_I); -} - -void icache_disable(void) -{ - cache_disable(CR_I); -} - -int icache_status(void) +/* flush I/D-cache */ +static void cache_flush (void) { - return (get_cr() & CR_I) != 0; -} + unsigned long i = 0; -/* we will never enable dcache, because we have to setup MMU first */ -void dcache_enable (void) -{ - return; -} - -void dcache_disable (void) -{ - return; -} - -int dcache_status (void) -{ - return 0; /* always off */ + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); } /* FIXME */ diff --git a/cpu/lh7a40x/cpu.c b/cpu/lh7a40x/cpu.c index 2c6799f13f..e862251ca2 100644 --- a/cpu/lh7a40x/cpu.c +++ b/cpu/lh7a40x/cpu.c @@ -38,13 +38,7 @@ DECLARE_GLOBAL_DATA_PTR; #endif -static void cp_delay (void) -{ - volatile int i; - - /* copro seems to need some delay between reading and writing */ - for (i = 0; i < 100; i++); -} +static void cache_flush(void); int cpu_init (void) { @@ -67,19 +61,16 @@ int cleanup_before_linux (void) * we turn off caches etc ... */ - unsigned long i; - disable_interrupts (); /* turn off I/D-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~(CR_C | CR_I); - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + icache_disable(); + dcache_disable(); /* flush I/D-cache */ - i = 0; - asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); - return (0); + cache_flush(); + + return 0; } int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) @@ -90,52 +81,11 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return (0); } -void icache_enable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - set_cr (reg | CR_I); -} -void icache_disable (void) +/* flush I/D-cache */ +static void cache_flush (void) { - ulong reg; + unsigned long i = 0; - reg = get_cr (); - cp_delay (); - set_cr (reg & ~CR_I); -} - -int icache_status (void) -{ - return (get_cr () & CR_I) != 0; -} - -#ifdef USE_920T_MMU -/* It makes no sense to use the dcache if the MMU is not enabled */ -void dcache_enable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - set_cr (reg | CR_C); -} - -void dcache_disable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - reg &= ~CR_C; - set_cr (reg); -} - -int dcache_status (void) -{ - return (get_cr () & CR_C) != 0; + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); } -#endif diff --git a/cpu/pxa/cpu.c b/cpu/pxa/cpu.c index e27b6b9179..ab58d39efc 100644 --- a/cpu/pxa/cpu.c +++ b/cpu/pxa/cpu.c @@ -39,6 +39,8 @@ DECLARE_GLOBAL_DATA_PTR; #endif +static void cache_flush(void); + int cpu_init (void) { /* @@ -60,17 +62,14 @@ int cleanup_before_linux (void) * just disable everything that can disturb booting linux */ - unsigned long i; - disable_interrupts (); /* turn off I-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~0x1000; - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + icache_disable(); + dcache_disable(); /* flush I-cache */ - asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); + cache_flush(); return (0); } @@ -87,55 +86,12 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return (0); } -/* cache_bit must be either CR_I or CR_C */ -static void cache_enable(uint32_t cache_bit) -{ - uint32_t reg; - - reg = get_cr(); /* get control reg. */ - cp_delay(); - set_cr(reg | cache_bit); -} - -/* cache_bit must be either CR_I or CR_C */ -static void cache_disable(uint32_t cache_bit) -{ - uint32_t reg; - - reg = get_cr(); - cp_delay(); - set_cr(reg & ~cache_bit); -} - -void icache_enable(void) -{ - cache_enable(CR_I); -} - -void icache_disable(void) +/* flush I/D-cache */ +static void cache_flush (void) { - cache_disable(CR_I); -} + unsigned long i = 0; -int icache_status(void) -{ - return (get_cr() & CR_I) != 0; -} - -/* we will never enable dcache, because we have to setup MMU first */ -void dcache_enable (void) -{ - return; -} - -void dcache_disable (void) -{ - return; -} - -int dcache_status (void) -{ - return 0; /* always off */ + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); } #ifndef CONFIG_CPU_MONAHANS diff --git a/cpu/sa1100/cpu.c b/cpu/sa1100/cpu.c index d0dfa3d140..6c897d0d56 100644 --- a/cpu/sa1100/cpu.c +++ b/cpu/sa1100/cpu.c @@ -38,6 +38,8 @@ DECLARE_GLOBAL_DATA_PTR; #endif +static void cache_flush(void); + int cpu_init (void) { /* @@ -59,17 +61,14 @@ int cleanup_before_linux (void) * just disable everything that can disturb booting linux */ - unsigned long i; - disable_interrupts (); /* turn off I-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~0x1000; - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + icache_disable(); + dcache_disable(); /* flush I-cache */ - asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); + cache_flush(); return (0); } @@ -86,49 +85,10 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return (0); } -static void cp_delay (void) -{ - volatile int i; - - /* copro seems to need some delay between reading and writing */ - for (i = 0; i < 100; i++); -} - -void icache_enable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - set_cr (reg | CR_C); -} - -void icache_disable (void) -{ - ulong reg; - - reg = get_cr (); - cp_delay (); - set_cr (reg & ~CR_C); -} - -int icache_status (void) -{ - return (get_cr () & CR_C) != 0; -} - -/* we will never enable dcache, because we have to setup MMU first */ -void dcache_enable (void) +/* flush I/D-cache */ +static void cache_flush (void) { - return; -} - -void dcache_disable (void) -{ - return; -} + unsigned long i = 0; -int dcache_status (void) -{ - return 0; /* always off */ + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); } diff --git a/include/configs/B2.h b/include/configs/B2.h index 01b65c515d..35fad5c553 100644 --- a/include/configs/B2.h +++ b/include/configs/B2.h @@ -38,6 +38,7 @@ #define CONFIG_B2 1 /* on an B2 Board */ #define CONFIG_ARM_THUMB 1 /* this is an ARM7TDMI */ #undef CONFIG_ARM7_REVD /* disable ARM720 REV.D Workarounds */ +#define CONFIG_SYS_NO_CP15_CACHE #define CONFIG_S3C44B0_CLOCK_SPEED 75 /* we have a 75Mhz S3C44B0*/ diff --git a/include/configs/assabet.h b/include/configs/assabet.h index a6c442b51a..8c5b84cf69 100644 --- a/include/configs/assabet.h +++ b/include/configs/assabet.h @@ -37,6 +37,8 @@ #define CONFIG_ASSABET 1 /* on an Intel Assabet Board */ #undef CONFIG_USE_IRQ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE #define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ #define CONFIG_SETUP_MEMORY_TAGS 1 diff --git a/include/configs/cerf250.h b/include/configs/cerf250.h index 751e03c13f..82d1401469 100644 --- a/include/configs/cerf250.h +++ b/include/configs/cerf250.h @@ -41,6 +41,9 @@ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE + /* * Size of malloc() pool */ diff --git a/include/configs/cradle.h b/include/configs/cradle.h index 850d93b03e..75c5f9bb3e 100644 --- a/include/configs/cradle.h +++ b/include/configs/cradle.h @@ -37,6 +37,9 @@ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE + /* * Size of malloc() pool */ diff --git a/include/configs/csb226.h b/include/configs/csb226.h index d9f85f01ee..ed1845009e 100644 --- a/include/configs/csb226.h +++ b/include/configs/csb226.h @@ -42,6 +42,10 @@ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ /* for timer/console/ethernet */ + +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE + /* * Hardware drivers */ diff --git a/include/configs/delta.h b/include/configs/delta.h index f5508b7740..bacbd90b5d 100644 --- a/include/configs/delta.h +++ b/include/configs/delta.h @@ -39,6 +39,9 @@ #undef CONFIG_SKIP_RELOCATE_UBOOT #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE + /* * Size of malloc() pool */ diff --git a/include/configs/dnp1110.h b/include/configs/dnp1110.h index 8f615bdb84..b6cfc6721d 100644 --- a/include/configs/dnp1110.h +++ b/include/configs/dnp1110.h @@ -42,6 +42,8 @@ #define CONFIG_DNP1110 1 /* on an DNP/1110 Board */ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE /* * Size of malloc() pool diff --git a/include/configs/evb4510.h b/include/configs/evb4510.h index ffc9408bc8..0f415d9c8b 100644 --- a/include/configs/evb4510.h +++ b/include/configs/evb4510.h @@ -43,6 +43,7 @@ #define CONFIG_ARM_THUMB 1 /* this is an ARM7TDMI */ #define CONFIG_S3C4510B 1 /* it's a S3C4510B chip */ #define CONFIG_EVB4510 1 /* on an EVB4510 Board */ +#define CONFIG_SYS_NO_CP15_CACHE #define CONFIG_USE_IRQ #define CONFIG_STACKSIZE_IRQ (4*1024) diff --git a/include/configs/gcplus.h b/include/configs/gcplus.h index 77d45783c3..b2fbca2f3c 100644 --- a/include/configs/gcplus.h +++ b/include/configs/gcplus.h @@ -49,6 +49,8 @@ #define CONFIG_GCPLUS 1 /* on an ADS GCPlus Board */ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE #define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ #define CONFIG_SETUP_MEMORY_TAGS 1 diff --git a/include/configs/innokom.h b/include/configs/innokom.h index 895998adf4..69654c7c0f 100644 --- a/include/configs/innokom.h +++ b/include/configs/innokom.h @@ -39,6 +39,10 @@ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ /* for timer/console/ethernet */ + +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE + /* * Hardware drivers */ diff --git a/include/configs/lart.h b/include/configs/lart.h index e34ec222b8..5d6d460424 100644 --- a/include/configs/lart.h +++ b/include/configs/lart.h @@ -35,6 +35,8 @@ #define CONFIG_LART 1 /* on an LART Board */ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE /* * Size of malloc() pool diff --git a/include/configs/logodl.h b/include/configs/logodl.h index 9afa800139..889a9a344d 100644 --- a/include/configs/logodl.h +++ b/include/configs/logodl.h @@ -39,6 +39,10 @@ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ /* for timer/console/ethernet */ + +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE + /* * Hardware drivers */ diff --git a/include/configs/lubbock.h b/include/configs/lubbock.h index a4b430bbc5..2cf9c02815 100644 --- a/include/configs/lubbock.h +++ b/include/configs/lubbock.h @@ -46,6 +46,9 @@ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE + /* * Size of malloc() pool */ diff --git a/include/configs/pleb2.h b/include/configs/pleb2.h index ab9ea4fdee..ed873faca7 100644 --- a/include/configs/pleb2.h +++ b/include/configs/pleb2.h @@ -42,6 +42,9 @@ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE + /* * Size of malloc() pool */ diff --git a/include/configs/pxa255_idp.h b/include/configs/pxa255_idp.h index 5e2e7cfcc8..7485f7241c 100644 --- a/include/configs/pxa255_idp.h +++ b/include/configs/pxa255_idp.h @@ -68,6 +68,9 @@ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE + /* * Size of malloc() pool */ diff --git a/include/configs/shannon.h b/include/configs/shannon.h index c8b0b161d8..13cc5ff3b7 100644 --- a/include/configs/shannon.h +++ b/include/configs/shannon.h @@ -44,6 +44,8 @@ #define CONFIG_SHANNON 1 /* on an SHANNON/TuxScreen Board */ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE /* * Size of malloc() pool diff --git a/include/configs/trizepsiv.h b/include/configs/trizepsiv.h index c2744b5eba..49173181fb 100644 --- a/include/configs/trizepsiv.h +++ b/include/configs/trizepsiv.h @@ -47,6 +47,9 @@ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE + #define RTC /* diff --git a/include/configs/wepep250.h b/include/configs/wepep250.h index e74303da85..197ac0bbd6 100644 --- a/include/configs/wepep250.h +++ b/include/configs/wepep250.h @@ -27,6 +27,8 @@ #define CONFIG_WEPEP250 1 /* config for wepep250 board */ #undef CONFIG_USE_IRQ /* don't need use IRQ/FIQ */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE /* * Select serial console configuration diff --git a/include/configs/xaeniax.h b/include/configs/xaeniax.h index 086ca69c10..1632d29622 100644 --- a/include/configs/xaeniax.h +++ b/include/configs/xaeniax.h @@ -49,6 +49,9 @@ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE + /* * select serial console configuration */ diff --git a/include/configs/xm250.h b/include/configs/xm250.h index 922eb2c6b0..c8bdf3186b 100644 --- a/include/configs/xm250.h +++ b/include/configs/xm250.h @@ -36,6 +36,9 @@ #define CONFIG_XM250 1 /* on a MicroSys XM250 Board */ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE + /* * Size of malloc() pool; this lives below the uppermost 128 KiB which are * used for the RAM copy of the uboot code diff --git a/include/configs/xsengine.h b/include/configs/xsengine.h index cad414c1d9..7e2abbf346 100644 --- a/include/configs/xsengine.h +++ b/include/configs/xsengine.h @@ -35,6 +35,9 @@ #define CONFIG_DOS_PARTITION 1 #define BOARD_LATE_INIT 1 #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE + #define CONFIG_SYS_HZ 1000 #define CONFIG_SYS_CPUSPEED 0x161 /* set core clock to 400/200/100 MHz */ diff --git a/include/configs/zylonite.h b/include/configs/zylonite.h index 064740d3cc..217636a618 100644 --- a/include/configs/zylonite.h +++ b/include/configs/zylonite.h @@ -47,6 +47,9 @@ #undef CONFIG_SKIP_RELOCATE_UBOOT #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ +/* we will never enable dcache, because we have to setup MMU first */ +#define CONFIG_SYS_NO_DCACHE + /* * Size of malloc() pool */ diff --git a/lib_arm/Makefile b/lib_arm/Makefile index c8795b2314..3ac9d1f093 100644 --- a/lib_arm/Makefile +++ b/lib_arm/Makefile @@ -35,6 +35,9 @@ SOBJS-y += _umodsi3.o COBJS-y += board.o COBJS-y += bootm.o COBJS-y += cache.o +ifndef CONFIG_SYS_NO_CP15_CACHE +COBJS-y += cache-cp15.o +endif COBJS-y += div0.o COBJS-y += interrupts.o diff --git a/lib_arm/cache-cp15.c b/lib_arm/cache-cp15.c new file mode 100644 index 0000000000..62ed54fb4d --- /dev/null +++ b/lib_arm/cache-cp15.c @@ -0,0 +1,120 @@ +/* + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * 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 +#include + +#if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE)) +static void cp_delay (void) +{ + volatile int i; + + /* copro seems to need some delay between reading and writing */ + for (i = 0; i < 100; i++) + nop(); +} + +/* cache_bit must be either CR_I or CR_C */ +static void cache_enable(uint32_t cache_bit) +{ + uint32_t reg; + + reg = get_cr(); /* get control reg. */ + cp_delay(); + set_cr(reg | cache_bit); +} + +/* cache_bit must be either CR_I or CR_C */ +static void cache_disable(uint32_t cache_bit) +{ + uint32_t reg; + + reg = get_cr(); + cp_delay(); + set_cr(reg & ~cache_bit); +} +#endif + +#ifdef CONFIG_SYS_NO_ICACHE +void icache_enable (void) +{ + return; +} + +void icache_disable (void) +{ + return; +} + +int icache_status (void) +{ + return 0; /* always off */ +} +#else +void icache_enable(void) +{ + cache_enable(CR_I); +} + +void icache_disable(void) +{ + cache_disable(CR_I); +} + +int icache_status(void) +{ + return (get_cr() & CR_I) != 0; +} +#endif + +#ifdef CONFIG_SYS_NO_DCACHE +void dcache_enable (void) +{ + return; +} + +void dcache_disable (void) +{ + return; +} + +int dcache_status (void) +{ + return 0; /* always off */ +} +#else +void dcache_enable(void) +{ + cache_enable(CR_C); +} + +void dcache_disable(void) +{ + cache_disable(CR_C); +} + +int dcache_status(void) +{ + return (get_cr() & CR_C) != 0; +} +#endif