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