xref: /original-bsd/sys/vax/vax/kdb_machdep.c (revision c95cd016)
1 /*	@(#)kdb_machdep.c	7.3 (Berkeley) 05/19/88	*/
2 
3 #include "param.h"
4 #include "conf.h"
5 #include "dir.h"
6 #include "user.h"
7 #include "proc.h"
8 #include "uio.h"
9 #include "systm.h"
10 #include "reboot.h"
11 #include "vmmac.h"
12 #include "ioctl.h"
13 #include "tty.h"
14 
15 #include "cpu.h"
16 #include "mtpr.h"
17 #include "psl.h"
18 #include "pte.h"
19 #include "reg.h"
20 #include "trap.h"
21 #include "kdbparam.h"
22 
23 #define	KDBSPACE	1024	/* 1K of memory for breakpoint table */
24 static	char kdbbuf[KDBSPACE];
25 static	char *kdbend = kdbbuf;
26 /*
27  * Dynamically allocate space for the debugger.
28  */
29 char *
30 kdbmalloc(n)
31 	u_int n;
32 {
33 	char *old = kdbend;
34 
35 	if (kdbend+n >= kdbbuf+KDBSPACE) {
36 		printf("kdb: Out of space\n");
37 		return ((char *)-1);
38 	}
39 	kdbend += n;
40 	return (old);
41 }
42 
43 /*
44  * Initialize the kernel debugger.
45  */
46 kdb_init()
47 {
48 	char *symtab, *strtab;
49 	int strsize;
50 	extern int end;
51 
52 	kdbsetup();
53 	if (bootesym > (char *)&end) {
54 		symtab = (char *)&end + sizeof (int);
55 #define	symsize	*(int *)&end
56 		strtab = symtab + symsize;
57 		strsize = roundup(*(int *)strtab, sizeof (int));
58 		if (strtab + strsize == bootesym) {
59 			printf("[Preserving %d bytes of symbol information]\n",
60 			    symsize + strsize);
61 			kdbsetsym(symtab, strtab, strtab, strsize);
62 		} else
63 			printf("kdb_init: bad bootesym %x, calculated %x\n",
64 			    bootesym, strtab + strsize);
65 	}
66 	/*
67 	 * If boot flags indicate, force entry into the debugger.
68 	 */
69 	if ((boothowto&(RB_HALT|RB_KDB)) == (RB_HALT|RB_KDB))
70 		setsoftkdb();
71 #undef	symsize
72 }
73 
74 int	kdbactive = 0;
75 #define	ESC	'\033'
76 
77 /*
78  * Process a keyboard interrupt from the console.
79  * We look for an escape sequence which signals
80  * a request to enter the debugger.
81  */
82 kdbrintr(c, tp)
83 	int c;
84 	struct tty *tp;
85 {
86 	static int escape = 0;
87 
88 	c &= 0177;			/* strip parity also */
89 	if (!escape)
90 		return (c == ESC &&  ++escape);
91 	escape = 0;
92 	/*
93 	 * Transfer control to the debugger only if the
94 	 * system was booted with RB_KDB and the trap
95 	 * enable flag (RB_NOYSNC) is set.
96 	 */
97 	if ((boothowto&(RB_KDB|RB_NOSYNC)) != (RB_KDB|RB_NOSYNC) ||
98 	    (c != 'k' && c != 'K' && c != CTRL('k'))) {
99 		(*linesw[tp->t_line].l_rint)(ESC, tp);
100 		return (0);
101 	}
102 	if (!kdbactive)
103 		setsoftkdb();
104 	return (1);
105 }
106 
107 static int
108 movpsl()
109 {
110 
111 	asm("	movpsl	r0");		/* XXX */
112 }
113 
114 #define	TYPE	SP+1
115 #define	CODE	PC-1
116 #define	USER	040
117 static	caddr_t kdbnofault;		/* label for peek & poke */
118 /*
119  * Field a kdb-related trap or fault.
120  */
121 kdb_trap(apsl)
122 	register int *apsl;
123 {
124 	register int *locr0, type;
125 	int code, retval;
126 	static int prevtype = -1, prevcode;
127 	extern char *trap_type[];
128 	extern int TRAP_TYPES;
129 
130 	/*
131 	 * Allow panic if the debugger is not enabled.
132 	 */
133 	if ((boothowto&RB_KDB) == 0)
134 		return (0);
135 	locr0 = apsl - PS;
136 	type = locr0[TYPE], code = locr0[CODE];
137 	if (type == T_KDBTRAP && prevtype != -1) {
138 		type = prevtype, code = prevcode;
139 		prevtype = -1;
140 	}
141 	if (type != T_TRCTRAP && type != T_BPTFLT) {
142 		/*
143 		 * Catch traps from kdbpeek and kdbpoke and perform
144 		 * non-local goto to error label setup in routines.
145 		 */
146 		if (kdbnofault) {
147 			locr0[PC] = (int)kdbnofault;
148 			return (1);
149 		}
150 		type &= ~USER;
151 	}
152 	/*
153 	 * We prefer to run the debugger from the interrupt stack to
154 	 * avoid overflowing the kernel stack.  Thus, if we're not
155 	 * currently on the interrupt stack and the ipl is low, schedule
156 	 * a software interrupt to force reentry on the interrupt stack
157 	 * immediately after the rei that'll take place on return.
158 	 */
159 	if ((movpsl()&PSL_IS) == 0) {
160 		int s = splhigh();
161 		if (s < KDB_IPL) {
162 			prevtype = type, prevcode = code;
163 			setsoftkdb();
164 			return (1);
165 		}
166 		splx(s);
167 		printf("(from kernel stack)\n");
168 	}
169 	getpcb(locr0);
170 	/*
171 	 * Mark debugger active and initiate input
172 	 * polling in the console device driver.
173 	 */
174 	cnpoll(kdbactive = 1);
175 	retval = kdb(type, code, noproc ? (struct proc *)0 : u.u_procp);
176 	cnpoll(kdbactive = 0);
177 	setpcb(locr0);
178 	return (retval);
179 }
180 
181 static	char *codenames[] = {
182 	"code = 0",
183 	"integer overflow",
184 	"integer divide by zero",
185 	"floating overflow",
186 	"floating/decimal divide by zero",
187 	"floating underflow",
188 	"decimal overflow",
189 	"subscript out of range",
190 	"floating overflow",
191 	"floating divide by zero",
192 	"floating undeflow"
193 };
194 #define	NCODES	(sizeof (codenames) / sizeof (codenames[0]))
195 
196 /*
197  * Announce a trap.
198  */
199 kdbprinttrap(type, code)
200 	int type, code;
201 {
202 
203 	extern int TRAP_TYPES;
204 	extern char *trap_type[];
205 
206 	if (type != T_TRCTRAP && type != T_BPTFLT) {
207 		if (type < TRAP_TYPES && trap_type[type])
208 			printf(trap_type[type]);
209 		else
210 			printf("trap type %d", type);
211 		if (type == T_ARITHTRAP && (unsigned)code < NCODES)
212 			printf(", %s", code);
213 		else if (code)
214 			printf(", code = %d", code);
215 		printf("\n");
216 	}
217 }
218 
219 /*
220  * Read character from the console.
221  */
222 kdbreadc(cp)
223 	char *cp;
224 {
225 
226 	*cp = cngetc();
227 	return (1);
228 }
229 
230 /*
231  * Write characters to the console.
232  */
233 kdbwrite(cp, len)
234 	register char *cp;
235 	register int len;
236 {
237 
238 	while (len-- > 0)
239 		cnputc(*cp++);
240 }
241 
242 /*
243  * Fetch a longword carefully.
244  */
245 kdbpeek(addr)
246 	register caddr_t addr;
247 {
248 	register long v = 0;
249 
250 	asm("movab 1f,_kdbnofault");
251 	v = *(long *)addr;
252 asm("1:");
253 	kdbnofault = 0;
254 	return (v);
255 }
256 
257 /*
258  * Put a longword carefully.
259  */
260 kdbpoke(addr, v)
261 	register caddr_t addr;
262 	long v;
263 {
264 	register int pn, *pte, opte = 0;
265 	extern char Sysbase[], etext;
266 
267 	/*
268 	 * If we're writing to the kernel's text space,
269 	 * make the page writeable for the duration of
270 	 * the access.
271 	 */
272 	if ((caddr_t)Sysbase <= addr && addr <= (caddr_t)&etext) {
273 		pn = btop((int)addr &~ 0x80000000);
274 		pte = (int *)&Sysmap[pn];
275 		opte = *pte;
276 		*pte = (*pte &~ PG_PROT)|PG_KW;
277 		mtpr(TBIS, addr);
278 	}
279 	asm("movab 1f,_kdbnofault");
280 	*(long *)addr = v;
281 asm("1:");
282 	kdbnofault = 0;
283 	if (opte) {
284 		*pte = opte;
285 		mtpr(TBIS, addr);
286 	}
287 }
288 
289 static
290 getpcb(locr0)
291 	register int *locr0;
292 {
293 	extern struct pcb kdbpcb;
294 	register struct pcb *pcb = &kdbpcb;
295 
296 	pcb->pcb_r0 = locr0[R0];
297 	pcb->pcb_r1 = locr0[R1];
298 	pcb->pcb_r2 = locr0[R2];
299 	pcb->pcb_r3 = locr0[R3];
300 	pcb->pcb_r4 = locr0[R4];
301 	pcb->pcb_r5 = locr0[R5];
302 	pcb->pcb_r6 = locr0[R6];
303 	pcb->pcb_r7 = locr0[R7];
304 	pcb->pcb_r8 = locr0[R8];
305 	pcb->pcb_r9 = locr0[R9];
306 	pcb->pcb_r10 = locr0[R10];
307 	pcb->pcb_r11 = locr0[R11];
308 	pcb->pcb_ap = locr0[AP];
309 	pcb->pcb_fp = locr0[FP];
310 	pcb->pcb_usp = locr0[SP];
311 	pcb->pcb_pc = locr0[PC];
312 	pcb->pcb_psl = locr0[PS];
313 	pcb->pcb_ksp = mfpr(KSP);
314 	pcb->pcb_esp = mfpr(ISP);
315 	pcb->pcb_p0br = (struct pte *)mfpr(P0BR);
316 	pcb->pcb_p0lr = mfpr(P0LR);
317 	pcb->pcb_p1br = (struct pte *)mfpr(P1BR);
318 	pcb->pcb_p1lr = mfpr(P1LR);
319 }
320 
321 static
322 setpcb(locr0)
323 	register int *locr0;
324 {
325 	extern struct pcb kdbpcb;
326 	register struct pcb *pcb = &kdbpcb;
327 
328 	locr0[R0] = pcb->pcb_r0;
329 	locr0[R1] = pcb->pcb_r1;
330 	locr0[R2] = pcb->pcb_r2;
331 	locr0[R3] = pcb->pcb_r3;
332 	locr0[R4] = pcb->pcb_r4;
333 	locr0[R5] = pcb->pcb_r5;
334 	locr0[R6] = pcb->pcb_r6;
335 	locr0[R7] = pcb->pcb_r7;
336 	locr0[R8] = pcb->pcb_r8;
337 	locr0[R9] = pcb->pcb_r9;
338 	locr0[R10] = pcb->pcb_r10;
339 	locr0[R11] = pcb->pcb_r11;
340 	locr0[AP] = pcb->pcb_ap;
341 	locr0[FP] = pcb->pcb_fp;
342 	locr0[SP] = pcb->pcb_usp;
343 	locr0[PC] = pcb->pcb_pc;
344 	locr0[PS] = pcb->pcb_psl;
345 }
346