|
|
1.1 root 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: */
22: /*
23: * Copyright (c) 1997 Apple Computer, Inc. All rights reserved.
24: * Copyright (c) 1994 NeXT Computer, Inc. All rights reserved.
25: *
26: * machdep/ppc/kdp_machdep.c
27: *
28: * Machine-dependent code for Remote Debugging Protocol
29: *
30: * March, 1997 Created. Umesh Vaishampayan [[email protected]]
31: *
32: */
33:
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>
41:
42: #define KDP_TEST_HARNESS 0
43: #if KDP_TEST_HARNESS
44: #define dprintf(x) kprintf x
45: #else
46: #define dprintf(x)
47: #endif
48:
49: void print_saved_state(void *);
50: void kdp_call(void);
51: void kdp_trap( unsigned int, struct ppc_thread_state *);
52: int kdp_getc(void);
53: boolean_t kdp_call_kdb(void);
54:
55: void
56: kdp_exception(
57: unsigned char *pkt,
58: int *len,
59: unsigned short *remote_port,
60: unsigned int exception,
61: unsigned int code,
62: unsigned int subcode
63: )
64: {
65: struct {
66: kdp_exception_t pkt;
67: kdp_exc_info_t exc;
68: } aligned_pkt;
69: kdp_exception_t *rq = (kdp_exception_t *)&aligned_pkt;
70:
71: bcopy((char *)pkt, (char *)rq, sizeof(*rq));
72: rq->hdr.request = KDP_EXCEPTION;
73: rq->hdr.is_reply = 0;
74: rq->hdr.seq = kdp.exception_seq;
75: rq->hdr.key = 0;
76: rq->hdr.len = sizeof (*rq) + sizeof(kdp_exc_info_t);
77:
78: rq->n_exc_info = 1;
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;
83:
84: rq->hdr.len += rq->n_exc_info * sizeof (kdp_exc_info_t);
85:
86: bcopy((char *)rq, (char *)pkt, rq->hdr.len);
87:
88: kdp.exception_ack_needed = TRUE;
89:
90: *remote_port = kdp.exception_port;
91: *len = rq->hdr.len;
92: }
93:
94: boolean_t
95: kdp_exception_ack(
96: unsigned char *pkt,
97: int len
98: )
99: {
100: kdp_exception_ack_t aligned_pkt;
101: kdp_exception_ack_t *rq = (kdp_exception_ack_t *)&aligned_pkt;
102:
103: if (len < sizeof (*rq))
104: return(FALSE);
105:
106: bcopy((char *)pkt, (char *)rq, sizeof(*rq));
107:
108: if (!rq->hdr.is_reply || rq->hdr.request != KDP_EXCEPTION)
109: return(FALSE);
110:
111: dprintf(("kdp_exception_ack seq %x %x\n", rq->hdr.seq, kdp.exception_seq));
112:
113: if (rq->hdr.seq == kdp.exception_seq) {
114: kdp.exception_ack_needed = FALSE;
115: kdp.exception_seq++;
116: }
117: return(TRUE);
118: }
119:
120: static void
121: kdp_getintegerstate(
122: struct ppc_thread_state *state
123: )
124: {
125: struct ppc_thread_state *saved_state;
126:
127: saved_state = kdp.saved_state;
128:
129: bzero((char *)state,sizeof (struct ppc_thread_state)) ;
130:
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 */
170: }
171:
172: kdp_error_t
173: kdp_machine_read_regs(
174: unsigned int cpu,
175: unsigned int flavor,
176: char *data,
177: int *size
178: )
179: {
180: switch (flavor) {
181:
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;
187:
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;
193:
194: default:
195: dprintf(("kdp_readregs bad flavor %d\n"));
196: return KDPERR_BADFLAVOR;
197: }
198: }
199:
200: static void
201: kdp_setintegerstate(
202: struct ppc_thread_state *state
203: )
204: {
205: struct ppc_thread_state *saved_state;
206:
207: saved_state = kdp.saved_state;
208:
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 */
248: }
249:
250: kdp_error_t
251: kdp_machine_write_regs(
252: unsigned int cpu,
253: unsigned int flavor,
254: char *data,
255: int *size
256: )
257: {
258: switch (flavor) {
259:
260: case PPC_THREAD_STATE:
261: dprintf(("kdp_writeregs THREAD_STATE\n"));
262: kdp_setintegerstate((struct ppc_thread_state *)data);
263:
264: #if KDP_TEST_HARNESS
265: DumpTheSave((struct savearea *)data); /* (TEST/DEBUG) */
266: #endif
267: return KDPERR_NO_ERROR;
268:
269: case PPC_FLOAT_STATE:
270: dprintf(("kdp_writeregs THREAD_FPSTATE\n"));
271: return KDPERR_NO_ERROR;
272:
273: default:
274: dprintf(("kdp_writeregs bad flavor %d\n"));
275: return KDPERR_BADFLAVOR;
276: }
277: }
278:
279: void
280: kdp_machine_hostinfo(
281: kdp_hostinfo_t *hostinfo
282: )
283: {
284: machine_slot_t m;
285: int i;
286:
287: hostinfo->cpus_mask = 0;
288:
289: for (i = 0; i < machine_info.max_cpus; i++) {
290: m = &machine_slot[i];
291: if (!m->is_cpu)
292: continue;
293:
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;
298: }
299: }
300: }
301:
302: void
303: kdp_panic(
304: const char *msg
305: )
306: {
307: printf("kdp panic: %s\n", msg);
308: while(1) {}
309: }
310:
311:
312: void
313: kdp_reboot(void)
314: {
315: halt_all_cpus(TRUE);;
316: }
317:
318: int
319: kdp_intr_disbl(void)
320: {
321: return (splhigh());
322: }
323:
324: void
325: kdp_intr_enbl(int s)
326: {
327: splx(s);
328: }
329:
330: void
331: kdp_us_spin(int usec)
332: {
333: extern void delay(int);
334:
335: delay(usec/100);
336: }
337:
338: void print_saved_state(void *state)
339: {
340: struct ppc_thread_state *saved_state;
341:
342: saved_state = state;
343:
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);
348:
349: }
350:
351: void
352: kdp_call()
353: {
354: Debugger("inline call to debugger(machine_startup)");
355: }
356:
357: /*
358: * table to convert system specific code to generic codes for kdb
359: */
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) */
411: };
412:
413: int
414: kdp_getc()
415: {
416: return(cnmaygetc());
417: }
418:
419: int kdp_backtrace;
420: int kdp_sr_dump;
421: int kdp_dabr;
422: int kdp_noisy;
423:
424: #define kdp_code(x) kdp_trap_codes[((x)==T_AST?0x31:(x)/T_VECTOR_SIZE)]
425:
426: void
427: kdp_trap(
428: unsigned int exception,
429: struct ppc_thread_state *saved_state
430: )
431: {
432: unsigned int *fp;
433: unsigned int register sp;
434: struct ppc_thread_state *state;
435:
436: if (kdp_noisy) {
437: if (kdp_backtrace) {
438: printf("\nvector=%x, \n", exception/4);
439: #ifdef XXX
440: regDump(saved_state);
441: #endif
442: sp = saved_state->r1;
443: printf("stack backtrace - sp(%x) ", sp);
444: fp = (unsigned int *) *((unsigned int *)sp);
445: while (fp) {
446: printf("0x%08x ", fp[2]);
447: fp = (unsigned int *)*fp;
448: }
449: printf("\n");
450: }
451: #ifdef XXX
452: if (kdp_sr_dump) {
453: dump_segment_registers();
454: }
455: #endif
456:
457: printf("vector=%d ", exception/4);
458: }
459:
460: kdp_raise_exception(kdp_code(exception), 0, 0, saved_state);
461:
462: if (kdp_noisy)
463: printf("kdp_trap: kdp_raise_exception() ret\n");
464:
465: if (*((int *)saved_state->srr0) == 0x7c800008)
466: saved_state->srr0 += 4; /* BKPT_SIZE */
467:
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 */
470: }
471: else db_run_mode = STEP_CONTINUE; /* Otherwise we are continuing */
472:
473:
474: #ifdef XXX
475: mtspr(dabr, kdp_dabr);
476: #endif
477: }
478:
479: boolean_t
480: kdp_call_kdb(
481: void)
482: {
483: switch_debugger=1;
484: return(TRUE);
485: }
486:
487: void kdp_print_registers(struct ppc_saved_state *state)
488: {
489: int i;
490: for (i=0; i<32; i++) {
491: if ((i % 8) == 0)
492: printf("\n%4d :",i);
493: printf(" %08x",*(&state->r0+i));
494: }
495: printf("\n");
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);
506: printf("\n");
507: }
508:
509: void
510: kdp_print_backtrace(
511: unsigned int exception,
512: struct ppc_saved_state *saved_state)
513: {
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;
517:
518: disableDebugOuput = FALSE;
519: debug_mode = TRUE;
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");
525: while(1);
526: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.