summaryrefslogtreecommitdiffstats
path: root/arch/mips64/kernel/r4k_tlb.S
diff options
context:
space:
mode:
authorKanoj Sarcar <kanoj@engr.sgi.com>2000-06-30 00:48:29 +0000
committerKanoj Sarcar <kanoj@engr.sgi.com>2000-06-30 00:48:29 +0000
commit72d92cedc30af23d855fec53b04d9266d88c6671 (patch)
treea3d02ad3d35bc5939c34c0527daba0793c799ab9 /arch/mips64/kernel/r4k_tlb.S
parent706a11128cbe9c614436350e5ff807b6d6ac79ea (diff)
Implement a functional vmalloc(). THe vmalloc range address translations
are stashed in an array of page tables, starting from kptbl[]. The fast tlbmiss handler quickly checks to see if the faulting address is in the vmalloc range, and if so, it uses the translations in the kptbl to update the tlbs. Still to do: tlb invalid faults in the vmalloc range needs to be handled properly.
Diffstat (limited to 'arch/mips64/kernel/r4k_tlb.S')
-rw-r--r--arch/mips64/kernel/r4k_tlb.S59
1 files changed, 54 insertions, 5 deletions
diff --git a/arch/mips64/kernel/r4k_tlb.S b/arch/mips64/kernel/r4k_tlb.S
index 2baa35ca1..54c4b934b 100644
--- a/arch/mips64/kernel/r4k_tlb.S
+++ b/arch/mips64/kernel/r4k_tlb.S
@@ -1,4 +1,4 @@
-/* $Id: r4k_tlb.S,v 1.1 2000/05/25 19:33:16 ulfc Exp $
+/* $Id: r4k_tlb.S,v 1.2 2000/06/13 23:48:20 kanoj Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -33,13 +33,14 @@
#endif
dmfc0 \tmp, CP0_BADVADDR
ld \ptr, (\ptr)
- dsrl \tmp, 28 # get pgd offset
- andi \tmp, 0x1ff8
+ bltz \tmp, kaddr
+ dsrl \tmp, (PGDIR_SHIFT-3) # get pgd offset in bytes
+ andi \tmp, ((PTRS_PER_PGD - 1)<<3)
daddu \ptr, \tmp # add in pgd offset
dmfc0 \tmp, CP0_BADVADDR
ld \ptr, (\ptr) # get pmd pointer
- dsrl \tmp, 18 # get pmd offset
- andi \tmp, 0x1ff8
+ dsrl \tmp, (PMD_SHIFT-3) # get pmd offset in bytes
+ andi \tmp, ((PTRS_PER_PMD - 1)<<3)
daddu \ptr, \tmp # add in pmd offset
dmfc0 \tmp, CP0_XCONTEXT
ld \ptr, (\ptr) # get pte pointer
@@ -82,3 +83,51 @@ FEXPORT(except_vec1_r10k)
nop
tlbwr
eret
+kaddr:
+ dla k0, handle_vmalloc_address # MAPPED kernel needs this
+ jr k0
+ nop
+
+ .align 5
+FEXPORT(handle_vmalloc_address)
+ .set noat
+ /*
+ * First, determine that the address is in/above vmalloc range.
+ */
+ dmfc0 k0, CP0_BADVADDR
+ dli k1, VMALLOC_START
+ sltu k1, k0, k1
+ bne k1, zero, not_vmalloc
+ dli k1, VMALLOC_START
+
+ /*
+ * Now find offset into kptbl.
+ */
+ dsubu k0, k0, k1
+ dla k1, kptbl
+ dsrl k0, (PAGE_SHIFT+1) # get vpn2
+ dsll k0, 4 # byte offset of pte
+ daddu k1, k1, k0
+
+ /*
+ * Determine that fault address is within vmalloc range.
+ */
+ dla k0, ekptbl
+ sltu k0, k1, k0
+ beq k0, zero, not_vmalloc
+
+ /*
+ * Load cp0 registers.
+ */
+ ld k0, 0(k1) # get even pte
+ ld k1, 8(k1) # get odd pte
+1:
+ PTE_RELOAD k0 k1
+ nop
+ tlbwr
+ eret
+not_vmalloc:
+ daddu k0, zero, zero
+ daddu k1, zero, zero
+ j 1b
+ nop