]> git.saurik.com Git - apple/xnu.git/blame - osfmk/kdp/ml/ppc/kdp_machdep.c
xnu-1456.1.26.tar.gz
[apple/xnu.git] / osfmk / kdp / ml / ppc / kdp_machdep.c
CommitLineData
1c79356b 1/*
2d21ac55 2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
1c79356b 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
8f6c56a5 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b 27 */
1c79356b
A
28
29#include <mach/mach_types.h>
30#include <mach/exception_types.h>
31#include <ppc/exception.h>
32#include <ppc/proc_reg.h>
33#include <kdp/kdp_internal.h>
34#include <ppc/savearea.h>
2d21ac55 35#include <ppc/misc_protos.h>
1c79356b 36#include <kern/debug.h>
91447636 37#include <IOKit/IOPlatformExpert.h>
1c79356b 38
0c530ab8
A
39#include <kern/thread.h>
40#include <ppc/thread.h>
41#include <vm/vm_map.h>
42#include <ppc/pmap.h>
43
1c79356b
A
44#define KDP_TEST_HARNESS 0
45#if KDP_TEST_HARNESS
46#define dprintf(x) kprintf x
47#else
48#define dprintf(x)
49#endif
50
51void print_saved_state(void *);
52void kdp_call(void);
1c79356b
A
53int kdp_getc(void);
54boolean_t kdp_call_kdb(void);
55
0c530ab8 56extern pmap_t kdp_pmap;
0c530ab8
A
57
58int
2d21ac55 59machine_trace_thread(thread_t thread, char *tracepos, char *tracebound, int nframes, boolean_t user_p);
0c530ab8
A
60
61int
2d21ac55 62machine_trace_thread64(thread_t thread, char *tracepos, char *tracebound, int nframes, boolean_t user_p);
0c530ab8
A
63
64unsigned
65machine_read64(addr64_t srcaddr, caddr_t dstaddr, uint32_t len);
66
1c79356b
A
67void
68kdp_exception(
69 unsigned char *pkt,
70 int *len,
71 unsigned short *remote_port,
72 unsigned int exception,
73 unsigned int code,
74 unsigned int subcode
75)
76{
77 struct {
78 kdp_exception_t pkt;
79 kdp_exc_info_t exc;
80 } aligned_pkt;
81 kdp_exception_t *rq = (kdp_exception_t *)&aligned_pkt;
82
83 bcopy((char *)pkt, (char *)rq, sizeof(*rq));
84 rq->hdr.request = KDP_EXCEPTION;
85 rq->hdr.is_reply = 0;
86 rq->hdr.seq = kdp.exception_seq;
87 rq->hdr.key = 0;
88 rq->hdr.len = sizeof (*rq) + sizeof(kdp_exc_info_t);
89
90 rq->n_exc_info = 1;
91 rq->exc_info[0].cpu = 0;
92 rq->exc_info[0].exception = exception;
93 rq->exc_info[0].code = code;
94 rq->exc_info[0].subcode = subcode;
95
96 rq->hdr.len += rq->n_exc_info * sizeof (kdp_exc_info_t);
97
98 bcopy((char *)rq, (char *)pkt, rq->hdr.len);
99
100 kdp.exception_ack_needed = TRUE;
101
102 *remote_port = kdp.exception_port;
103 *len = rq->hdr.len;
104}
105
106boolean_t
107kdp_exception_ack(
108 unsigned char *pkt,
109 int len
110)
111{
112 kdp_exception_ack_t aligned_pkt;
113 kdp_exception_ack_t *rq = (kdp_exception_ack_t *)&aligned_pkt;
114
2d21ac55 115 if ((size_t)len < sizeof (*rq))
1c79356b
A
116 return(FALSE);
117
118 bcopy((char *)pkt, (char *)rq, sizeof(*rq));
119
120 if (!rq->hdr.is_reply || rq->hdr.request != KDP_EXCEPTION)
121 return(FALSE);
122
123 dprintf(("kdp_exception_ack seq %x %x\n", rq->hdr.seq, kdp.exception_seq));
124
125 if (rq->hdr.seq == kdp.exception_seq) {
126 kdp.exception_ack_needed = FALSE;
127 kdp.exception_seq++;
128 }
129 return(TRUE);
130}
131
132static void
133kdp_getintegerstate(
134 struct ppc_thread_state *state
135)
136{
9bccf70c 137 struct savearea *saved_state;
1c79356b
A
138
139 saved_state = kdp.saved_state;
140
141 bzero((char *)state,sizeof (struct ppc_thread_state)) ;
142
55e303ae
A
143 state->srr0 = (unsigned int)saved_state->save_srr0;
144 state->srr1 = (unsigned int)saved_state->save_srr1;
145 state->r0 = (unsigned int)saved_state->save_r0;
146 state->r1 = (unsigned int)saved_state->save_r1;
147 state->r2 = (unsigned int)saved_state->save_r2;
148 state->r3 = (unsigned int)saved_state->save_r3;
149 state->r4 = (unsigned int)saved_state->save_r4;
150 state->r5 = (unsigned int)saved_state->save_r5;
151 state->r6 = (unsigned int)saved_state->save_r6;
152 state->r7 = (unsigned int)saved_state->save_r7;
153 state->r8 = (unsigned int)saved_state->save_r8;
154 state->r9 = (unsigned int)saved_state->save_r9;
155 state->r10 = (unsigned int)saved_state->save_r10;
156 state->r11 = (unsigned int)saved_state->save_r11;
157 state->r12 = (unsigned int)saved_state->save_r12;
158 state->r13 = (unsigned int)saved_state->save_r13;
159 state->r14 = (unsigned int)saved_state->save_r14;
160 state->r15 = (unsigned int)saved_state->save_r15;
161 state->r16 = (unsigned int)saved_state->save_r16;
162 state->r17 = (unsigned int)saved_state->save_r17;
163 state->r18 = (unsigned int)saved_state->save_r18;
164 state->r19 = (unsigned int)saved_state->save_r19;
165 state->r20 = (unsigned int)saved_state->save_r20;
166 state->r21 = (unsigned int)saved_state->save_r21;
167 state->r22 = (unsigned int)saved_state->save_r22;
168 state->r23 = (unsigned int)saved_state->save_r23;
169 state->r24 = (unsigned int)saved_state->save_r24;
170 state->r25 = (unsigned int)saved_state->save_r25;
171 state->r26 = (unsigned int)saved_state->save_r26;
172 state->r27 = (unsigned int)saved_state->save_r27;
173 state->r28 = (unsigned int)saved_state->save_r28;
174 state->r29 = (unsigned int)saved_state->save_r29;
175 state->r30 = (unsigned int)saved_state->save_r30;
176 state->r31 = (unsigned int)saved_state->save_r31;
177 state->cr = (unsigned int)saved_state->save_cr;
178 state->xer = (unsigned int)saved_state->save_xer;
179 state->lr = (unsigned int)saved_state->save_lr;
180 state->ctr = (unsigned int)saved_state->save_ctr;
181}
182
183static void
184kdp_getintegerstate64(
185 struct ppc_thread_state64 *state
186)
187{
188 struct savearea *saved_state;
189
190 saved_state = kdp.saved_state;
191
192 bzero((char *)state,sizeof (struct ppc_thread_state64)) ;
193
9bccf70c
A
194 state->srr0 = saved_state->save_srr0;
195 state->srr1 = saved_state->save_srr1;
196 state->r0 = saved_state->save_r0;
197 state->r1 = saved_state->save_r1;
198 state->r2 = saved_state->save_r2;
199 state->r3 = saved_state->save_r3;
200 state->r4 = saved_state->save_r4;
201 state->r5 = saved_state->save_r5;
202 state->r6 = saved_state->save_r6;
203 state->r7 = saved_state->save_r7;
204 state->r8 = saved_state->save_r8;
205 state->r9 = saved_state->save_r9;
206 state->r10 = saved_state->save_r10;
207 state->r11 = saved_state->save_r11;
208 state->r12 = saved_state->save_r12;
209 state->r13 = saved_state->save_r13;
210 state->r14 = saved_state->save_r14;
211 state->r15 = saved_state->save_r15;
212 state->r16 = saved_state->save_r16;
213 state->r17 = saved_state->save_r17;
214 state->r18 = saved_state->save_r18;
215 state->r19 = saved_state->save_r19;
216 state->r20 = saved_state->save_r20;
217 state->r21 = saved_state->save_r21;
218 state->r22 = saved_state->save_r22;
219 state->r23 = saved_state->save_r23;
220 state->r24 = saved_state->save_r24;
221 state->r25 = saved_state->save_r25;
222 state->r26 = saved_state->save_r26;
223 state->r27 = saved_state->save_r27;
224 state->r28 = saved_state->save_r28;
225 state->r29 = saved_state->save_r29;
226 state->r30 = saved_state->save_r30;
227 state->r31 = saved_state->save_r31;
228 state->cr = saved_state->save_cr;
229 state->xer = saved_state->save_xer;
230 state->lr = saved_state->save_lr;
231 state->ctr = saved_state->save_ctr;
1c79356b
A
232}
233
234kdp_error_t
235kdp_machine_read_regs(
2d21ac55 236 __unused unsigned int cpu,
1c79356b
A
237 unsigned int flavor,
238 char *data,
239 int *size
240)
241{
242 switch (flavor) {
243
244 case PPC_THREAD_STATE:
245 dprintf(("kdp_readregs THREAD_STATE\n"));
246 kdp_getintegerstate((struct ppc_thread_state *)data);
247 *size = PPC_THREAD_STATE_COUNT * sizeof(int);
248 return KDPERR_NO_ERROR;
55e303ae
A
249
250 case PPC_THREAD_STATE64:
251 dprintf(("kdp_readregs THREAD_STATE\n"));
252 kdp_getintegerstate64((struct ppc_thread_state64 *)data);
253 *size = PPC_THREAD_STATE64_COUNT * sizeof(int);
254 return KDPERR_NO_ERROR;
255
1c79356b
A
256 case PPC_FLOAT_STATE:
257 dprintf(("kdp_readregs THREAD_FPSTATE\n"));
258 bzero((char *)data ,sizeof(struct ppc_float_state));
259 *size = PPC_FLOAT_STATE_COUNT * sizeof(int);
260 return KDPERR_NO_ERROR;
55e303ae 261
1c79356b
A
262 default:
263 dprintf(("kdp_readregs bad flavor %d\n"));
264 return KDPERR_BADFLAVOR;
265 }
266}
267
268static void
269kdp_setintegerstate(
270 struct ppc_thread_state *state
271)
272{
9bccf70c 273 struct savearea *saved_state;
1c79356b
A
274
275 saved_state = kdp.saved_state;
276
9bccf70c
A
277 saved_state->save_srr0 = state->srr0;
278 saved_state->save_srr1 = state->srr1;
279 saved_state->save_r0 = state->r0;
280 saved_state->save_r1 = state->r1;
281 saved_state->save_r2 = state->r2;
282 saved_state->save_r3 = state->r3;
283 saved_state->save_r4 = state->r4;
284 saved_state->save_r5 = state->r5;
285 saved_state->save_r6 = state->r6;
286 saved_state->save_r7 = state->r7;
287 saved_state->save_r8 = state->r8;
288 saved_state->save_r9 = state->r9;
289 saved_state->save_r10 = state->r10;
290 saved_state->save_r11 = state->r11;
291 saved_state->save_r12 = state->r12;
292 saved_state->save_r13 = state->r13;
293 saved_state->save_r14 = state->r14;
294 saved_state->save_r15 = state->r15;
295 saved_state->save_r16 = state->r16;
296 saved_state->save_r17 = state->r17;
297 saved_state->save_r18 = state->r18;
298 saved_state->save_r19 = state->r19;
299 saved_state->save_r20 = state->r20;
300 saved_state->save_r21 = state->r21;
301 saved_state->save_r22 = state->r22;
302 saved_state->save_r23 = state->r23;
303 saved_state->save_r24 = state->r24;
304 saved_state->save_r25 = state->r25;
305 saved_state->save_r26 = state->r26;
306 saved_state->save_r27 = state->r27;
307 saved_state->save_r28 = state->r28;
308 saved_state->save_r29 = state->r29;
309 saved_state->save_r30 = state->r30;
310 saved_state->save_r31 = state->r31;
311 saved_state->save_cr = state->cr;
312 saved_state->save_xer = state->xer;
313 saved_state->save_lr = state->lr;
314 saved_state->save_ctr = state->ctr;
1c79356b
A
315}
316
55e303ae
A
317static void
318kdp_setintegerstate64(
319 struct ppc_thread_state64 *state
320)
321{
322 struct savearea *saved_state;
323
324 saved_state = kdp.saved_state;
325
326 saved_state->save_srr0 = state->srr0;
327 saved_state->save_srr1 = state->srr1;
328 saved_state->save_r0 = state->r0;
329 saved_state->save_r1 = state->r1;
330 saved_state->save_r2 = state->r2;
331 saved_state->save_r3 = state->r3;
332 saved_state->save_r4 = state->r4;
333 saved_state->save_r5 = state->r5;
334 saved_state->save_r6 = state->r6;
335 saved_state->save_r7 = state->r7;
336 saved_state->save_r8 = state->r8;
337 saved_state->save_r9 = state->r9;
338 saved_state->save_r10 = state->r10;
339 saved_state->save_r11 = state->r11;
340 saved_state->save_r12 = state->r12;
341 saved_state->save_r13 = state->r13;
342 saved_state->save_r14 = state->r14;
343 saved_state->save_r15 = state->r15;
344 saved_state->save_r16 = state->r16;
345 saved_state->save_r17 = state->r17;
346 saved_state->save_r18 = state->r18;
347 saved_state->save_r19 = state->r19;
348 saved_state->save_r20 = state->r20;
349 saved_state->save_r21 = state->r21;
350 saved_state->save_r22 = state->r22;
351 saved_state->save_r23 = state->r23;
352 saved_state->save_r24 = state->r24;
353 saved_state->save_r25 = state->r25;
354 saved_state->save_r26 = state->r26;
355 saved_state->save_r27 = state->r27;
356 saved_state->save_r28 = state->r28;
357 saved_state->save_r29 = state->r29;
358 saved_state->save_r30 = state->r30;
359 saved_state->save_r31 = state->r31;
360 saved_state->save_cr = state->cr;
361 saved_state->save_xer = state->xer;
362 saved_state->save_lr = state->lr;
363 saved_state->save_ctr = state->ctr;
364}
365
1c79356b
A
366kdp_error_t
367kdp_machine_write_regs(
2d21ac55 368 __unused unsigned int cpu,
1c79356b
A
369 unsigned int flavor,
370 char *data,
2d21ac55 371 __unused int *size
1c79356b
A
372)
373{
374 switch (flavor) {
375
376 case PPC_THREAD_STATE:
377 dprintf(("kdp_writeregs THREAD_STATE\n"));
378 kdp_setintegerstate((struct ppc_thread_state *)data);
379
380#if KDP_TEST_HARNESS
381 DumpTheSave((struct savearea *)data); /* (TEST/DEBUG) */
382#endif
383 return KDPERR_NO_ERROR;
55e303ae
A
384
385 case PPC_THREAD_STATE64:
386 dprintf(("kdp_writeregs THREAD_STATE64\n"));
387 kdp_setintegerstate64((struct ppc_thread_state64 *)data);
388
389#if KDP_TEST_HARNESS
390 DumpTheSave((struct savearea *)data); /* (TEST/DEBUG) */
391#endif
392 return KDPERR_NO_ERROR;
1c79356b
A
393 case PPC_FLOAT_STATE:
394 dprintf(("kdp_writeregs THREAD_FPSTATE\n"));
395 return KDPERR_NO_ERROR;
55e303ae 396
1c79356b
A
397 default:
398 dprintf(("kdp_writeregs bad flavor %d\n"));
399 return KDPERR_BADFLAVOR;
400 }
401}
402
403void
404kdp_machine_hostinfo(
405 kdp_hostinfo_t *hostinfo
406)
407{
1c79356b
A
408 int i;
409
410 hostinfo->cpus_mask = 0;
0b4e3aa0 411 hostinfo->cpu_type = 0;
1c79356b
A
412
413 for (i = 0; i < machine_info.max_cpus; i++) {
91447636
A
414 if ((PerProcTable[i].ppe_vaddr == (struct per_proc_info *)NULL) ||
415 !(PerProcTable[i].ppe_vaddr->running))
1c79356b
A
416 continue;
417
418 hostinfo->cpus_mask |= (1 << i);
419 if (hostinfo->cpu_type == 0) {
91447636
A
420 hostinfo->cpu_type = slot_type(i);
421 hostinfo->cpu_subtype = slot_subtype(i);
1c79356b
A
422 }
423 }
424}
425
426void
427kdp_panic(
428 const char *msg
429)
430{
431 printf("kdp panic: %s\n", msg);
432 while(1) {}
433}
434
2d21ac55 435extern void halt_all_cpus(boolean_t);
1c79356b
A
436
437void
b0d623f7 438kdp_machine_reboot(void)
1c79356b 439{
91447636
A
440 printf("Attempting system restart...");
441 /* Call the platform specific restart*/
442 if (PE_halt_restart)
443 (*PE_halt_restart)(kPERestartCPU);
444 /* If we do reach this, give up */
445 halt_all_cpus(TRUE);
1c79356b
A
446}
447
448int
449kdp_intr_disbl(void)
450{
451 return (splhigh());
452}
453
454void
455kdp_intr_enbl(int s)
456{
457 splx(s);
458}
459
460void
461kdp_us_spin(int usec)
462{
1c79356b
A
463 delay(usec/100);
464}
465
466void print_saved_state(void *state)
467{
468 struct ppc_thread_state *saved_state;
469
470 saved_state = state;
471
472 printf("pc = 0x%x\n", saved_state->srr0);
473 printf("msr = 0x%x\n", saved_state->srr1);
474 printf("rp = 0x%x\n", saved_state->lr);
475 printf("sp = 0x%x\n", saved_state->r1);
476
477}
478
479void
2d21ac55 480kdp_call(void)
1c79356b
A
481{
482 Debugger("inline call to debugger(machine_startup)");
483}
484
485/*
486 * table to convert system specific code to generic codes for kdb
487 */
488int kdp_trap_codes[] = {
489 EXC_BAD_ACCESS, /* 0x0000 INVALID EXCEPTION */
490 EXC_BAD_ACCESS, /* 0x0100 System reset */
491 EXC_BAD_ACCESS, /* 0x0200 Machine check */
492 EXC_BAD_ACCESS, /* 0x0300 Data access */
493 EXC_BAD_ACCESS, /* 0x0400 Instruction access */
494 EXC_BAD_ACCESS, /* 0x0500 External interrupt */
495 EXC_BAD_ACCESS, /* 0x0600 Alignment */
496 EXC_BREAKPOINT, /* 0x0700 Program - fp exc, ill/priv instr, trap */
497 EXC_ARITHMETIC, /* 0x0800 Floating point disabled */
498 EXC_SOFTWARE, /* 0x0900 Decrementer */
499 EXC_BAD_ACCESS, /* 0x0A00 I/O controller interface */
500 EXC_BAD_ACCESS, /* 0x0B00 INVALID EXCEPTION */
501 EXC_SOFTWARE, /* 0x0C00 System call exception */
502 EXC_BREAKPOINT, /* 0x0D00 Trace */
503 EXC_SOFTWARE, /* 0x0E00 FP assist */
504 EXC_SOFTWARE, /* 0x0F00 Performance monitoring */
505 EXC_ARITHMETIC, /* 0x0F20 Altivec disabled */
506 EXC_BAD_ACCESS, /* 0x1000 Instruction PTE miss */
507 EXC_BAD_ACCESS, /* 0x1100 Data load PTE miss */
508 EXC_BAD_ACCESS, /* 0x1200 Data store PTE miss */
509 EXC_BREAKPOINT, /* 0x1300 Instruction bkpt */
510 EXC_SOFTWARE, /* 0x1400 System management */
511 EXC_BAD_ACCESS, /* 0x1500 INVALID EXCEPTION */
512 EXC_ARITHMETIC, /* 0x1600 Altivec Assist */
513 EXC_BAD_ACCESS, /* 0x1700 INVALID EXCEPTION */
514 EXC_BAD_ACCESS, /* 0x1800 INVALID EXCEPTION */
515 EXC_BAD_ACCESS, /* 0x1900 INVALID EXCEPTION */
516 EXC_BAD_ACCESS, /* 0x1A00 INVALID EXCEPTION */
517 EXC_BAD_ACCESS, /* 0x1B00 INVALID EXCEPTION */
518 EXC_BAD_ACCESS, /* 0x1C00 INVALID EXCEPTION */
519 EXC_BAD_ACCESS, /* 0x1D00 INVALID EXCEPTION */
520 EXC_BAD_ACCESS, /* 0x1E00 INVALID EXCEPTION */
521 EXC_BAD_ACCESS, /* 0x1F00 INVALID EXCEPTION */
522 EXC_BREAKPOINT, /* 0x2000 Run Mode/Trace */
523 EXC_BAD_ACCESS, /* 0x2100 INVALID EXCEPTION */
524 EXC_BAD_ACCESS, /* 0x2200 INVALID EXCEPTION */
525 EXC_BAD_ACCESS, /* 0x2300 INVALID EXCEPTION */
526 EXC_BAD_ACCESS, /* 0x2400 INVALID EXCEPTION */
527 EXC_BAD_ACCESS, /* 0x2500 INVALID EXCEPTION */
528 EXC_BAD_ACCESS, /* 0x2600 INVALID EXCEPTION */
529 EXC_BAD_ACCESS, /* 0x2700 INVALID EXCEPTION */
530 EXC_BAD_ACCESS, /* 0x2800 INVALID EXCEPTION */
531 EXC_BAD_ACCESS, /* 0x2900 INVALID EXCEPTION */
532 EXC_BAD_ACCESS, /* 0x2A00 INVALID EXCEPTION */
533 EXC_BAD_ACCESS, /* 0x2B00 INVALID EXCEPTION */
534 EXC_BAD_ACCESS, /* 0x2C00 INVALID EXCEPTION */
535 EXC_BAD_ACCESS, /* 0x2D00 INVALID EXCEPTION */
536 EXC_BAD_ACCESS, /* 0x2E00 INVALID EXCEPTION */
537 EXC_BAD_ACCESS, /* 0x2F00 INVALID EXCEPTION */
538 EXC_SOFTWARE /* 0x3000 AST trap (software) */
539};
540
541int
2d21ac55 542kdp_getc(void)
1c79356b
A
543{
544 return(cnmaygetc());
545}
546
547int kdp_backtrace;
548int kdp_sr_dump;
549int kdp_dabr;
550int kdp_noisy;
551
552#define kdp_code(x) kdp_trap_codes[((x)==T_AST?0x31:(x)/T_VECTOR_SIZE)]
553
554void
555kdp_trap(
556 unsigned int exception,
9bccf70c 557 struct savearea *saved_state
1c79356b
A
558)
559{
560 unsigned int *fp;
55e303ae 561 unsigned int sp;
1c79356b
A
562
563 if (kdp_noisy) {
564 if (kdp_backtrace) {
565 printf("\nvector=%x, \n", exception/4);
9bccf70c 566 sp = saved_state->save_r1;
1c79356b
A
567 printf("stack backtrace - sp(%x) ", sp);
568 fp = (unsigned int *) *((unsigned int *)sp);
569 while (fp) {
570 printf("0x%08x ", fp[2]);
571 fp = (unsigned int *)*fp;
572 }
573 printf("\n");
574 }
575#ifdef XXX
576 if (kdp_sr_dump) {
577 dump_segment_registers();
578 }
579#endif
580
9bccf70c 581 printf("vector=%d ", exception/4);
1c79356b 582 }
1c79356b
A
583 kdp_raise_exception(kdp_code(exception), 0, 0, saved_state);
584
585 if (kdp_noisy)
586 printf("kdp_trap: kdp_raise_exception() ret\n");
587
55e303ae 588 if ((unsigned int)(saved_state->save_srr0) == 0x7c800008)
9bccf70c
A
589 saved_state->save_srr0 += 4; /* BKPT_SIZE */
590
591 if(saved_state->save_srr1 & (MASK(MSR_SE) | MASK(MSR_BE))) { /* Are we just stepping or continuing */
1c79356b
A
592 db_run_mode = STEP_ONCE; /* We are stepping */
593 }
594 else db_run_mode = STEP_CONTINUE; /* Otherwise we are continuing */
9bccf70c 595
1c79356b
A
596#ifdef XXX
597 mtspr(dabr, kdp_dabr);
598#endif
599}
600
601boolean_t
602kdp_call_kdb(
603 void)
604{
605 switch_debugger=1;
606 return(TRUE);
607}
608
2d21ac55 609static void kdp_print_registers(struct savearea *state)
1c79356b
A
610{
611 int i;
612 for (i=0; i<32; i++) {
613 if ((i % 8) == 0)
614 printf("\n%4d :",i);
2d21ac55 615 printf(" %08llx",*(&state->save_r0+i));
1c79356b
A
616 }
617 printf("\n");
9bccf70c 618 printf("cr = 0x%08x\t\t",state->save_cr);
2d21ac55
A
619 printf("xer = 0x%08llx\n",state->save_xer);
620 printf("lr = 0x%08llx\t\t",state->save_lr);
621 printf("ctr = 0x%08llx\n",state->save_ctr);
622 printf("srr0(iar) = 0x%08llx\t\t",state->save_srr0);
b0d623f7 623 printf("srr1(msr) = 0x%08llx\n",state->save_srr1);
1c79356b
A
624 printf("\n");
625}
626
2d21ac55
A
627void kdp_print_backtrace(unsigned, struct savearea *);
628
1c79356b
A
629void
630kdp_print_backtrace(
631 unsigned int exception,
9bccf70c 632 struct savearea *saved_state)
1c79356b 633{
2d21ac55 634 disable_debug_output = FALSE;
1c79356b
A
635 debug_mode = TRUE;
636 printf("re-entering kdp:\n");
637 printf("vector=%x, \n", exception/4);
638 kdp_print_registers(saved_state);
639 print_backtrace(saved_state);
640 printf("panic: We are hanging here...\n");
641 while(1);
642}
9bccf70c 643
b0d623f7
A
644void
645kdp_machine_get_breakinsn(
646 uint8_t *bytes,
647 uint32_t *size
648)
9bccf70c 649{
b0d623f7
A
650 *(uint32_t *)bytes = 0x7fe00008;
651 *size = sizeof(uint32_t);
9bccf70c 652}
b0d623f7 653
0c530ab8
A
654#define LR_OFFSET 8
655#define LR_OFFSET64 16
656
657int
2d21ac55 658machine_trace_thread(thread_t thread, char *tracepos, char *tracebound, int nframes, boolean_t user_p)
0c530ab8
A
659{
660 uint32_t *tracebuf = (uint32_t *)tracepos;
661 uint32_t fence = 0;
662 uint32_t stackptr = 0;
663 uint32_t stacklimit = 0xb0000000;
664 int framecount = 0;
665 uint32_t init_srr0 = 0;
666 uint32_t prevsp = 0;
667 uint32_t framesize = 2 * sizeof(vm_offset_t);
668
669 if (user_p) {
670 /* Examine the user savearea */
671 init_srr0 = thread->machine.upcb->save_srr0;
672 stackptr = thread->machine.upcb->save_r1;
673 /* This bound isn't useful, but it doesn't hinder us */
674 stacklimit = 0xffffffff;
675 kdp_pmap = thread->task->map->pmap;
676 }
677 else {
678 stackptr = thread->machine.pcb->save_r1;
679 init_srr0 = thread->machine.pcb->save_srr0;
680 }
681 /* Fill in the "current" program counter */
682 *tracebuf++ = init_srr0;
683
684 for (framecount = 0; framecount < nframes; framecount++) {
685/* Bounds check */
2d21ac55 686 if ((uint32_t) (tracebound - ((char *)tracebuf)) < (4 * framesize)) {
0c530ab8
A
687 tracebuf--;
688 break;
689 }
690
691 *tracebuf++ = stackptr;
692/* Invalid frame, or hit fence */
693 if (!stackptr || (stackptr == fence)) {
694 break;
695 }
696/* Stack grows downward */
697 if (stackptr < prevsp) {
698 break;
699 }
700/* Unaligned frame */
701 if (stackptr & 0x000000F) {
702 break;
703 }
704 if (stackptr > stacklimit) {
705 break;
706 }
707/* Assume there's a saved link register, and read it */
b0d623f7 708 if (kdp_machine_vm_read((caddr_t) (stackptr + LR_OFFSET), (caddr_t) tracebuf, sizeof(caddr_t)) != sizeof(caddr_t)) {
0c530ab8
A
709 break;
710 }
711
712 tracebuf++;
713 prevsp = stackptr;
714/* Next frame */
b0d623f7 715 if (kdp_machine_vm_read((caddr_t) stackptr, (caddr_t) &stackptr, sizeof(caddr_t)) != sizeof(caddr_t)) {
0c530ab8
A
716 *tracebuf++ = 0;
717 break;
718 }
719 }
720/* Reset the target pmap */
2d21ac55
A
721 kdp_pmap = NULL;
722 return (uint32_t) (((char *) tracebuf) - tracepos);
0c530ab8
A
723}
724
725/* Routine to encapsulate the 64-bit address read hack*/
726unsigned
727machine_read64(addr64_t srcaddr, caddr_t dstaddr, uint32_t len)
728{
0c530ab8
A
729 unsigned retval;
730
b0d623f7 731 retval = kdp_machine_vm_read(srcaddr, dstaddr, len);
0c530ab8
A
732 return retval;
733}
734
735int
2d21ac55 736machine_trace_thread64(thread_t thread, char *tracepos, char *tracebound, int nframes, boolean_t user_p)
0c530ab8
A
737{
738 uint64_t *tracebuf = (uint64_t *)tracepos;
739 uint32_t fence = 0;
740 addr64_t stackptr = 0;
741 uint64_t stacklimit = 0xb0000000;
742 int framecount = 0;
743 addr64_t init_srr0 = 0;
744 addr64_t prevsp = 0;
745 unsigned framesize = 2 * sizeof(addr64_t);
746
747 if (user_p) {
748 init_srr0 = thread->machine.upcb->save_srr0;
749 stackptr = thread->machine.upcb->save_r1;
750 stacklimit = 0xffffffffffffffffULL;
751 kdp_pmap = thread->task->map->pmap;
752 }
753 else {
754 stackptr = thread->machine.pcb->save_r1;
755 init_srr0 = thread->machine.pcb->save_srr0;
756 }
757
758 *tracebuf++ = init_srr0;
759
760 for (framecount = 0; framecount < nframes; framecount++) {
761
2d21ac55 762 if ((uint32_t)(tracebound - ((char *)tracebuf)) < (4 * framesize)) {
0c530ab8
A
763 tracebuf--;
764 break;
765 }
766
767 *tracebuf++ = stackptr;
768
769 if (!stackptr || (stackptr == fence)){
770 break;
771 }
772 if (stackptr < prevsp) {
773 break;
774 }
775 if (stackptr & 0x000000F) {
776 break;
777 }
778 if (stackptr > stacklimit) {
779 break;
780 }
781
782 if (machine_read64(stackptr+LR_OFFSET64, (caddr_t) tracebuf, sizeof(addr64_t)) != sizeof(addr64_t)) {
783 break;
784 }
785 tracebuf++;
786
787 prevsp = stackptr;
788 if (machine_read64(stackptr, (caddr_t) &stackptr, sizeof(addr64_t)) != sizeof(addr64_t)) {
789 *tracebuf++ = 0;
790 break;
791 }
792 }
793
2d21ac55
A
794 kdp_pmap = NULL;
795 return (uint32_t) (((char *) tracebuf) - tracepos);
796}
797
0c530ab8 798
2d21ac55
A
799void
800kdp_ml_enter_debugger(void)
801{
802 __asm__ __volatile__("tw 4,r3,r3");
0c530ab8 803}
b0d623f7
A
804
805int
806kdp_machine_ioport_read(kdp_readioport_req_t *rq, caddr_t data, uint16_t lcpu)
807{
808 return 0;
809}
810
811int
812kdp_machine_ioport_write(kdp_writeioport_req_t *rq, caddr_t data, uint16_t lcpu)
813{
814 return 0;
815}
816
817int
818kdp_machine_msr64_read(kdp_readmsr64_req_t *rq, caddr_t data, uint16_t lcpu)
819{
820 return 0;
821}
822
823int
824kdp_machine_msr64_write(kdp_writemsr64_req_t *rq, __unused caddr_t data, uint16_t lcpu)
825{
826 return 0;
827}