aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/mm/tlb-flush.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2006-12-27 20:31:48 -0500
committerPaul Mundt <lethal@linux-sh.org>2007-02-12 20:54:44 -0500
commit26b7a78c55fbc0e23a7dc19e89fd50f200efc002 (patch)
treea830e70a57d4e9cbc669bc362db73ba5ace30d4d /arch/sh/mm/tlb-flush.c
parent7a847f819063b80cc5b38d39e8aad4d60f6ca2fd (diff)
sh: Lazy dcache writeback optimizations.
This converts the lazy dcache handling to the model described in Documentation/cachetlb.txt and drops the ptep_get_and_clear() hacks used for the aliasing dcaches on SH-4 and SH7705 in 32kB mode. As a bonus, this slightly cuts down on the cache flushing frequency. With that and the PTEA handling out of the way, the update_mmu_cache() implementations can be consolidated, and we no longer have to worry about which configuration the cache is in for the SH7705 case. And finally, explicitly disable the lazy writeback on SMP (SH-4A). Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/mm/tlb-flush.c')
-rw-r--r--arch/sh/mm/tlb-flush.c55
1 files changed, 54 insertions, 1 deletions
diff --git a/arch/sh/mm/tlb-flush.c b/arch/sh/mm/tlb-flush.c
index 73ec7f6084fa..9347534aa894 100644
--- a/arch/sh/mm/tlb-flush.c
+++ b/arch/sh/mm/tlb-flush.c
@@ -2,15 +2,17 @@
2 * TLB flushing operations for SH with an MMU. 2 * TLB flushing operations for SH with an MMU.
3 * 3 *
4 * Copyright (C) 1999 Niibe Yutaka 4 * Copyright (C) 1999 Niibe Yutaka
5 * Copyright (C) 2003 Paul Mundt 5 * Copyright (C) 2003 - 2006 Paul Mundt
6 * 6 *
7 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive 8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details. 9 * for more details.
10 */ 10 */
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/io.h>
12#include <asm/mmu_context.h> 13#include <asm/mmu_context.h>
13#include <asm/tlbflush.h> 14#include <asm/tlbflush.h>
15#include <asm/cacheflush.h>
14 16
15void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) 17void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
16{ 18{
@@ -132,3 +134,54 @@ void flush_tlb_all(void)
132 ctrl_barrier(); 134 ctrl_barrier();
133 local_irq_restore(flags); 135 local_irq_restore(flags);
134} 136}
137
138void update_mmu_cache(struct vm_area_struct *vma,
139 unsigned long address, pte_t pte)
140{
141 unsigned long flags;
142 unsigned long pteval;
143 unsigned long vpn;
144 struct page *page;
145 unsigned long pfn = pte_pfn(pte);
146 struct address_space *mapping;
147
148 if (!pfn_valid(pfn))
149 return;
150
151 page = pfn_to_page(pfn);
152 mapping = page_mapping(page);
153 if (mapping) {
154 unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
155 int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
156
157 if (dirty)
158 __flush_wback_region((void *)P1SEGADDR(phys),
159 PAGE_SIZE);
160 }
161
162 local_irq_save(flags);
163
164 /* Set PTEH register */
165 vpn = (address & MMU_VPN_MASK) | get_asid();
166 ctrl_outl(vpn, MMU_PTEH);
167
168 pteval = pte_val(pte);
169
170#ifdef CONFIG_CPU_HAS_PTEA
171 /* Set PTEA register */
172 /* TODO: make this look less hacky */
173 ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
174#endif
175
176 /* Set PTEL register */
177 pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
178#ifdef CONFIG_SH_WRITETHROUGH
179 pteval |= _PAGE_WT;
180#endif
181 /* conveniently, we want all the software flags to be 0 anyway */
182 ctrl_outl(pteval, MMU_PTEL);
183
184 /* Load the TLB */
185 asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
186 local_irq_restore(flags);
187}