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