aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/mm
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-03-17 04:49:49 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-03-17 04:49:49 -0400
commit8263a67e169fdf0d06d172acbf6c03ae172a69d4 (patch)
treecdfefd2d72c7854101287a9e39e3ad97cad6cb5b /arch/sh/mm
parentda78800632197ac12adcdefbf09991d82adb8201 (diff)
sh: Support for extended ASIDs on PTEAEX-capable SH-X3 cores.
This adds support for extended ASIDs (up to 16-bits) on newer SH-X3 cores that implement the PTAEX register and respective functionality. Presently only the 65nm SH7786 (90nm only supports legacy 8-bit ASIDs). The main change is in how the PTE is written out when loading the entry in to the TLB, as well as in how the TLB entry is selectively flushed. While SH-X2 extended mode splits out the memory-mapped U and I-TLB data arrays for extra bits, extended ASID mode splits out the address arrays. While we don't use the memory-mapped data array access, the address array accesses are necessary for selective TLB flushes, so these are implemented newly and replace the generic SH-4 implementation. With this, TLB flushes in switch_mm() are almost non-existent on newer parts. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/mm')
-rw-r--r--arch/sh/mm/Makefile_326
-rw-r--r--arch/sh/mm/tlb-pteaex.c99
2 files changed, 103 insertions, 2 deletions
diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32
index 469ff1672451..986a1e055834 100644
--- a/arch/sh/mm/Makefile_32
+++ b/arch/sh/mm/Makefile_32
@@ -25,8 +25,10 @@ obj-$(CONFIG_CPU_SH4) += cache-debugfs.o
25endif 25endif
26 26
27ifdef CONFIG_MMU 27ifdef CONFIG_MMU
28obj-$(CONFIG_CPU_SH3) += tlb-sh3.o 28tlb-$(CONFIG_CPU_SH3) := tlb-sh3.o
29obj-$(CONFIG_CPU_SH4) += tlb-sh4.o 29tlb-$(CONFIG_CPU_SH4) := tlb-sh4.o
30tlb-$(CONFIG_CPU_HAS_PTEAEX) := tlb-pteaex.o
31obj-y += $(tlb-y)
30ifndef CONFIG_CACHE_OFF 32ifndef CONFIG_CACHE_OFF
31obj-$(CONFIG_CPU_SH4) += pg-sh4.o 33obj-$(CONFIG_CPU_SH4) += pg-sh4.o
32obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o 34obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o
diff --git a/arch/sh/mm/tlb-pteaex.c b/arch/sh/mm/tlb-pteaex.c
new file mode 100644
index 000000000000..5c9b2d781e08
--- /dev/null
+++ b/arch/sh/mm/tlb-pteaex.c
@@ -0,0 +1,99 @@
1/*
2 * arch/sh/mm/tlb-pteaex.c
3 *
4 * TLB operations for SH-X3 CPUs featuring PTE ASID Extensions.
5 *
6 * Copyright (C) 2009 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/kernel.h>
13#include <linux/mm.h>
14#include <linux/io.h>
15#include <asm/system.h>
16#include <asm/mmu_context.h>
17#include <asm/cacheflush.h>
18
19void update_mmu_cache(struct vm_area_struct * vma,
20 unsigned long address, pte_t pte)
21{
22 unsigned long flags;
23 unsigned long pteval;
24 unsigned long vpn;
25
26 /* Ptrace may call this routine. */
27 if (vma && current->active_mm != vma->vm_mm)
28 return;
29
30#ifndef CONFIG_CACHE_OFF
31 {
32 unsigned long pfn = pte_pfn(pte);
33
34 if (pfn_valid(pfn)) {
35 struct page *page = pfn_to_page(pfn);
36
37 if (!test_bit(PG_mapped, &page->flags)) {
38 unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
39 __flush_wback_region((void *)P1SEGADDR(phys),
40 PAGE_SIZE);
41 __set_bit(PG_mapped, &page->flags);
42 }
43 }
44 }
45#endif
46
47 local_irq_save(flags);
48
49 /* Set PTEH register */
50 vpn = address & MMU_VPN_MASK;
51 __raw_writel(vpn, MMU_PTEH);
52
53 /* Set PTEAEX */
54 __raw_writel(get_asid(), MMU_PTEAEX);
55
56 pteval = pte.pte_low;
57
58 /* Set PTEA register */
59#ifdef CONFIG_X2TLB
60 /*
61 * For the extended mode TLB this is trivial, only the ESZ and
62 * EPR bits need to be written out to PTEA, with the remainder of
63 * the protection bits (with the exception of the compat-mode SZ
64 * and PR bits, which are cleared) being written out in PTEL.
65 */
66 __raw_writel(pte.pte_high, MMU_PTEA);
67#else
68 /* TODO: make this look less hacky */
69 __raw_writel(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
70#endif
71
72 /* Set PTEL register */
73 pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
74#ifdef CONFIG_CACHE_WRITETHROUGH
75 pteval |= _PAGE_WT;
76#endif
77 /* conveniently, we want all the software flags to be 0 anyway */
78 __raw_writel(pteval, MMU_PTEL);
79
80 /* Load the TLB */
81 asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
82 local_irq_restore(flags);
83}
84
85/*
86 * While SH-X2 extended TLB mode splits out the memory-mapped I/UTLB
87 * data arrays, SH-X3 cores with PTEAEX split out the memory-mapped
88 * address arrays. In compat mode the second array is inaccessible, while
89 * in extended mode, the legacy 8-bit ASID field in address array 1 has
90 * undefined behaviour.
91 */
92void __uses_jump_to_uncached local_flush_tlb_one(unsigned long asid,
93 unsigned long page)
94{
95 jump_to_uncached();
96 __raw_writel(page, MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT);
97 __raw_writel(asid, MMU_UTLB_ADDRESS_ARRAY2 | MMU_PAGE_ASSOC_BIT);
98 back_to_cached();
99}