2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
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>
31 #define KDP_TEST_HARNESS 0
33 #define dprintf(x) kprintf x
38 void print_saved_state(void *);
40 void kdp_trap( unsigned int, struct savearea
*saved_state
);
42 boolean_t
kdp_call_kdb(void);
48 unsigned short *remote_port
,
49 unsigned int exception
,
58 kdp_exception_t
*rq
= (kdp_exception_t
*)&aligned_pkt
;
60 bcopy((char *)pkt
, (char *)rq
, sizeof(*rq
));
61 rq
->hdr
.request
= KDP_EXCEPTION
;
63 rq
->hdr
.seq
= kdp
.exception_seq
;
65 rq
->hdr
.len
= sizeof (*rq
) + sizeof(kdp_exc_info_t
);
68 rq
->exc_info
[0].cpu
= 0;
69 rq
->exc_info
[0].exception
= exception
;
70 rq
->exc_info
[0].code
= code
;
71 rq
->exc_info
[0].subcode
= subcode
;
73 rq
->hdr
.len
+= rq
->n_exc_info
* sizeof (kdp_exc_info_t
);
75 bcopy((char *)rq
, (char *)pkt
, rq
->hdr
.len
);
77 kdp
.exception_ack_needed
= TRUE
;
79 *remote_port
= kdp
.exception_port
;
89 kdp_exception_ack_t aligned_pkt
;
90 kdp_exception_ack_t
*rq
= (kdp_exception_ack_t
*)&aligned_pkt
;
92 if (len
< sizeof (*rq
))
95 bcopy((char *)pkt
, (char *)rq
, sizeof(*rq
));
97 if (!rq
->hdr
.is_reply
|| rq
->hdr
.request
!= KDP_EXCEPTION
)
100 dprintf(("kdp_exception_ack seq %x %x\n", rq
->hdr
.seq
, kdp
.exception_seq
));
102 if (rq
->hdr
.seq
== kdp
.exception_seq
) {
103 kdp
.exception_ack_needed
= FALSE
;
111 struct ppc_thread_state
*state
114 struct savearea
*saved_state
;
116 saved_state
= kdp
.saved_state
;
118 bzero((char *)state
,sizeof (struct ppc_thread_state
)) ;
120 state
->srr0
= saved_state
->save_srr0
;
121 state
->srr1
= saved_state
->save_srr1
;
122 state
->r0
= saved_state
->save_r0
;
123 state
->r1
= saved_state
->save_r1
;
124 state
->r2
= saved_state
->save_r2
;
125 state
->r3
= saved_state
->save_r3
;
126 state
->r4
= saved_state
->save_r4
;
127 state
->r5
= saved_state
->save_r5
;
128 state
->r6
= saved_state
->save_r6
;
129 state
->r7
= saved_state
->save_r7
;
130 state
->r8
= saved_state
->save_r8
;
131 state
->r9
= saved_state
->save_r9
;
132 state
->r10
= saved_state
->save_r10
;
133 state
->r11
= saved_state
->save_r11
;
134 state
->r12
= saved_state
->save_r12
;
135 state
->r13
= saved_state
->save_r13
;
136 state
->r14
= saved_state
->save_r14
;
137 state
->r15
= saved_state
->save_r15
;
138 state
->r16
= saved_state
->save_r16
;
139 state
->r17
= saved_state
->save_r17
;
140 state
->r18
= saved_state
->save_r18
;
141 state
->r19
= saved_state
->save_r19
;
142 state
->r20
= saved_state
->save_r20
;
143 state
->r21
= saved_state
->save_r21
;
144 state
->r22
= saved_state
->save_r22
;
145 state
->r23
= saved_state
->save_r23
;
146 state
->r24
= saved_state
->save_r24
;
147 state
->r25
= saved_state
->save_r25
;
148 state
->r26
= saved_state
->save_r26
;
149 state
->r27
= saved_state
->save_r27
;
150 state
->r28
= saved_state
->save_r28
;
151 state
->r29
= saved_state
->save_r29
;
152 state
->r30
= saved_state
->save_r30
;
153 state
->r31
= saved_state
->save_r31
;
154 state
->cr
= saved_state
->save_cr
;
155 state
->xer
= saved_state
->save_xer
;
156 state
->lr
= saved_state
->save_lr
;
157 state
->ctr
= saved_state
->save_ctr
;
161 kdp_machine_read_regs(
170 case PPC_THREAD_STATE
:
171 dprintf(("kdp_readregs THREAD_STATE\n"));
172 kdp_getintegerstate((struct ppc_thread_state
*)data
);
173 *size
= PPC_THREAD_STATE_COUNT
* sizeof(int);
174 return KDPERR_NO_ERROR
;
176 case PPC_FLOAT_STATE
:
177 dprintf(("kdp_readregs THREAD_FPSTATE\n"));
178 bzero((char *)data
,sizeof(struct ppc_float_state
));
179 *size
= PPC_FLOAT_STATE_COUNT
* sizeof(int);
180 return KDPERR_NO_ERROR
;
183 dprintf(("kdp_readregs bad flavor %d\n"));
184 return KDPERR_BADFLAVOR
;
190 struct ppc_thread_state
*state
193 struct savearea
*saved_state
;
195 saved_state
= kdp
.saved_state
;
197 saved_state
->save_srr0
= state
->srr0
;
198 saved_state
->save_srr1
= state
->srr1
;
199 saved_state
->save_r0
= state
->r0
;
200 saved_state
->save_r1
= state
->r1
;
201 saved_state
->save_r2
= state
->r2
;
202 saved_state
->save_r3
= state
->r3
;
203 saved_state
->save_r4
= state
->r4
;
204 saved_state
->save_r5
= state
->r5
;
205 saved_state
->save_r6
= state
->r6
;
206 saved_state
->save_r7
= state
->r7
;
207 saved_state
->save_r8
= state
->r8
;
208 saved_state
->save_r9
= state
->r9
;
209 saved_state
->save_r10
= state
->r10
;
210 saved_state
->save_r11
= state
->r11
;
211 saved_state
->save_r12
= state
->r12
;
212 saved_state
->save_r13
= state
->r13
;
213 saved_state
->save_r14
= state
->r14
;
214 saved_state
->save_r15
= state
->r15
;
215 saved_state
->save_r16
= state
->r16
;
216 saved_state
->save_r17
= state
->r17
;
217 saved_state
->save_r18
= state
->r18
;
218 saved_state
->save_r19
= state
->r19
;
219 saved_state
->save_r20
= state
->r20
;
220 saved_state
->save_r21
= state
->r21
;
221 saved_state
->save_r22
= state
->r22
;
222 saved_state
->save_r23
= state
->r23
;
223 saved_state
->save_r24
= state
->r24
;
224 saved_state
->save_r25
= state
->r25
;
225 saved_state
->save_r26
= state
->r26
;
226 saved_state
->save_r27
= state
->r27
;
227 saved_state
->save_r28
= state
->r28
;
228 saved_state
->save_r29
= state
->r29
;
229 saved_state
->save_r30
= state
->r30
;
230 saved_state
->save_r31
= state
->r31
;
231 saved_state
->save_cr
= state
->cr
;
232 saved_state
->save_xer
= state
->xer
;
233 saved_state
->save_lr
= state
->lr
;
234 saved_state
->save_ctr
= state
->ctr
;
238 kdp_machine_write_regs(
247 case PPC_THREAD_STATE
:
248 dprintf(("kdp_writeregs THREAD_STATE\n"));
249 kdp_setintegerstate((struct ppc_thread_state
*)data
);
252 DumpTheSave((struct savearea
*)data
); /* (TEST/DEBUG) */
254 return KDPERR_NO_ERROR
;
256 case PPC_FLOAT_STATE
:
257 dprintf(("kdp_writeregs THREAD_FPSTATE\n"));
258 return KDPERR_NO_ERROR
;
261 dprintf(("kdp_writeregs bad flavor %d\n"));
262 return KDPERR_BADFLAVOR
;
267 kdp_machine_hostinfo(
268 kdp_hostinfo_t
*hostinfo
274 hostinfo
->cpus_mask
= 0;
275 hostinfo
->cpu_type
= 0;
277 for (i
= 0; i
< machine_info
.max_cpus
; i
++) {
278 m
= &machine_slot
[i
];
282 hostinfo
->cpus_mask
|= (1 << i
);
283 if (hostinfo
->cpu_type
== 0) {
284 hostinfo
->cpu_type
= m
->cpu_type
;
285 hostinfo
->cpu_subtype
= m
->cpu_subtype
;
295 printf("kdp panic: %s\n", msg
);
303 halt_all_cpus(TRUE
);;
319 kdp_us_spin(int usec
)
321 extern void delay(int);
326 void print_saved_state(void *state
)
328 struct ppc_thread_state
*saved_state
;
332 printf("pc = 0x%x\n", saved_state
->srr0
);
333 printf("msr = 0x%x\n", saved_state
->srr1
);
334 printf("rp = 0x%x\n", saved_state
->lr
);
335 printf("sp = 0x%x\n", saved_state
->r1
);
342 Debugger("inline call to debugger(machine_startup)");
346 * table to convert system specific code to generic codes for kdb
348 int kdp_trap_codes
[] = {
349 EXC_BAD_ACCESS
, /* 0x0000 INVALID EXCEPTION */
350 EXC_BAD_ACCESS
, /* 0x0100 System reset */
351 EXC_BAD_ACCESS
, /* 0x0200 Machine check */
352 EXC_BAD_ACCESS
, /* 0x0300 Data access */
353 EXC_BAD_ACCESS
, /* 0x0400 Instruction access */
354 EXC_BAD_ACCESS
, /* 0x0500 External interrupt */
355 EXC_BAD_ACCESS
, /* 0x0600 Alignment */
356 EXC_BREAKPOINT
, /* 0x0700 Program - fp exc, ill/priv instr, trap */
357 EXC_ARITHMETIC
, /* 0x0800 Floating point disabled */
358 EXC_SOFTWARE
, /* 0x0900 Decrementer */
359 EXC_BAD_ACCESS
, /* 0x0A00 I/O controller interface */
360 EXC_BAD_ACCESS
, /* 0x0B00 INVALID EXCEPTION */
361 EXC_SOFTWARE
, /* 0x0C00 System call exception */
362 EXC_BREAKPOINT
, /* 0x0D00 Trace */
363 EXC_SOFTWARE
, /* 0x0E00 FP assist */
364 EXC_SOFTWARE
, /* 0x0F00 Performance monitoring */
365 EXC_ARITHMETIC
, /* 0x0F20 Altivec disabled */
366 EXC_BAD_ACCESS
, /* 0x1000 Instruction PTE miss */
367 EXC_BAD_ACCESS
, /* 0x1100 Data load PTE miss */
368 EXC_BAD_ACCESS
, /* 0x1200 Data store PTE miss */
369 EXC_BREAKPOINT
, /* 0x1300 Instruction bkpt */
370 EXC_SOFTWARE
, /* 0x1400 System management */
371 EXC_BAD_ACCESS
, /* 0x1500 INVALID EXCEPTION */
372 EXC_ARITHMETIC
, /* 0x1600 Altivec Assist */
373 EXC_BAD_ACCESS
, /* 0x1700 INVALID EXCEPTION */
374 EXC_BAD_ACCESS
, /* 0x1800 INVALID EXCEPTION */
375 EXC_BAD_ACCESS
, /* 0x1900 INVALID EXCEPTION */
376 EXC_BAD_ACCESS
, /* 0x1A00 INVALID EXCEPTION */
377 EXC_BAD_ACCESS
, /* 0x1B00 INVALID EXCEPTION */
378 EXC_BAD_ACCESS
, /* 0x1C00 INVALID EXCEPTION */
379 EXC_BAD_ACCESS
, /* 0x1D00 INVALID EXCEPTION */
380 EXC_BAD_ACCESS
, /* 0x1E00 INVALID EXCEPTION */
381 EXC_BAD_ACCESS
, /* 0x1F00 INVALID EXCEPTION */
382 EXC_BREAKPOINT
, /* 0x2000 Run Mode/Trace */
383 EXC_BAD_ACCESS
, /* 0x2100 INVALID EXCEPTION */
384 EXC_BAD_ACCESS
, /* 0x2200 INVALID EXCEPTION */
385 EXC_BAD_ACCESS
, /* 0x2300 INVALID EXCEPTION */
386 EXC_BAD_ACCESS
, /* 0x2400 INVALID EXCEPTION */
387 EXC_BAD_ACCESS
, /* 0x2500 INVALID EXCEPTION */
388 EXC_BAD_ACCESS
, /* 0x2600 INVALID EXCEPTION */
389 EXC_BAD_ACCESS
, /* 0x2700 INVALID EXCEPTION */
390 EXC_BAD_ACCESS
, /* 0x2800 INVALID EXCEPTION */
391 EXC_BAD_ACCESS
, /* 0x2900 INVALID EXCEPTION */
392 EXC_BAD_ACCESS
, /* 0x2A00 INVALID EXCEPTION */
393 EXC_BAD_ACCESS
, /* 0x2B00 INVALID EXCEPTION */
394 EXC_BAD_ACCESS
, /* 0x2C00 INVALID EXCEPTION */
395 EXC_BAD_ACCESS
, /* 0x2D00 INVALID EXCEPTION */
396 EXC_BAD_ACCESS
, /* 0x2E00 INVALID EXCEPTION */
397 EXC_BAD_ACCESS
, /* 0x2F00 INVALID EXCEPTION */
398 EXC_SOFTWARE
/* 0x3000 AST trap (software) */
412 #define kdp_code(x) kdp_trap_codes[((x)==T_AST?0x31:(x)/T_VECTOR_SIZE)]
416 unsigned int exception
,
417 struct savearea
*saved_state
421 unsigned int register sp
;
422 struct savearea
*state
;
426 printf("\nvector=%x, \n", exception
/4);
427 sp
= saved_state
->save_r1
;
428 printf("stack backtrace - sp(%x) ", sp
);
429 fp
= (unsigned int *) *((unsigned int *)sp
);
431 printf("0x%08x ", fp
[2]);
432 fp
= (unsigned int *)*fp
;
438 dump_segment_registers();
442 printf("vector=%d ", exception
/4);
444 kdp_raise_exception(kdp_code(exception
), 0, 0, saved_state
);
447 printf("kdp_trap: kdp_raise_exception() ret\n");
449 if (*((int *)saved_state
->save_srr0
) == 0x7c800008)
450 saved_state
->save_srr0
+= 4; /* BKPT_SIZE */
452 if(saved_state
->save_srr1
& (MASK(MSR_SE
) | MASK(MSR_BE
))) { /* Are we just stepping or continuing */
453 db_run_mode
= STEP_ONCE
; /* We are stepping */
455 else db_run_mode
= STEP_CONTINUE
; /* Otherwise we are continuing */
458 mtspr(dabr
, kdp_dabr
);
470 void kdp_print_registers(struct savearea
*state
)
473 for (i
=0; i
<32; i
++) {
476 printf(" %08x",*(&state
->save_r0
+i
));
479 printf("cr = 0x%08x\t\t",state
->save_cr
);
480 printf("xer = 0x%08x\n",state
->save_xer
);
481 printf("lr = 0x%08x\t\t",state
->save_lr
);
482 printf("ctr = 0x%08x\n",state
->save_ctr
);
483 printf("srr0(iar) = 0x%08x\t\t",state
->save_srr0
);
484 printf("srr1(msr) = 0x%08B\n",state
->save_srr1
,
485 "\x10\x11""EE\x12PR\x13""FP\x14ME\x15""FE0\x16SE\x18"
486 "FE1\x19""AL\x1a""EP\x1bIT\x1c""DT");
492 unsigned int exception
,
493 struct savearea
*saved_state
)
495 extern void kdp_print_registers(struct savearea
*);
496 extern void print_backtrace(struct savearea
*);
497 extern unsigned int debug_mode
, disableDebugOuput
;
499 disableDebugOuput
= FALSE
;
501 printf("re-entering kdp:\n");
502 printf("vector=%x, \n", exception
/4);
503 kdp_print_registers(saved_state
);
504 print_backtrace(saved_state
);
505 printf("panic: We are hanging here...\n");
509 unsigned int kdp_ml_get_breakinsn()