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 * Copyright (c) 1997 Apple Computer, Inc. All rights reserved.
24 * Copyright (c) 1994 NeXT Computer, Inc. All rights reserved.
26 * machdep/ppc/kdp_machdep.c
28 * Machine-dependent code for Remote Debugging Protocol
30 * March, 1997 Created. Umesh Vaishampayan [umeshv@NeXT.com]
34 #include <mach/mach_types.h>
35 #include <mach/exception_types.h>
36 #include <ppc/exception.h>
37 #include <ppc/proc_reg.h>
38 #include <kdp/kdp_internal.h>
39 #include <ppc/savearea.h>
40 #include <kern/debug.h>
42 #define KDP_TEST_HARNESS 0
44 #define dprintf(x) kprintf x
49 void print_saved_state(void *);
51 void kdp_trap( unsigned int, struct ppc_thread_state
*);
53 boolean_t
kdp_call_kdb(void);
59 unsigned short *remote_port
,
60 unsigned int exception
,
69 kdp_exception_t
*rq
= (kdp_exception_t
*)&aligned_pkt
;
71 bcopy((char *)pkt
, (char *)rq
, sizeof(*rq
));
72 rq
->hdr
.request
= KDP_EXCEPTION
;
74 rq
->hdr
.seq
= kdp
.exception_seq
;
76 rq
->hdr
.len
= sizeof (*rq
) + sizeof(kdp_exc_info_t
);
79 rq
->exc_info
[0].cpu
= 0;
80 rq
->exc_info
[0].exception
= exception
;
81 rq
->exc_info
[0].code
= code
;
82 rq
->exc_info
[0].subcode
= subcode
;
84 rq
->hdr
.len
+= rq
->n_exc_info
* sizeof (kdp_exc_info_t
);
86 bcopy((char *)rq
, (char *)pkt
, rq
->hdr
.len
);
88 kdp
.exception_ack_needed
= TRUE
;
90 *remote_port
= kdp
.exception_port
;
100 kdp_exception_ack_t aligned_pkt
;
101 kdp_exception_ack_t
*rq
= (kdp_exception_ack_t
*)&aligned_pkt
;
103 if (len
< sizeof (*rq
))
106 bcopy((char *)pkt
, (char *)rq
, sizeof(*rq
));
108 if (!rq
->hdr
.is_reply
|| rq
->hdr
.request
!= KDP_EXCEPTION
)
111 dprintf(("kdp_exception_ack seq %x %x\n", rq
->hdr
.seq
, kdp
.exception_seq
));
113 if (rq
->hdr
.seq
== kdp
.exception_seq
) {
114 kdp
.exception_ack_needed
= FALSE
;
122 struct ppc_thread_state
*state
125 struct ppc_thread_state
*saved_state
;
127 saved_state
= kdp
.saved_state
;
129 bzero((char *)state
,sizeof (struct ppc_thread_state
)) ;
131 state
->srr0
= saved_state
->srr0
;
132 state
->srr1
= saved_state
->srr1
;
133 state
->r0
= saved_state
->r0
;
134 state
->r1
= saved_state
->r1
;
135 state
->r2
= saved_state
->r2
;
136 state
->r3
= saved_state
->r3
;
137 state
->r4
= saved_state
->r4
;
138 state
->r5
= saved_state
->r5
;
139 state
->r6
= saved_state
->r6
;
140 state
->r7
= saved_state
->r7
;
141 state
->r8
= saved_state
->r8
;
142 state
->r9
= saved_state
->r9
;
143 state
->r10
= saved_state
->r10
;
144 state
->r11
= saved_state
->r11
;
145 state
->r12
= saved_state
->r12
;
146 state
->r13
= saved_state
->r13
;
147 state
->r14
= saved_state
->r14
;
148 state
->r15
= saved_state
->r15
;
149 state
->r16
= saved_state
->r16
;
150 state
->r17
= saved_state
->r17
;
151 state
->r18
= saved_state
->r18
;
152 state
->r19
= saved_state
->r19
;
153 state
->r20
= saved_state
->r20
;
154 state
->r21
= saved_state
->r21
;
155 state
->r22
= saved_state
->r22
;
156 state
->r23
= saved_state
->r23
;
157 state
->r24
= saved_state
->r24
;
158 state
->r25
= saved_state
->r25
;
159 state
->r26
= saved_state
->r26
;
160 state
->r27
= saved_state
->r27
;
161 state
->r28
= saved_state
->r28
;
162 state
->r29
= saved_state
->r29
;
163 state
->r30
= saved_state
->r30
;
164 state
->r31
= saved_state
->r31
;
165 state
->cr
= saved_state
->cr
;
166 state
->xer
= saved_state
->xer
;
167 state
->lr
= saved_state
->lr
;
168 state
->ctr
= saved_state
->ctr
;
169 state
->mq
= saved_state
->mq
; /* This is BOGUS ! (601) ONLY */
173 kdp_machine_read_regs(
182 case PPC_THREAD_STATE
:
183 dprintf(("kdp_readregs THREAD_STATE\n"));
184 kdp_getintegerstate((struct ppc_thread_state
*)data
);
185 *size
= PPC_THREAD_STATE_COUNT
* sizeof(int);
186 return KDPERR_NO_ERROR
;
188 case PPC_FLOAT_STATE
:
189 dprintf(("kdp_readregs THREAD_FPSTATE\n"));
190 bzero((char *)data
,sizeof(struct ppc_float_state
));
191 *size
= PPC_FLOAT_STATE_COUNT
* sizeof(int);
192 return KDPERR_NO_ERROR
;
195 dprintf(("kdp_readregs bad flavor %d\n"));
196 return KDPERR_BADFLAVOR
;
202 struct ppc_thread_state
*state
205 struct ppc_thread_state
*saved_state
;
207 saved_state
= kdp
.saved_state
;
209 saved_state
->srr0
= state
->srr0
;
210 saved_state
->srr1
= state
->srr1
;
211 saved_state
->r0
= state
->r0
;
212 saved_state
->r1
= state
->r1
;
213 saved_state
->r2
= state
->r2
;
214 saved_state
->r3
= state
->r3
;
215 saved_state
->r4
= state
->r4
;
216 saved_state
->r5
= state
->r5
;
217 saved_state
->r6
= state
->r6
;
218 saved_state
->r7
= state
->r7
;
219 saved_state
->r8
= state
->r8
;
220 saved_state
->r9
= state
->r9
;
221 saved_state
->r10
= state
->r10
;
222 saved_state
->r11
= state
->r11
;
223 saved_state
->r12
= state
->r12
;
224 saved_state
->r13
= state
->r13
;
225 saved_state
->r14
= state
->r14
;
226 saved_state
->r15
= state
->r15
;
227 saved_state
->r16
= state
->r16
;
228 saved_state
->r17
= state
->r17
;
229 saved_state
->r18
= state
->r18
;
230 saved_state
->r19
= state
->r19
;
231 saved_state
->r20
= state
->r20
;
232 saved_state
->r21
= state
->r21
;
233 saved_state
->r22
= state
->r22
;
234 saved_state
->r23
= state
->r23
;
235 saved_state
->r24
= state
->r24
;
236 saved_state
->r25
= state
->r25
;
237 saved_state
->r26
= state
->r26
;
238 saved_state
->r27
= state
->r27
;
239 saved_state
->r28
= state
->r28
;
240 saved_state
->r29
= state
->r29
;
241 saved_state
->r30
= state
->r30
;
242 saved_state
->r31
= state
->r31
;
243 saved_state
->cr
= state
->cr
;
244 saved_state
->xer
= state
->xer
;
245 saved_state
->lr
= state
->lr
;
246 saved_state
->ctr
= state
->ctr
;
247 saved_state
->mq
= state
->mq
; /* BOGUS! (601)ONLY */
251 kdp_machine_write_regs(
260 case PPC_THREAD_STATE
:
261 dprintf(("kdp_writeregs THREAD_STATE\n"));
262 kdp_setintegerstate((struct ppc_thread_state
*)data
);
265 DumpTheSave((struct savearea
*)data
); /* (TEST/DEBUG) */
267 return KDPERR_NO_ERROR
;
269 case PPC_FLOAT_STATE
:
270 dprintf(("kdp_writeregs THREAD_FPSTATE\n"));
271 return KDPERR_NO_ERROR
;
274 dprintf(("kdp_writeregs bad flavor %d\n"));
275 return KDPERR_BADFLAVOR
;
280 kdp_machine_hostinfo(
281 kdp_hostinfo_t
*hostinfo
287 hostinfo
->cpus_mask
= 0;
289 for (i
= 0; i
< machine_info
.max_cpus
; i
++) {
290 m
= &machine_slot
[i
];
294 hostinfo
->cpus_mask
|= (1 << i
);
295 if (hostinfo
->cpu_type
== 0) {
296 hostinfo
->cpu_type
= m
->cpu_type
;
297 hostinfo
->cpu_subtype
= m
->cpu_subtype
;
307 printf("kdp panic: %s\n", msg
);
315 halt_all_cpus(TRUE
);;
331 kdp_us_spin(int usec
)
333 extern void delay(int);
338 void print_saved_state(void *state
)
340 struct ppc_thread_state
*saved_state
;
344 printf("pc = 0x%x\n", saved_state
->srr0
);
345 printf("msr = 0x%x\n", saved_state
->srr1
);
346 printf("rp = 0x%x\n", saved_state
->lr
);
347 printf("sp = 0x%x\n", saved_state
->r1
);
354 Debugger("inline call to debugger(machine_startup)");
358 * table to convert system specific code to generic codes for kdb
360 int kdp_trap_codes
[] = {
361 EXC_BAD_ACCESS
, /* 0x0000 INVALID EXCEPTION */
362 EXC_BAD_ACCESS
, /* 0x0100 System reset */
363 EXC_BAD_ACCESS
, /* 0x0200 Machine check */
364 EXC_BAD_ACCESS
, /* 0x0300 Data access */
365 EXC_BAD_ACCESS
, /* 0x0400 Instruction access */
366 EXC_BAD_ACCESS
, /* 0x0500 External interrupt */
367 EXC_BAD_ACCESS
, /* 0x0600 Alignment */
368 EXC_BREAKPOINT
, /* 0x0700 Program - fp exc, ill/priv instr, trap */
369 EXC_ARITHMETIC
, /* 0x0800 Floating point disabled */
370 EXC_SOFTWARE
, /* 0x0900 Decrementer */
371 EXC_BAD_ACCESS
, /* 0x0A00 I/O controller interface */
372 EXC_BAD_ACCESS
, /* 0x0B00 INVALID EXCEPTION */
373 EXC_SOFTWARE
, /* 0x0C00 System call exception */
374 EXC_BREAKPOINT
, /* 0x0D00 Trace */
375 EXC_SOFTWARE
, /* 0x0E00 FP assist */
376 EXC_SOFTWARE
, /* 0x0F00 Performance monitoring */
377 EXC_ARITHMETIC
, /* 0x0F20 Altivec disabled */
378 EXC_BAD_ACCESS
, /* 0x1000 Instruction PTE miss */
379 EXC_BAD_ACCESS
, /* 0x1100 Data load PTE miss */
380 EXC_BAD_ACCESS
, /* 0x1200 Data store PTE miss */
381 EXC_BREAKPOINT
, /* 0x1300 Instruction bkpt */
382 EXC_SOFTWARE
, /* 0x1400 System management */
383 EXC_BAD_ACCESS
, /* 0x1500 INVALID EXCEPTION */
384 EXC_ARITHMETIC
, /* 0x1600 Altivec Assist */
385 EXC_BAD_ACCESS
, /* 0x1700 INVALID EXCEPTION */
386 EXC_BAD_ACCESS
, /* 0x1800 INVALID EXCEPTION */
387 EXC_BAD_ACCESS
, /* 0x1900 INVALID EXCEPTION */
388 EXC_BAD_ACCESS
, /* 0x1A00 INVALID EXCEPTION */
389 EXC_BAD_ACCESS
, /* 0x1B00 INVALID EXCEPTION */
390 EXC_BAD_ACCESS
, /* 0x1C00 INVALID EXCEPTION */
391 EXC_BAD_ACCESS
, /* 0x1D00 INVALID EXCEPTION */
392 EXC_BAD_ACCESS
, /* 0x1E00 INVALID EXCEPTION */
393 EXC_BAD_ACCESS
, /* 0x1F00 INVALID EXCEPTION */
394 EXC_BREAKPOINT
, /* 0x2000 Run Mode/Trace */
395 EXC_BAD_ACCESS
, /* 0x2100 INVALID EXCEPTION */
396 EXC_BAD_ACCESS
, /* 0x2200 INVALID EXCEPTION */
397 EXC_BAD_ACCESS
, /* 0x2300 INVALID EXCEPTION */
398 EXC_BAD_ACCESS
, /* 0x2400 INVALID EXCEPTION */
399 EXC_BAD_ACCESS
, /* 0x2500 INVALID EXCEPTION */
400 EXC_BAD_ACCESS
, /* 0x2600 INVALID EXCEPTION */
401 EXC_BAD_ACCESS
, /* 0x2700 INVALID EXCEPTION */
402 EXC_BAD_ACCESS
, /* 0x2800 INVALID EXCEPTION */
403 EXC_BAD_ACCESS
, /* 0x2900 INVALID EXCEPTION */
404 EXC_BAD_ACCESS
, /* 0x2A00 INVALID EXCEPTION */
405 EXC_BAD_ACCESS
, /* 0x2B00 INVALID EXCEPTION */
406 EXC_BAD_ACCESS
, /* 0x2C00 INVALID EXCEPTION */
407 EXC_BAD_ACCESS
, /* 0x2D00 INVALID EXCEPTION */
408 EXC_BAD_ACCESS
, /* 0x2E00 INVALID EXCEPTION */
409 EXC_BAD_ACCESS
, /* 0x2F00 INVALID EXCEPTION */
410 EXC_SOFTWARE
/* 0x3000 AST trap (software) */
424 #define kdp_code(x) kdp_trap_codes[((x)==T_AST?0x31:(x)/T_VECTOR_SIZE)]
428 unsigned int exception
,
429 struct ppc_thread_state
*saved_state
433 unsigned int register sp
;
434 struct ppc_thread_state
*state
;
438 printf("\nvector=%x, \n", exception
/4);
440 regDump(saved_state
);
442 sp
= saved_state
->r1
;
443 printf("stack backtrace - sp(%x) ", sp
);
444 fp
= (unsigned int *) *((unsigned int *)sp
);
446 printf("0x%08x ", fp
[2]);
447 fp
= (unsigned int *)*fp
;
453 dump_segment_registers();
457 printf("vector=%d ", exception
/4);
460 kdp_raise_exception(kdp_code(exception
), 0, 0, saved_state
);
463 printf("kdp_trap: kdp_raise_exception() ret\n");
465 if (*((int *)saved_state
->srr0
) == 0x7c800008)
466 saved_state
->srr0
+= 4; /* BKPT_SIZE */
468 if(saved_state
->srr1
& (MASK(MSR_SE
) | MASK(MSR_BE
))) { /* Are we just stepping or continuing */
469 db_run_mode
= STEP_ONCE
; /* We are stepping */
471 else db_run_mode
= STEP_CONTINUE
; /* Otherwise we are continuing */
475 mtspr(dabr
, kdp_dabr
);
487 void kdp_print_registers(struct ppc_saved_state
*state
)
490 for (i
=0; i
<32; i
++) {
493 printf(" %08x",*(&state
->r0
+i
));
496 printf("cr = 0x%08x\t\t",state
->cr
);
497 printf("xer = 0x%08x\n",state
->xer
);
498 printf("lr = 0x%08x\t\t",state
->lr
);
499 printf("ctr = 0x%08x\n",state
->ctr
);
500 printf("srr0(iar) = 0x%08x\t\t",state
->srr0
);
501 printf("srr1(msr) = 0x%08B\n",state
->srr1
,
502 "\x10\x11""EE\x12PR\x13""FP\x14ME\x15""FE0\x16SE\x18"
503 "FE1\x19""AL\x1a""EP\x1bIT\x1c""DT");
504 printf("mq = 0x%08x\t\t",state
->mq
);
505 printf("sr_copyin = 0x%08x\n",state
->sr_copyin
);
511 unsigned int exception
,
512 struct ppc_saved_state
*saved_state
)
514 extern void kdp_print_registers(struct ppc_saved_state
*);
515 extern void print_backtrace(struct ppc_saved_state
*);
516 extern unsigned int debug_mode
, disableDebugOuput
;
518 disableDebugOuput
= FALSE
;
520 printf("re-entering kdp:\n");
521 printf("vector=%x, \n", exception
/4);
522 kdp_print_registers(saved_state
);
523 print_backtrace(saved_state
);
524 printf("panic: We are hanging here...\n");