xref: /original-bsd/sys/vax/vax/kdb_machdep.c (revision 2a4161ef)
1 /*	@(#)kdb_machdep.c	7.4 (Berkeley) 02/17/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 /*
26  * Dynamically allocate space for the debugger.
27  */
28 char *
29 kdbmalloc(n)
30 	u_int n;
31 {
32 	char *old = kdbend;
33 
34 	if (kdbend+n >= kdbbuf+KDBSPACE) {
35 		printf("kdb: Out of space\n");
36 		return ((char *)-1);
37 	}
38 	kdbend += n;
39 	return (old);
40 }
41 
42 /*
43  * Initialize the kernel debugger.
44  */
45 kdb_init()
46 {
47 	char *symtab, *strtab;
48 	int strsize;
49 	extern int end;
50 
51 	kdbsetup();
52 	if (bootesym > (char *)&end) {
53 		symtab = (char *)&end + sizeof (int);
54 #define	symsize	*(int *)&end
55 		strtab = symtab + symsize;
56 		strsize = roundup(*(int *)strtab, sizeof (int));
57 		if (strtab + strsize == bootesym) {
58 			printf("[Preserving %d bytes of symbol information]\n",
59 			    symsize + strsize);
60 			kdbsetsym(symtab, strtab, strtab, strsize);
61 		} else
62 			printf("kdb_init: bad bootesym %x, calculated %x\n",
63 			    bootesym, strtab + strsize);
64 	}
65 	/*
66 	 * If boot flags indicate, force entry into the debugger.
67 	 */
68 	if ((boothowto&(RB_HALT|RB_KDB)) == (RB_HALT|RB_KDB))
69 		setsoftkdb();
70 #undef	symsize
71 }
72 
73 int	kdbactive = 0;
74 #define	ESC	'\033'
75 
76 /*
77  * Process a keyboard interrupt from the console.
78  * We look for an escape sequence which signals
79  * a request to enter the debugger.
80  */
81 kdbrintr(c, tp)
82 	int c;
83 	struct tty *tp;
84 {
85 	static int escape = 0;
86 
87 	c &= 0177;			/* strip parity also */
88 	if (!escape)
89 		return (c == ESC &&  ++escape);
90 	escape = 0;
91 	/*
92 	 * Transfer control to the debugger only if the
93 	 * system was booted with RB_KDB and the trap
94 	 * enable flag (RB_NOYSNC) is set.
95 	 */
96 	if ((boothowto&(RB_KDB|RB_NOSYNC)) != (RB_KDB|RB_NOSYNC) ||
97 	    (c != 'k' && c != 'K' && c != CTRL('k'))) {
98 		(*linesw[tp->t_line].l_rint)(ESC, tp);
99 		return (0);
100 	}
101 	if (!kdbactive)
102 		setsoftkdb();
103 	return (1);
104 }
105 
106 static int
107 movpsl()
108 {
109 
110 	asm("	movpsl	r0");		/* XXX */
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",
182 	"integer overflow",
183 	"integer divide by zero",
184 	"floating overflow",
185 	"floating/decimal divide by zero",
186 	"floating underflow",
187 	"decimal overflow",
188 	"subscript out of range",
189 	"floating overflow",
190 	"floating divide by zero",
191 	"floating undeflow"
192 };
193 #define	NCODES	(sizeof (codenames) / sizeof (codenames[0]))
194 
195 /*
196  * Announce a trap.
197  */
198 kdbprinttrap(type, code)
199 	int type, code;
200 {
201 
202 	extern int TRAP_TYPES;
203 	extern char *trap_type[];
204 
205 	if (type != T_TRCTRAP && type != T_BPTFLT) {
206 		if (type < TRAP_TYPES && trap_type[type])
207 			printf(trap_type[type]);
208 		else
209 			printf("trap type %d", type);
210 		if (type == T_ARITHTRAP && (unsigned)code < NCODES)
211 			printf(", %s", code);
212 		else if (code)
213 			printf(", code = %d", code);
214 		printf("\n");
215 	}
216 }
217 
218 /*
219  * Read character from the console.
220  */
221 kdbreadc(cp)
222 	char *cp;
223 {
224 
225 	*cp = cngetc();
226 	return (1);
227 }
228 
229 /*
230  * Write characters to the console.
231  */
232 kdbwrite(cp, len)
233 	register char *cp;
234 	register int len;
235 {
236 
237 	while (len-- > 0)
238 		cnputc(*cp++);
239 }
240 
241 /*
242  * Fetch a longword carefully.
243  */
244 kdbpeek(addr)
245 	register caddr_t addr;
246 {
247 	register long v = 0;
248 
249 	asm("movab 1f,_kdbnofault");
250 	v = *(long *)addr;
251 asm("1:");
252 	kdbnofault = 0;
253 	return (v);
254 }
255 
256 /*
257  * Put a longword carefully.
258  */
259 kdbpoke(addr, v)
260 	register caddr_t addr;
261 	long v;
262 {
263 	register int pn, *pte, opte = 0;
264 	extern char Sysbase[], etext;
265 
266 	/*
267 	 * If we're writing to the kernel's text space,
268 	 * make the page writeable for the duration of
269 	 * the access.
270 	 */
271 	if ((caddr_t)Sysbase <= addr && addr <= (caddr_t)&etext) {
272 		pn = btop((int)addr &~ 0x80000000);
273 		pte = (int *)&Sysmap[pn];
274 		opte = *pte;
275 		*pte = (*pte &~ PG_PROT)|PG_KW;
276 		mtpr(TBIS, addr);
277 	}
278 	asm("movab 1f,_kdbnofault");
279 	*(long *)addr = v;
280 asm("1:");
281 	kdbnofault = 0;
282 	if (opte) {
283 		*pte = opte;
284 		mtpr(TBIS, addr);
285 	}
286 }
287 
288 static
289 getpcb(locr0)
290 	register int *locr0;
291 {
292 	extern struct pcb kdbpcb;
293 	register struct pcb *pcb = &kdbpcb;
294 
295 	pcb->pcb_r0 = locr0[R0];
296 	pcb->pcb_r1 = locr0[R1];
297 	pcb->pcb_r2 = locr0[R2];
298 	pcb->pcb_r3 = locr0[R3];
299 	pcb->pcb_r4 = locr0[R4];
300 	pcb->pcb_r5 = locr0[R5];
301 	pcb->pcb_r6 = locr0[R6];
302 	pcb->pcb_r7 = locr0[R7];
303 	pcb->pcb_r8 = locr0[R8];
304 	pcb->pcb_r9 = locr0[R9];
305 	pcb->pcb_r10 = locr0[R10];
306 	pcb->pcb_r11 = locr0[R11];
307 	pcb->pcb_ap = locr0[AP];
308 	pcb->pcb_fp = locr0[FP];
309 	pcb->pcb_usp = locr0[SP];
310 	pcb->pcb_pc = locr0[PC];
311 	pcb->pcb_psl = locr0[PS];
312 	pcb->pcb_ksp = mfpr(KSP);
313 	pcb->pcb_esp = mfpr(ISP);
314 	pcb->pcb_p0br = (struct pte *)mfpr(P0BR);
315 	pcb->pcb_p0lr = mfpr(P0LR);
316 	pcb->pcb_p1br = (struct pte *)mfpr(P1BR);
317 	pcb->pcb_p1lr = mfpr(P1LR);
318 }
319 
320 static
321 setpcb(locr0)
322 	register int *locr0;
323 {
324 	extern struct pcb kdbpcb;
325 	register struct pcb *pcb = &kdbpcb;
326 
327 	locr0[R0] = pcb->pcb_r0;
328 	locr0[R1] = pcb->pcb_r1;
329 	locr0[R2] = pcb->pcb_r2;
330 	locr0[R3] = pcb->pcb_r3;
331 	locr0[R4] = pcb->pcb_r4;
332 	locr0[R5] = pcb->pcb_r5;
333 	locr0[R6] = pcb->pcb_r6;
334 	locr0[R7] = pcb->pcb_r7;
335 	locr0[R8] = pcb->pcb_r8;
336 	locr0[R9] = pcb->pcb_r9;
337 	locr0[R10] = pcb->pcb_r10;
338 	locr0[R11] = pcb->pcb_r11;
339 	locr0[AP] = pcb->pcb_ap;
340 	locr0[FP] = pcb->pcb_fp;
341 	locr0[SP] = pcb->pcb_usp;
342 	locr0[PC] = pcb->pcb_pc;
343 	locr0[PS] = pcb->pcb_psl;
344 }
345