|
|
1.1 ! root 1: /* @(#)kdb_machdep.c 7.7 (Berkeley) 4/3/90 */ ! 2: ! 3: #include "param.h" ! 4: #include "conf.h" ! 5: #include "user.h" ! 6: #include "proc.h" ! 7: #include "uio.h" ! 8: #include "systm.h" ! 9: #include "reboot.h" ! 10: #include "vmmac.h" ! 11: #include "ioctl.h" ! 12: #include "tty.h" ! 13: ! 14: #include "cpu.h" ! 15: #include "mtpr.h" ! 16: #include "psl.h" ! 17: #include "pte.h" ! 18: #include "reg.h" ! 19: #include "trap.h" ! 20: #include "kdbparam.h" ! 21: ! 22: #define KDBSPACE 1024 /* 1K of memory for breakpoint table */ ! 23: static char kdbbuf[KDBSPACE]; ! 24: static char *kdbend = kdbbuf; ! 25: int kdb_escape; /* allow kdb to be entered on console escape */ ! 26: int kdb_panic; /* allow kdb to be entered on panic/trap */ ! 27: ! 28: extern int (*v_putc)(); ! 29: extern int (*v_getc)(); ! 30: extern int (*v_poll)(); ! 31: /* ! 32: * Dynamically allocate space for the debugger. ! 33: */ ! 34: char * ! 35: kdbmalloc(n) ! 36: u_int n; ! 37: { ! 38: char *old = kdbend; ! 39: ! 40: if (kdbend+n >= kdbbuf+KDBSPACE) { ! 41: printf("kdb: Out of space\n"); ! 42: return ((char *)-1); ! 43: } ! 44: kdbend += n; ! 45: return (old); ! 46: } ! 47: ! 48: /* ! 49: * Initialize the kernel debugger. ! 50: */ ! 51: kdb_init() ! 52: { ! 53: char *symtab, *strtab; ! 54: int strsize; ! 55: extern int end; ! 56: ! 57: kdbsetup(); ! 58: if (bootesym > (char *)&end) { ! 59: symtab = (char *)&end + sizeof (int); ! 60: #define symsize *(int *)&end ! 61: strtab = symtab + symsize; ! 62: strsize = roundup(*(int *)strtab, sizeof (int)); ! 63: if (strtab + strsize == bootesym) { ! 64: printf("[Preserving %d bytes of symbol information]\n", ! 65: symsize + strsize); ! 66: kdbsetsym(symtab, strtab, strtab, strsize); ! 67: } else ! 68: printf("kdb_init: bad bootesym %x, calculated %x\n", ! 69: bootesym, strtab + strsize); ! 70: } ! 71: /* ! 72: * Transfer control to the debugger when magic console sequence ! 73: * is typed only if the system was booted with RB_KDB and the trap ! 74: * enable flag (RB_NOYSNC) set. ! 75: */ ! 76: if ((boothowto&(RB_KDB|RB_NOSYNC)) == (RB_KDB|RB_NOSYNC)) ! 77: kdb_escape = 1; ! 78: ! 79: if (boothowto&RB_KDB) ! 80: kdb_panic = 1; ! 81: ! 82: /* ! 83: * If boot flags indicate, force entry into the debugger. ! 84: */ ! 85: if ((boothowto&(RB_HALT|RB_KDB)) == (RB_HALT|RB_KDB)) ! 86: setsoftkdb(); ! 87: #undef symsize ! 88: } ! 89: ! 90: int kdbactive = 0; ! 91: #define ESC '\033' ! 92: ! 93: /* ! 94: * Process a keyboard interrupt from the console. ! 95: * We look for an escape sequence which signals ! 96: * a request to enter the debugger. ! 97: */ ! 98: kdbrintr(c, tp) ! 99: int c; ! 100: struct tty *tp; ! 101: { ! 102: static int escape = 0; ! 103: ! 104: c &= 0177; /* strip parity also */ ! 105: if (!escape) ! 106: return (c == ESC && ++escape); ! 107: escape = 0; ! 108: /* ! 109: * Transfer control to the debugger only if the ! 110: * system was booted with RB_KDB and the trap ! 111: * enable flag (RB_NOYSNC) is set. ! 112: */ ! 113: if ((boothowto&(RB_KDB|RB_NOSYNC)) != (RB_KDB|RB_NOSYNC) || ! 114: (c != 'k' && c != 'K' && c != CTRL('k'))) { ! 115: (*linesw[tp->t_line].l_rint)(ESC, tp); ! 116: return (0); ! 117: } ! 118: if (!kdbactive) ! 119: setsoftkdb(); ! 120: return (1); ! 121: } ! 122: ! 123: static int ! 124: movpsl() ! 125: { ! 126: ! 127: asm(" movpsl r0"); /* XXX */ ! 128: } ! 129: ! 130: #define TYPE SP+1 ! 131: #define CODE PC-1 ! 132: #define USER 040 ! 133: static caddr_t kdbnofault; /* label for peek & poke */ ! 134: /* ! 135: * Field a kdb-related trap or fault. ! 136: */ ! 137: kdb_trap(apsl) ! 138: register int *apsl; ! 139: { ! 140: register int *locr0, type; ! 141: int code, retval, kstack = 0; ! 142: static int prevtype = -1, prevcode; ! 143: extern char *trap_type[]; ! 144: extern int TRAP_TYPES; ! 145: ! 146: /* ! 147: * Allow panic if the debugger is not enabled. ! 148: */ ! 149: if ((boothowto&RB_KDB) == 0) ! 150: return (0); ! 151: locr0 = apsl - PS; ! 152: type = locr0[TYPE], code = locr0[CODE]; ! 153: if (type == T_KDBTRAP && prevtype != -1) { ! 154: type = prevtype, code = prevcode; ! 155: prevtype = -1; ! 156: } ! 157: if (type != T_TRCTRAP && type != T_BPTFLT) { ! 158: /* ! 159: * Catch traps from kdbpeek and kdbpoke and perform ! 160: * non-local goto to error label setup in routines. ! 161: */ ! 162: if (kdbnofault) { ! 163: locr0[PC] = (int)kdbnofault; ! 164: return (1); ! 165: } ! 166: type &= ~USER; ! 167: } ! 168: /* ! 169: * We prefer to run the debugger from the interrupt stack to ! 170: * avoid overflowing the kernel stack. Thus, if we're not ! 171: * currently on the interrupt stack and the ipl is low, schedule ! 172: * a software interrupt to force reentry on the interrupt stack ! 173: * immediately after the rei that'll take place on return. ! 174: */ ! 175: if ((movpsl()&PSL_IS) == 0) { ! 176: int s = splhigh(); ! 177: if (s < KDB_IPL) { ! 178: prevtype = type, prevcode = code; ! 179: setsoftkdb(); ! 180: return (1); ! 181: } ! 182: splx(s); ! 183: kstack++; ! 184: } ! 185: getpcb(locr0); ! 186: /* ! 187: * Mark debugger active and initiate input ! 188: * polling in the console device driver. ! 189: */ ! 190: (*v_poll)(kdbactive = 1); ! 191: retval = kdb(type, code, noproc ? (struct proc *)0 : u.u_procp, kstack); ! 192: (*v_poll)(kdbactive = 0); ! 193: setpcb(locr0); ! 194: return (retval); ! 195: } ! 196: ! 197: static char *codenames[] = { ! 198: "code = 0", ! 199: "integer overflow", ! 200: "integer divide by zero", ! 201: "floating overflow", ! 202: "floating/decimal divide by zero", ! 203: "floating underflow", ! 204: "decimal overflow", ! 205: "subscript out of range", ! 206: "floating overflow", ! 207: "floating divide by zero", ! 208: "floating undeflow" ! 209: }; ! 210: #define NCODES (sizeof (codenames) / sizeof (codenames[0])) ! 211: ! 212: /* ! 213: * Announce a trap. ! 214: */ ! 215: kdbprinttrap(type, code) ! 216: int type, code; ! 217: { ! 218: ! 219: extern int TRAP_TYPES; ! 220: extern char *trap_type[]; ! 221: ! 222: if (type != T_TRCTRAP && type != T_BPTFLT) { ! 223: if (type < TRAP_TYPES && trap_type[type]) ! 224: printf(trap_type[type]); ! 225: else ! 226: printf("trap type %d", type); ! 227: if (type == T_ARITHTRAP && (unsigned)code < NCODES) ! 228: printf(", %s", code); ! 229: else if (code) ! 230: printf(", code = %d", code); ! 231: printf("\n"); ! 232: } ! 233: } ! 234: ! 235: /* ! 236: * Read character from the console. ! 237: */ ! 238: kdbreadc(cp) ! 239: char *cp; ! 240: { ! 241: ! 242: *cp = (*v_getc)(); ! 243: return (1); ! 244: } ! 245: ! 246: /* ! 247: * Write characters to the console. ! 248: */ ! 249: kdbwrite(cp, len) ! 250: register char *cp; ! 251: register int len; ! 252: { ! 253: ! 254: while (len-- > 0) ! 255: (*v_putc)(*cp++); ! 256: } ! 257: ! 258: /* ! 259: * Fetch a longword carefully. ! 260: */ ! 261: kdbpeek(addr) ! 262: register caddr_t addr; ! 263: { ! 264: register long v = 0; ! 265: ! 266: asm("movab 1f,_kdbnofault"); ! 267: v = *(long *)addr; ! 268: asm("1:"); ! 269: kdbnofault = 0; ! 270: return (v); ! 271: } ! 272: ! 273: /* ! 274: * Put a longword carefully. ! 275: */ ! 276: kdbpoke(addr, v) ! 277: register caddr_t addr; ! 278: long v; ! 279: { ! 280: register int pn, *pte, opte = 0; ! 281: extern char Sysbase[], etext; ! 282: ! 283: /* ! 284: * If we're writing to the kernel's text space, ! 285: * make the page writeable for the duration of ! 286: * the access. ! 287: */ ! 288: if ((caddr_t)Sysbase <= addr && addr <= (caddr_t)&etext) { ! 289: pn = btop((int)addr &~ 0x80000000); ! 290: pte = (int *)&Sysmap[pn]; ! 291: opte = *pte; ! 292: *pte = (*pte &~ PG_PROT)|PG_KW; ! 293: mtpr(TBIS, addr); ! 294: } ! 295: asm("movab 1f,_kdbnofault"); ! 296: *(long *)addr = v; ! 297: asm("1:"); ! 298: kdbnofault = 0; ! 299: if (opte) { ! 300: *pte = opte; ! 301: mtpr(TBIS, addr); ! 302: } ! 303: } ! 304: ! 305: static ! 306: getpcb(locr0) ! 307: register int *locr0; ! 308: { ! 309: extern struct pcb kdbpcb; ! 310: register struct pcb *pcb = &kdbpcb; ! 311: ! 312: pcb->pcb_r0 = locr0[R0]; ! 313: pcb->pcb_r1 = locr0[R1]; ! 314: pcb->pcb_r2 = locr0[R2]; ! 315: pcb->pcb_r3 = locr0[R3]; ! 316: pcb->pcb_r4 = locr0[R4]; ! 317: pcb->pcb_r5 = locr0[R5]; ! 318: pcb->pcb_r6 = locr0[R6]; ! 319: pcb->pcb_r7 = locr0[R7]; ! 320: pcb->pcb_r8 = locr0[R8]; ! 321: pcb->pcb_r9 = locr0[R9]; ! 322: pcb->pcb_r10 = locr0[R10]; ! 323: pcb->pcb_r11 = locr0[R11]; ! 324: pcb->pcb_ap = locr0[AP]; ! 325: pcb->pcb_fp = locr0[FP]; ! 326: pcb->pcb_usp = locr0[SP]; ! 327: pcb->pcb_pc = locr0[PC]; ! 328: pcb->pcb_psl = locr0[PS]; ! 329: pcb->pcb_ksp = mfpr(KSP); ! 330: pcb->pcb_esp = mfpr(ISP); ! 331: pcb->pcb_p0br = (struct pte *)mfpr(P0BR); ! 332: pcb->pcb_p0lr = mfpr(P0LR); ! 333: pcb->pcb_p1br = (struct pte *)mfpr(P1BR); ! 334: pcb->pcb_p1lr = mfpr(P1LR); ! 335: } ! 336: ! 337: static ! 338: setpcb(locr0) ! 339: register int *locr0; ! 340: { ! 341: extern struct pcb kdbpcb; ! 342: register struct pcb *pcb = &kdbpcb; ! 343: ! 344: locr0[R0] = pcb->pcb_r0; ! 345: locr0[R1] = pcb->pcb_r1; ! 346: locr0[R2] = pcb->pcb_r2; ! 347: locr0[R3] = pcb->pcb_r3; ! 348: locr0[R4] = pcb->pcb_r4; ! 349: locr0[R5] = pcb->pcb_r5; ! 350: locr0[R6] = pcb->pcb_r6; ! 351: locr0[R7] = pcb->pcb_r7; ! 352: locr0[R8] = pcb->pcb_r8; ! 353: locr0[R9] = pcb->pcb_r9; ! 354: locr0[R10] = pcb->pcb_r10; ! 355: locr0[R11] = pcb->pcb_r11; ! 356: locr0[AP] = pcb->pcb_ap; ! 357: locr0[FP] = pcb->pcb_fp; ! 358: locr0[SP] = pcb->pcb_usp; ! 359: locr0[PC] = pcb->pcb_pc; ! 360: locr0[PS] = pcb->pcb_psl; ! 361: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.