]> git.saurik.com Git - apple/xnu.git/blame - osfmk/kdp/ml/ppc/kdp_machdep.c
xnu-344.tar.gz
[apple/xnu.git] / osfmk / kdp / ml / ppc / kdp_machdep.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 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 */
1c79356b
A
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
31#define KDP_TEST_HARNESS 0
32#if KDP_TEST_HARNESS
33#define dprintf(x) kprintf x
34#else
35#define dprintf(x)
36#endif
37
38void print_saved_state(void *);
39void kdp_call(void);
9bccf70c 40void kdp_trap( unsigned int, struct savearea *saved_state);
1c79356b
A
41int kdp_getc(void);
42boolean_t kdp_call_kdb(void);
43
44void
45kdp_exception(
46 unsigned char *pkt,
47 int *len,
48 unsigned short *remote_port,
49 unsigned int exception,
50 unsigned int code,
51 unsigned int subcode
52)
53{
54 struct {
55 kdp_exception_t pkt;
56 kdp_exc_info_t exc;
57 } aligned_pkt;
58 kdp_exception_t *rq = (kdp_exception_t *)&aligned_pkt;
59
60 bcopy((char *)pkt, (char *)rq, sizeof(*rq));
61 rq->hdr.request = KDP_EXCEPTION;
62 rq->hdr.is_reply = 0;
63 rq->hdr.seq = kdp.exception_seq;
64 rq->hdr.key = 0;
65 rq->hdr.len = sizeof (*rq) + sizeof(kdp_exc_info_t);
66
67 rq->n_exc_info = 1;
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;
72
73 rq->hdr.len += rq->n_exc_info * sizeof (kdp_exc_info_t);
74
75 bcopy((char *)rq, (char *)pkt, rq->hdr.len);
76
77 kdp.exception_ack_needed = TRUE;
78
79 *remote_port = kdp.exception_port;
80 *len = rq->hdr.len;
81}
82
83boolean_t
84kdp_exception_ack(
85 unsigned char *pkt,
86 int len
87)
88{
89 kdp_exception_ack_t aligned_pkt;
90 kdp_exception_ack_t *rq = (kdp_exception_ack_t *)&aligned_pkt;
91
92 if (len < sizeof (*rq))
93 return(FALSE);
94
95 bcopy((char *)pkt, (char *)rq, sizeof(*rq));
96
97 if (!rq->hdr.is_reply || rq->hdr.request != KDP_EXCEPTION)
98 return(FALSE);
99
100 dprintf(("kdp_exception_ack seq %x %x\n", rq->hdr.seq, kdp.exception_seq));
101
102 if (rq->hdr.seq == kdp.exception_seq) {
103 kdp.exception_ack_needed = FALSE;
104 kdp.exception_seq++;
105 }
106 return(TRUE);
107}
108
109static void
110kdp_getintegerstate(
111 struct ppc_thread_state *state
112)
113{
9bccf70c 114 struct savearea *saved_state;
1c79356b
A
115
116 saved_state = kdp.saved_state;
117
118 bzero((char *)state,sizeof (struct ppc_thread_state)) ;
119
9bccf70c
A
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;
1c79356b
A
158}
159
160kdp_error_t
161kdp_machine_read_regs(
162 unsigned int cpu,
163 unsigned int flavor,
164 char *data,
165 int *size
166)
167{
168 switch (flavor) {
169
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;
175
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;
181
182 default:
183 dprintf(("kdp_readregs bad flavor %d\n"));
184 return KDPERR_BADFLAVOR;
185 }
186}
187
188static void
189kdp_setintegerstate(
190 struct ppc_thread_state *state
191)
192{
9bccf70c 193 struct savearea *saved_state;
1c79356b
A
194
195 saved_state = kdp.saved_state;
196
9bccf70c
A
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;
1c79356b
A
235}
236
237kdp_error_t
238kdp_machine_write_regs(
239 unsigned int cpu,
240 unsigned int flavor,
241 char *data,
242 int *size
243)
244{
245 switch (flavor) {
246
247 case PPC_THREAD_STATE:
248 dprintf(("kdp_writeregs THREAD_STATE\n"));
249 kdp_setintegerstate((struct ppc_thread_state *)data);
250
251#if KDP_TEST_HARNESS
252 DumpTheSave((struct savearea *)data); /* (TEST/DEBUG) */
253#endif
254 return KDPERR_NO_ERROR;
255
256 case PPC_FLOAT_STATE:
257 dprintf(("kdp_writeregs THREAD_FPSTATE\n"));
258 return KDPERR_NO_ERROR;
259
260 default:
261 dprintf(("kdp_writeregs bad flavor %d\n"));
262 return KDPERR_BADFLAVOR;
263 }
264}
265
266void
267kdp_machine_hostinfo(
268 kdp_hostinfo_t *hostinfo
269)
270{
271 machine_slot_t m;
272 int i;
273
274 hostinfo->cpus_mask = 0;
0b4e3aa0 275 hostinfo->cpu_type = 0;
1c79356b
A
276
277 for (i = 0; i < machine_info.max_cpus; i++) {
278 m = &machine_slot[i];
279 if (!m->is_cpu)
280 continue;
281
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;
286 }
287 }
288}
289
290void
291kdp_panic(
292 const char *msg
293)
294{
295 printf("kdp panic: %s\n", msg);
296 while(1) {}
297}
298
299
300void
301kdp_reboot(void)
302{
303 halt_all_cpus(TRUE);;
304}
305
306int
307kdp_intr_disbl(void)
308{
309 return (splhigh());
310}
311
312void
313kdp_intr_enbl(int s)
314{
315 splx(s);
316}
317
318void
319kdp_us_spin(int usec)
320{
321 extern void delay(int);
322
323 delay(usec/100);
324}
325
326void print_saved_state(void *state)
327{
328 struct ppc_thread_state *saved_state;
329
330 saved_state = state;
331
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);
336
337}
338
339void
340kdp_call()
341{
342 Debugger("inline call to debugger(machine_startup)");
343}
344
345/*
346 * table to convert system specific code to generic codes for kdb
347 */
348int 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) */
399};
400
401int
402kdp_getc()
403{
404 return(cnmaygetc());
405}
406
407int kdp_backtrace;
408int kdp_sr_dump;
409int kdp_dabr;
410int kdp_noisy;
411
412#define kdp_code(x) kdp_trap_codes[((x)==T_AST?0x31:(x)/T_VECTOR_SIZE)]
413
414void
415kdp_trap(
416 unsigned int exception,
9bccf70c 417 struct savearea *saved_state
1c79356b
A
418)
419{
420 unsigned int *fp;
9bccf70c
A
421 unsigned int register sp;
422 struct savearea *state;
1c79356b
A
423
424 if (kdp_noisy) {
425 if (kdp_backtrace) {
426 printf("\nvector=%x, \n", exception/4);
9bccf70c 427 sp = saved_state->save_r1;
1c79356b
A
428 printf("stack backtrace - sp(%x) ", sp);
429 fp = (unsigned int *) *((unsigned int *)sp);
430 while (fp) {
431 printf("0x%08x ", fp[2]);
432 fp = (unsigned int *)*fp;
433 }
434 printf("\n");
435 }
436#ifdef XXX
437 if (kdp_sr_dump) {
438 dump_segment_registers();
439 }
440#endif
441
9bccf70c 442 printf("vector=%d ", exception/4);
1c79356b 443 }
1c79356b
A
444 kdp_raise_exception(kdp_code(exception), 0, 0, saved_state);
445
446 if (kdp_noisy)
447 printf("kdp_trap: kdp_raise_exception() ret\n");
448
9bccf70c
A
449 if (*((int *)saved_state->save_srr0) == 0x7c800008)
450 saved_state->save_srr0 += 4; /* BKPT_SIZE */
451
452 if(saved_state->save_srr1 & (MASK(MSR_SE) | MASK(MSR_BE))) { /* Are we just stepping or continuing */
1c79356b
A
453 db_run_mode = STEP_ONCE; /* We are stepping */
454 }
455 else db_run_mode = STEP_CONTINUE; /* Otherwise we are continuing */
9bccf70c 456
1c79356b
A
457#ifdef XXX
458 mtspr(dabr, kdp_dabr);
459#endif
460}
461
462boolean_t
463kdp_call_kdb(
464 void)
465{
466 switch_debugger=1;
467 return(TRUE);
468}
469
9bccf70c 470void kdp_print_registers(struct savearea *state)
1c79356b
A
471{
472 int i;
473 for (i=0; i<32; i++) {
474 if ((i % 8) == 0)
475 printf("\n%4d :",i);
9bccf70c 476 printf(" %08x",*(&state->save_r0+i));
1c79356b
A
477 }
478 printf("\n");
9bccf70c
A
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,
1c79356b
A
485 "\x10\x11""EE\x12PR\x13""FP\x14ME\x15""FE0\x16SE\x18"
486 "FE1\x19""AL\x1a""EP\x1bIT\x1c""DT");
1c79356b
A
487 printf("\n");
488}
489
490void
491kdp_print_backtrace(
492 unsigned int exception,
9bccf70c 493 struct savearea *saved_state)
1c79356b 494{
9bccf70c
A
495 extern void kdp_print_registers(struct savearea *);
496 extern void print_backtrace(struct savearea *);
1c79356b
A
497 extern unsigned int debug_mode, disableDebugOuput;
498
499 disableDebugOuput = FALSE;
500 debug_mode = TRUE;
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");
506 while(1);
507}
9bccf70c
A
508
509unsigned int kdp_ml_get_breakinsn()
510{
511 return 0x7fe00008;
512}