|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)kdb_machdep.c 7.9 (Berkeley) 4/3/90 ! 7: */ ! 8: ! 9: #include "param.h" ! 10: #include "conf.h" ! 11: #include "user.h" ! 12: #include "proc.h" ! 13: #include "systm.h" ! 14: #include "reboot.h" ! 15: #include "vmmac.h" ! 16: #include "ioctl.h" ! 17: #include "tty.h" ! 18: ! 19: #include "cpu.h" ! 20: #include "mtpr.h" ! 21: #include "psl.h" ! 22: #include "pte.h" ! 23: #include "reg.h" ! 24: #include "trap.h" ! 25: #include "kdbparam.h" ! 26: ! 27: #define KDBSPACE 1024 /* 1K of memory for breakpoint table */ ! 28: static char kdbbuf[KDBSPACE]; ! 29: static char *kdbend = kdbbuf; ! 30: int kdb_escape; /* allow kdb to be entered on console escape */ ! 31: int kdb_panic; /* allow kdb to be entered on panic/trap */ ! 32: /* ! 33: * Dynamically allocate space for the debugger. ! 34: */ ! 35: char * ! 36: kdbmalloc(n) ! 37: u_int n; ! 38: { ! 39: char *old = kdbend; ! 40: ! 41: if (kdbend+n >= kdbbuf+KDBSPACE) { ! 42: printf("kdb: Out of space\n"); ! 43: return ((char *)-1); ! 44: } ! 45: kdbend += n; ! 46: return (old); ! 47: } ! 48: ! 49: /* ! 50: * Initialize the kernel debugger. ! 51: */ ! 52: kdb_init() ! 53: { ! 54: char *symtab, *strtab; ! 55: int strsize; ! 56: extern int end; ! 57: ! 58: kdbsetup(); ! 59: if (bootesym > (char *)&end) { ! 60: symtab = (char *)&end + sizeof (int); ! 61: #define symsize *(int *)&end ! 62: strtab = symtab + symsize; ! 63: strsize = roundup(*(int *)strtab, sizeof (int)); ! 64: if (strtab + strsize == bootesym) { ! 65: printf("[Preserving %d bytes of symbol information]\n", ! 66: symsize + strsize); ! 67: kdbsetsym(symtab, strtab, strtab, strsize); ! 68: } else ! 69: printf("kdb_init: bad bootesym %x, calculated %x\n", ! 70: bootesym, strtab + strsize); ! 71: } ! 72: /* ! 73: * Transfer control to the debugger when magic console sequence ! 74: * is typed only if the system was booted with RB_KDB and the trap ! 75: * enable flag (RB_NOYSNC) set. ! 76: */ ! 77: if ((boothowto&(RB_KDB|RB_NOSYNC)) == (RB_KDB|RB_NOSYNC)) ! 78: kdb_escape = 1; ! 79: ! 80: if (boothowto&RB_KDB) ! 81: kdb_panic = 1; ! 82: ! 83: /* ! 84: * If boot flags indicate, force entry into the debugger. ! 85: */ ! 86: if ((boothowto&(RB_HALT|RB_KDB)) == (RB_HALT|RB_KDB)) ! 87: setsoftkdb(); ! 88: #undef symsize ! 89: } ! 90: ! 91: int kdbactive = 0; ! 92: #define ESC CTRL('[') ! 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: /* ! 105: * Transfer control to the debugger only if the ! 106: * system was booted with RB_KDB and the trap ! 107: * enable flag (RB_NOYSNC) is set. ! 108: */ ! 109: if (kdb_escape == 0) ! 110: return (0); ! 111: c &= 0177; /* strip parity also */ ! 112: if (!escape) ! 113: return (c == ESC && ++escape); ! 114: escape = 0; ! 115: if ((c != 'k' && c != 'K' && c != CTRL('k'))) { ! 116: (*linesw[tp->t_line].l_rint)(ESC, tp); ! 117: return (0); ! 118: } ! 119: if (!kdbactive) ! 120: setsoftkdb(); ! 121: return (1); ! 122: } ! 123: ! 124: #define TYPE SP+1 ! 125: #define CODE PC-1 ! 126: #define USER 040 ! 127: static caddr_t kdbnofault; /* label for peek & poke */ ! 128: /* ! 129: * Field a kdb-related trap or fault. ! 130: */ ! 131: kdb_trap(apsl) ! 132: register int *apsl; ! 133: { ! 134: register int *locr0, type; ! 135: int code, retval, kstack = 0; ! 136: static int prevtype = -1, prevcode; ! 137: extern char *trap_type[]; ! 138: ! 139: /* ! 140: * Allow panic if the debugger is not enabled. ! 141: */ ! 142: if (kdb_panic == 0) ! 143: return (0); ! 144: locr0 = apsl - PS; ! 145: type = locr0[TYPE]; ! 146: /* ! 147: * If we were invoked from kernel stack and are now back ! 148: * on the interrupt stack, restore the saved type and code. ! 149: * If we return, trap will have the correct type. ! 150: */ ! 151: if (type == T_KDBTRAP && prevtype != -1) { ! 152: locr0[TYPE] = type = prevtype; ! 153: locr0[CODE] = prevcode; ! 154: prevtype = -1; ! 155: } ! 156: code = locr0[CODE]; ! 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: cnpoll(kdbactive = 1); ! 191: retval = kdb(type, code, noproc ? (struct proc *)0 : u.u_procp, kstack); ! 192: cnpoll(kdbactive = 0); ! 193: setpcb(locr0); ! 194: /* ! 195: * Return 1 (return from trap) if this was a kdb trap ! 196: * (from breakpoint, keyboard or panic) ! 197: * unless a panic has been requested (kdb returns 0). ! 198: * Otherwise, return 0 (panic because of trap). ! 199: */ ! 200: return ((type == T_KDBTRAP && retval != 0) || ! 201: type == T_TRCTRAP || type == T_BPTFLT); ! 202: } ! 203: ! 204: static char *codenames[] = { ! 205: "code = 0", /* not defined */ ! 206: "integer overflow", ! 207: "integer divide by zero", ! 208: "floating divide by zero", ! 209: "floating overflow", ! 210: "float underflow" ! 211: }; ! 212: #define NCODES (sizeof (codenames) / sizeof (codenames[0])) ! 213: ! 214: /* ! 215: * Announce a trap. ! 216: */ ! 217: kdbprinttrap(type, code) ! 218: long type, code; ! 219: { ! 220: ! 221: extern int TRAP_TYPES; ! 222: extern char *trap_type[]; ! 223: ! 224: if (type != T_TRCTRAP && type != T_BPTFLT) { ! 225: if (type < TRAP_TYPES && trap_type[type]) ! 226: printf(trap_type[type]); ! 227: else ! 228: printf("trap type %d", type); ! 229: if (type == T_ARITHTRAP && (unsigned)code < NCODES) ! 230: printf(", %s", code); ! 231: else if (code) ! 232: printf(", code = %x", code); ! 233: printf("\n"); ! 234: } ! 235: } ! 236: ! 237: /* ! 238: * Read character from the console. ! 239: */ ! 240: kdbreadc(cp) ! 241: char *cp; ! 242: { ! 243: ! 244: *cp = cngetc(); ! 245: return (1); ! 246: } ! 247: ! 248: /* ! 249: * Write characters to the console. ! 250: */ ! 251: kdbwrite(cp, len) ! 252: register char *cp; ! 253: register int len; ! 254: { ! 255: ! 256: while (len-- > 0) ! 257: cnputc(*cp++); ! 258: } ! 259: ! 260: /* ! 261: * Fetch a longword carefully. ! 262: */ ! 263: kdbpeek(addr) ! 264: register caddr_t addr; ! 265: { ! 266: register long v = 0; ! 267: ! 268: asm("movab 1f,_kdbnofault"); ! 269: switch ((int)addr&03) { ! 270: case 0: ! 271: v = *(long *)addr; ! 272: break; ! 273: case 2: ! 274: v = *(u_short *)addr, addr += sizeof (short); ! 275: v = (v << 16) | *(u_short *)addr; ! 276: break; ! 277: case 1: case 3: ! 278: v = *(u_char *)addr++; ! 279: v = (v << 8) | *(u_char *)addr++; ! 280: v = (v << 8) | *(u_char *)addr++; ! 281: v = (v << 8) | *(u_char *)addr; ! 282: break; ! 283: } ! 284: asm("1:"); ! 285: kdbnofault = 0; ! 286: return (v); ! 287: } ! 288: ! 289: /* ! 290: * Put a longword carefully. ! 291: */ ! 292: kdbpoke(addr, v) ! 293: register caddr_t addr; ! 294: long v; ! 295: { ! 296: register int pn, *pte, opte = 0; ! 297: extern caddr_t Sysbase; ! 298: extern int etext; ! 299: u_short *wp; ! 300: u_char *cp; ! 301: ! 302: /* ! 303: * If we're writing to the kernel's text space, ! 304: * make the page writeable for the duration of ! 305: * the access. ! 306: */ ! 307: if (Sysbase <= addr && addr <= (caddr_t)&etext) { ! 308: pn = btop((int)addr &~ 0xc0000000); ! 309: pte = (int *)&Sysmap[pn]; ! 310: opte = *pte; ! 311: *pte = (*pte &~ PG_PROT)|PG_KW; ! 312: mtpr(TBIS, addr); ! 313: } ! 314: asm("movab 1f,_kdbnofault"); ! 315: switch ((int)addr&03) { ! 316: case 0: ! 317: *(long *)addr = v; ! 318: break; ! 319: case 2: ! 320: wp = (u_short *)&v; ! 321: *(u_short*)addr = *wp++, addr += sizeof (short); ! 322: *(u_short *)addr = *wp; ! 323: break; ! 324: case 1: case 3: ! 325: cp = (u_char *)&v; ! 326: *(u_char *)addr++ = *cp++; ! 327: *(u_char *)addr++ = *cp++; ! 328: *(u_char *)addr++ = *cp++; ! 329: *(u_char *)addr = *cp; ! 330: break; ! 331: } ! 332: asm("1:"); ! 333: kdbnofault = 0; ! 334: if (opte) { ! 335: *pte = opte; ! 336: mtpr(TBIS, addr); ! 337: mtpr(PACC, 1); ! 338: } ! 339: } ! 340: ! 341: static ! 342: getpcb(locr0) ! 343: register int *locr0; ! 344: { ! 345: extern struct pcb kdbpcb; ! 346: register struct pcb *pcb = &kdbpcb; ! 347: ! 348: pcb->pcb_r0 = locr0[R0]; ! 349: pcb->pcb_r1 = locr0[R1]; ! 350: pcb->pcb_r2 = locr0[R2]; ! 351: pcb->pcb_r3 = locr0[R3]; ! 352: pcb->pcb_r4 = locr0[R4]; ! 353: pcb->pcb_r5 = locr0[R5]; ! 354: pcb->pcb_r6 = locr0[R6]; ! 355: pcb->pcb_r7 = locr0[R7]; ! 356: pcb->pcb_r8 = locr0[R8]; ! 357: pcb->pcb_r9 = locr0[R9]; ! 358: pcb->pcb_r10 = locr0[R10]; ! 359: pcb->pcb_r11 = locr0[R11]; ! 360: pcb->pcb_r12 = locr0[R12]; ! 361: pcb->pcb_fp = locr0[FP]; ! 362: pcb->pcb_usp = locr0[SP]; ! 363: pcb->pcb_pc = locr0[PC]; ! 364: pcb->pcb_psl = locr0[PS]; ! 365: pcb->pcb_ksp = mfpr(KSP); ! 366: pcb->pcb_p0br = (struct pte *)mfpr(P0BR); ! 367: pcb->pcb_p0lr = mfpr(P0LR); ! 368: pcb->pcb_p1br = (struct pte *)mfpr(P1BR); ! 369: pcb->pcb_p1lr = mfpr(P1LR); ! 370: pcb->pcb_p2br = (struct pte *)mfpr(P2BR); ! 371: pcb->pcb_p2lr = mfpr(P2LR); ! 372: pcb->pcb_ach = locr0[RACH]; ! 373: pcb->pcb_acl = locr0[RACL]; ! 374: } ! 375: ! 376: static ! 377: setpcb(locr0) ! 378: register int *locr0; ! 379: { ! 380: extern struct pcb kdbpcb; ! 381: register struct pcb *pcb = &kdbpcb; ! 382: ! 383: locr0[R0] = pcb->pcb_r0; ! 384: locr0[R1] = pcb->pcb_r1; ! 385: locr0[R2] = pcb->pcb_r2; ! 386: locr0[R3] = pcb->pcb_r3; ! 387: locr0[R4] = pcb->pcb_r4; ! 388: locr0[R5] = pcb->pcb_r5; ! 389: locr0[R6] = pcb->pcb_r6; ! 390: locr0[R7] = pcb->pcb_r7; ! 391: locr0[R8] = pcb->pcb_r8; ! 392: locr0[R9] = pcb->pcb_r9; ! 393: locr0[R10] = pcb->pcb_r10; ! 394: locr0[R11] = pcb->pcb_r11; ! 395: locr0[R12] = pcb->pcb_r12; ! 396: locr0[FP] = pcb->pcb_fp; ! 397: locr0[SP] = pcb->pcb_usp; ! 398: locr0[PC] = pcb->pcb_pc; ! 399: locr0[PS] = pcb->pcb_psl; ! 400: locr0[RACH] = pcb->pcb_ach; ! 401: locr0[RACL] = pcb->pcb_acl; ! 402: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.