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