diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-07-31 17:07:28 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2007-09-21 11:57:46 +0900 |
commit | e7bd34a15b85655f24d1b45edbe3bdfebf9d027e (patch) | |
tree | 051647273266582fe95dcc5cf008534c264be5ae /arch/sh/mm | |
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/mm')
-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 |
4 files changed, 38 insertions, 19 deletions
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 093d491424f..c2777555003 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -2,7 +2,6 @@ # Processor families # config CPU_SH2 - select SH_WRITETHROUGH if !CPU_SH2A bool config CPU_SH2A @@ -414,8 +413,17 @@ config SH_DIRECT_MAPPED Turn this option off for platforms that do not have a direct-mapped cache, and you have no need to run the caches in such a configuration. -config SH_WRITETHROUGH - bool "Use write-through caching" +choice + prompt "Cache mode" + default CACHE_WRITEBACK if CPU_SH2A || CPU_SH3 || CPU_SH4 + default CACHE_WRITETHROUGH if (CPU_SH2 && !CPU_SH2A) + +config CACHE_WRITEBACK + bool "Write-back" + depends on CPU_SH2A || CPU_SH3 || CPU_SH4 + +config CACHE_WRITETHROUGH + bool "Write-through" help Selecting this option will configure the caches in write-through mode, as opposed to the default write-back configuration. @@ -426,4 +434,9 @@ config SH_WRITETHROUGH If unsure, say N. +config CACHE_OFF + bool "Off" + +endchoice + endmenu diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index 4061e89d84d..e73d7f970ce 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -4,9 +4,10 @@ obj-y := init.o extable.o consistent.o -obj-$(CONFIG_CPU_SH2) += cache-sh2.o -obj-$(CONFIG_CPU_SH3) += cache-sh3.o -obj-$(CONFIG_CPU_SH4) += cache-sh4.o +cache-$(CONFIG_CPU_SH2) := cache-sh2.o +cache-$(CONFIG_CPU_SH3) := cache-sh3.o +cache-$(CONFIG_CPU_SH4) := cache-sh4.o pg-sh4.o +cache-$(CONFIG_CACHE_OFF) := mmu-y := tlb-nommu.o pg-nommu.o mmu-$(CONFIG_CPU_SH3) += fault-nommu.o @@ -14,7 +15,7 @@ mmu-$(CONFIG_CPU_SH4) += fault-nommu.o mmu-$(CONFIG_MMU) := fault.o clear_page.o copy_page.o tlb-flush.o \ ioremap.o -obj-y += $(mmu-y) +obj-y += $(cache-y) $(mmu-y) ifdef CONFIG_DEBUG_FS obj-$(CONFIG_CPU_SH4) += cache-debugfs.o @@ -22,7 +23,7 @@ endif ifdef CONFIG_MMU obj-$(CONFIG_CPU_SH3) += tlb-sh3.o -obj-$(CONFIG_CPU_SH4) += tlb-sh4.o pg-sh4.o +obj-$(CONFIG_CPU_SH4) += tlb-sh4.o obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o endif diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index a08a4a958ad..7d43758dc24 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -145,7 +145,7 @@ repeat: ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos)); -#ifdef CONFIG_SH_WRITETHROUGH +#ifdef CONFIG_CACHE_WRITETHROUGH /* * When we are in 32-bit address extended mode, CCR.CB becomes * 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 f74cf667c8f..13fde8cc717 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, unsigned long flags; unsigned long pteval; unsigned long vpn; - struct page *page; - unsigned long pfn; /* Ptrace may call this routine. */ if (vma && current->active_mm != vma->vm_mm) return; - pfn = pte_pfn(pte); - if (pfn_valid(pfn)) { - page = pfn_to_page(pfn); - if (!test_bit(PG_mapped, &page->flags)) { - unsigned long phys = pte_val(pte) & PTE_PHYS_MASK; - __flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE); - __set_bit(PG_mapped, &page->flags); +#ifndef CONFIG_CACHE_OFF + { + unsigned long pfn = pte_pfn(pte); + + if (pfn_valid(pfn)) { + struct page *page = pfn_to_page(pfn); + + if (!test_bit(PG_mapped, &page->flags)) { + unsigned long phys = pte_val(pte) & PTE_PHYS_MASK; + __flush_wback_region((void *)P1SEGADDR(phys), + PAGE_SIZE); + __set_bit(PG_mapped, &page->flags); + } } } +#endif local_irq_save(flags); @@ -66,7 +71,7 @@ void update_mmu_cache(struct vm_area_struct * vma, /* Set PTEL register */ pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */ -#ifdef CONFIG_SH_WRITETHROUGH +#ifdef CONFIG_CACHE_WRITETHROUGH pteval |= _PAGE_WT; #endif /* conveniently, we want all the software flags to be 0 anyway */ |