diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-07-31 04:07:28 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2007-09-20 22:57:46 -0400 |
commit | e7bd34a15b85655f24d1b45edbe3bdfebf9d027e (patch) | |
tree | 051647273266582fe95dcc5cf008534c264be5ae /arch/sh | |
parent | ac919986d7dfc5d1d9f5585521307f222a8ebeaf (diff) |
sh: Support explicit L1 cache disabling.
This reworks the cache mode configuration in Kconfig, and allows for
explicit selection of write-back/write-through/off configurations.
All of the cache flushing routines are optimized away for the off
case.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/kernel/cpu/init.c | 11 | ||||
-rw-r--r-- | arch/sh/kernel/sh_ksyms.c | 7 | ||||
-rw-r--r-- | arch/sh/mm/Kconfig | 19 | ||||
-rw-r--r-- | arch/sh/mm/Makefile | 11 | ||||
-rw-r--r-- | arch/sh/mm/pmb.c | 2 | ||||
-rw-r--r-- | arch/sh/mm/tlb-sh4.c | 25 |
6 files changed, 49 insertions, 26 deletions
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 9172e97dc26a..fdc245b7b043 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c | |||
@@ -143,12 +143,15 @@ static void __init cache_init(void) | |||
143 | flags &= ~CCR_CACHE_EMODE; | 143 | flags &= ~CCR_CACHE_EMODE; |
144 | #endif | 144 | #endif |
145 | 145 | ||
146 | #ifdef CONFIG_SH_WRITETHROUGH | 146 | #if defined(CONFIG_CACHE_WRITETHROUGH) |
147 | /* Turn on Write-through caching */ | 147 | /* Write-through */ |
148 | flags |= CCR_CACHE_WT; | 148 | flags |= CCR_CACHE_WT; |
149 | #else | 149 | #elif defined(CONFIG_CACHE_WRITEBACK) |
150 | /* .. or default to Write-back */ | 150 | /* Write-back */ |
151 | flags |= CCR_CACHE_CB; | 151 | flags |= CCR_CACHE_CB; |
152 | #else | ||
153 | /* Off */ | ||
154 | flags &= ~CCR_CACHE_ENABLE; | ||
152 | #endif | 155 | #endif |
153 | 156 | ||
154 | ctrl_outl(flags, CCR); | 157 | ctrl_outl(flags, CCR); |
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index 37aef0a85197..de250705c35e 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c | |||
@@ -128,7 +128,8 @@ DECLARE_EXPORT(__movstrSI12_i4); | |||
128 | #endif /* __GNUC__ == 4 */ | 128 | #endif /* __GNUC__ == 4 */ |
129 | #endif | 129 | #endif |
130 | 130 | ||
131 | #if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB) | 131 | #if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \ |
132 | defined(CONFIG_SH7705_CACHE_32KB)) | ||
132 | /* needed by some modules */ | 133 | /* needed by some modules */ |
133 | EXPORT_SYMBOL(flush_cache_all); | 134 | EXPORT_SYMBOL(flush_cache_all); |
134 | EXPORT_SYMBOL(flush_cache_range); | 135 | EXPORT_SYMBOL(flush_cache_range); |
@@ -136,8 +137,8 @@ EXPORT_SYMBOL(flush_dcache_page); | |||
136 | EXPORT_SYMBOL(__flush_purge_region); | 137 | EXPORT_SYMBOL(__flush_purge_region); |
137 | #endif | 138 | #endif |
138 | 139 | ||
139 | #if defined(CONFIG_MMU) && (defined(CONFIG_CPU_SH4) || \ | 140 | #if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \ |
140 | defined(CONFIG_SH7705_CACHE_32KB)) | 141 | (defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)) |
141 | EXPORT_SYMBOL(clear_user_page); | 142 | EXPORT_SYMBOL(clear_user_page); |
142 | #endif | 143 | #endif |
143 | 144 | ||
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 093d491424fd..c2777555003e 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig | |||
@@ -2,7 +2,6 @@ | |||
2 | # Processor families | 2 | # Processor families |
3 | # | 3 | # |
4 | config CPU_SH2 | 4 | config CPU_SH2 |
5 | select SH_WRITETHROUGH if !CPU_SH2A | ||
6 | bool | 5 | bool |
7 | 6 | ||
8 | config CPU_SH2A | 7 | config CPU_SH2A |
@@ -414,8 +413,17 @@ config SH_DIRECT_MAPPED | |||
414 | Turn this option off for platforms that do not have a direct-mapped | 413 | Turn this option off for platforms that do not have a direct-mapped |
415 | cache, and you have no need to run the caches in such a configuration. | 414 | cache, and you have no need to run the caches in such a configuration. |
416 | 415 | ||
417 | config SH_WRITETHROUGH | 416 | choice |
418 | bool "Use write-through caching" | 417 | prompt "Cache mode" |
418 | default CACHE_WRITEBACK if CPU_SH2A || CPU_SH3 || CPU_SH4 | ||
419 | default CACHE_WRITETHROUGH if (CPU_SH2 && !CPU_SH2A) | ||
420 | |||
421 | config CACHE_WRITEBACK | ||
422 | bool "Write-back" | ||
423 | depends on CPU_SH2A || CPU_SH3 || CPU_SH4 | ||
424 | |||
425 | config CACHE_WRITETHROUGH | ||
426 | bool "Write-through" | ||
419 | help | 427 | help |
420 | Selecting this option will configure the caches in write-through | 428 | Selecting this option will configure the caches in write-through |
421 | mode, as opposed to the default write-back configuration. | 429 | mode, as opposed to the default write-back configuration. |
@@ -426,4 +434,9 @@ config SH_WRITETHROUGH | |||
426 | 434 | ||
427 | If unsure, say N. | 435 | If unsure, say N. |
428 | 436 | ||
437 | config CACHE_OFF | ||
438 | bool "Off" | ||
439 | |||
440 | endchoice | ||
441 | |||
429 | endmenu | 442 | endmenu |
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index 4061e89d84d0..e73d7f970ce0 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile | |||
@@ -4,9 +4,10 @@ | |||
4 | 4 | ||
5 | obj-y := init.o extable.o consistent.o | 5 | obj-y := init.o extable.o consistent.o |
6 | 6 | ||
7 | obj-$(CONFIG_CPU_SH2) += cache-sh2.o | 7 | cache-$(CONFIG_CPU_SH2) := cache-sh2.o |
8 | obj-$(CONFIG_CPU_SH3) += cache-sh3.o | 8 | cache-$(CONFIG_CPU_SH3) := cache-sh3.o |
9 | obj-$(CONFIG_CPU_SH4) += cache-sh4.o | 9 | cache-$(CONFIG_CPU_SH4) := cache-sh4.o pg-sh4.o |
10 | cache-$(CONFIG_CACHE_OFF) := | ||
10 | 11 | ||
11 | mmu-y := tlb-nommu.o pg-nommu.o | 12 | mmu-y := tlb-nommu.o pg-nommu.o |
12 | mmu-$(CONFIG_CPU_SH3) += fault-nommu.o | 13 | mmu-$(CONFIG_CPU_SH3) += fault-nommu.o |
@@ -14,7 +15,7 @@ mmu-$(CONFIG_CPU_SH4) += fault-nommu.o | |||
14 | mmu-$(CONFIG_MMU) := fault.o clear_page.o copy_page.o tlb-flush.o \ | 15 | mmu-$(CONFIG_MMU) := fault.o clear_page.o copy_page.o tlb-flush.o \ |
15 | ioremap.o | 16 | ioremap.o |
16 | 17 | ||
17 | obj-y += $(mmu-y) | 18 | obj-y += $(cache-y) $(mmu-y) |
18 | 19 | ||
19 | ifdef CONFIG_DEBUG_FS | 20 | ifdef CONFIG_DEBUG_FS |
20 | obj-$(CONFIG_CPU_SH4) += cache-debugfs.o | 21 | obj-$(CONFIG_CPU_SH4) += cache-debugfs.o |
@@ -22,7 +23,7 @@ endif | |||
22 | 23 | ||
23 | ifdef CONFIG_MMU | 24 | ifdef CONFIG_MMU |
24 | obj-$(CONFIG_CPU_SH3) += tlb-sh3.o | 25 | obj-$(CONFIG_CPU_SH3) += tlb-sh3.o |
25 | obj-$(CONFIG_CPU_SH4) += tlb-sh4.o pg-sh4.o | 26 | obj-$(CONFIG_CPU_SH4) += tlb-sh4.o |
26 | obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o | 27 | obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o |
27 | endif | 28 | endif |
28 | 29 | ||
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index a08a4a958add..7d43758dc244 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c | |||
@@ -145,7 +145,7 @@ repeat: | |||
145 | 145 | ||
146 | ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos)); | 146 | ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos)); |
147 | 147 | ||
148 | #ifdef CONFIG_SH_WRITETHROUGH | 148 | #ifdef CONFIG_CACHE_WRITETHROUGH |
149 | /* | 149 | /* |
150 | * When we are in 32-bit address extended mode, CCR.CB becomes | 150 | * When we are in 32-bit address extended mode, CCR.CB becomes |
151 | * invalid, so care must be taken to manually adjust cacheable | 151 | * invalid, so care must be taken to manually adjust cacheable |
diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c index f74cf667c8fa..13fde8cc7179 100644 --- a/arch/sh/mm/tlb-sh4.c +++ b/arch/sh/mm/tlb-sh4.c | |||
@@ -34,22 +34,27 @@ void update_mmu_cache(struct vm_area_struct * vma, | |||
34 | unsigned long flags; | 34 | unsigned long flags; |
35 | unsigned long pteval; | 35 | unsigned long pteval; |
36 | unsigned long vpn; | 36 | unsigned long vpn; |
37 | struct page *page; | ||
38 | unsigned long pfn; | ||
39 | 37 | ||
40 | /* Ptrace may call this routine. */ | 38 | /* Ptrace may call this routine. */ |
41 | if (vma && current->active_mm != vma->vm_mm) | 39 | if (vma && current->active_mm != vma->vm_mm) |
42 | return; | 40 | return; |
43 | 41 | ||
44 | pfn = pte_pfn(pte); | 42 | #ifndef CONFIG_CACHE_OFF |
45 | if (pfn_valid(pfn)) { | 43 | { |
46 | page = pfn_to_page(pfn); | 44 | unsigned long pfn = pte_pfn(pte); |
47 | if (!test_bit(PG_mapped, &page->flags)) { | 45 | |
48 | unsigned long phys = pte_val(pte) & PTE_PHYS_MASK; | 46 | if (pfn_valid(pfn)) { |
49 | __flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE); | 47 | struct page *page = pfn_to_page(pfn); |
50 | __set_bit(PG_mapped, &page->flags); | 48 | |
49 | if (!test_bit(PG_mapped, &page->flags)) { | ||
50 | unsigned long phys = pte_val(pte) & PTE_PHYS_MASK; | ||
51 | __flush_wback_region((void *)P1SEGADDR(phys), | ||
52 | PAGE_SIZE); | ||
53 | __set_bit(PG_mapped, &page->flags); | ||
54 | } | ||
51 | } | 55 | } |
52 | } | 56 | } |
57 | #endif | ||
53 | 58 | ||
54 | local_irq_save(flags); | 59 | local_irq_save(flags); |
55 | 60 | ||
@@ -66,7 +71,7 @@ void update_mmu_cache(struct vm_area_struct * vma, | |||
66 | 71 | ||
67 | /* Set PTEL register */ | 72 | /* Set PTEL register */ |
68 | pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */ | 73 | pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */ |
69 | #ifdef CONFIG_SH_WRITETHROUGH | 74 | #ifdef CONFIG_CACHE_WRITETHROUGH |
70 | pteval |= _PAGE_WT; | 75 | pteval |= _PAGE_WT; |
71 | #endif | 76 | #endif |
72 | /* conveniently, we want all the software flags to be 0 anyway */ | 77 | /* conveniently, we want all the software flags to be 0 anyway */ |