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
6 * Copyright (C) 2000 Silicon Graphics, Inc.
7 * Written by Ulf Carlsson (ulfc@engr.sgi.com)
8 * Copyright (C) 2002 Maciej W. Rozycki
10 #include <linux/config.h>
11 #include <linux/init.h>
12 #include <linux/threads.h>
14 #include <asm/regdef.h>
15 #include <asm/mipsregs.h>
16 #include <asm/pgtable.h>
17 #include <asm/stackframe.h>
21 .comm pgd_current, NR_CPUS * 8, 8
24 * After this macro runs we have a pointer to the pte of the address
25 * that caused the fault in PTR.
27 .macro LOAD_PTE2, ptr, tmp, kaddr
29 dmfc0 \ptr, CP0_CONTEXT
30 dmfc0 \tmp, CP0_BADVADDR
31 dsra \ptr, 23 # get pgd_current[cpu]
33 dmfc0 \tmp, CP0_BADVADDR
38 dsrl \tmp, (PGDIR_SHIFT-3) # get pgd offset in bytes
39 andi \tmp, ((PTRS_PER_PGD - 1)<<3)
40 daddu \ptr, \tmp # add in pgd offset
41 dmfc0 \tmp, CP0_BADVADDR
42 ld \ptr, (\ptr) # get pmd pointer
43 dsrl \tmp, (PMD_SHIFT-3) # get pmd offset in bytes
44 andi \tmp, ((PTRS_PER_PMD - 1)<<3)
45 daddu \ptr, \tmp # add in pmd offset
46 dmfc0 \tmp, CP0_XCONTEXT
47 ld \ptr, (\ptr) # get pte pointer
48 andi \tmp, 0xff0 # get pte offset
54 * Ditto for the kernel table.
56 .macro LOAD_KPTE2, ptr, tmp, not_vmalloc
58 * First, determine that the address is in/above vmalloc range.
60 dmfc0 \tmp, CP0_BADVADDR
61 dli \ptr, VMALLOC_START
64 * Now find offset into kptbl.
66 dsubu \tmp, \tmp, \ptr
68 dsrl \tmp, (PAGE_SHIFT+1) # get vpn2
69 dsll \tmp, 4 # byte offset of pte
70 daddu \ptr, \ptr, \tmp
73 * Determine that fault address is within vmalloc range.
77 beqz \tmp, \not_vmalloc # not vmalloc
83 * This places the even/odd pte pair in the page table at the pte
84 * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1.
86 .macro PTE_RELOAD, pte0, pte1
87 dsrl \pte0, 6 # convert to entrylo0
88 dmtc0 \pte0, CP0_ENTRYLO0 # load it
89 dsrl \pte1, 6 # convert to entrylo1
90 dmtc0 \pte1, CP0_ENTRYLO1 # load it
101 LEAF(except_vec0_generic)
103 PANIC("Unused vector called")
106 END(except_vec0_generic)
110 * TLB refill handlers for the R4000 and SB1.
111 * Attention: We may only use 32 instructions / 128 bytes.
114 LEAF(except_vec1_r4k)
116 dla k0, handle_vec1_r4k
121 LEAF(except_vec1_sb1)
123 dmfc0 k0, CP0_BADVADDR
124 dmfc0 k1, CP0_ENTRYHI
126 dsrl k0, k0, PAGE_SHIFT+1
130 dla k0, handle_vec1_r4k
141 LEAF(handle_vec1_r4k)
144 ld k0, 0(k1) # get even pte
145 ld k1, 8(k1) # get odd pte
152 9: # handle the vmalloc range
153 LOAD_KPTE2 k1 k0 invalid_vmalloc_address
154 ld k0, 0(k1) # get even pte
155 ld k1, 8(k1) # get odd pte
167 * TLB refill handler for the R10000.
168 * Attention: We may only use 32 instructions / 128 bytes.
171 LEAF(except_vec1_r10k)
173 dla k0, handle_vec1_r10k
176 END(except_vec1_r10k)
181 LEAF(handle_vec1_r10k)
184 ld k0, 0(k1) # get even pte
185 ld k1, 8(k1) # get odd pte
191 9: # handle the vmalloc range
192 LOAD_KPTE2 k1 k0 invalid_vmalloc_address
193 ld k0, 0(k1) # get even pte
194 ld k1, 8(k1) # get odd pte
199 END(handle_vec1_r10k)
203 LEAF(invalid_vmalloc_address)
205 PANIC("Invalid kernel address")
208 END(invalid_vmalloc_address)