diff options
Diffstat (limited to 'arch/sh/mm/tlb-sh5.c')
-rw-r--r-- | arch/sh/mm/tlb-sh5.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/arch/sh/mm/tlb-sh5.c b/arch/sh/mm/tlb-sh5.c index fdb64e41ec50..f27dbe1c1599 100644 --- a/arch/sh/mm/tlb-sh5.c +++ b/arch/sh/mm/tlb-sh5.c | |||
@@ -143,3 +143,42 @@ void sh64_setup_tlb_slot(unsigned long long config_addr, unsigned long eaddr, | |||
143 | */ | 143 | */ |
144 | void sh64_teardown_tlb_slot(unsigned long long config_addr) | 144 | void sh64_teardown_tlb_slot(unsigned long long config_addr) |
145 | __attribute__ ((alias("__flush_tlb_slot"))); | 145 | __attribute__ ((alias("__flush_tlb_slot"))); |
146 | |||
147 | static int dtlb_entry; | ||
148 | static unsigned long long dtlb_entries[64]; | ||
149 | |||
150 | void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte) | ||
151 | { | ||
152 | unsigned long long entry; | ||
153 | unsigned long paddr, flags; | ||
154 | |||
155 | BUG_ON(dtlb_entry == ARRAY_SIZE(dtlb_entries)); | ||
156 | |||
157 | local_irq_save(flags); | ||
158 | |||
159 | entry = sh64_get_wired_dtlb_entry(); | ||
160 | dtlb_entries[dtlb_entry++] = entry; | ||
161 | |||
162 | paddr = pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK; | ||
163 | paddr &= ~PAGE_MASK; | ||
164 | |||
165 | sh64_setup_tlb_slot(entry, addr, get_asid(), paddr); | ||
166 | |||
167 | local_irq_restore(flags); | ||
168 | } | ||
169 | |||
170 | void tlb_unwire_entry(void) | ||
171 | { | ||
172 | unsigned long long entry; | ||
173 | unsigned long flags; | ||
174 | |||
175 | BUG_ON(!dtlb_entry); | ||
176 | |||
177 | local_irq_save(flags); | ||
178 | entry = dtlb_entries[dtlb_entry--]; | ||
179 | |||
180 | sh64_teardown_tlb_slot(entry); | ||
181 | sh64_put_wired_dtlb_entry(entry); | ||
182 | |||
183 | local_irq_restore(flags); | ||
184 | } | ||