diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-01-19 09:20:35 +0300 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-01-19 09:20:35 +0300 |
commit | bb29c677b366fdf4f6522cd82228a32567aa98c7 (patch) | |
tree | 0235c7477ed635c8c21131b90094d151663ae889 /arch/sh/mm/tlb-sh5.c | |
parent | 046581f9623b53f551a93864bb74e15ad2514f0c (diff) | |
download | linux-bb29c677b366fdf4f6522cd82228a32567aa98c7.tar.xz |
sh: Split out MMUCR.URB based entry wiring in to shared helper.
Presently this is duplicated between tlb-sh4 and tlb-pteaex. Split the
helpers out in to a generic tlb-urb that can be used by any parts
equipped with MMUCR.URB.
At the same time, move the SH-5 code out-of-line, as we require single
global state for DTLB entry wiring.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
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, */ 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); +} |