|
|
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.