xref: /original-bsd/sys/tahoe/tahoe/kdb_machdep.c (revision 179d6f6f)
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.10 (Berkeley) 12/16/90
7  */
8 
9 #include "sys/param.h"
10 #include "sys/conf.h"
11 #include "sys/user.h"
12 #include "sys/proc.h"
13 #include "sys/systm.h"
14 #include "sys/reboot.h"
15 #include "sys/vmmac.h"
16 #include "sys/ioctl.h"
17 #include "sys/tty.h"
18 
19 #include "../include/cpu.h"
20 #include "../include/mtpr.h"
21 #include "../include/psl.h"
22 #include "../include/pte.h"
23 #include "../include/reg.h"
24 #include "../include/trap.h"
25 #include "../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 }
403