]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * The contents of this file constitute Original Code as defined in and | |
7 | * are subject to the Apple Public Source License Version 1.1 (the | |
8 | * "License"). You may not use this file except in compliance with the | |
9 | * License. Please obtain a copy of the License at | |
10 | * http://www.apple.com/publicsource and read it before using this file. | |
11 | * | |
12 | * This Original Code and all software distributed under the License are | |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
17 | * License for the specific language governing rights and limitations | |
18 | * under the License. | |
19 | * | |
20 | * @APPLE_LICENSE_HEADER_END@ | |
21 | */ | |
22 | ||
23 | #include <mach/mach_types.h> | |
24 | #include <mach/exception_types.h> | |
25 | #include <ppc/exception.h> | |
26 | #include <ppc/proc_reg.h> | |
27 | #include <kdp/kdp_internal.h> | |
28 | #include <ppc/savearea.h> | |
29 | #include <kern/debug.h> | |
30 | #include <IOKit/IOPlatformExpert.h> | |
31 | ||
32 | #define KDP_TEST_HARNESS 0 | |
33 | #if KDP_TEST_HARNESS | |
34 | #define dprintf(x) kprintf x | |
35 | #else | |
36 | #define dprintf(x) | |
37 | #endif | |
38 | ||
39 | void print_saved_state(void *); | |
40 | void kdp_call(void); | |
41 | void kdp_trap( unsigned int, struct savearea *saved_state); | |
42 | int kdp_getc(void); | |
43 | boolean_t kdp_call_kdb(void); | |
44 | ||
45 | void | |
46 | kdp_exception( | |
47 | unsigned char *pkt, | |
48 | int *len, | |
49 | unsigned short *remote_port, | |
50 | unsigned int exception, | |
51 | unsigned int code, | |
52 | unsigned int subcode | |
53 | ) | |
54 | { | |
55 | struct { | |
56 | kdp_exception_t pkt; | |
57 | kdp_exc_info_t exc; | |
58 | } aligned_pkt; | |
59 | kdp_exception_t *rq = (kdp_exception_t *)&aligned_pkt; | |
60 | ||
61 | bcopy((char *)pkt, (char *)rq, sizeof(*rq)); | |
62 | rq->hdr.request = KDP_EXCEPTION; | |
63 | rq->hdr.is_reply = 0; | |
64 | rq->hdr.seq = kdp.exception_seq; | |
65 | rq->hdr.key = 0; | |
66 | rq->hdr.len = sizeof (*rq) + sizeof(kdp_exc_info_t); | |
67 | ||
68 | rq->n_exc_info = 1; | |
69 | rq->exc_info[0].cpu = 0; | |
70 | rq->exc_info[0].exception = exception; | |
71 | rq->exc_info[0].code = code; | |
72 | rq->exc_info[0].subcode = subcode; | |
73 | ||
74 | rq->hdr.len += rq->n_exc_info * sizeof (kdp_exc_info_t); | |
75 | ||
76 | bcopy((char *)rq, (char *)pkt, rq->hdr.len); | |
77 | ||
78 | kdp.exception_ack_needed = TRUE; | |
79 | ||
80 | *remote_port = kdp.exception_port; | |
81 | *len = rq->hdr.len; | |
82 | } | |
83 | ||
84 | boolean_t | |
85 | kdp_exception_ack( | |
86 | unsigned char *pkt, | |
87 | int len | |
88 | ) | |
89 | { | |
90 | kdp_exception_ack_t aligned_pkt; | |
91 | kdp_exception_ack_t *rq = (kdp_exception_ack_t *)&aligned_pkt; | |
92 | ||
93 | if (len < sizeof (*rq)) | |
94 | return(FALSE); | |
95 | ||
96 | bcopy((char *)pkt, (char *)rq, sizeof(*rq)); | |
97 | ||
98 | if (!rq->hdr.is_reply || rq->hdr.request != KDP_EXCEPTION) | |
99 | return(FALSE); | |
100 | ||
101 | dprintf(("kdp_exception_ack seq %x %x\n", rq->hdr.seq, kdp.exception_seq)); | |
102 | ||
103 | if (rq->hdr.seq == kdp.exception_seq) { | |
104 | kdp.exception_ack_needed = FALSE; | |
105 | kdp.exception_seq++; | |
106 | } | |
107 | return(TRUE); | |
108 | } | |
109 | ||
110 | static void | |
111 | kdp_getintegerstate( | |
112 | struct ppc_thread_state *state | |
113 | ) | |
114 | { | |
115 | struct savearea *saved_state; | |
116 | ||
117 | saved_state = kdp.saved_state; | |
118 | ||
119 | bzero((char *)state,sizeof (struct ppc_thread_state)) ; | |
120 | ||
121 | state->srr0 = (unsigned int)saved_state->save_srr0; | |
122 | state->srr1 = (unsigned int)saved_state->save_srr1; | |
123 | state->r0 = (unsigned int)saved_state->save_r0; | |
124 | state->r1 = (unsigned int)saved_state->save_r1; | |
125 | state->r2 = (unsigned int)saved_state->save_r2; | |
126 | state->r3 = (unsigned int)saved_state->save_r3; | |
127 | state->r4 = (unsigned int)saved_state->save_r4; | |
128 | state->r5 = (unsigned int)saved_state->save_r5; | |
129 | state->r6 = (unsigned int)saved_state->save_r6; | |
130 | state->r7 = (unsigned int)saved_state->save_r7; | |
131 | state->r8 = (unsigned int)saved_state->save_r8; | |
132 | state->r9 = (unsigned int)saved_state->save_r9; | |
133 | state->r10 = (unsigned int)saved_state->save_r10; | |
134 | state->r11 = (unsigned int)saved_state->save_r11; | |
135 | state->r12 = (unsigned int)saved_state->save_r12; | |
136 | state->r13 = (unsigned int)saved_state->save_r13; | |
137 | state->r14 = (unsigned int)saved_state->save_r14; | |
138 | state->r15 = (unsigned int)saved_state->save_r15; | |
139 | state->r16 = (unsigned int)saved_state->save_r16; | |
140 | state->r17 = (unsigned int)saved_state->save_r17; | |
141 | state->r18 = (unsigned int)saved_state->save_r18; | |
142 | state->r19 = (unsigned int)saved_state->save_r19; | |
143 | state->r20 = (unsigned int)saved_state->save_r20; | |
144 | state->r21 = (unsigned int)saved_state->save_r21; | |
145 | state->r22 = (unsigned int)saved_state->save_r22; | |
146 | state->r23 = (unsigned int)saved_state->save_r23; | |
147 | state->r24 = (unsigned int)saved_state->save_r24; | |
148 | state->r25 = (unsigned int)saved_state->save_r25; | |
149 | state->r26 = (unsigned int)saved_state->save_r26; | |
150 | state->r27 = (unsigned int)saved_state->save_r27; | |
151 | state->r28 = (unsigned int)saved_state->save_r28; | |
152 | state->r29 = (unsigned int)saved_state->save_r29; | |
153 | state->r30 = (unsigned int)saved_state->save_r30; | |
154 | state->r31 = (unsigned int)saved_state->save_r31; | |
155 | state->cr = (unsigned int)saved_state->save_cr; | |
156 | state->xer = (unsigned int)saved_state->save_xer; | |
157 | state->lr = (unsigned int)saved_state->save_lr; | |
158 | state->ctr = (unsigned int)saved_state->save_ctr; | |
159 | } | |
160 | ||
161 | static void | |
162 | kdp_getintegerstate64( | |
163 | struct ppc_thread_state64 *state | |
164 | ) | |
165 | { | |
166 | struct savearea *saved_state; | |
167 | ||
168 | saved_state = kdp.saved_state; | |
169 | ||
170 | bzero((char *)state,sizeof (struct ppc_thread_state64)) ; | |
171 | ||
172 | state->srr0 = saved_state->save_srr0; | |
173 | state->srr1 = saved_state->save_srr1; | |
174 | state->r0 = saved_state->save_r0; | |
175 | state->r1 = saved_state->save_r1; | |
176 | state->r2 = saved_state->save_r2; | |
177 | state->r3 = saved_state->save_r3; | |
178 | state->r4 = saved_state->save_r4; | |
179 | state->r5 = saved_state->save_r5; | |
180 | state->r6 = saved_state->save_r6; | |
181 | state->r7 = saved_state->save_r7; | |
182 | state->r8 = saved_state->save_r8; | |
183 | state->r9 = saved_state->save_r9; | |
184 | state->r10 = saved_state->save_r10; | |
185 | state->r11 = saved_state->save_r11; | |
186 | state->r12 = saved_state->save_r12; | |
187 | state->r13 = saved_state->save_r13; | |
188 | state->r14 = saved_state->save_r14; | |
189 | state->r15 = saved_state->save_r15; | |
190 | state->r16 = saved_state->save_r16; | |
191 | state->r17 = saved_state->save_r17; | |
192 | state->r18 = saved_state->save_r18; | |
193 | state->r19 = saved_state->save_r19; | |
194 | state->r20 = saved_state->save_r20; | |
195 | state->r21 = saved_state->save_r21; | |
196 | state->r22 = saved_state->save_r22; | |
197 | state->r23 = saved_state->save_r23; | |
198 | state->r24 = saved_state->save_r24; | |
199 | state->r25 = saved_state->save_r25; | |
200 | state->r26 = saved_state->save_r26; | |
201 | state->r27 = saved_state->save_r27; | |
202 | state->r28 = saved_state->save_r28; | |
203 | state->r29 = saved_state->save_r29; | |
204 | state->r30 = saved_state->save_r30; | |
205 | state->r31 = saved_state->save_r31; | |
206 | state->cr = saved_state->save_cr; | |
207 | state->xer = saved_state->save_xer; | |
208 | state->lr = saved_state->save_lr; | |
209 | state->ctr = saved_state->save_ctr; | |
210 | } | |
211 | ||
212 | kdp_error_t | |
213 | kdp_machine_read_regs( | |
214 | unsigned int cpu, | |
215 | unsigned int flavor, | |
216 | char *data, | |
217 | int *size | |
218 | ) | |
219 | { | |
220 | switch (flavor) { | |
221 | ||
222 | case PPC_THREAD_STATE: | |
223 | dprintf(("kdp_readregs THREAD_STATE\n")); | |
224 | kdp_getintegerstate((struct ppc_thread_state *)data); | |
225 | *size = PPC_THREAD_STATE_COUNT * sizeof(int); | |
226 | return KDPERR_NO_ERROR; | |
227 | ||
228 | case PPC_THREAD_STATE64: | |
229 | dprintf(("kdp_readregs THREAD_STATE\n")); | |
230 | kdp_getintegerstate64((struct ppc_thread_state64 *)data); | |
231 | *size = PPC_THREAD_STATE64_COUNT * sizeof(int); | |
232 | return KDPERR_NO_ERROR; | |
233 | ||
234 | case PPC_FLOAT_STATE: | |
235 | dprintf(("kdp_readregs THREAD_FPSTATE\n")); | |
236 | bzero((char *)data ,sizeof(struct ppc_float_state)); | |
237 | *size = PPC_FLOAT_STATE_COUNT * sizeof(int); | |
238 | return KDPERR_NO_ERROR; | |
239 | ||
240 | default: | |
241 | dprintf(("kdp_readregs bad flavor %d\n")); | |
242 | return KDPERR_BADFLAVOR; | |
243 | } | |
244 | } | |
245 | ||
246 | static void | |
247 | kdp_setintegerstate( | |
248 | struct ppc_thread_state *state | |
249 | ) | |
250 | { | |
251 | struct savearea *saved_state; | |
252 | ||
253 | saved_state = kdp.saved_state; | |
254 | ||
255 | saved_state->save_srr0 = state->srr0; | |
256 | saved_state->save_srr1 = state->srr1; | |
257 | saved_state->save_r0 = state->r0; | |
258 | saved_state->save_r1 = state->r1; | |
259 | saved_state->save_r2 = state->r2; | |
260 | saved_state->save_r3 = state->r3; | |
261 | saved_state->save_r4 = state->r4; | |
262 | saved_state->save_r5 = state->r5; | |
263 | saved_state->save_r6 = state->r6; | |
264 | saved_state->save_r7 = state->r7; | |
265 | saved_state->save_r8 = state->r8; | |
266 | saved_state->save_r9 = state->r9; | |
267 | saved_state->save_r10 = state->r10; | |
268 | saved_state->save_r11 = state->r11; | |
269 | saved_state->save_r12 = state->r12; | |
270 | saved_state->save_r13 = state->r13; | |
271 | saved_state->save_r14 = state->r14; | |
272 | saved_state->save_r15 = state->r15; | |
273 | saved_state->save_r16 = state->r16; | |
274 | saved_state->save_r17 = state->r17; | |
275 | saved_state->save_r18 = state->r18; | |
276 | saved_state->save_r19 = state->r19; | |
277 | saved_state->save_r20 = state->r20; | |
278 | saved_state->save_r21 = state->r21; | |
279 | saved_state->save_r22 = state->r22; | |
280 | saved_state->save_r23 = state->r23; | |
281 | saved_state->save_r24 = state->r24; | |
282 | saved_state->save_r25 = state->r25; | |
283 | saved_state->save_r26 = state->r26; | |
284 | saved_state->save_r27 = state->r27; | |
285 | saved_state->save_r28 = state->r28; | |
286 | saved_state->save_r29 = state->r29; | |
287 | saved_state->save_r30 = state->r30; | |
288 | saved_state->save_r31 = state->r31; | |
289 | saved_state->save_cr = state->cr; | |
290 | saved_state->save_xer = state->xer; | |
291 | saved_state->save_lr = state->lr; | |
292 | saved_state->save_ctr = state->ctr; | |
293 | } | |
294 | ||
295 | static void | |
296 | kdp_setintegerstate64( | |
297 | struct ppc_thread_state64 *state | |
298 | ) | |
299 | { | |
300 | struct savearea *saved_state; | |
301 | ||
302 | saved_state = kdp.saved_state; | |
303 | ||
304 | saved_state->save_srr0 = state->srr0; | |
305 | saved_state->save_srr1 = state->srr1; | |
306 | saved_state->save_r0 = state->r0; | |
307 | saved_state->save_r1 = state->r1; | |
308 | saved_state->save_r2 = state->r2; | |
309 | saved_state->save_r3 = state->r3; | |
310 | saved_state->save_r4 = state->r4; | |
311 | saved_state->save_r5 = state->r5; | |
312 | saved_state->save_r6 = state->r6; | |
313 | saved_state->save_r7 = state->r7; | |
314 | saved_state->save_r8 = state->r8; | |
315 | saved_state->save_r9 = state->r9; | |
316 | saved_state->save_r10 = state->r10; | |
317 | saved_state->save_r11 = state->r11; | |
318 | saved_state->save_r12 = state->r12; | |
319 | saved_state->save_r13 = state->r13; | |
320 | saved_state->save_r14 = state->r14; | |
321 | saved_state->save_r15 = state->r15; | |
322 | saved_state->save_r16 = state->r16; | |
323 | saved_state->save_r17 = state->r17; | |
324 | saved_state->save_r18 = state->r18; | |
325 | saved_state->save_r19 = state->r19; | |
326 | saved_state->save_r20 = state->r20; | |
327 | saved_state->save_r21 = state->r21; | |
328 | saved_state->save_r22 = state->r22; | |
329 | saved_state->save_r23 = state->r23; | |
330 | saved_state->save_r24 = state->r24; | |
331 | saved_state->save_r25 = state->r25; | |
332 | saved_state->save_r26 = state->r26; | |
333 | saved_state->save_r27 = state->r27; | |
334 | saved_state->save_r28 = state->r28; | |
335 | saved_state->save_r29 = state->r29; | |
336 | saved_state->save_r30 = state->r30; | |
337 | saved_state->save_r31 = state->r31; | |
338 | saved_state->save_cr = state->cr; | |
339 | saved_state->save_xer = state->xer; | |
340 | saved_state->save_lr = state->lr; | |
341 | saved_state->save_ctr = state->ctr; | |
342 | } | |
343 | ||
344 | kdp_error_t | |
345 | kdp_machine_write_regs( | |
346 | unsigned int cpu, | |
347 | unsigned int flavor, | |
348 | char *data, | |
349 | int *size | |
350 | ) | |
351 | { | |
352 | switch (flavor) { | |
353 | ||
354 | case PPC_THREAD_STATE: | |
355 | dprintf(("kdp_writeregs THREAD_STATE\n")); | |
356 | kdp_setintegerstate((struct ppc_thread_state *)data); | |
357 | ||
358 | #if KDP_TEST_HARNESS | |
359 | DumpTheSave((struct savearea *)data); /* (TEST/DEBUG) */ | |
360 | #endif | |
361 | return KDPERR_NO_ERROR; | |
362 | ||
363 | case PPC_THREAD_STATE64: | |
364 | dprintf(("kdp_writeregs THREAD_STATE64\n")); | |
365 | kdp_setintegerstate64((struct ppc_thread_state64 *)data); | |
366 | ||
367 | #if KDP_TEST_HARNESS | |
368 | DumpTheSave((struct savearea *)data); /* (TEST/DEBUG) */ | |
369 | #endif | |
370 | return KDPERR_NO_ERROR; | |
371 | case PPC_FLOAT_STATE: | |
372 | dprintf(("kdp_writeregs THREAD_FPSTATE\n")); | |
373 | return KDPERR_NO_ERROR; | |
374 | ||
375 | default: | |
376 | dprintf(("kdp_writeregs bad flavor %d\n")); | |
377 | return KDPERR_BADFLAVOR; | |
378 | } | |
379 | } | |
380 | ||
381 | void | |
382 | kdp_machine_hostinfo( | |
383 | kdp_hostinfo_t *hostinfo | |
384 | ) | |
385 | { | |
386 | int i; | |
387 | ||
388 | hostinfo->cpus_mask = 0; | |
389 | hostinfo->cpu_type = 0; | |
390 | ||
391 | for (i = 0; i < machine_info.max_cpus; i++) { | |
392 | if ((PerProcTable[i].ppe_vaddr == (struct per_proc_info *)NULL) || | |
393 | !(PerProcTable[i].ppe_vaddr->running)) | |
394 | continue; | |
395 | ||
396 | hostinfo->cpus_mask |= (1 << i); | |
397 | if (hostinfo->cpu_type == 0) { | |
398 | hostinfo->cpu_type = slot_type(i); | |
399 | hostinfo->cpu_subtype = slot_subtype(i); | |
400 | } | |
401 | } | |
402 | } | |
403 | ||
404 | void | |
405 | kdp_panic( | |
406 | const char *msg | |
407 | ) | |
408 | { | |
409 | printf("kdp panic: %s\n", msg); | |
410 | while(1) {} | |
411 | } | |
412 | ||
413 | ||
414 | void | |
415 | kdp_reboot(void) | |
416 | { | |
417 | printf("Attempting system restart..."); | |
418 | /* Call the platform specific restart*/ | |
419 | if (PE_halt_restart) | |
420 | (*PE_halt_restart)(kPERestartCPU); | |
421 | /* If we do reach this, give up */ | |
422 | halt_all_cpus(TRUE); | |
423 | } | |
424 | ||
425 | int | |
426 | kdp_intr_disbl(void) | |
427 | { | |
428 | return (splhigh()); | |
429 | } | |
430 | ||
431 | void | |
432 | kdp_intr_enbl(int s) | |
433 | { | |
434 | splx(s); | |
435 | } | |
436 | ||
437 | void | |
438 | kdp_us_spin(int usec) | |
439 | { | |
440 | extern void delay(int); | |
441 | ||
442 | delay(usec/100); | |
443 | } | |
444 | ||
445 | void print_saved_state(void *state) | |
446 | { | |
447 | struct ppc_thread_state *saved_state; | |
448 | ||
449 | saved_state = state; | |
450 | ||
451 | printf("pc = 0x%x\n", saved_state->srr0); | |
452 | printf("msr = 0x%x\n", saved_state->srr1); | |
453 | printf("rp = 0x%x\n", saved_state->lr); | |
454 | printf("sp = 0x%x\n", saved_state->r1); | |
455 | ||
456 | } | |
457 | ||
458 | void | |
459 | kdp_call() | |
460 | { | |
461 | Debugger("inline call to debugger(machine_startup)"); | |
462 | } | |
463 | ||
464 | /* | |
465 | * table to convert system specific code to generic codes for kdb | |
466 | */ | |
467 | int kdp_trap_codes[] = { | |
468 | EXC_BAD_ACCESS, /* 0x0000 INVALID EXCEPTION */ | |
469 | EXC_BAD_ACCESS, /* 0x0100 System reset */ | |
470 | EXC_BAD_ACCESS, /* 0x0200 Machine check */ | |
471 | EXC_BAD_ACCESS, /* 0x0300 Data access */ | |
472 | EXC_BAD_ACCESS, /* 0x0400 Instruction access */ | |
473 | EXC_BAD_ACCESS, /* 0x0500 External interrupt */ | |
474 | EXC_BAD_ACCESS, /* 0x0600 Alignment */ | |
475 | EXC_BREAKPOINT, /* 0x0700 Program - fp exc, ill/priv instr, trap */ | |
476 | EXC_ARITHMETIC, /* 0x0800 Floating point disabled */ | |
477 | EXC_SOFTWARE, /* 0x0900 Decrementer */ | |
478 | EXC_BAD_ACCESS, /* 0x0A00 I/O controller interface */ | |
479 | EXC_BAD_ACCESS, /* 0x0B00 INVALID EXCEPTION */ | |
480 | EXC_SOFTWARE, /* 0x0C00 System call exception */ | |
481 | EXC_BREAKPOINT, /* 0x0D00 Trace */ | |
482 | EXC_SOFTWARE, /* 0x0E00 FP assist */ | |
483 | EXC_SOFTWARE, /* 0x0F00 Performance monitoring */ | |
484 | EXC_ARITHMETIC, /* 0x0F20 Altivec disabled */ | |
485 | EXC_BAD_ACCESS, /* 0x1000 Instruction PTE miss */ | |
486 | EXC_BAD_ACCESS, /* 0x1100 Data load PTE miss */ | |
487 | EXC_BAD_ACCESS, /* 0x1200 Data store PTE miss */ | |
488 | EXC_BREAKPOINT, /* 0x1300 Instruction bkpt */ | |
489 | EXC_SOFTWARE, /* 0x1400 System management */ | |
490 | EXC_BAD_ACCESS, /* 0x1500 INVALID EXCEPTION */ | |
491 | EXC_ARITHMETIC, /* 0x1600 Altivec Assist */ | |
492 | EXC_BAD_ACCESS, /* 0x1700 INVALID EXCEPTION */ | |
493 | EXC_BAD_ACCESS, /* 0x1800 INVALID EXCEPTION */ | |
494 | EXC_BAD_ACCESS, /* 0x1900 INVALID EXCEPTION */ | |
495 | EXC_BAD_ACCESS, /* 0x1A00 INVALID EXCEPTION */ | |
496 | EXC_BAD_ACCESS, /* 0x1B00 INVALID EXCEPTION */ | |
497 | EXC_BAD_ACCESS, /* 0x1C00 INVALID EXCEPTION */ | |
498 | EXC_BAD_ACCESS, /* 0x1D00 INVALID EXCEPTION */ | |
499 | EXC_BAD_ACCESS, /* 0x1E00 INVALID EXCEPTION */ | |
500 | EXC_BAD_ACCESS, /* 0x1F00 INVALID EXCEPTION */ | |
501 | EXC_BREAKPOINT, /* 0x2000 Run Mode/Trace */ | |
502 | EXC_BAD_ACCESS, /* 0x2100 INVALID EXCEPTION */ | |
503 | EXC_BAD_ACCESS, /* 0x2200 INVALID EXCEPTION */ | |
504 | EXC_BAD_ACCESS, /* 0x2300 INVALID EXCEPTION */ | |
505 | EXC_BAD_ACCESS, /* 0x2400 INVALID EXCEPTION */ | |
506 | EXC_BAD_ACCESS, /* 0x2500 INVALID EXCEPTION */ | |
507 | EXC_BAD_ACCESS, /* 0x2600 INVALID EXCEPTION */ | |
508 | EXC_BAD_ACCESS, /* 0x2700 INVALID EXCEPTION */ | |
509 | EXC_BAD_ACCESS, /* 0x2800 INVALID EXCEPTION */ | |
510 | EXC_BAD_ACCESS, /* 0x2900 INVALID EXCEPTION */ | |
511 | EXC_BAD_ACCESS, /* 0x2A00 INVALID EXCEPTION */ | |
512 | EXC_BAD_ACCESS, /* 0x2B00 INVALID EXCEPTION */ | |
513 | EXC_BAD_ACCESS, /* 0x2C00 INVALID EXCEPTION */ | |
514 | EXC_BAD_ACCESS, /* 0x2D00 INVALID EXCEPTION */ | |
515 | EXC_BAD_ACCESS, /* 0x2E00 INVALID EXCEPTION */ | |
516 | EXC_BAD_ACCESS, /* 0x2F00 INVALID EXCEPTION */ | |
517 | EXC_SOFTWARE /* 0x3000 AST trap (software) */ | |
518 | }; | |
519 | ||
520 | int | |
521 | kdp_getc() | |
522 | { | |
523 | return(cnmaygetc()); | |
524 | } | |
525 | ||
526 | int kdp_backtrace; | |
527 | int kdp_sr_dump; | |
528 | int kdp_dabr; | |
529 | int kdp_noisy; | |
530 | ||
531 | #define kdp_code(x) kdp_trap_codes[((x)==T_AST?0x31:(x)/T_VECTOR_SIZE)] | |
532 | ||
533 | void | |
534 | kdp_trap( | |
535 | unsigned int exception, | |
536 | struct savearea *saved_state | |
537 | ) | |
538 | { | |
539 | unsigned int *fp; | |
540 | unsigned int sp; | |
541 | struct savearea *state; | |
542 | ||
543 | if (kdp_noisy) { | |
544 | if (kdp_backtrace) { | |
545 | printf("\nvector=%x, \n", exception/4); | |
546 | sp = saved_state->save_r1; | |
547 | printf("stack backtrace - sp(%x) ", sp); | |
548 | fp = (unsigned int *) *((unsigned int *)sp); | |
549 | while (fp) { | |
550 | printf("0x%08x ", fp[2]); | |
551 | fp = (unsigned int *)*fp; | |
552 | } | |
553 | printf("\n"); | |
554 | } | |
555 | #ifdef XXX | |
556 | if (kdp_sr_dump) { | |
557 | dump_segment_registers(); | |
558 | } | |
559 | #endif | |
560 | ||
561 | printf("vector=%d ", exception/4); | |
562 | } | |
563 | kdp_raise_exception(kdp_code(exception), 0, 0, saved_state); | |
564 | ||
565 | if (kdp_noisy) | |
566 | printf("kdp_trap: kdp_raise_exception() ret\n"); | |
567 | ||
568 | if ((unsigned int)(saved_state->save_srr0) == 0x7c800008) | |
569 | saved_state->save_srr0 += 4; /* BKPT_SIZE */ | |
570 | ||
571 | if(saved_state->save_srr1 & (MASK(MSR_SE) | MASK(MSR_BE))) { /* Are we just stepping or continuing */ | |
572 | db_run_mode = STEP_ONCE; /* We are stepping */ | |
573 | } | |
574 | else db_run_mode = STEP_CONTINUE; /* Otherwise we are continuing */ | |
575 | ||
576 | #ifdef XXX | |
577 | mtspr(dabr, kdp_dabr); | |
578 | #endif | |
579 | } | |
580 | ||
581 | boolean_t | |
582 | kdp_call_kdb( | |
583 | void) | |
584 | { | |
585 | switch_debugger=1; | |
586 | return(TRUE); | |
587 | } | |
588 | ||
589 | void kdp_print_registers(struct savearea *state) | |
590 | { | |
591 | int i; | |
592 | for (i=0; i<32; i++) { | |
593 | if ((i % 8) == 0) | |
594 | printf("\n%4d :",i); | |
595 | printf(" %08x",*(&state->save_r0+i)); | |
596 | } | |
597 | printf("\n"); | |
598 | printf("cr = 0x%08x\t\t",state->save_cr); | |
599 | printf("xer = 0x%08x\n",state->save_xer); | |
600 | printf("lr = 0x%08x\t\t",state->save_lr); | |
601 | printf("ctr = 0x%08x\n",state->save_ctr); | |
602 | printf("srr0(iar) = 0x%08x\t\t",state->save_srr0); | |
603 | printf("srr1(msr) = 0x%08B\n",state->save_srr1, | |
604 | "\x10\x11""EE\x12PR\x13""FP\x14ME\x15""FE0\x16SE\x18" | |
605 | "FE1\x19""AL\x1a""EP\x1bIT\x1c""DT"); | |
606 | printf("\n"); | |
607 | } | |
608 | ||
609 | void | |
610 | kdp_print_backtrace( | |
611 | unsigned int exception, | |
612 | struct savearea *saved_state) | |
613 | { | |
614 | extern void kdp_print_registers(struct savearea *); | |
615 | extern void print_backtrace(struct savearea *); | |
616 | ||
617 | disableDebugOuput = FALSE; | |
618 | debug_mode = TRUE; | |
619 | printf("re-entering kdp:\n"); | |
620 | printf("vector=%x, \n", exception/4); | |
621 | kdp_print_registers(saved_state); | |
622 | print_backtrace(saved_state); | |
623 | printf("panic: We are hanging here...\n"); | |
624 | while(1); | |
625 | } | |
626 | ||
627 | unsigned int kdp_ml_get_breakinsn(void) | |
628 | { | |
629 | return 0x7fe00008; | |
630 | } |