Merge git://git.infradead.org/users/willy/linux-nvme
[deliverable/linux.git] / arch / xtensa / include / asm / tlbflush.h
CommitLineData
9a8fd558 1/*
9a8fd558
CZ
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
f615136c 6 * Copyright (C) 2001 - 2013 Tensilica Inc.
9a8fd558
CZ
7 */
8
9#ifndef _XTENSA_TLBFLUSH_H
10#define _XTENSA_TLBFLUSH_H
11
9a8fd558 12#include <linux/stringify.h>
173d6681
CZ
13#include <asm/processor.h>
14
15#define DTLB_WAY_PGD 7
16
17#define ITLB_ARF_WAYS 4
18#define DTLB_ARF_WAYS 4
19
20#define ITLB_HIT_BIT 3
21#define DTLB_HIT_BIT 4
22
23#ifndef __ASSEMBLY__
9a8fd558
CZ
24
25/* TLB flushing:
26 *
27 * - flush_tlb_all() flushes all processes TLB entries
28 * - flush_tlb_mm(mm) flushes the specified mm context TLB entries
29 * - flush_tlb_page(mm, vmaddr) flushes a single page
30 * - flush_tlb_range(mm, start, end) flushes a range of pages
31 */
32
f615136c
MF
33void local_flush_tlb_all(void);
34void local_flush_tlb_mm(struct mm_struct *mm);
35void local_flush_tlb_page(struct vm_area_struct *vma,
36 unsigned long page);
37void local_flush_tlb_range(struct vm_area_struct *vma,
38 unsigned long start, unsigned long end);
39
40#ifdef CONFIG_SMP
41
42void flush_tlb_all(void);
43void flush_tlb_mm(struct mm_struct *);
44void flush_tlb_page(struct vm_area_struct *, unsigned long);
45void flush_tlb_range(struct vm_area_struct *, unsigned long,
46 unsigned long);
47
48static inline void flush_tlb_kernel_range(unsigned long start,
49 unsigned long end)
50{
51 flush_tlb_all();
52}
53
54#else /* !CONFIG_SMP */
55
56#define flush_tlb_all() local_flush_tlb_all()
57#define flush_tlb_mm(mm) local_flush_tlb_mm(mm)
58#define flush_tlb_page(vma, page) local_flush_tlb_page(vma, page)
59#define flush_tlb_range(vma, vmaddr, end) local_flush_tlb_range(vma, vmaddr, \
60 end)
61#define flush_tlb_kernel_range(start, end) local_flush_tlb_all()
9a8fd558 62
f615136c 63#endif /* CONFIG_SMP */
9a8fd558 64
9a8fd558
CZ
65/* TLB operations. */
66
d99cf715 67static inline unsigned long itlb_probe(unsigned long addr)
9a8fd558
CZ
68{
69 unsigned long tmp;
70 __asm__ __volatile__("pitlb %0, %1\n\t" : "=a" (tmp) : "a" (addr));
71 return tmp;
72}
73
d99cf715 74static inline unsigned long dtlb_probe(unsigned long addr)
9a8fd558
CZ
75{
76 unsigned long tmp;
77 __asm__ __volatile__("pdtlb %0, %1\n\t" : "=a" (tmp) : "a" (addr));
78 return tmp;
79}
80
d99cf715 81static inline void invalidate_itlb_entry (unsigned long probe)
9a8fd558
CZ
82{
83 __asm__ __volatile__("iitlb %0; isync\n\t" : : "a" (probe));
84}
85
d99cf715 86static inline void invalidate_dtlb_entry (unsigned long probe)
9a8fd558
CZ
87{
88 __asm__ __volatile__("idtlb %0; dsync\n\t" : : "a" (probe));
89}
90
91/* Use the .._no_isync functions with caution. Generally, these are
92 * handy for bulk invalidates followed by a single 'isync'. The
93 * caller must follow up with an 'isync', which can be relatively
94 * expensive on some Xtensa implementations.
95 */
d99cf715 96static inline void invalidate_itlb_entry_no_isync (unsigned entry)
9a8fd558
CZ
97{
98 /* Caller must follow up with 'isync'. */
99 __asm__ __volatile__ ("iitlb %0\n" : : "a" (entry) );
100}
101
d99cf715 102static inline void invalidate_dtlb_entry_no_isync (unsigned entry)
9a8fd558
CZ
103{
104 /* Caller must follow up with 'isync'. */
105 __asm__ __volatile__ ("idtlb %0\n" : : "a" (entry) );
106}
107
d99cf715 108static inline void set_itlbcfg_register (unsigned long val)
9a8fd558 109{
bc5378fc 110 __asm__ __volatile__("wsr %0, itlbcfg\n\t" "isync\n\t"
9a8fd558
CZ
111 : : "a" (val));
112}
113
d99cf715 114static inline void set_dtlbcfg_register (unsigned long val)
9a8fd558 115{
bc5378fc 116 __asm__ __volatile__("wsr %0, dtlbcfg; dsync\n\t"
9a8fd558
CZ
117 : : "a" (val));
118}
119
d99cf715 120static inline void set_ptevaddr_register (unsigned long val)
9a8fd558 121{
bc5378fc 122 __asm__ __volatile__(" wsr %0, ptevaddr; isync\n"
9a8fd558
CZ
123 : : "a" (val));
124}
125
d99cf715 126static inline unsigned long read_ptevaddr_register (void)
9a8fd558
CZ
127{
128 unsigned long tmp;
bc5378fc 129 __asm__ __volatile__("rsr %0, ptevaddr\n\t" : "=a" (tmp));
9a8fd558
CZ
130 return tmp;
131}
132
d99cf715 133static inline void write_dtlb_entry (pte_t entry, int way)
9a8fd558
CZ
134{
135 __asm__ __volatile__("wdtlb %1, %0; dsync\n\t"
136 : : "r" (way), "r" (entry) );
137}
138
d99cf715 139static inline void write_itlb_entry (pte_t entry, int way)
9a8fd558
CZ
140{
141 __asm__ __volatile__("witlb %1, %0; isync\n\t"
142 : : "r" (way), "r" (entry) );
143}
144
d99cf715 145static inline void invalidate_page_directory (void)
9a8fd558 146{
173d6681
CZ
147 invalidate_dtlb_entry (DTLB_WAY_PGD);
148 invalidate_dtlb_entry (DTLB_WAY_PGD+1);
149 invalidate_dtlb_entry (DTLB_WAY_PGD+2);
9a8fd558
CZ
150}
151
d99cf715 152static inline void invalidate_itlb_mapping (unsigned address)
9a8fd558
CZ
153{
154 unsigned long tlb_entry;
173d6681
CZ
155 if (((tlb_entry = itlb_probe(address)) & (1 << ITLB_HIT_BIT)) != 0)
156 invalidate_itlb_entry(tlb_entry);
9a8fd558
CZ
157}
158
d99cf715 159static inline void invalidate_dtlb_mapping (unsigned address)
9a8fd558
CZ
160{
161 unsigned long tlb_entry;
173d6681
CZ
162 if (((tlb_entry = dtlb_probe(address)) & (1 << DTLB_HIT_BIT)) != 0)
163 invalidate_dtlb_entry(tlb_entry);
9a8fd558
CZ
164}
165
166#define check_pgt_cache() do { } while (0)
167
168
173d6681
CZ
169/*
170 * DO NOT USE THESE FUNCTIONS. These instructions aren't part of the Xtensa
9a8fd558
CZ
171 * ISA and exist only for test purposes..
172 * You may find it helpful for MMU debugging, however.
173 *
174 * 'at' is the unmodified input register
175 * 'as' is the output register, as follows (specific to the Linux config):
176 *
177 * as[31..12] contain the virtual address
178 * as[11..08] are meaningless
179 * as[07..00] contain the asid
180 */
181
d99cf715 182static inline unsigned long read_dtlb_virtual (int way)
9a8fd558
CZ
183{
184 unsigned long tmp;
185 __asm__ __volatile__("rdtlb0 %0, %1\n\t" : "=a" (tmp), "+a" (way));
186 return tmp;
187}
188
d99cf715 189static inline unsigned long read_dtlb_translation (int way)
9a8fd558
CZ
190{
191 unsigned long tmp;
192 __asm__ __volatile__("rdtlb1 %0, %1\n\t" : "=a" (tmp), "+a" (way));
193 return tmp;
194}
195
d99cf715 196static inline unsigned long read_itlb_virtual (int way)
9a8fd558
CZ
197{
198 unsigned long tmp;
199 __asm__ __volatile__("ritlb0 %0, %1\n\t" : "=a" (tmp), "+a" (way));
200 return tmp;
201}
202
d99cf715 203static inline unsigned long read_itlb_translation (int way)
9a8fd558
CZ
204{
205 unsigned long tmp;
206 __asm__ __volatile__("ritlb1 %0, %1\n\t" : "=a" (tmp), "+a" (way));
207 return tmp;
208}
209
173d6681 210#endif /* __ASSEMBLY__ */
173d6681 211#endif /* _XTENSA_TLBFLUSH_H */
This page took 0.913584 seconds and 5 git commands to generate.