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