summaryrefslogtreecommitdiffstats
path: root/arch/sh/mm/tlb-sh5.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/mm/tlb-sh5.c')
-rw-r--r--arch/sh/mm/tlb-sh5.c39
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,
*/
void sh64_teardown_tlb_slot(unsigned long long config_addr)
__attribute__ ((alias("__flush_tlb_slot")));
+
+static int dtlb_entry;
+static unsigned long long dtlb_entries[64];
+
+void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
+{
+ unsigned long long entry;
+ unsigned long paddr, flags;
+
+ BUG_ON(dtlb_entry == ARRAY_SIZE(dtlb_entries));
+
+ local_irq_save(flags);
+
+ entry = sh64_get_wired_dtlb_entry();
+ dtlb_entries[dtlb_entry++] = entry;
+
+ paddr = pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK;
+ paddr &= ~PAGE_MASK;
+
+ sh64_setup_tlb_slot(entry, addr, get_asid(), paddr);
+
+ local_irq_restore(flags);
+}
+
+void tlb_unwire_entry(void)
+{
+ unsigned long long entry;
+ unsigned long flags;
+
+ BUG_ON(!dtlb_entry);
+
+ local_irq_save(flags);
+ entry = dtlb_entries[dtlb_entry--];
+
+ sh64_teardown_tlb_slot(entry);
+ sh64_put_wired_dtlb_entry(entry);
+
+ local_irq_restore(flags);
+}