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