diff options
Diffstat (limited to 'arch/mn10300/mm/tlb-mn10300.S')
-rw-r--r-- | arch/mn10300/mm/tlb-mn10300.S | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/arch/mn10300/mm/tlb-mn10300.S b/arch/mn10300/mm/tlb-mn10300.S new file mode 100644 index 000000000000..789208094e98 --- /dev/null +++ b/arch/mn10300/mm/tlb-mn10300.S | |||
@@ -0,0 +1,207 @@ | |||
1 | ############################################################################### | ||
2 | # | ||
3 | # TLB loading functions | ||
4 | # | ||
5 | # Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. | ||
6 | # Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | ||
7 | # Modified by David Howells (dhowells@redhat.com) | ||
8 | # | ||
9 | # This program is free software; you can redistribute it and/or | ||
10 | # modify it under the terms of the GNU General Public Licence | ||
11 | # as published by the Free Software Foundation; either version | ||
12 | # 2 of the Licence, or (at your option) any later version. | ||
13 | # | ||
14 | ############################################################################### | ||
15 | #include <linux/sys.h> | ||
16 | #include <linux/linkage.h> | ||
17 | #include <asm/smp.h> | ||
18 | #include <asm/intctl-regs.h> | ||
19 | #include <asm/frame.inc> | ||
20 | #include <asm/page.h> | ||
21 | #include <asm/pgtable.h> | ||
22 | |||
23 | ############################################################################### | ||
24 | # | ||
25 | # Instruction TLB Miss handler entry point | ||
26 | # | ||
27 | ############################################################################### | ||
28 | .type itlb_miss,@function | ||
29 | ENTRY(itlb_miss) | ||
30 | and ~EPSW_NMID,epsw | ||
31 | #ifdef CONFIG_GDBSTUB | ||
32 | movm [d2,d3,a2],(sp) | ||
33 | #else | ||
34 | or EPSW_nAR,epsw # switch D0-D3 & A0-A3 to the alternate | ||
35 | # register bank | ||
36 | nop | ||
37 | nop | ||
38 | nop | ||
39 | #endif | ||
40 | |||
41 | mov (IPTEU),d3 | ||
42 | mov (PTBR),a2 | ||
43 | mov d3,d2 | ||
44 | and 0xffc00000,d2 | ||
45 | lsr 20,d2 | ||
46 | mov (a2,d2),a2 # PTD *ptd = PGD[addr 31..22] | ||
47 | btst _PAGE_VALID,a2 | ||
48 | beq itlb_miss_fault # jump if doesn't point anywhere | ||
49 | |||
50 | and ~(PAGE_SIZE-1),a2 | ||
51 | mov d3,d2 | ||
52 | and 0x003ff000,d2 | ||
53 | lsr 10,d2 | ||
54 | add d2,a2 | ||
55 | mov (a2),d2 # get pte from PTD[addr 21..12] | ||
56 | btst _PAGE_VALID,d2 | ||
57 | beq itlb_miss_fault # jump if doesn't point to a page | ||
58 | # (might be a swap id) | ||
59 | bset _PAGE_ACCESSED,(0,a2) | ||
60 | and ~(xPTEL_UNUSED1|xPTEL_UNUSED2),d2 | ||
61 | itlb_miss_set: | ||
62 | mov d2,(IPTEL) # change the TLB | ||
63 | #ifdef CONFIG_GDBSTUB | ||
64 | movm (sp),[d2,d3,a2] | ||
65 | #endif | ||
66 | rti | ||
67 | |||
68 | itlb_miss_fault: | ||
69 | mov _PAGE_VALID,d2 # force address error handler to be | ||
70 | # invoked | ||
71 | bra itlb_miss_set | ||
72 | |||
73 | .size itlb_miss, . - itlb_miss | ||
74 | |||
75 | ############################################################################### | ||
76 | # | ||
77 | # Data TLB Miss handler entry point | ||
78 | # | ||
79 | ############################################################################### | ||
80 | .type dtlb_miss,@function | ||
81 | ENTRY(dtlb_miss) | ||
82 | and ~EPSW_NMID,epsw | ||
83 | #ifdef CONFIG_GDBSTUB | ||
84 | movm [d2,d3,a2],(sp) | ||
85 | #else | ||
86 | or EPSW_nAR,epsw # switch D0-D3 & A0-A3 to the alternate | ||
87 | # register bank | ||
88 | nop | ||
89 | nop | ||
90 | nop | ||
91 | #endif | ||
92 | |||
93 | mov (DPTEU),d3 | ||
94 | mov (PTBR),a2 | ||
95 | mov d3,d2 | ||
96 | and 0xffc00000,d2 | ||
97 | lsr 20,d2 | ||
98 | mov (a2,d2),a2 # PTD *ptd = PGD[addr 31..22] | ||
99 | btst _PAGE_VALID,a2 | ||
100 | beq dtlb_miss_fault # jump if doesn't point anywhere | ||
101 | |||
102 | and ~(PAGE_SIZE-1),a2 | ||
103 | mov d3,d2 | ||
104 | and 0x003ff000,d2 | ||
105 | lsr 10,d2 | ||
106 | add d2,a2 | ||
107 | mov (a2),d2 # get pte from PTD[addr 21..12] | ||
108 | btst _PAGE_VALID,d2 | ||
109 | beq dtlb_miss_fault # jump if doesn't point to a page | ||
110 | # (might be a swap id) | ||
111 | bset _PAGE_ACCESSED,(0,a2) | ||
112 | and ~(xPTEL_UNUSED1|xPTEL_UNUSED2),d2 | ||
113 | dtlb_miss_set: | ||
114 | mov d2,(DPTEL) # change the TLB | ||
115 | #ifdef CONFIG_GDBSTUB | ||
116 | movm (sp),[d2,d3,a2] | ||
117 | #endif | ||
118 | rti | ||
119 | |||
120 | dtlb_miss_fault: | ||
121 | mov _PAGE_VALID,d2 # force address error handler to be | ||
122 | # invoked | ||
123 | bra dtlb_miss_set | ||
124 | .size dtlb_miss, . - dtlb_miss | ||
125 | |||
126 | ############################################################################### | ||
127 | # | ||
128 | # Instruction TLB Address Error handler entry point | ||
129 | # | ||
130 | ############################################################################### | ||
131 | .type itlb_aerror,@function | ||
132 | ENTRY(itlb_aerror) | ||
133 | and ~EPSW_NMID,epsw | ||
134 | add -4,sp | ||
135 | SAVE_ALL | ||
136 | add -4,sp # need to pass three params | ||
137 | |||
138 | # calculate the fault code | ||
139 | movhu (MMUFCR_IFC),d1 | ||
140 | or 0x00010000,d1 # it's an instruction fetch | ||
141 | |||
142 | # determine the page address | ||
143 | mov (IPTEU),a2 | ||
144 | mov a2,d0 | ||
145 | and PAGE_MASK,d0 | ||
146 | mov d0,(12,sp) | ||
147 | |||
148 | clr d0 | ||
149 | mov d0,(IPTEL) | ||
150 | |||
151 | and ~EPSW_NMID,epsw | ||
152 | or EPSW_IE,epsw | ||
153 | mov fp,d0 | ||
154 | call do_page_fault[],0 # do_page_fault(regs,code,addr | ||
155 | |||
156 | jmp ret_from_exception | ||
157 | .size itlb_aerror, . - itlb_aerror | ||
158 | |||
159 | ############################################################################### | ||
160 | # | ||
161 | # Data TLB Address Error handler entry point | ||
162 | # | ||
163 | ############################################################################### | ||
164 | .type dtlb_aerror,@function | ||
165 | ENTRY(dtlb_aerror) | ||
166 | and ~EPSW_NMID,epsw | ||
167 | add -4,sp | ||
168 | mov d1,(sp) | ||
169 | |||
170 | movhu (MMUFCR_DFC),d1 # is it the initial valid write | ||
171 | # to this page? | ||
172 | and MMUFCR_xFC_INITWR,d1 | ||
173 | beq dtlb_pagefault # jump if not | ||
174 | |||
175 | mov (DPTEL),d1 # set the dirty bit | ||
176 | # (don't replace with BSET!) | ||
177 | or _PAGE_DIRTY,d1 | ||
178 | mov d1,(DPTEL) | ||
179 | mov (sp),d1 | ||
180 | add 4,sp | ||
181 | rti | ||
182 | |||
183 | ALIGN | ||
184 | dtlb_pagefault: | ||
185 | mov (sp),d1 | ||
186 | SAVE_ALL | ||
187 | add -4,sp # need to pass three params | ||
188 | |||
189 | # calculate the fault code | ||
190 | movhu (MMUFCR_DFC),d1 | ||
191 | |||
192 | # determine the page address | ||
193 | mov (DPTEU),a2 | ||
194 | mov a2,d0 | ||
195 | and PAGE_MASK,d0 | ||
196 | mov d0,(12,sp) | ||
197 | |||
198 | clr d0 | ||
199 | mov d0,(DPTEL) | ||
200 | |||
201 | and ~EPSW_NMID,epsw | ||
202 | or EPSW_IE,epsw | ||
203 | mov fp,d0 | ||
204 | call do_page_fault[],0 # do_page_fault(regs,code,addr | ||
205 | |||
206 | jmp ret_from_exception | ||
207 | .size dtlb_aerror, . - dtlb_aerror | ||