db_interface.c revision 1.10 1 /* $NetBSD: db_interface.c,v 1.10 2001/06/13 06:01:50 simonb Exp $ */
2 /* $OpenBSD: db_interface.c,v 1.2 1996/12/28 06:21:50 rahnds Exp $ */
3
4 #define USERACC
5
6 #include "opt_ddb.h"
7 #include "opt_ppcarch.h"
8
9 #include <sys/param.h>
10 #include <sys/proc.h>
11 #include <sys/systm.h>
12
13 #include <machine/db_machdep.h>
14 #include <machine/frame.h>
15 #ifdef PPC_IBM4XX
16 #include <machine/tlb.h>
17 #include <powerpc/spr.h>
18 #include <uvm/uvm_extern.h>
19 #endif
20
21 #include <ddb/db_sym.h>
22 #include <ddb/db_command.h>
23 #include <ddb/db_extern.h>
24 #include <ddb/db_access.h>
25 #include <ddb/db_output.h>
26 #include <ddb/ddbvar.h>
27
28 extern label_t *db_recover;
29
30 void ddb_trap(void); /* Call into trap_subr.S */
31 int ddb_trap_glue(struct trapframe *); /* Called from trap_subr.S */
32 #ifdef PPC_IBM4XX
33 static void db_ppc4xx_ctx(db_expr_t, int, db_expr_t, char *);
34 static void db_ppc4xx_pv(db_expr_t, int, db_expr_t, char *);
35 static void db_ppc4xx_reset(db_expr_t, int, db_expr_t, char *);
36 static void db_ppc4xx_tf(db_expr_t, int, db_expr_t, char *);
37 static void db_ppc4xx_dumptlb(db_expr_t, int, db_expr_t, char *);
38 #ifdef USERACC
39 static void db_ppc4xx_useracc(db_expr_t, int, db_expr_t, char *);
40 #endif
41 #endif /* PPC_IBM4XX */
42
43 void
44 cpu_Debugger()
45 {
46 ddb_trap();
47 }
48
49 int
50 ddb_trap_glue(frame)
51 struct trapframe *frame;
52 {
53 if (!(frame->srr1 & PSL_PR)
54 && (frame->exc == EXC_TRC
55 || (frame->exc == EXC_PGM
56 && (frame->srr1 & 0x20000))
57 || frame->exc == EXC_BPT)) {
58
59 bcopy(frame->fixreg, DDB_REGS->r, 32 * sizeof(u_int32_t));
60 DDB_REGS->iar = frame->srr0;
61 DDB_REGS->msr = frame->srr1;
62
63 db_trap(T_BREAKPOINT, 0);
64
65 bcopy(DDB_REGS->r, frame->fixreg, 32 * sizeof(u_int32_t));
66
67 return 1;
68 }
69 return 0;
70 }
71
72 int
73 kdb_trap(type, v)
74 int type;
75 void *v;
76 {
77 struct trapframe *frame = v;
78
79 switch (type) {
80 case T_BREAKPOINT:
81 case -1:
82 break;
83 default:
84 if (!db_onpanic && db_recover == 0)
85 return 0;
86 if (db_recover != 0) {
87 db_error("Faulted in DDB; continuing...\n");
88 /*NOTREACHED*/
89 }
90 }
91
92 /* XXX Should switch to kdb's own stack here. */
93
94 bcopy(frame->fixreg, DDB_REGS->r, 32 * sizeof(u_int32_t));
95 DDB_REGS->iar = frame->srr0;
96 DDB_REGS->msr = frame->srr1;
97 #ifdef PPC_IBM4XX
98 DDB_REGS->lr = frame->lr;
99 DDB_REGS->ctr = frame->ctr;
100 DDB_REGS->cr = frame->cr;
101 DDB_REGS->xer = frame->xer;
102 DDB_REGS->dear = frame->dear;
103 DDB_REGS->esr = frame->esr;
104 DDB_REGS->pid = frame->pid;
105 #endif
106
107 db_trap(T_BREAKPOINT, 0);
108
109 bcopy(DDB_REGS->r, frame->fixreg, 32 * sizeof(u_int32_t));
110 frame->srr0 = DDB_REGS->iar;
111 frame->srr1 = DDB_REGS->msr;
112 #ifdef PPC_IBM4XX
113 frame->lr = DDB_REGS->lr;
114 frame->ctr = DDB_REGS->ctr;
115 frame->cr = DDB_REGS->cr;
116 frame->xer = DDB_REGS->xer;
117 frame->dear = DDB_REGS->dear;
118 frame->esr = DDB_REGS->esr;
119 frame->pid = DDB_REGS->pid;
120 #endif
121
122 return 1;
123 }
124
125 #ifdef PPC_IBM4XX
126 const struct db_command db_machine_command_table[] = {
127 { "ctx", db_ppc4xx_ctx, 0, 0 },
128 { "pv", db_ppc4xx_pv, 0, 0 },
129 { "reset", db_ppc4xx_reset, 0, 0 },
130 { "tf", db_ppc4xx_tf, 0, 0 },
131 { "tlb", db_ppc4xx_dumptlb, 0, 0 },
132 #ifdef USERACC
133 { "user", db_ppc4xx_useracc, 0, 0 },
134 #endif
135 { NULL, }
136 };
137
138 static void
139 db_ppc4xx_ctx(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
140 {
141 struct proc *p;
142
143 /* XXX LOCKING XXX */
144 for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
145 if (p->p_stat) {
146 db_printf("process %p:", p);
147 db_printf("pid:%d pmap:%p ctx:%d %s\n",
148 p->p_pid, p->p_vmspace->vm_map.pmap,
149 p->p_vmspace->vm_map.pmap->pm_ctx,
150 p->p_comm);
151 }
152 }
153 return;
154 }
155
156 static void
157 db_ppc4xx_pv(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
158 {
159 struct pv_entry {
160 struct pv_entry *pv_next; /* Linked list of mappings */
161 vaddr_t pv_va; /* virtual address of mapping */
162 struct pmap *pv_pm;
163 };
164 struct pv_entry *pa_to_pv(paddr_t);
165 struct pv_entry *pv;
166
167 if (!have_addr) {
168 db_printf("pv: <pa>\n");
169 return;
170 }
171 pv = pa_to_pv(addr);
172 db_printf("pv at %p\n", pv);
173 while (pv && pv->pv_pm) {
174 db_printf("next %p va %p pmap %p\n", pv->pv_next,
175 (void *)pv->pv_va, pv->pv_pm);
176 pv = pv->pv_next;
177 }
178 }
179
180 static void
181 db_ppc4xx_reset(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
182 {
183 printf("Reseting...\n");
184 ppc4xx_reset();
185 }
186
187 static void
188 db_ppc4xx_tf(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
189 {
190 struct trapframe *f;
191
192
193 if (have_addr) {
194 f = (struct trapframe *)addr;
195
196 db_printf("r0-r3: \t%8.8x %8.8x %8.8x %8.8x\n",
197 f->fixreg[0], f->fixreg[1],
198 f->fixreg[2], f->fixreg[3]);
199 db_printf("r4-r7: \t%8.8x %8.8x %8.8x %8.8x\n",
200 f->fixreg[4], f->fixreg[5],
201 f->fixreg[6], f->fixreg[7]);
202 db_printf("r8-r11: \t%8.8x %8.8x %8.8x %8.8x\n",
203 f->fixreg[8], f->fixreg[9],
204 f->fixreg[10], f->fixreg[11]);
205 db_printf("r12-r15:\t%8.8x %8.8x %8.8x %8.8x\n",
206 f->fixreg[12], f->fixreg[13],
207 f->fixreg[14], f->fixreg[15]);
208 db_printf("r16-r19:\t%8.8x %8.8x %8.8x %8.8x\n",
209 f->fixreg[16], f->fixreg[17],
210 f->fixreg[18], f->fixreg[19]);
211 db_printf("r20-r23:\t%8.8x %8.8x %8.8x %8.8x\n",
212 f->fixreg[20], f->fixreg[21],
213 f->fixreg[22], f->fixreg[23]);
214 db_printf("r24-r27:\t%8.8x %8.8x %8.8x %8.8x\n",
215 f->fixreg[24], f->fixreg[25],
216 f->fixreg[26], f->fixreg[27]);
217 db_printf("r28-r31:\t%8.8x %8.8x %8.8x %8.8x\n",
218 f->fixreg[28], f->fixreg[29],
219 f->fixreg[30], f->fixreg[31]);
220
221 db_printf("lr: %8.8x cr: %8.8x xer: %8.8x ctr: %8.8x\n",
222 f->lr, f->cr, f->xer, f->ctr);
223 db_printf("srr0(pc): %8.8x srr1(msr): %8.8x "
224 "dear: %8.8x esr: %8.8x\n",
225 f->srr0, f->srr1, f->dear, f->esr);
226 db_printf("exc: %8.8x pid: %8.8x\n",
227 f->exc, f->pid);
228 }
229 return;
230 }
231
232 static const char *const tlbsizes[] = {
233 "1kB",
234 "4kB",
235 "16kB",
236 "64kB",
237 "256kB",
238 "1MB",
239 "4MB",
240 "16MB"
241 };
242
243 static void
244 db_ppc4xx_dumptlb(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
245 {
246 int i, zone, tlbsize;
247 u_int zpr, pid, opid, msr;
248 u_long tlblo, tlbhi, tlbmask;
249
250 zpr = mfspr(SPR_ZPR);
251 for (i = 0; i < NTLB; i++) {
252 asm volatile("mfmsr %3;"
253 "mfpid %4;"
254 "li %0,0;"
255 "mtmsr %0;"
256 "sync; isync;"
257 "tlbre %0,%5,1;"
258 "tlbre %1,%5,0;"
259 "mfpid %2;"
260 "mtpid %4;"
261 "mtmsr %3;"
262 "sync; isync"
263 : "=&r" (tlblo), "=&r" (tlbhi), "=r" (pid),
264 "=&r" (msr), "=&r" (opid) : "r" (i));
265
266 if (strchr(modif, 'v') && !(tlbhi & TLB_VALID))
267 continue;
268
269 tlbsize = (tlbhi & TLB_SIZE_MASK) >> TLB_SIZE_SHFT;
270 /* map tlbsize 0 .. 7 to masks for 1kB .. 16MB */
271 tlbmask = ~(1 << (tlbsize * 2 + 10)) + 1;
272
273 if (have_addr && ((tlbhi & tlbmask) != (addr & tlbmask)))
274 continue;
275
276 zone = (tlblo & TLB_ZSEL_MASK) >> TLB_ZSEL_SHFT;
277 db_printf("tlb%c%2d", tlbhi & TLB_VALID ? ' ' : '*', i);
278 db_printf(" PID %3d EPN 0x%08lx %-5s",
279 pid,
280 tlbhi & tlbmask,
281 tlbsizes[tlbsize]);
282 db_printf(" RPN 0x%08lx ZONE %2d%c %s %s %c%c%c%c%c %s",
283 tlblo & tlbmask,
284 zone,
285 "NTTA"[(zpr >> ((15 - zone) * 2)) & 3],
286 tlblo & TLB_EX ? "EX" : " ",
287 tlblo & TLB_WR ? "WR" : " ",
288 tlblo & TLB_W ? 'W' : ' ',
289 tlblo & TLB_I ? 'I' : ' ',
290 tlblo & TLB_M ? 'M' : ' ',
291 tlblo & TLB_G ? 'G' : ' ',
292 tlbhi & TLB_ENDIAN ? 'E' : ' ',
293 tlbhi & TLB_U0 ? "U0" : " ");
294 db_printf("\n");
295 }
296 }
297
298 #ifdef USERACC
299 static void
300 db_ppc4xx_useracc(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
301 {
302 static paddr_t oldaddr = -1;
303 int instr = 0;
304 int data;
305 extern vaddr_t opc_disasm(vaddr_t loc, int);
306
307
308 if (!have_addr) {
309 addr = oldaddr;
310 }
311 if (addr == -1) {
312 db_printf("no address\n");
313 return;
314 }
315 addr &= ~0x3; /* align */
316 {
317 register char c, *cp = modif;
318 while ((c = *cp++) != 0)
319 if (c == 'i')
320 instr = 1;
321 }
322 while (count--) {
323 if (db_print_position() == 0) {
324 /* Always print the address. */
325 db_printf("%8.4lx:\t", addr);
326 }
327 oldaddr=addr;
328 copyin((void *)addr, &data, sizeof(data));
329 if (instr) {
330 opc_disasm(addr, data);
331 } else {
332 db_printf("%4.4x\n", data);
333 }
334 addr += 4;
335 db_end_line();
336 }
337
338 }
339 #endif
340
341 #endif /* PPC_IBM4XX */
342