|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Copyright (c) 1997 Apple Computer, Inc. All rights reserved.
27: * Copyright (c) 1994 NeXT Computer, Inc. All rights reserved.
28: *
29: * machdep/ppc/kdp_machdep.c
30: *
31: * Machine-dependent code for Remote Debugging Protocol
32: *
33: * History:
34: * March, 1997 Umesh Vaishampayan [[email protected]]
35: * Created.
36: * 03 Nov 1997 Herb Ruth [[email protected]]
37: * Added extern declarations for implicit function
38: * declarations. Changed dprintf macro to call kprintf()
39: * instead of kdp_printf() when KDP_TEST_HARNESS==1
40: * Added sync and isync ppc instructions to kdp_flush_cache().
41: *
42: */
43:
44: #import <sys/param.h>
45: #import <sys/systm.h>
46: #import <sys/mbuf.h>
47: #import <sys/socket.h>
48: #import <net/if.h>
49: #import <net/route.h>
50: #import <netinet/in.h>
51: #import <netinet/in_systm.h>
52: #import <netinet/ip.h>
53: #import <netinet/ip_var.h>
54: #import <netinet/in_pcb.h>
55: #import <mach/mach_types.h>
56: #import <kern/kdp_internal.h>
57: #import <kern/miniMon.h>
58: #import <bsd/sys/conf.h>
59: #import <bsd/sys/reboot.h>
60: #include <stdarg.h>
61: #import <sys/subr_prf.h>
62: #include <mach/exception.h>
63:
64: #define KDP_TEST_HARNESS 0
65: #if KDP_TEST_HARNESS
66: /*#define dprintf(x) kdp_printf x*/
67: #define dprintf(x) kprintf x
68: #else
69: #define dprintf(x)
70: #endif
71:
72: /* 03 Nov 1997 */
73: #warning extern declarations -- FIXME XXX
74:
75: extern int cnputc(char c);
76: extern void kprintf(const char *format, ...);
77: extern boot(int paniced, int howto, char *command);
78:
79: extern unsigned splhigh(void);
80: extern void splx(unsigned level);
81: extern void us_spin(int usec);
82:
83: void
84: kdp_printf(
85: const char *format,
86: ...
87: )
88: {
89: va_list ap;
90: static char rdpPrintfBuf[512];
91: char *p = rdpPrintfBuf;
92:
93: va_start(ap, format);
94: prf(format, ap, TOSTR, (struct tty *)&p);
95: va_end(ap);
96: *p++ = '\0';
97:
98: p = rdpPrintfBuf;
99: while (*p)
100: cnputc(*p++);
101: }
102:
103:
104: void
105: kdp_exception(
106: unsigned char *pkt,
107: int *len,
108: unsigned short *remote_port,
109: unsigned int exception,
110: unsigned int code,
111: unsigned int subcode
112: )
113: {
114: struct {
115: kdp_exception_t pkt;
116: kdp_exc_info_t exc;
117: } aligned_pkt;
118:
119: kdp_exception_t *rq = (kdp_exception_t *)&aligned_pkt;
120:
121: bcopy(pkt, rq, sizeof(*rq));
122: rq->hdr.request = KDP_EXCEPTION;
123: rq->hdr.is_reply = 0;
124: rq->hdr.seq = kdp.exception_seq;
125: rq->hdr.key = 0;
126: rq->hdr.len = sizeof (*rq) + sizeof(kdp_exc_info_t);
127:
128: rq->n_exc_info = 1;
129: rq->exc_info[0].cpu = 0;
130: rq->exc_info[0].exception = exception;
131: rq->exc_info[0].code = code;
132: rq->exc_info[0].subcode = subcode;
133:
134: rq->hdr.len += rq->n_exc_info * sizeof (kdp_exc_info_t);
135:
136: bcopy(rq, pkt, rq->hdr.len);
137:
138: kdp.exception_ack_needed = TRUE;
139:
140: *remote_port = kdp.exception_port;
141: *len = rq->hdr.len;
142: }
143:
144: void
145: kdp_exception_ack(
146: unsigned char *pkt,
147: int len
148: )
149: {
150: kdp_exception_ack_t aligned_pkt;
151: kdp_exception_ack_t *rq = (kdp_exception_ack_t *)&aligned_pkt;
152:
153: if (len < sizeof (*rq))
154: return;
155:
156: bcopy(pkt, rq, sizeof(*rq));
157:
158: if (!rq->hdr.is_reply || rq->hdr.request != KDP_EXCEPTION)
159: return;
160:
161: dprintf(("kdp_exception_ack: seq 0x%08x 0x%08x\n",
162: rq->hdr.seq, kdp.exception_seq));
163:
164: if (rq->hdr.seq == kdp.exception_seq) {
165: kdp.exception_ack_needed = FALSE;
166: kdp.exception_seq++;
167: }
168: }
169:
170: static void
171: kdp_getintegerstate(
172: struct ppc_thread_state *state
173: )
174: {
175: struct ppc_thread_state *saved_state;
176:
177: saved_state = kdp.saved_state;
178:
179: *state = (struct ppc_thread_state) { 0 };
180:
181: state->srr0 = saved_state->srr0;
182: state->srr1 = saved_state->srr1;
183: state->r0 = saved_state->r0;
184: state->r1 = saved_state->r1;
185: state->r2 = saved_state->r2;
186: state->r3 = saved_state->r3;
187: state->r4 = saved_state->r4;
188: state->r5 = saved_state->r5;
189: state->r6 = saved_state->r6;
190: state->r7 = saved_state->r7;
191: state->r8 = saved_state->r8;
192: state->r9 = saved_state->r9;
193: state->r10 = saved_state->r10;
194: state->r11 = saved_state->r11;
195: state->r12 = saved_state->r12;
196: state->r13 = saved_state->r13;
197: state->r14 = saved_state->r14;
198: state->r15 = saved_state->r15;
199: state->r16 = saved_state->r16;
200: state->r17 = saved_state->r17;
201: state->r18 = saved_state->r18;
202: state->r19 = saved_state->r19;
203: state->r20 = saved_state->r20;
204: state->r21 = saved_state->r21;
205: state->r22 = saved_state->r22;
206: state->r23 = saved_state->r23;
207: state->r24 = saved_state->r24;
208: state->r25 = saved_state->r25;
209: state->r26 = saved_state->r26;
210: state->r27 = saved_state->r27;
211: state->r28 = saved_state->r28;
212: state->r29 = saved_state->r29;
213: state->r30 = saved_state->r30;
214: state->r31 = saved_state->r31;
215: state->cr = saved_state->cr;
216: state->xer = saved_state->xer;
217: state->lr = saved_state->lr;
218: state->ctr = saved_state->ctr;
219: state->mq = saved_state->mq; /* This is BOGUS ! (601) ONLY */
220: state->pad = saved_state->pad;
221: }
222:
223: kdp_error_t
224: kdp_machine_read_regs(
225: unsigned int cpu,
226: unsigned int flavor,
227: char *data,
228: int *size
229: )
230: {
231: switch (flavor) {
232:
233: case PPC_THREAD_STATE:
234: // dprintf(("kdp_machine_read_regs: THREAD_STATE\n"));
235: dprintf(("kdp_machine_read_regs\n"));
236: kdp_getintegerstate((struct ppc_thread_state *)data);
237: *size = sizeof (struct ppc_thread_state);
238: return KDPERR_NO_ERROR;
239:
240: case PPC_FLOAT_STATE:
241: dprintf(("kdp_machine_read_regs: THREAD_FPSTATE\n"));
242: *(struct ppc_float_state *)data = (struct ppc_float_state) { {0.0}, 0, 0 };
243: *size = sizeof (struct ppc_float_state);
244: return KDPERR_NO_ERROR;
245:
246: default:
247: dprintf(("kdp_machine_read_regs: bad flavor %d\n"));
248: return KDPERR_BADFLAVOR;
249: }
250: }
251:
252: static void
253: kdp_setintegerstate(
254: struct ppc_thread_state *state
255: )
256: {
257: struct ppc_thread_state *saved_state;
258:
259: saved_state = kdp.saved_state;
260:
261: saved_state->srr0 = state->srr0 ;
262: saved_state->srr1 = state->srr1 ;
263: saved_state->r0 = state->r0 ;
264: saved_state->r1 = state->r1 ;
265: saved_state->r2 = state->r2 ;
266: saved_state->r3 = state->r3 ;
267: saved_state->r4 = state->r4 ;
268: saved_state->r5 = state->r5 ;
269: saved_state->r6 = state->r6 ;
270: saved_state->r7 = state->r7 ;
271: saved_state->r8 = state->r8 ;
272: saved_state->r9 = state->r9 ;
273: saved_state->r10 = state->r10 ;
274: saved_state->r11 = state->r11 ;
275: saved_state->r12 = state->r12 ;
276: saved_state->r13 = state->r13 ;
277: saved_state->r14 = state->r14 ;
278: saved_state->r15 = state->r15 ;
279: saved_state->r16 = state->r16 ;
280: saved_state->r17 = state->r17 ;
281: saved_state->r18 = state->r18 ;
282: saved_state->r19 = state->r19 ;
283: saved_state->r20 = state->r20 ;
284: saved_state->r21 = state->r21 ;
285: saved_state->r22 = state->r22 ;
286: saved_state->r23 = state->r23 ;
287: saved_state->r24 = state->r24 ;
288: saved_state->r25 = state->r25 ;
289: saved_state->r26 = state->r26 ;
290: saved_state->r27 = state->r27 ;
291: saved_state->r28 = state->r28 ;
292: saved_state->r29 = state->r29 ;
293: saved_state->r30 = state->r30 ;
294: saved_state->r31 = state->r31 ;
295: saved_state->cr = state->cr ;
296: saved_state->xer = state->xer ;
297: saved_state->lr = state->lr ;
298: saved_state->ctr = state->ctr ;
299: saved_state->mq = state->mq ; /* BOGUS! (601)ONLY */
300: saved_state->pad = state->pad ;
301: }
302:
303: kdp_error_t
304: kdp_machine_write_regs(
305: unsigned int cpu,
306: unsigned int flavor,
307: char *data,
308: int *size
309: )
310: {
311: switch (flavor) {
312:
313: case PPC_THREAD_STATE:
314: // dprintf(("kdp_machine_write_regs: THREAD_STATE\n"));
315: dprintf(("kdp_machine_write_regs\n"));
316: kdp_setintegerstate((struct ppc_thread_state *)data);
317: return KDPERR_NO_ERROR;
318:
319: case PPC_FLOAT_STATE:
320: dprintf(("kdp_machine_write_regs: THREAD_FPSTATE\n"));
321: return KDPERR_NO_ERROR;
322:
323: default:
324: dprintf(("kdp_machine_write_regs: bad flavor %d\n"));
325: return KDPERR_BADFLAVOR;
326: }
327: }
328:
329: void
330: kdp_machine_hostinfo(
331: kdp_hostinfo_t *hostinfo
332: )
333: {
334: machine_slot_t m;
335: int i;
336:
337: hostinfo->cpus_mask = 0;
338:
339: for (i = 0; i < machine_info.max_cpus; i++) {
340: m = &machine_slot[i];
341: if (!m->is_cpu)
342: continue;
343:
344: hostinfo->cpus_mask |= (1 << i);
345: if (hostinfo->cpu_type == 0) {
346: hostinfo->cpu_type = m->cpu_type;
347: hostinfo->cpu_subtype = m->cpu_subtype;
348: }
349: }
350: }
351:
352: void
353: kdp_panic(
354: const char *msg
355: )
356: {
357: dprintf(("kdp_panic: exception, code & subcode not passed to safe_prf.\n"));
358: safe_prf("kdp panic: %s\n", msg);
359: while(1) {}
360: }
361:
362:
363: void
364: kdp_reboot(void)
365: {
366: boot(RB_BOOT, RB_AUTOBOOT | RB_NOSYNC, "");
367: }
368:
369: int
370: kdp_intr_disbl(void)
371: {
372: return splhigh();
373: }
374:
375: void
376: kdp_intr_enbl(int s)
377: {
378: splx(s);
379: }
380:
381: void
382: kdp_us_spin(int usec)
383: {
384: us_spin(usec);
385: }
386:
387: void print_saved_state(void *state)
388: {
389: struct ppc_thread_state *saved_state;
390:
391: saved_state = state;
392:
393: safe_prf("pc = 0x%x\n", saved_state->srr0);
394: safe_prf("msr = 0x%x\n", saved_state->srr1);
395: safe_prf("rp = 0x%x\n", saved_state->lr);
396: safe_prf("sp = 0x%x\n", saved_state->r1);
397: }
398:
399: void
400: kdp_flush_cache(void)
401: {
402: __asm__ volatile ("sync");
403: __asm__ volatile ("isync");
404: }
405:
406: #if 1
407: void
408: kdp_init_integerstate(struct ppc_thread_state *instate)
409: {
410: __asm__ volatile (".set SS_R0,8");
411: __asm__ volatile (".set SS_R1,12");
412: __asm__ volatile (".set SS_R2,16");
413: __asm__ volatile (".set SS_R3,20");
414: __asm__ volatile (".set SS_R4,24");
415: __asm__ volatile (".set SS_R5,28");
416: __asm__ volatile (".set SS_R6,32");
417: __asm__ volatile (".set SS_R7,36");
418: __asm__ volatile (".set SS_R8,40");
419: __asm__ volatile (".set SS_R9,44");
420: __asm__ volatile (".set SS_R10,48");
421: __asm__ volatile (".set SS_R11,52");
422: __asm__ volatile (".set SS_R12,56");
423: __asm__ volatile (".set SS_R13,60");
424: __asm__ volatile (".set SS_R14,64");
425: __asm__ volatile (".set SS_R15,68");
426: __asm__ volatile (".set SS_R16,72");
427: __asm__ volatile (".set SS_R17,76");
428: __asm__ volatile (".set SS_R18,80");
429: __asm__ volatile (".set SS_R19,84");
430: __asm__ volatile (".set SS_R20,88");
431: __asm__ volatile (".set SS_R21,92");
432: __asm__ volatile (".set SS_R22,96");
433: __asm__ volatile (".set SS_R23,100");
434: __asm__ volatile (".set SS_R24,104");
435: __asm__ volatile (".set SS_R25,108");
436: __asm__ volatile (".set SS_R26,112");
437: __asm__ volatile (".set SS_R27,116");
438: __asm__ volatile (".set SS_R28,120");
439: __asm__ volatile (".set SS_R29,124");
440: __asm__ volatile (".set SS_R30,128");
441: __asm__ volatile (".set SS_R31,132");
442: __asm__ volatile (".set SS_CR,136");
443: __asm__ volatile (".set SS_XER,140");
444: __asm__ volatile (".set SS_LR,144");
445: __asm__ volatile (".set SS_CTR,148");
446: __asm__ volatile (".set SS_SRR0,0");
447: __asm__ volatile (".set SS_SRR1,4");
448:
449: __asm__ volatile("stw r0, SS_R0(r3)");
450: __asm__ volatile("stw r5, SS_R5(r3)");
451:
452: __asm__ volatile("addis r5, 0, hi16(L_kdbmarker)");
453: __asm__ volatile("ori r5, r5, lo16(L_kdbmarker)");
454:
455: __asm__ volatile("lwz r0, 0(r1)");
456: __asm__ volatile("stw r0, SS_R1(r3)");
457: __asm__ volatile(".noflag_reg 2");
458: __asm__ volatile("stw r2, SS_R2(r3)");
459: __asm__ volatile(".flag_reg 2");
460: __asm__ volatile("stw r3, SS_R3(r3)");
461: __asm__ volatile("stw r4, SS_R4(r3)");
462: __asm__ volatile("stw r6, SS_R6(r3)");
463: __asm__ volatile("stw r7, SS_R7(r3)");
464: __asm__ volatile("stw r8, SS_R8(r3)");
465: __asm__ volatile("stw r9, SS_R9(r3)");
466: __asm__ volatile("stw r10, SS_R10(r3)");
467: __asm__ volatile("stw r11, SS_R11(r3)");
468: __asm__ volatile("stw r12, SS_R12(r3)");
469: __asm__ volatile(".noflag_reg 13");
470: __asm__ volatile("stw r13, SS_R13(r3)");
471: __asm__ volatile(".flag_reg 13");
472: __asm__ volatile("stw r14, SS_R14(r3)");
473: __asm__ volatile("stw r15, SS_R15(r3)");
474: __asm__ volatile("stw r16, SS_R16(r3)");
475: __asm__ volatile("stw r17, SS_R17(r3)");
476: __asm__ volatile("stw r18, SS_R18(r3)");
477: __asm__ volatile("stw r19, SS_R19(r3)");
478: __asm__ volatile("stw r20, SS_R20(r3)");
479: __asm__ volatile("stw r21, SS_R21(r3)");
480: __asm__ volatile("stw r22, SS_R22(r3)");
481: __asm__ volatile("stw r23, SS_R23(r3)");
482: __asm__ volatile("stw r24, SS_R24(r3)");
483: __asm__ volatile("stw r25, SS_R25(r3)");
484: __asm__ volatile("stw r26, SS_R26(r3)");
485: __asm__ volatile("stw r27, SS_R27(r3)");
486: __asm__ volatile("stw r28, SS_R28(r3)");
487: __asm__ volatile("stw r29, SS_R29(r3)");
488: __asm__ volatile("stw r30, SS_R30(r3)");
489: __asm__ volatile("stw r31, SS_R31(r3)");
490:
491: __asm__ volatile("mfcr r0");
492: __asm__ volatile("stw r0, SS_CR(r3)");
493:
494: __asm__ volatile("stw r5, SS_SRR0(r3)");
495:
496: // __asm__ volatile("mfsrr0 r0");
497: // __asm__ volatile("stw r0, SS_SRR0(r3)");
498: __asm__ volatile("mfsrr1 r0");
499: __asm__ volatile("stw r0, SS_SRR1(r3)");
500: __asm__ volatile("mfxer r0");
501: __asm__ volatile("stw r0, SS_XER(r3)");
502: __asm__ volatile("mflr r0");
503: __asm__ volatile("stw r0, SS_LR(r3)");
504: __asm__ volatile("mfctr r0");
505: __asm__ volatile("stw r0, SS_CTR(r3)");
506:
507: }
508:
509:
510: void
511: call_kdp()
512: {
513: static struct ppc_thread_state __kdp_space;
514: kdp_init_integerstate(&__kdp_space);
515: kdp_raise_exception(EXC_SOFTWARE, 0, 0, &__kdp_space);
516:
517: __asm__ volatile("L_kdbmarker:");
518: __asm__ volatile("nop");
519:
520: }
521: #endif
522:
523: /*
524: * table to convert system specific code to generic codes for kdb
525: */
526: int kdp_trap_codes[] = {
527: EXC_BAD_ACCESS, /* 0x0000 INVALID EXCEPTION */
528: EXC_BAD_ACCESS, /* 0x0100 System reset */
529: EXC_BAD_ACCESS, /* 0x0200 Machine check */
530: EXC_BAD_ACCESS, /* 0x0300 Data access */
531: EXC_BAD_ACCESS, /* 0x0400 Instruction access */
532: EXC_BAD_ACCESS, /* 0x0500 External interrupt */
533: EXC_BAD_ACCESS, /* 0x0600 Alignment */
534: EXC_BREAKPOINT, /* 0x0700 Program - fp exc, ill/priv instr, trap */
535: EXC_ARITHMETIC, /* 0x0800 Floating point disabled */
536: EXC_SOFTWARE, /* 0x0900 Decrementer */
537: EXC_BAD_ACCESS, /* 0x0A00 I/O controller interface */
538: EXC_BAD_ACCESS, /* 0x0B00 INVALID EXCEPTION */
539: EXC_SOFTWARE, /* 0x0C00 System call exception */
540: EXC_BREAKPOINT, /* 0x0D00 Trace */
541: EXC_SOFTWARE, /* 0x0E00 FP assist */
542: EXC_SOFTWARE, /* 0x0F00 Performance monitoring */
543: EXC_BAD_ACCESS, /* 0x1000 Instruction PTE miss */
544: EXC_BAD_ACCESS, /* 0x1100 Data load PTE miss */
545: EXC_BAD_ACCESS, /* 0x1200 Data store PTE miss */
546: EXC_BREAKPOINT, /* 0x1300 Instruction bkpt */
547: EXC_SOFTWARE, /* 0x1400 System management */
548: EXC_BAD_ACCESS, /* 0x1500 INVALID EXCEPTION */
549: EXC_BAD_ACCESS, /* 0x1600 INVALID EXCEPTION */
550: EXC_BAD_ACCESS, /* 0x1700 INVALID EXCEPTION */
551: EXC_BAD_ACCESS, /* 0x1800 INVALID EXCEPTION */
552: EXC_BAD_ACCESS, /* 0x1900 INVALID EXCEPTION */
553: EXC_BAD_ACCESS, /* 0x1A00 INVALID EXCEPTION */
554: EXC_BAD_ACCESS, /* 0x1B00 INVALID EXCEPTION */
555: EXC_BAD_ACCESS, /* 0x1C00 INVALID EXCEPTION */
556: EXC_BAD_ACCESS, /* 0x1D00 INVALID EXCEPTION */
557: EXC_BAD_ACCESS, /* 0x1E00 INVALID EXCEPTION */
558: EXC_BAD_ACCESS, /* 0x1F00 INVALID EXCEPTION */
559: EXC_BREAKPOINT, /* 0x2000 Run Mode/Trace */
560: EXC_BAD_ACCESS, /* 0x2100 INVALID EXCEPTION */
561: EXC_BAD_ACCESS, /* 0x2200 INVALID EXCEPTION */
562: EXC_BAD_ACCESS, /* 0x2300 INVALID EXCEPTION */
563: EXC_BAD_ACCESS, /* 0x2400 INVALID EXCEPTION */
564: EXC_BAD_ACCESS, /* 0x2500 INVALID EXCEPTION */
565: EXC_BAD_ACCESS, /* 0x2600 INVALID EXCEPTION */
566: EXC_BAD_ACCESS, /* 0x2700 INVALID EXCEPTION */
567: EXC_BAD_ACCESS, /* 0x2800 INVALID EXCEPTION */
568: EXC_BAD_ACCESS, /* 0x2900 INVALID EXCEPTION */
569: EXC_BAD_ACCESS, /* 0x2A00 INVALID EXCEPTION */
570: EXC_BAD_ACCESS, /* 0x2B00 INVALID EXCEPTION */
571: EXC_BAD_ACCESS, /* 0x2C00 INVALID EXCEPTION */
572: EXC_BAD_ACCESS, /* 0x2D00 INVALID EXCEPTION */
573: EXC_BAD_ACCESS, /* 0x2E00 INVALID EXCEPTION */
574: EXC_BAD_ACCESS, /* 0x2F00 INVALID EXCEPTION */
575: EXC_SOFTWARE /* 0x3000 AST trap (software) */
576: };
577:
578: int kdp_segments[16] = {
579: -1, -1, 0, 3,
580: 4, 5, 0xB, -1,
581: -1, -1, -1, -1,
582: -1, -1, -1, -1
583: };
584:
585: int kdp_space;
586:
587: int
588: kdp_map_segment(unsigned int segment)
589: {
590: segment &= 0xF;
591: return kdp_segments[segment];
592: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.