diff options
author | Richard Curnow <richard.curnow@st.com> | 2006-09-27 14:09:26 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2006-09-27 14:09:26 +0900 |
commit | b638d0b921dc95229af0dfd09cd24850336a2f75 (patch) | |
tree | 0ef34527a47b22421fb92ba2141052fecfe36482 /arch/sh/kernel | |
parent | fdfc74f9fcebdda14609159d5010b758a9409acf (diff) |
sh: Optimized cache handling for SH-4/SH-4A caches.
This reworks some of the SH-4 cache handling code to more easily
accomodate newer-style caches (particularly for the > direct-mapped
case), as well as optimizing some of the old code.
Signed-off-by: Richard Curnow <richard.curnow@st.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/cpu/init.c | 16 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/probe.c | 11 |
2 files changed, 26 insertions, 1 deletions
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 868e68b28880..731dd61419dd 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -4,6 +4,7 @@ * CPU init code * * Copyright (C) 2002, 2003 Paul Mundt + * Copyright (C) 2003 Richard Curnow * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -51,7 +52,15 @@ static void __init cache_init(void) ccr = ctrl_inl(CCR); /* - * If the cache is already enabled .. flush it. + * At this point we don't know whether the cache is enabled or not - a + * bootloader may have enabled it. There are at least 2 things that + * could be dirty in the cache at this point: + * 1. kernel command line set up by boot loader + * 2. spilled registers from the prolog of this function + * => before re-initialising the cache, we must do a purge of the whole + * cache out to memory for safety. As long as nothing is spilled + * during the loop to lines that have already been done, this is safe. + * - RPC */ if (ccr & CCR_CACHE_ENABLE) { unsigned long ways, waysize, addrstart; @@ -98,6 +107,8 @@ static void __init cache_init(void) /* Force EMODE if possible */ if (cpu_data->dcache.ways > 1) flags |= CCR_CACHE_EMODE; + else + flags &= ~CCR_CACHE_EMODE; #endif #ifdef CONFIG_SH_WRITETHROUGH @@ -112,6 +123,9 @@ static void __init cache_init(void) /* Turn on OCRAM -- halve the OC */ flags |= CCR_CACHE_ORA; cpu_data->dcache.sets >>= 1; + + cpu_data->dcache.way_size = cpu_data->dcache.sets * + cpu_data->dcache.linesz; #endif ctrl_outl(flags, CCR); diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index 42427b79697b..1208da8fe5db 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -113,6 +113,11 @@ int __init detect_cpu_and_cache_system(void) break; } +#ifdef CONFIG_SH_DIRECT_MAPPED + cpu_data->icache.ways = 1; + cpu_data->dcache.ways = 1; +#endif + /* * On anything that's not a direct-mapped cache, look to the CVR * for I/D-cache specifics. @@ -125,6 +130,9 @@ int __init detect_cpu_and_cache_system(void) (cpu_data->icache.way_incr - (1 << 5)); } + cpu_data->icache.way_size = cpu_data->icache.sets * + cpu_data->icache.linesz; + if (cpu_data->dcache.ways > 1) { size = sizes[(cvr >> 16) & 0xf]; cpu_data->dcache.way_incr = (size >> 1); @@ -133,6 +141,9 @@ int __init detect_cpu_and_cache_system(void) (cpu_data->dcache.way_incr - (1 << 5)); } + cpu_data->dcache.way_size = cpu_data->dcache.sets * + cpu_data->dcache.linesz; + return 0; } |