Commit | Line | Data |
---|---|---|
b920de1b DH |
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) | |
b920de1b DH |
30 | #ifdef CONFIG_GDBSTUB |
31 | movm [d2,d3,a2],(sp) | |
32 | #else | |
33 | or EPSW_nAR,epsw # switch D0-D3 & A0-A3 to the alternate | |
34 | # register bank | |
35 | nop | |
36 | nop | |
37 | nop | |
38 | #endif | |
39 | ||
8f19e3da AT |
40 | #if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR) |
41 | mov (MMUCTR),d2 | |
42 | mov d2,(MMUCTR) | |
43 | #endif | |
44 | ||
45 | and ~EPSW_NMID,epsw | |
b920de1b DH |
46 | mov (IPTEU),d3 |
47 | mov (PTBR),a2 | |
48 | mov d3,d2 | |
49 | and 0xffc00000,d2 | |
50 | lsr 20,d2 | |
51 | mov (a2,d2),a2 # PTD *ptd = PGD[addr 31..22] | |
52 | btst _PAGE_VALID,a2 | |
53 | beq itlb_miss_fault # jump if doesn't point anywhere | |
54 | ||
55 | and ~(PAGE_SIZE-1),a2 | |
56 | mov d3,d2 | |
57 | and 0x003ff000,d2 | |
58 | lsr 10,d2 | |
59 | add d2,a2 | |
60 | mov (a2),d2 # get pte from PTD[addr 21..12] | |
61 | btst _PAGE_VALID,d2 | |
62 | beq itlb_miss_fault # jump if doesn't point to a page | |
63 | # (might be a swap id) | |
dccbf485 | 64 | #if ((_PAGE_ACCESSED & 0xffffff00) == 0) |
b920de1b | 65 | bset _PAGE_ACCESSED,(0,a2) |
dccbf485 AT |
66 | #elif ((_PAGE_ACCESSED & 0xffff00ff) == 0) |
67 | bset +(_PAGE_ACCESSED >> 8),(1,a2) | |
68 | #else | |
69 | #error "_PAGE_ACCESSED value is out of range" | |
70 | #endif | |
71 | and ~xPTEL2_UNUSED1,d2 | |
b920de1b | 72 | itlb_miss_set: |
dccbf485 | 73 | mov d2,(IPTEL2) # change the TLB |
b920de1b DH |
74 | #ifdef CONFIG_GDBSTUB |
75 | movm (sp),[d2,d3,a2] | |
76 | #endif | |
77 | rti | |
78 | ||
79 | itlb_miss_fault: | |
80 | mov _PAGE_VALID,d2 # force address error handler to be | |
81 | # invoked | |
82 | bra itlb_miss_set | |
83 | ||
84 | .size itlb_miss, . - itlb_miss | |
85 | ||
86 | ############################################################################### | |
87 | # | |
88 | # Data TLB Miss handler entry point | |
89 | # | |
90 | ############################################################################### | |
91 | .type dtlb_miss,@function | |
92 | ENTRY(dtlb_miss) | |
b920de1b DH |
93 | #ifdef CONFIG_GDBSTUB |
94 | movm [d2,d3,a2],(sp) | |
95 | #else | |
96 | or EPSW_nAR,epsw # switch D0-D3 & A0-A3 to the alternate | |
97 | # register bank | |
98 | nop | |
99 | nop | |
100 | nop | |
101 | #endif | |
102 | ||
8f19e3da AT |
103 | #if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR) |
104 | mov (MMUCTR),d2 | |
105 | mov d2,(MMUCTR) | |
106 | #endif | |
107 | ||
108 | and ~EPSW_NMID,epsw | |
b920de1b DH |
109 | mov (DPTEU),d3 |
110 | mov (PTBR),a2 | |
111 | mov d3,d2 | |
112 | and 0xffc00000,d2 | |
113 | lsr 20,d2 | |
114 | mov (a2,d2),a2 # PTD *ptd = PGD[addr 31..22] | |
115 | btst _PAGE_VALID,a2 | |
116 | beq dtlb_miss_fault # jump if doesn't point anywhere | |
117 | ||
118 | and ~(PAGE_SIZE-1),a2 | |
119 | mov d3,d2 | |
120 | and 0x003ff000,d2 | |
121 | lsr 10,d2 | |
122 | add d2,a2 | |
123 | mov (a2),d2 # get pte from PTD[addr 21..12] | |
124 | btst _PAGE_VALID,d2 | |
125 | beq dtlb_miss_fault # jump if doesn't point to a page | |
126 | # (might be a swap id) | |
dccbf485 | 127 | #if ((_PAGE_ACCESSED & 0xffffff00) == 0) |
b920de1b | 128 | bset _PAGE_ACCESSED,(0,a2) |
dccbf485 AT |
129 | #elif ((_PAGE_ACCESSED & 0xffff00ff) == 0) |
130 | bset +(_PAGE_ACCESSED >> 8),(1,a2) | |
131 | #else | |
132 | #error "_PAGE_ACCESSED value is out of range" | |
133 | #endif | |
134 | and ~xPTEL2_UNUSED1,d2 | |
b920de1b | 135 | dtlb_miss_set: |
dccbf485 | 136 | mov d2,(DPTEL2) # change the TLB |
b920de1b DH |
137 | #ifdef CONFIG_GDBSTUB |
138 | movm (sp),[d2,d3,a2] | |
139 | #endif | |
140 | rti | |
141 | ||
142 | dtlb_miss_fault: | |
143 | mov _PAGE_VALID,d2 # force address error handler to be | |
144 | # invoked | |
145 | bra dtlb_miss_set | |
146 | .size dtlb_miss, . - dtlb_miss | |
147 | ||
148 | ############################################################################### | |
149 | # | |
150 | # Instruction TLB Address Error handler entry point | |
151 | # | |
152 | ############################################################################### | |
153 | .type itlb_aerror,@function | |
154 | ENTRY(itlb_aerror) | |
b920de1b DH |
155 | add -4,sp |
156 | SAVE_ALL | |
8f19e3da AT |
157 | |
158 | #if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR) | |
159 | mov (MMUCTR),d1 | |
160 | mov d1,(MMUCTR) | |
161 | #endif | |
162 | ||
163 | and ~EPSW_NMID,epsw | |
b920de1b DH |
164 | add -4,sp # need to pass three params |
165 | ||
166 | # calculate the fault code | |
167 | movhu (MMUFCR_IFC),d1 | |
168 | or 0x00010000,d1 # it's an instruction fetch | |
169 | ||
170 | # determine the page address | |
dccbf485 | 171 | mov (IPTEU),d0 |
b920de1b DH |
172 | and PAGE_MASK,d0 |
173 | mov d0,(12,sp) | |
174 | ||
175 | clr d0 | |
dccbf485 | 176 | mov d0,(IPTEL2) |
b920de1b | 177 | |
b920de1b DH |
178 | or EPSW_IE,epsw |
179 | mov fp,d0 | |
180 | call do_page_fault[],0 # do_page_fault(regs,code,addr | |
181 | ||
182 | jmp ret_from_exception | |
183 | .size itlb_aerror, . - itlb_aerror | |
184 | ||
185 | ############################################################################### | |
186 | # | |
187 | # Data TLB Address Error handler entry point | |
188 | # | |
189 | ############################################################################### | |
190 | .type dtlb_aerror,@function | |
191 | ENTRY(dtlb_aerror) | |
b920de1b | 192 | add -4,sp |
b920de1b | 193 | SAVE_ALL |
8f19e3da AT |
194 | |
195 | #if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR) | |
196 | mov (MMUCTR),d1 | |
197 | mov d1,(MMUCTR) | |
198 | #endif | |
199 | ||
b920de1b | 200 | add -4,sp # need to pass three params |
8f19e3da | 201 | and ~EPSW_NMID,epsw |
b920de1b DH |
202 | |
203 | # calculate the fault code | |
204 | movhu (MMUFCR_DFC),d1 | |
205 | ||
206 | # determine the page address | |
207 | mov (DPTEU),a2 | |
208 | mov a2,d0 | |
209 | and PAGE_MASK,d0 | |
210 | mov d0,(12,sp) | |
211 | ||
212 | clr d0 | |
dccbf485 | 213 | mov d0,(DPTEL2) |
b920de1b | 214 | |
b920de1b DH |
215 | or EPSW_IE,epsw |
216 | mov fp,d0 | |
217 | call do_page_fault[],0 # do_page_fault(regs,code,addr | |
218 | ||
219 | jmp ret_from_exception | |
220 | .size dtlb_aerror, . - dtlb_aerror |