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