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 *
kdbmalloc(n)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 */
kdb_init()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 */
kdbrintr(c,tp)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 */
kdb_trap(apsl)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 */
kdbprinttrap(type,code)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 */
kdbreadc(cp)240 kdbreadc(cp)
241 char *cp;
242 {
243
244 *cp = cngetc();
245 return (1);
246 }
247
248 /*
249 * Write characters to the console.
250 */
kdbwrite(cp,len)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 */
kdbpeek(addr)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 */
kdbpoke(addr,v)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
getpcb(locr0)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
setpcb(locr0)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