diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/mips/kernel/gdb-low.S |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/mips/kernel/gdb-low.S')
-rw-r--r-- | arch/mips/kernel/gdb-low.S | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/arch/mips/kernel/gdb-low.S b/arch/mips/kernel/gdb-low.S new file mode 100644 index 000000000000..ece6ddaf7011 --- /dev/null +++ b/arch/mips/kernel/gdb-low.S | |||
@@ -0,0 +1,370 @@ | |||
1 | /* | ||
2 | * gdb-low.S contains the low-level trap handler for the GDB stub. | ||
3 | * | ||
4 | * Copyright (C) 1995 Andreas Busse | ||
5 | */ | ||
6 | #include <linux/config.h> | ||
7 | #include <linux/sys.h> | ||
8 | |||
9 | #include <asm/asm.h> | ||
10 | #include <asm/errno.h> | ||
11 | #include <asm/mipsregs.h> | ||
12 | #include <asm/regdef.h> | ||
13 | #include <asm/stackframe.h> | ||
14 | #include <asm/gdb-stub.h> | ||
15 | |||
16 | #ifdef CONFIG_MIPS32 | ||
17 | #define DMFC0 mfc0 | ||
18 | #define DMTC0 mtc0 | ||
19 | #define LDC1 lwc1 | ||
20 | #define SDC1 lwc1 | ||
21 | #endif | ||
22 | #ifdef CONFIG_MIPS64 | ||
23 | #define DMFC0 dmfc0 | ||
24 | #define DMTC0 dmtc0 | ||
25 | #define LDC1 ldc1 | ||
26 | #define SDC1 ldc1 | ||
27 | #endif | ||
28 | |||
29 | /* | ||
30 | * [jsun] We reserves about 2x GDB_FR_SIZE in stack. The lower (addressed) | ||
31 | * part is used to store registers and passed to exception handler. | ||
32 | * The upper part is reserved for "call func" feature where gdb client | ||
33 | * saves some of the regs, setups call frame and passes args. | ||
34 | * | ||
35 | * A trace shows about 200 bytes are used to store about half of all regs. | ||
36 | * The rest should be big enough for frame setup and passing args. | ||
37 | */ | ||
38 | |||
39 | /* | ||
40 | * The low level trap handler | ||
41 | */ | ||
42 | .align 5 | ||
43 | NESTED(trap_low, GDB_FR_SIZE, sp) | ||
44 | .set noat | ||
45 | .set noreorder | ||
46 | |||
47 | mfc0 k0, CP0_STATUS | ||
48 | sll k0, 3 /* extract cu0 bit */ | ||
49 | bltz k0, 1f | ||
50 | move k1, sp | ||
51 | |||
52 | /* | ||
53 | * Called from user mode, go somewhere else. | ||
54 | */ | ||
55 | lui k1, %hi(saved_vectors) | ||
56 | mfc0 k0, CP0_CAUSE | ||
57 | andi k0, k0, 0x7c | ||
58 | add k1, k1, k0 | ||
59 | lw k0, %lo(saved_vectors)(k1) | ||
60 | jr k0 | ||
61 | nop | ||
62 | 1: | ||
63 | move k0, sp | ||
64 | subu sp, k1, GDB_FR_SIZE*2 # see comment above | ||
65 | LONG_S k0, GDB_FR_REG29(sp) | ||
66 | LONG_S $2, GDB_FR_REG2(sp) | ||
67 | |||
68 | /* | ||
69 | * First save the CP0 and special registers | ||
70 | */ | ||
71 | |||
72 | mfc0 v0, CP0_STATUS | ||
73 | LONG_S v0, GDB_FR_STATUS(sp) | ||
74 | mfc0 v0, CP0_CAUSE | ||
75 | LONG_S v0, GDB_FR_CAUSE(sp) | ||
76 | DMFC0 v0, CP0_EPC | ||
77 | LONG_S v0, GDB_FR_EPC(sp) | ||
78 | DMFC0 v0, CP0_BADVADDR | ||
79 | LONG_S v0, GDB_FR_BADVADDR(sp) | ||
80 | mfhi v0 | ||
81 | LONG_S v0, GDB_FR_HI(sp) | ||
82 | mflo v0 | ||
83 | LONG_S v0, GDB_FR_LO(sp) | ||
84 | |||
85 | /* | ||
86 | * Now the integer registers | ||
87 | */ | ||
88 | |||
89 | LONG_S zero, GDB_FR_REG0(sp) /* I know... */ | ||
90 | LONG_S $1, GDB_FR_REG1(sp) | ||
91 | /* v0 already saved */ | ||
92 | LONG_S $3, GDB_FR_REG3(sp) | ||
93 | LONG_S $4, GDB_FR_REG4(sp) | ||
94 | LONG_S $5, GDB_FR_REG5(sp) | ||
95 | LONG_S $6, GDB_FR_REG6(sp) | ||
96 | LONG_S $7, GDB_FR_REG7(sp) | ||
97 | LONG_S $8, GDB_FR_REG8(sp) | ||
98 | LONG_S $9, GDB_FR_REG9(sp) | ||
99 | LONG_S $10, GDB_FR_REG10(sp) | ||
100 | LONG_S $11, GDB_FR_REG11(sp) | ||
101 | LONG_S $12, GDB_FR_REG12(sp) | ||
102 | LONG_S $13, GDB_FR_REG13(sp) | ||
103 | LONG_S $14, GDB_FR_REG14(sp) | ||
104 | LONG_S $15, GDB_FR_REG15(sp) | ||
105 | LONG_S $16, GDB_FR_REG16(sp) | ||
106 | LONG_S $17, GDB_FR_REG17(sp) | ||
107 | LONG_S $18, GDB_FR_REG18(sp) | ||
108 | LONG_S $19, GDB_FR_REG19(sp) | ||
109 | LONG_S $20, GDB_FR_REG20(sp) | ||
110 | LONG_S $21, GDB_FR_REG21(sp) | ||
111 | LONG_S $22, GDB_FR_REG22(sp) | ||
112 | LONG_S $23, GDB_FR_REG23(sp) | ||
113 | LONG_S $24, GDB_FR_REG24(sp) | ||
114 | LONG_S $25, GDB_FR_REG25(sp) | ||
115 | LONG_S $26, GDB_FR_REG26(sp) | ||
116 | LONG_S $27, GDB_FR_REG27(sp) | ||
117 | LONG_S $28, GDB_FR_REG28(sp) | ||
118 | /* sp already saved */ | ||
119 | LONG_S $30, GDB_FR_REG30(sp) | ||
120 | LONG_S $31, GDB_FR_REG31(sp) | ||
121 | |||
122 | CLI /* disable interrupts */ | ||
123 | |||
124 | /* | ||
125 | * Followed by the floating point registers | ||
126 | */ | ||
127 | mfc0 v0, CP0_STATUS /* FPU enabled? */ | ||
128 | srl v0, v0, 16 | ||
129 | andi v0, v0, (ST0_CU1 >> 16) | ||
130 | |||
131 | beqz v0,2f /* disabled, skip */ | ||
132 | nop | ||
133 | |||
134 | SDC1 $0, GDB_FR_FPR0(sp) | ||
135 | SDC1 $1, GDB_FR_FPR1(sp) | ||
136 | SDC1 $2, GDB_FR_FPR2(sp) | ||
137 | SDC1 $3, GDB_FR_FPR3(sp) | ||
138 | SDC1 $4, GDB_FR_FPR4(sp) | ||
139 | SDC1 $5, GDB_FR_FPR5(sp) | ||
140 | SDC1 $6, GDB_FR_FPR6(sp) | ||
141 | SDC1 $7, GDB_FR_FPR7(sp) | ||
142 | SDC1 $8, GDB_FR_FPR8(sp) | ||
143 | SDC1 $9, GDB_FR_FPR9(sp) | ||
144 | SDC1 $10, GDB_FR_FPR10(sp) | ||
145 | SDC1 $11, GDB_FR_FPR11(sp) | ||
146 | SDC1 $12, GDB_FR_FPR12(sp) | ||
147 | SDC1 $13, GDB_FR_FPR13(sp) | ||
148 | SDC1 $14, GDB_FR_FPR14(sp) | ||
149 | SDC1 $15, GDB_FR_FPR15(sp) | ||
150 | SDC1 $16, GDB_FR_FPR16(sp) | ||
151 | SDC1 $17, GDB_FR_FPR17(sp) | ||
152 | SDC1 $18, GDB_FR_FPR18(sp) | ||
153 | SDC1 $19, GDB_FR_FPR19(sp) | ||
154 | SDC1 $20, GDB_FR_FPR20(sp) | ||
155 | SDC1 $21, GDB_FR_FPR21(sp) | ||
156 | SDC1 $22, GDB_FR_FPR22(sp) | ||
157 | SDC1 $23, GDB_FR_FPR23(sp) | ||
158 | SDC1 $24, GDB_FR_FPR24(sp) | ||
159 | SDC1 $25, GDB_FR_FPR25(sp) | ||
160 | SDC1 $26, GDB_FR_FPR26(sp) | ||
161 | SDC1 $27, GDB_FR_FPR27(sp) | ||
162 | SDC1 $28, GDB_FR_FPR28(sp) | ||
163 | SDC1 $29, GDB_FR_FPR29(sp) | ||
164 | SDC1 $30, GDB_FR_FPR30(sp) | ||
165 | SDC1 $31, GDB_FR_FPR31(sp) | ||
166 | |||
167 | /* | ||
168 | * FPU control registers | ||
169 | */ | ||
170 | |||
171 | cfc1 v0, CP1_STATUS | ||
172 | LONG_S v0, GDB_FR_FSR(sp) | ||
173 | cfc1 v0, CP1_REVISION | ||
174 | LONG_S v0, GDB_FR_FIR(sp) | ||
175 | |||
176 | /* | ||
177 | * Current stack frame ptr | ||
178 | */ | ||
179 | |||
180 | 2: | ||
181 | LONG_S sp, GDB_FR_FRP(sp) | ||
182 | |||
183 | /* | ||
184 | * CP0 registers (R4000/R4400 unused registers skipped) | ||
185 | */ | ||
186 | |||
187 | mfc0 v0, CP0_INDEX | ||
188 | LONG_S v0, GDB_FR_CP0_INDEX(sp) | ||
189 | mfc0 v0, CP0_RANDOM | ||
190 | LONG_S v0, GDB_FR_CP0_RANDOM(sp) | ||
191 | DMFC0 v0, CP0_ENTRYLO0 | ||
192 | LONG_S v0, GDB_FR_CP0_ENTRYLO0(sp) | ||
193 | DMFC0 v0, CP0_ENTRYLO1 | ||
194 | LONG_S v0, GDB_FR_CP0_ENTRYLO1(sp) | ||
195 | DMFC0 v0, CP0_CONTEXT | ||
196 | LONG_S v0, GDB_FR_CP0_CONTEXT(sp) | ||
197 | mfc0 v0, CP0_PAGEMASK | ||
198 | LONG_S v0, GDB_FR_CP0_PAGEMASK(sp) | ||
199 | mfc0 v0, CP0_WIRED | ||
200 | LONG_S v0, GDB_FR_CP0_WIRED(sp) | ||
201 | DMFC0 v0, CP0_ENTRYHI | ||
202 | LONG_S v0, GDB_FR_CP0_ENTRYHI(sp) | ||
203 | mfc0 v0, CP0_PRID | ||
204 | LONG_S v0, GDB_FR_CP0_PRID(sp) | ||
205 | |||
206 | .set at | ||
207 | |||
208 | /* | ||
209 | * Continue with the higher level handler | ||
210 | */ | ||
211 | |||
212 | move a0,sp | ||
213 | |||
214 | jal handle_exception | ||
215 | nop | ||
216 | |||
217 | /* | ||
218 | * Restore all writable registers, in reverse order | ||
219 | */ | ||
220 | |||
221 | .set noat | ||
222 | |||
223 | LONG_L v0, GDB_FR_CP0_ENTRYHI(sp) | ||
224 | LONG_L v1, GDB_FR_CP0_WIRED(sp) | ||
225 | DMTC0 v0, CP0_ENTRYHI | ||
226 | mtc0 v1, CP0_WIRED | ||
227 | LONG_L v0, GDB_FR_CP0_PAGEMASK(sp) | ||
228 | LONG_L v1, GDB_FR_CP0_ENTRYLO1(sp) | ||
229 | mtc0 v0, CP0_PAGEMASK | ||
230 | DMTC0 v1, CP0_ENTRYLO1 | ||
231 | LONG_L v0, GDB_FR_CP0_ENTRYLO0(sp) | ||
232 | LONG_L v1, GDB_FR_CP0_INDEX(sp) | ||
233 | DMTC0 v0, CP0_ENTRYLO0 | ||
234 | LONG_L v0, GDB_FR_CP0_CONTEXT(sp) | ||
235 | mtc0 v1, CP0_INDEX | ||
236 | DMTC0 v0, CP0_CONTEXT | ||
237 | |||
238 | |||
239 | /* | ||
240 | * Next, the floating point registers | ||
241 | */ | ||
242 | mfc0 v0, CP0_STATUS /* check if the FPU is enabled */ | ||
243 | srl v0, v0, 16 | ||
244 | andi v0, v0, (ST0_CU1 >> 16) | ||
245 | |||
246 | beqz v0, 3f /* disabled, skip */ | ||
247 | nop | ||
248 | |||
249 | LDC1 $31, GDB_FR_FPR31(sp) | ||
250 | LDC1 $30, GDB_FR_FPR30(sp) | ||
251 | LDC1 $29, GDB_FR_FPR29(sp) | ||
252 | LDC1 $28, GDB_FR_FPR28(sp) | ||
253 | LDC1 $27, GDB_FR_FPR27(sp) | ||
254 | LDC1 $26, GDB_FR_FPR26(sp) | ||
255 | LDC1 $25, GDB_FR_FPR25(sp) | ||
256 | LDC1 $24, GDB_FR_FPR24(sp) | ||
257 | LDC1 $23, GDB_FR_FPR23(sp) | ||
258 | LDC1 $22, GDB_FR_FPR22(sp) | ||
259 | LDC1 $21, GDB_FR_FPR21(sp) | ||
260 | LDC1 $20, GDB_FR_FPR20(sp) | ||
261 | LDC1 $19, GDB_FR_FPR19(sp) | ||
262 | LDC1 $18, GDB_FR_FPR18(sp) | ||
263 | LDC1 $17, GDB_FR_FPR17(sp) | ||
264 | LDC1 $16, GDB_FR_FPR16(sp) | ||
265 | LDC1 $15, GDB_FR_FPR15(sp) | ||
266 | LDC1 $14, GDB_FR_FPR14(sp) | ||
267 | LDC1 $13, GDB_FR_FPR13(sp) | ||
268 | LDC1 $12, GDB_FR_FPR12(sp) | ||
269 | LDC1 $11, GDB_FR_FPR11(sp) | ||
270 | LDC1 $10, GDB_FR_FPR10(sp) | ||
271 | LDC1 $9, GDB_FR_FPR9(sp) | ||
272 | LDC1 $8, GDB_FR_FPR8(sp) | ||
273 | LDC1 $7, GDB_FR_FPR7(sp) | ||
274 | LDC1 $6, GDB_FR_FPR6(sp) | ||
275 | LDC1 $5, GDB_FR_FPR5(sp) | ||
276 | LDC1 $4, GDB_FR_FPR4(sp) | ||
277 | LDC1 $3, GDB_FR_FPR3(sp) | ||
278 | LDC1 $2, GDB_FR_FPR2(sp) | ||
279 | LDC1 $1, GDB_FR_FPR1(sp) | ||
280 | LDC1 $0, GDB_FR_FPR0(sp) | ||
281 | |||
282 | /* | ||
283 | * Now the CP0 and integer registers | ||
284 | */ | ||
285 | |||
286 | 3: | ||
287 | mfc0 t0, CP0_STATUS | ||
288 | ori t0, 0x1f | ||
289 | xori t0, 0x1f | ||
290 | mtc0 t0, CP0_STATUS | ||
291 | |||
292 | LONG_L v0, GDB_FR_STATUS(sp) | ||
293 | LONG_L v1, GDB_FR_EPC(sp) | ||
294 | mtc0 v0, CP0_STATUS | ||
295 | DMTC0 v1, CP0_EPC | ||
296 | LONG_L v0, GDB_FR_HI(sp) | ||
297 | LONG_L v1, GDB_FR_LO(sp) | ||
298 | mthi v0 | ||
299 | mtlo v1 | ||
300 | LONG_L $31, GDB_FR_REG31(sp) | ||
301 | LONG_L $30, GDB_FR_REG30(sp) | ||
302 | LONG_L $28, GDB_FR_REG28(sp) | ||
303 | LONG_L $27, GDB_FR_REG27(sp) | ||
304 | LONG_L $26, GDB_FR_REG26(sp) | ||
305 | LONG_L $25, GDB_FR_REG25(sp) | ||
306 | LONG_L $24, GDB_FR_REG24(sp) | ||
307 | LONG_L $23, GDB_FR_REG23(sp) | ||
308 | LONG_L $22, GDB_FR_REG22(sp) | ||
309 | LONG_L $21, GDB_FR_REG21(sp) | ||
310 | LONG_L $20, GDB_FR_REG20(sp) | ||
311 | LONG_L $19, GDB_FR_REG19(sp) | ||
312 | LONG_L $18, GDB_FR_REG18(sp) | ||
313 | LONG_L $17, GDB_FR_REG17(sp) | ||
314 | LONG_L $16, GDB_FR_REG16(sp) | ||
315 | LONG_L $15, GDB_FR_REG15(sp) | ||
316 | LONG_L $14, GDB_FR_REG14(sp) | ||
317 | LONG_L $13, GDB_FR_REG13(sp) | ||
318 | LONG_L $12, GDB_FR_REG12(sp) | ||
319 | LONG_L $11, GDB_FR_REG11(sp) | ||
320 | LONG_L $10, GDB_FR_REG10(sp) | ||
321 | LONG_L $9, GDB_FR_REG9(sp) | ||
322 | LONG_L $8, GDB_FR_REG8(sp) | ||
323 | LONG_L $7, GDB_FR_REG7(sp) | ||
324 | LONG_L $6, GDB_FR_REG6(sp) | ||
325 | LONG_L $5, GDB_FR_REG5(sp) | ||
326 | LONG_L $4, GDB_FR_REG4(sp) | ||
327 | LONG_L $3, GDB_FR_REG3(sp) | ||
328 | LONG_L $2, GDB_FR_REG2(sp) | ||
329 | LONG_L $1, GDB_FR_REG1(sp) | ||
330 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | ||
331 | LONG_L k0, GDB_FR_EPC(sp) | ||
332 | LONG_L $29, GDB_FR_REG29(sp) /* Deallocate stack */ | ||
333 | jr k0 | ||
334 | rfe | ||
335 | #else | ||
336 | LONG_L sp, GDB_FR_REG29(sp) /* Deallocate stack */ | ||
337 | |||
338 | .set mips3 | ||
339 | eret | ||
340 | .set mips0 | ||
341 | #endif | ||
342 | .set at | ||
343 | .set reorder | ||
344 | END(trap_low) | ||
345 | |||
346 | LEAF(kgdb_read_byte) | ||
347 | 4: lb t0, (a0) | ||
348 | sb t0, (a1) | ||
349 | li v0, 0 | ||
350 | jr ra | ||
351 | .section __ex_table,"a" | ||
352 | PTR 4b, kgdbfault | ||
353 | .previous | ||
354 | END(kgdb_read_byte) | ||
355 | |||
356 | LEAF(kgdb_write_byte) | ||
357 | 5: sb a0, (a1) | ||
358 | li v0, 0 | ||
359 | jr ra | ||
360 | .section __ex_table,"a" | ||
361 | PTR 5b, kgdbfault | ||
362 | .previous | ||
363 | END(kgdb_write_byte) | ||
364 | |||
365 | .type kgdbfault@function | ||
366 | .ent kgdbfault | ||
367 | |||
368 | kgdbfault: li v0, -EFAULT | ||
369 | jr ra | ||
370 | .end kgdbfault | ||