diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-30 00:44:45 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-30 00:44:45 +0400 |
commit | 8d231c11fd0b694c447e59e687754b6999eea0a2 (patch) | |
tree | b0b3c17efff7018bbf948e489f642c8079f33cc0 /arch/mips/mm/c-r4k.c | |
parent | 1f1332f727c3229eb2166a83fec5d3de6a73dce2 (diff) | |
parent | 8db089c6b5594c961fb6bc6d613b9926e0d3d98f (diff) | |
download | linux-8d231c11fd0b694c447e59e687754b6999eea0a2.tar.xz |
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (33 commits)
[MIPS] Add missing backslashes to macro definitions.
[MIPS] Death list of board support to be removed after 2.6.18.
[MIPS] Remove BSD and Sys V compat data types.
[MIPS] ioc3.h: Uses u8, so include <linux/types.h>.
[MIPS] 74K: Assume it will also have an AR bit in config7
[MIPS] Treat CPUs with AR bit as physically indexed.
[MIPS] Oprofile: Support VSMP on 34K.
[MIPS] MIPS32/MIPS64 S-cache fix and cleanup
[MIPS] excite: PCI makefile needs to use += if it wants a chance to work.
[MIPS] excite: plat_setup -> plat_mem_setup.
[MIPS] au1xxx: export dbdma functions
[MIPS] au1xxx: dbdma, no sleeping under spin_lock
[MIPS] au1xxx: fix PSC_SMBTXRX_RSR.
[MIPS] Early printk for IP27.
[MIPS] Fix handling of 0 length I & D caches.
[MIPS] Typo fixes.
[MIPS] MIPS32/MIPS64 secondary cache management
[MIPS] Fix FIXADDR_TOP for TX39/TX49.
[MIPS] Remove first timer interrupt setup in wrppmc_timer_setup()
[MIPS] Fix configuration of R2 CPU features and multithreading.
...
Diffstat (limited to 'arch/mips/mm/c-r4k.c')
-rw-r--r-- | arch/mips/mm/c-r4k.c | 99 |
1 files changed, 68 insertions, 31 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 4a43924cd4fc..75d887e89739 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -60,13 +60,13 @@ static unsigned long scache_size __read_mostly; /* * Dummy cache handling routines for machines without boardcaches */ -static void no_sc_noop(void) {} +static void cache_noop(void) {} static struct bcache_ops no_sc_ops = { - .bc_enable = (void *)no_sc_noop, - .bc_disable = (void *)no_sc_noop, - .bc_wback_inv = (void *)no_sc_noop, - .bc_inv = (void *)no_sc_noop + .bc_enable = (void *)cache_noop, + .bc_disable = (void *)cache_noop, + .bc_wback_inv = (void *)cache_noop, + .bc_inv = (void *)cache_noop }; struct bcache_ops *bcops = &no_sc_ops; @@ -94,7 +94,9 @@ static inline void r4k_blast_dcache_page_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); - if (dc_lsize == 16) + if (dc_lsize == 0) + r4k_blast_dcache_page = (void *)cache_noop; + else if (dc_lsize == 16) r4k_blast_dcache_page = blast_dcache16_page; else if (dc_lsize == 32) r4k_blast_dcache_page = r4k_blast_dcache_page_dc32; @@ -106,7 +108,9 @@ static inline void r4k_blast_dcache_page_indexed_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); - if (dc_lsize == 16) + if (dc_lsize == 0) + r4k_blast_dcache_page_indexed = (void *)cache_noop; + else if (dc_lsize == 16) r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed; else if (dc_lsize == 32) r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed; @@ -118,7 +122,9 @@ static inline void r4k_blast_dcache_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); - if (dc_lsize == 16) + if (dc_lsize == 0) + r4k_blast_dcache = (void *)cache_noop; + else if (dc_lsize == 16) r4k_blast_dcache = blast_dcache16; else if (dc_lsize == 32) r4k_blast_dcache = blast_dcache32; @@ -201,7 +207,9 @@ static inline void r4k_blast_icache_page_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); - if (ic_lsize == 16) + if (ic_lsize == 0) + r4k_blast_icache_page = (void *)cache_noop; + else if (ic_lsize == 16) r4k_blast_icache_page = blast_icache16_page; else if (ic_lsize == 32) r4k_blast_icache_page = blast_icache32_page; @@ -216,7 +224,9 @@ static inline void r4k_blast_icache_page_indexed_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); - if (ic_lsize == 16) + if (ic_lsize == 0) + r4k_blast_icache_page_indexed = (void *)cache_noop; + else if (ic_lsize == 16) r4k_blast_icache_page_indexed = blast_icache16_page_indexed; else if (ic_lsize == 32) { if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x()) @@ -238,7 +248,9 @@ static inline void r4k_blast_icache_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); - if (ic_lsize == 16) + if (ic_lsize == 0) + r4k_blast_icache = (void *)cache_noop; + else if (ic_lsize == 16) r4k_blast_icache = blast_icache16; else if (ic_lsize == 32) { if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x()) @@ -258,7 +270,7 @@ static inline void r4k_blast_scache_page_setup(void) unsigned long sc_lsize = cpu_scache_line_size(); if (scache_size == 0) - r4k_blast_scache_page = (void *)no_sc_noop; + r4k_blast_scache_page = (void *)cache_noop; else if (sc_lsize == 16) r4k_blast_scache_page = blast_scache16_page; else if (sc_lsize == 32) @@ -276,7 +288,7 @@ static inline void r4k_blast_scache_page_indexed_setup(void) unsigned long sc_lsize = cpu_scache_line_size(); if (scache_size == 0) - r4k_blast_scache_page_indexed = (void *)no_sc_noop; + r4k_blast_scache_page_indexed = (void *)cache_noop; else if (sc_lsize == 16) r4k_blast_scache_page_indexed = blast_scache16_page_indexed; else if (sc_lsize == 32) @@ -294,7 +306,7 @@ static inline void r4k_blast_scache_setup(void) unsigned long sc_lsize = cpu_scache_line_size(); if (scache_size == 0) - r4k_blast_scache = (void *)no_sc_noop; + r4k_blast_scache = (void *)cache_noop; else if (sc_lsize == 16) r4k_blast_scache = blast_scache16; else if (sc_lsize == 32) @@ -508,7 +520,7 @@ static inline void local_r4k_flush_icache_range(void *args) unsigned long end = fir_args->end; if (!cpu_has_ic_fills_f_dc) { - if (end - start > dcache_size) { + if (end - start >= dcache_size) { r4k_blast_dcache(); } else { R4600_HIT_CACHEOP_WAR_IMPL; @@ -683,10 +695,12 @@ static void local_r4k_flush_cache_sigtramp(void * arg) unsigned long addr = (unsigned long) arg; R4600_HIT_CACHEOP_WAR_IMPL; - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); + if (dc_lsize) + protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); if (!cpu_icache_snoops_remote_store && scache_size) protected_writeback_scache_line(addr & ~(sc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); + if (ic_lsize) + protected_flush_icache_line(addr & ~(ic_lsize - 1)); if (MIPS4K_ICACHE_REFILL_WAR) { __asm__ __volatile__ ( ".set push\n\t" @@ -973,8 +987,10 @@ static void __init probe_pcache(void) c->icache.waysize = icache_size / c->icache.ways; c->dcache.waysize = dcache_size / c->dcache.ways; - c->icache.sets = icache_size / (c->icache.linesz * c->icache.ways); - c->dcache.sets = dcache_size / (c->dcache.linesz * c->dcache.ways); + c->icache.sets = c->icache.linesz ? + icache_size / (c->icache.linesz * c->icache.ways) : 0; + c->dcache.sets = c->dcache.linesz ? + dcache_size / (c->dcache.linesz * c->dcache.ways) : 0; /* * R10000 and R12000 P-caches are odd in a positive way. They're 32kB @@ -993,10 +1009,16 @@ static void __init probe_pcache(void) break; case CPU_24K: case CPU_34K: - if (!(read_c0_config7() & (1 << 16))) + case CPU_74K: + if ((read_c0_config7() & (1 << 16))) { + /* effectively physically indexed dcache, + thus no virtual aliases. */ + c->dcache.flags |= MIPS_CACHE_PINDEX; + break; + } default: - if (c->dcache.waysize > PAGE_SIZE) - c->dcache.flags |= MIPS_CACHE_ALIASES; + if (c->dcache.waysize > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; } switch (c->cputype) { @@ -1092,6 +1114,7 @@ static int __init probe_scache(void) extern int r5k_sc_init(void); extern int rm7k_sc_init(void); +extern int mips_sc_init(void); static void __init setup_scache(void) { @@ -1139,17 +1162,29 @@ static void __init setup_scache(void) return; default: + if (c->isa_level == MIPS_CPU_ISA_M32R1 || + c->isa_level == MIPS_CPU_ISA_M32R2 || + c->isa_level == MIPS_CPU_ISA_M64R1 || + c->isa_level == MIPS_CPU_ISA_M64R2) { +#ifdef CONFIG_MIPS_CPU_SCACHE + if (mips_sc_init ()) { + scache_size = c->scache.ways * c->scache.sets * c->scache.linesz; + printk("MIPS secondary cache %ldkB, %s, linesize %d bytes.\n", + scache_size >> 10, + way_string[c->scache.ways], c->scache.linesz); + } +#else + if (!(c->scache.flags & MIPS_CACHE_NOT_PRESENT)) + panic("Dunno how to handle MIPS32 / MIPS64 second level cache"); +#endif + return; + } sc_present = 0; } if (!sc_present) return; - if ((c->isa_level == MIPS_CPU_ISA_M32R1 || - c->isa_level == MIPS_CPU_ISA_M64R1) && - !(c->scache.flags & MIPS_CACHE_NOT_PRESENT)) - panic("Dunno how to handle MIPS32 / MIPS64 second level cache"); - /* compute a couple of other cache variables */ c->scache.waysize = scache_size / c->scache.ways; @@ -1246,10 +1281,12 @@ void __init r4k_cache_init(void) * This code supports virtually indexed processors and will be * unnecessarily inefficient on physically indexed processors. */ - shm_align_mask = max_t( unsigned long, - c->dcache.sets * c->dcache.linesz - 1, - PAGE_SIZE - 1); - + if (c->dcache.linesz) + shm_align_mask = max_t( unsigned long, + c->dcache.sets * c->dcache.linesz - 1, + PAGE_SIZE - 1); + else + shm_align_mask = PAGE_SIZE-1; flush_cache_all = r4k_flush_cache_all; __flush_cache_all = r4k___flush_cache_all; flush_cache_mm = r4k_flush_cache_mm; |