xref: /original-bsd/sys/vax/vax/kdb_machdep.c (revision 51e389b0)
1 /*	@(#)kdb_machdep.c	7.8 (Berkeley) 12/16/90	*/
2 
3 #include "sys/param.h"
4 #include "sys/conf.h"
5 #include "sys/user.h"
6 #include "sys/proc.h"
7 #include "sys/uio.h"
8 #include "sys/systm.h"
9 #include "sys/reboot.h"
10 #include "sys/vmmac.h"
11 #include "sys/ioctl.h"
12 #include "sys/tty.h"
13 
14 #include "../include/cpu.h"
15 #include "../include/mtpr.h"
16 #include "../include/psl.h"
17 #include "../include/pte.h"
18 #include "../include/reg.h"
19 #include "../include/trap.h"
20 #include "../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 }
362