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