db_interface.c revision 1.42 1 1.41 phx /* $NetBSD: db_interface.c,v 1.42 2010/01/28 12:45:01 phx Exp $ */
2 1.1 sakamoto /* $OpenBSD: db_interface.c,v 1.2 1996/12/28 06:21:50 rahnds Exp $ */
3 1.29 lukem
4 1.29 lukem #include <sys/cdefs.h>
5 1.41 phx __KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.42 2010/01/28 12:45:01 phx Exp $");
6 1.3 jonathan
7 1.10 simonb #define USERACC
8 1.10 simonb
9 1.3 jonathan #include "opt_ddb.h"
10 1.17 dbj #include "opt_kgdb.h"
11 1.10 simonb #include "opt_ppcarch.h"
12 1.1 sakamoto
13 1.1 sakamoto #include <sys/param.h>
14 1.1 sakamoto #include <sys/proc.h>
15 1.4 tsubai #include <sys/systm.h>
16 1.6 kleink
17 1.11 simonb #include <dev/cons.h>
18 1.11 simonb
19 1.7 tsubai #include <machine/db_machdep.h>
20 1.7 tsubai #include <machine/frame.h>
21 1.10 simonb #ifdef PPC_IBM4XX
22 1.10 simonb #include <machine/tlb.h>
23 1.42 phx #include <powerpc/spr.h>
24 1.10 simonb #include <uvm/uvm_extern.h>
25 1.10 simonb #endif
26 1.7 tsubai
27 1.17 dbj #ifdef DDB
28 1.6 kleink #include <ddb/db_sym.h>
29 1.6 kleink #include <ddb/db_command.h>
30 1.6 kleink #include <ddb/db_extern.h>
31 1.6 kleink #include <ddb/db_access.h>
32 1.22 scw #include <ddb/db_lex.h>
33 1.6 kleink #include <ddb/db_output.h>
34 1.6 kleink #include <ddb/ddbvar.h>
35 1.17 dbj #endif
36 1.17 dbj
37 1.17 dbj #ifdef KGDB
38 1.17 dbj #include <sys/kgdb.h>
39 1.39 garbled #define db_printf printf
40 1.17 dbj #endif
41 1.17 dbj
42 1.17 dbj #include <dev/ofw/openfirm.h>
43 1.1 sakamoto
44 1.11 simonb int db_active = 0;
45 1.11 simonb
46 1.19 matt db_regs_t ddb_regs;
47 1.8 tsubai
48 1.10 simonb void ddb_trap(void); /* Call into trap_subr.S */
49 1.10 simonb int ddb_trap_glue(struct trapframe *); /* Called from trap_subr.S */
50 1.10 simonb #ifdef PPC_IBM4XX
51 1.37 matt static void db_ppc4xx_ctx(db_expr_t, bool, db_expr_t, const char *);
52 1.37 matt static void db_ppc4xx_pv(db_expr_t, bool, db_expr_t, const char *);
53 1.37 matt static void db_ppc4xx_reset(db_expr_t, bool, db_expr_t, const char *);
54 1.37 matt static void db_ppc4xx_tf(db_expr_t, bool, db_expr_t, const char *);
55 1.37 matt static void db_ppc4xx_dumptlb(db_expr_t, bool, db_expr_t, const char *);
56 1.37 matt static void db_ppc4xx_dcr(db_expr_t, bool, db_expr_t, const char *);
57 1.22 scw static db_expr_t db_ppc4xx_mfdcr(db_expr_t);
58 1.22 scw static void db_ppc4xx_mtdcr(db_expr_t, db_expr_t);
59 1.10 simonb #ifdef USERACC
60 1.37 matt static void db_ppc4xx_useracc(db_expr_t, bool, db_expr_t, const char *);
61 1.10 simonb #endif
62 1.10 simonb #endif /* PPC_IBM4XX */
63 1.9 briggs
64 1.17 dbj #ifdef DDB
65 1.1 sakamoto void
66 1.31 matt cpu_Debugger(void)
67 1.1 sakamoto {
68 1.1 sakamoto ddb_trap();
69 1.1 sakamoto }
70 1.17 dbj #endif
71 1.1 sakamoto
72 1.1 sakamoto int
73 1.31 matt ddb_trap_glue(struct trapframe *frame)
74 1.1 sakamoto {
75 1.25 thorpej #ifdef PPC_IBM4XX
76 1.25 thorpej if ((frame->srr1 & PSL_PR) == 0)
77 1.25 thorpej return kdb_trap(frame->exc, frame);
78 1.28 matt #else /* PPC_OEA */
79 1.25 thorpej if ((frame->srr1 & PSL_PR) == 0 &&
80 1.32 matt (frame->exc == EXC_TRC ||
81 1.32 matt frame->exc == EXC_RUNMODETRC ||
82 1.25 thorpej (frame->exc == EXC_PGM && (frame->srr1 & 0x20000)) ||
83 1.32 matt frame->exc == EXC_BPT ||
84 1.32 matt frame->exc == EXC_DSI)) {
85 1.17 dbj int type = frame->exc;
86 1.17 dbj if (type == EXC_PGM && (frame->srr1 & 0x20000)) {
87 1.17 dbj type = T_BREAKPOINT;
88 1.17 dbj }
89 1.17 dbj return kdb_trap(type, frame);
90 1.1 sakamoto }
91 1.25 thorpej #endif
92 1.1 sakamoto return 0;
93 1.8 tsubai }
94 1.8 tsubai
95 1.8 tsubai int
96 1.31 matt kdb_trap(int type, void *v)
97 1.8 tsubai {
98 1.8 tsubai struct trapframe *frame = v;
99 1.8 tsubai
100 1.17 dbj #ifdef DDB
101 1.30 matt if (db_recover != 0 && (type != -1 && type != T_BREAKPOINT)) {
102 1.30 matt db_error("Faulted in DDB; continuing...\n");
103 1.30 matt /* NOTREACHED */
104 1.8 tsubai }
105 1.17 dbj #endif
106 1.8 tsubai
107 1.8 tsubai /* XXX Should switch to kdb's own stack here. */
108 1.8 tsubai
109 1.12 wiz memcpy(DDB_REGS->r, frame->fixreg, 32 * sizeof(u_int32_t));
110 1.8 tsubai DDB_REGS->iar = frame->srr0;
111 1.8 tsubai DDB_REGS->msr = frame->srr1;
112 1.10 simonb DDB_REGS->lr = frame->lr;
113 1.10 simonb DDB_REGS->ctr = frame->ctr;
114 1.10 simonb DDB_REGS->cr = frame->cr;
115 1.10 simonb DDB_REGS->xer = frame->xer;
116 1.28 matt #ifdef PPC_OEA
117 1.27 matt DDB_REGS->mq = frame->tf_xtra[TF_MQ];
118 1.27 matt #endif
119 1.16 dbj #ifdef PPC_IBM4XX
120 1.27 matt DDB_REGS->dear = frame->dar;
121 1.27 matt DDB_REGS->esr = frame->tf_xtra[TF_ESR];
122 1.27 matt DDB_REGS->pid = frame->tf_xtra[TF_PID];
123 1.10 simonb #endif
124 1.8 tsubai
125 1.17 dbj #ifdef DDB
126 1.11 simonb db_active++;
127 1.11 simonb cnpollc(1);
128 1.15 dbj db_trap(type, 0);
129 1.11 simonb cnpollc(0);
130 1.11 simonb db_active--;
131 1.17 dbj #elif defined(KGDB)
132 1.17 dbj if (!kgdb_trap(type, DDB_REGS))
133 1.17 dbj return 0;
134 1.17 dbj #endif
135 1.17 dbj
136 1.17 dbj /* KGDB isn't smart about advancing PC if we
137 1.17 dbj * take a breakpoint trap after kgdb_active is set.
138 1.17 dbj * Therefore, we help out here.
139 1.17 dbj */
140 1.17 dbj if (IS_BREAKPOINT_TRAP(type, 0)) {
141 1.17 dbj int bkpt;
142 1.17 dbj db_read_bytes(PC_REGS(DDB_REGS),BKPT_SIZE,(void *)&bkpt);
143 1.17 dbj if (bkpt== BKPT_INST) {
144 1.17 dbj PC_REGS(DDB_REGS) += BKPT_SIZE;
145 1.17 dbj }
146 1.17 dbj }
147 1.8 tsubai
148 1.12 wiz memcpy(frame->fixreg, DDB_REGS->r, 32 * sizeof(u_int32_t));
149 1.8 tsubai frame->srr0 = DDB_REGS->iar;
150 1.8 tsubai frame->srr1 = DDB_REGS->msr;
151 1.10 simonb frame->lr = DDB_REGS->lr;
152 1.10 simonb frame->ctr = DDB_REGS->ctr;
153 1.10 simonb frame->cr = DDB_REGS->cr;
154 1.10 simonb frame->xer = DDB_REGS->xer;
155 1.28 matt #ifdef PPC_OEA
156 1.27 matt frame->tf_xtra[TF_MQ] = DDB_REGS->mq;
157 1.27 matt #endif
158 1.16 dbj #ifdef PPC_IBM4XX
159 1.27 matt frame->dar = DDB_REGS->dear;
160 1.27 matt frame->tf_xtra[TF_ESR] = DDB_REGS->esr;
161 1.27 matt frame->tf_xtra[TF_PID] = DDB_REGS->pid;
162 1.10 simonb #endif
163 1.8 tsubai
164 1.8 tsubai return 1;
165 1.1 sakamoto }
166 1.10 simonb
167 1.10 simonb #ifdef PPC_IBM4XX
168 1.24 scw db_addr_t
169 1.24 scw branch_taken(int inst, db_addr_t pc, db_regs_t *regs)
170 1.24 scw {
171 1.24 scw
172 1.24 scw if ((inst & M_B ) == I_B || (inst & M_B ) == I_BL) {
173 1.24 scw db_expr_t off;
174 1.24 scw off = ((db_expr_t)((inst & 0x03fffffc) << 6)) >> 6;
175 1.24 scw return (((inst & 0x2) ? 0 : pc) + off);
176 1.24 scw }
177 1.24 scw
178 1.24 scw if ((inst & M_BC) == I_BC || (inst & M_BC) == I_BCL) {
179 1.24 scw db_expr_t off;
180 1.24 scw off = ((db_expr_t)((inst & 0x0000fffc) << 16)) >> 16;
181 1.24 scw return (((inst & 0x2) ? 0 : pc) + off);
182 1.24 scw }
183 1.24 scw
184 1.24 scw if ((inst & M_RTS) == I_RTS || (inst & M_RTS) == I_BLRL)
185 1.24 scw return (regs->lr);
186 1.24 scw
187 1.24 scw if ((inst & M_BCTR) == I_BCTR || (inst & M_BCTR) == I_BCTRL)
188 1.24 scw return (regs->ctr);
189 1.24 scw
190 1.24 scw db_printf("branch_taken: can't figure out branch target for 0x%x!\n",
191 1.24 scw inst);
192 1.24 scw return (0);
193 1.24 scw }
194 1.24 scw
195 1.42 phx #ifdef DDB
196 1.42 phx const struct db_command db_machine_command_table[] = {
197 1.42 phx { DDB_ADD_CMD("ctx", db_ppc4xx_ctx, 0,
198 1.42 phx "Print process MMU context information", NULL,NULL) },
199 1.42 phx { DDB_ADD_CMD("pv", db_ppc4xx_pv, 0,
200 1.42 phx "Print PA->VA mapping information",
201 1.42 phx "address",
202 1.42 phx " address:\tphysical address to look up") },
203 1.42 phx { DDB_ADD_CMD("reset", db_ppc4xx_reset, 0,
204 1.42 phx "Reset the system ", NULL,NULL) },
205 1.42 phx { DDB_ADD_CMD("tf", db_ppc4xx_tf, 0,
206 1.42 phx "Display the contents of the trapframe",
207 1.42 phx "address",
208 1.42 phx " address:\tthe struct trapframe to print") },
209 1.42 phx { DDB_ADD_CMD("tlb", db_ppc4xx_dumptlb, 0,
210 1.42 phx "Display instruction translation storage buffer information.",
211 1.42 phx NULL,NULL) },
212 1.42 phx { DDB_ADD_CMD("dcr", db_ppc4xx_dcr, CS_MORE|CS_SET_DOT,
213 1.42 phx "Set the DCR register",
214 1.42 phx "dcr",
215 1.42 phx " dcr:\tNew DCR value (between 0x0 and 0x3ff)") },
216 1.42 phx #ifdef USERACC
217 1.42 phx { DDB_ADD_CMD("user", db_ppc4xx_useracc, 0,
218 1.42 phx "Display user memory.", "[address][,count]",
219 1.42 phx " address:\tuserspace address to start\n"
220 1.42 phx " count:\tnumber of bytes to display") },
221 1.42 phx #endif
222 1.42 phx { DDB_ADD_CMD(NULL, NULL, 0,
223 1.42 phx NULL,NULL,NULL) }
224 1.42 phx };
225 1.41 phx
226 1.10 simonb static void
227 1.37 matt db_ppc4xx_ctx(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
228 1.10 simonb {
229 1.10 simonb struct proc *p;
230 1.10 simonb
231 1.10 simonb /* XXX LOCKING XXX */
232 1.10 simonb for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
233 1.10 simonb if (p->p_stat) {
234 1.10 simonb db_printf("process %p:", p);
235 1.10 simonb db_printf("pid:%d pmap:%p ctx:%d %s\n",
236 1.10 simonb p->p_pid, p->p_vmspace->vm_map.pmap,
237 1.10 simonb p->p_vmspace->vm_map.pmap->pm_ctx,
238 1.10 simonb p->p_comm);
239 1.10 simonb }
240 1.10 simonb }
241 1.10 simonb return;
242 1.10 simonb }
243 1.10 simonb
244 1.10 simonb static void
245 1.37 matt db_ppc4xx_pv(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
246 1.10 simonb {
247 1.10 simonb struct pv_entry {
248 1.10 simonb struct pv_entry *pv_next; /* Linked list of mappings */
249 1.10 simonb vaddr_t pv_va; /* virtual address of mapping */
250 1.10 simonb struct pmap *pv_pm;
251 1.10 simonb };
252 1.10 simonb struct pv_entry *pa_to_pv(paddr_t);
253 1.10 simonb struct pv_entry *pv;
254 1.10 simonb
255 1.10 simonb if (!have_addr) {
256 1.10 simonb db_printf("pv: <pa>\n");
257 1.10 simonb return;
258 1.10 simonb }
259 1.10 simonb pv = pa_to_pv(addr);
260 1.10 simonb db_printf("pv at %p\n", pv);
261 1.10 simonb while (pv && pv->pv_pm) {
262 1.10 simonb db_printf("next %p va %p pmap %p\n", pv->pv_next,
263 1.10 simonb (void *)pv->pv_va, pv->pv_pm);
264 1.10 simonb pv = pv->pv_next;
265 1.10 simonb }
266 1.10 simonb }
267 1.10 simonb
268 1.10 simonb static void
269 1.37 matt db_ppc4xx_reset(db_expr_t addr, bool have_addr, db_expr_t count,
270 1.34 scw const char *modif)
271 1.10 simonb {
272 1.10 simonb printf("Reseting...\n");
273 1.10 simonb ppc4xx_reset();
274 1.10 simonb }
275 1.10 simonb
276 1.10 simonb static void
277 1.37 matt db_ppc4xx_tf(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
278 1.10 simonb {
279 1.10 simonb struct trapframe *f;
280 1.10 simonb
281 1.10 simonb
282 1.10 simonb if (have_addr) {
283 1.10 simonb f = (struct trapframe *)addr;
284 1.10 simonb
285 1.27 matt db_printf("r0-r3: \t%8.8lx %8.8lx %8.8lx %8.8lx\n",
286 1.10 simonb f->fixreg[0], f->fixreg[1],
287 1.10 simonb f->fixreg[2], f->fixreg[3]);
288 1.27 matt db_printf("r4-r7: \t%8.8lx %8.8lx %8.8lx %8.8lx\n",
289 1.10 simonb f->fixreg[4], f->fixreg[5],
290 1.10 simonb f->fixreg[6], f->fixreg[7]);
291 1.27 matt db_printf("r8-r11: \t%8.8lx %8.8lx %8.8lx %8.8lx\n",
292 1.10 simonb f->fixreg[8], f->fixreg[9],
293 1.10 simonb f->fixreg[10], f->fixreg[11]);
294 1.27 matt db_printf("r12-r15:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
295 1.10 simonb f->fixreg[12], f->fixreg[13],
296 1.10 simonb f->fixreg[14], f->fixreg[15]);
297 1.27 matt db_printf("r16-r19:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
298 1.10 simonb f->fixreg[16], f->fixreg[17],
299 1.10 simonb f->fixreg[18], f->fixreg[19]);
300 1.27 matt db_printf("r20-r23:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
301 1.10 simonb f->fixreg[20], f->fixreg[21],
302 1.10 simonb f->fixreg[22], f->fixreg[23]);
303 1.27 matt db_printf("r24-r27:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
304 1.10 simonb f->fixreg[24], f->fixreg[25],
305 1.10 simonb f->fixreg[26], f->fixreg[27]);
306 1.27 matt db_printf("r28-r31:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
307 1.10 simonb f->fixreg[28], f->fixreg[29],
308 1.10 simonb f->fixreg[30], f->fixreg[31]);
309 1.10 simonb
310 1.27 matt db_printf("lr: %8.8lx cr: %8.8x xer: %8.8x ctr: %8.8lx\n",
311 1.10 simonb f->lr, f->cr, f->xer, f->ctr);
312 1.27 matt db_printf("srr0(pc): %8.8lx srr1(msr): %8.8lx "
313 1.27 matt "dear: %8.8lx esr: %8.8x\n",
314 1.27 matt f->srr0, f->srr1, f->dar, f->tf_xtra[TF_ESR]);
315 1.10 simonb db_printf("exc: %8.8x pid: %8.8x\n",
316 1.27 matt f->exc, f->tf_xtra[TF_PID]);
317 1.10 simonb }
318 1.10 simonb return;
319 1.10 simonb }
320 1.10 simonb
321 1.10 simonb static const char *const tlbsizes[] = {
322 1.10 simonb "1kB",
323 1.10 simonb "4kB",
324 1.10 simonb "16kB",
325 1.10 simonb "64kB",
326 1.10 simonb "256kB",
327 1.10 simonb "1MB",
328 1.10 simonb "4MB",
329 1.10 simonb "16MB"
330 1.10 simonb };
331 1.10 simonb
332 1.10 simonb static void
333 1.37 matt db_ppc4xx_dumptlb(db_expr_t addr, bool have_addr, db_expr_t count,
334 1.34 scw const char *modif)
335 1.10 simonb {
336 1.10 simonb int i, zone, tlbsize;
337 1.10 simonb u_int zpr, pid, opid, msr;
338 1.10 simonb u_long tlblo, tlbhi, tlbmask;
339 1.10 simonb
340 1.10 simonb zpr = mfspr(SPR_ZPR);
341 1.10 simonb for (i = 0; i < NTLB; i++) {
342 1.36 perry __asm volatile("mfmsr %3;"
343 1.10 simonb "mfpid %4;"
344 1.10 simonb "li %0,0;"
345 1.10 simonb "mtmsr %0;"
346 1.10 simonb "sync; isync;"
347 1.21 thorpej "tlbrelo %0,%5;"
348 1.21 thorpej "tlbrehi %1,%5;"
349 1.10 simonb "mfpid %2;"
350 1.10 simonb "mtpid %4;"
351 1.10 simonb "mtmsr %3;"
352 1.10 simonb "sync; isync"
353 1.10 simonb : "=&r" (tlblo), "=&r" (tlbhi), "=r" (pid),
354 1.10 simonb "=&r" (msr), "=&r" (opid) : "r" (i));
355 1.10 simonb
356 1.10 simonb if (strchr(modif, 'v') && !(tlbhi & TLB_VALID))
357 1.10 simonb continue;
358 1.10 simonb
359 1.10 simonb tlbsize = (tlbhi & TLB_SIZE_MASK) >> TLB_SIZE_SHFT;
360 1.10 simonb /* map tlbsize 0 .. 7 to masks for 1kB .. 16MB */
361 1.10 simonb tlbmask = ~(1 << (tlbsize * 2 + 10)) + 1;
362 1.10 simonb
363 1.10 simonb if (have_addr && ((tlbhi & tlbmask) != (addr & tlbmask)))
364 1.10 simonb continue;
365 1.10 simonb
366 1.10 simonb zone = (tlblo & TLB_ZSEL_MASK) >> TLB_ZSEL_SHFT;
367 1.10 simonb db_printf("tlb%c%2d", tlbhi & TLB_VALID ? ' ' : '*', i);
368 1.10 simonb db_printf(" PID %3d EPN 0x%08lx %-5s",
369 1.10 simonb pid,
370 1.10 simonb tlbhi & tlbmask,
371 1.10 simonb tlbsizes[tlbsize]);
372 1.10 simonb db_printf(" RPN 0x%08lx ZONE %2d%c %s %s %c%c%c%c%c %s",
373 1.10 simonb tlblo & tlbmask,
374 1.10 simonb zone,
375 1.10 simonb "NTTA"[(zpr >> ((15 - zone) * 2)) & 3],
376 1.10 simonb tlblo & TLB_EX ? "EX" : " ",
377 1.10 simonb tlblo & TLB_WR ? "WR" : " ",
378 1.10 simonb tlblo & TLB_W ? 'W' : ' ',
379 1.10 simonb tlblo & TLB_I ? 'I' : ' ',
380 1.10 simonb tlblo & TLB_M ? 'M' : ' ',
381 1.10 simonb tlblo & TLB_G ? 'G' : ' ',
382 1.10 simonb tlbhi & TLB_ENDIAN ? 'E' : ' ',
383 1.10 simonb tlbhi & TLB_U0 ? "U0" : " ");
384 1.10 simonb db_printf("\n");
385 1.10 simonb }
386 1.22 scw }
387 1.22 scw
388 1.22 scw static void
389 1.37 matt db_ppc4xx_dcr(db_expr_t address, bool have_addr, db_expr_t count,
390 1.34 scw const char *modif)
391 1.22 scw {
392 1.22 scw db_expr_t new_value;
393 1.22 scw db_expr_t addr;
394 1.23 scw
395 1.23 scw if (address < 0 || address > 0x3ff)
396 1.23 scw db_error("Invalid DCR address (Valid range is 0x0 - 0x3ff)\n");
397 1.22 scw
398 1.22 scw addr = address;
399 1.22 scw
400 1.22 scw while (db_expression(&new_value)) {
401 1.22 scw db_printf("dcr 0x%lx\t\t%s = ", addr,
402 1.22 scw db_num_to_str(db_ppc4xx_mfdcr(addr)));
403 1.22 scw db_ppc4xx_mtdcr(addr, new_value);
404 1.22 scw db_printf("%s\n", db_num_to_str(db_ppc4xx_mfdcr(addr)));
405 1.22 scw addr += 1;
406 1.22 scw }
407 1.22 scw
408 1.22 scw if (addr == address) {
409 1.22 scw db_next = (db_addr_t)addr + 1;
410 1.22 scw db_prev = (db_addr_t)addr;
411 1.22 scw db_printf("dcr 0x%lx\t\t%s\n", addr,
412 1.22 scw db_num_to_str(db_ppc4xx_mfdcr(addr)));
413 1.22 scw } else {
414 1.22 scw db_next = (db_addr_t)addr;
415 1.22 scw db_prev = (db_addr_t)addr - 1;
416 1.22 scw }
417 1.22 scw
418 1.22 scw db_skip_to_eol();
419 1.22 scw }
420 1.22 scw
421 1.22 scw /*
422 1.22 scw * XXX Grossness Alert! XXX
423 1.22 scw *
424 1.22 scw * Please look away now if you don't like self-modifying code
425 1.22 scw */
426 1.22 scw static u_int32_t db_ppc4xx_dcrfunc[4];
427 1.22 scw
428 1.22 scw static db_expr_t
429 1.22 scw db_ppc4xx_mfdcr(db_expr_t reg)
430 1.22 scw {
431 1.22 scw db_expr_t (*func)(void);
432 1.22 scw
433 1.22 scw reg = (((reg & 0x1f) << 5) | ((reg >> 5) & 0x1f)) << 11;
434 1.22 scw db_ppc4xx_dcrfunc[0] = 0x7c0004ac; /* sync */
435 1.22 scw db_ppc4xx_dcrfunc[1] = 0x4c00012c; /* isync */
436 1.22 scw db_ppc4xx_dcrfunc[2] = 0x7c600286 | reg; /* mfdcr reg, r3 */
437 1.22 scw db_ppc4xx_dcrfunc[3] = 0x4e800020; /* blr */
438 1.22 scw
439 1.22 scw __syncicache((void *)db_ppc4xx_dcrfunc, sizeof(db_ppc4xx_dcrfunc));
440 1.22 scw func = (db_expr_t (*)(void))(void *)db_ppc4xx_dcrfunc;
441 1.22 scw
442 1.22 scw return ((*func)());
443 1.22 scw }
444 1.22 scw
445 1.22 scw static void
446 1.22 scw db_ppc4xx_mtdcr(db_expr_t reg, db_expr_t val)
447 1.22 scw {
448 1.22 scw db_expr_t (*func)(db_expr_t);
449 1.22 scw
450 1.22 scw reg = (((reg & 0x1f) << 5) | ((reg >> 5) & 0x1f)) << 11;
451 1.22 scw db_ppc4xx_dcrfunc[0] = 0x7c0004ac; /* sync */
452 1.22 scw db_ppc4xx_dcrfunc[1] = 0x4c00012c; /* isync */
453 1.22 scw db_ppc4xx_dcrfunc[2] = 0x7c600386 | reg; /* mtdcr r3, reg */
454 1.22 scw db_ppc4xx_dcrfunc[3] = 0x4e800020; /* blr */
455 1.22 scw
456 1.22 scw __syncicache((void *)db_ppc4xx_dcrfunc, sizeof(db_ppc4xx_dcrfunc));
457 1.22 scw func = (db_expr_t (*)(db_expr_t))(void *)db_ppc4xx_dcrfunc;
458 1.22 scw
459 1.22 scw (*func)(val);
460 1.10 simonb }
461 1.10 simonb
462 1.10 simonb #ifdef USERACC
463 1.10 simonb static void
464 1.37 matt db_ppc4xx_useracc(db_expr_t addr, bool have_addr, db_expr_t count,
465 1.34 scw const char *modif)
466 1.10 simonb {
467 1.10 simonb static paddr_t oldaddr = -1;
468 1.10 simonb int instr = 0;
469 1.10 simonb int data;
470 1.10 simonb extern vaddr_t opc_disasm(vaddr_t loc, int);
471 1.10 simonb
472 1.10 simonb
473 1.10 simonb if (!have_addr) {
474 1.10 simonb addr = oldaddr;
475 1.10 simonb }
476 1.10 simonb if (addr == -1) {
477 1.10 simonb db_printf("no address\n");
478 1.10 simonb return;
479 1.10 simonb }
480 1.10 simonb addr &= ~0x3; /* align */
481 1.10 simonb {
482 1.34 scw const char *cp = modif;
483 1.34 scw char c;
484 1.10 simonb while ((c = *cp++) != 0)
485 1.10 simonb if (c == 'i')
486 1.10 simonb instr = 1;
487 1.10 simonb }
488 1.10 simonb while (count--) {
489 1.10 simonb if (db_print_position() == 0) {
490 1.10 simonb /* Always print the address. */
491 1.10 simonb db_printf("%8.4lx:\t", addr);
492 1.10 simonb }
493 1.10 simonb oldaddr=addr;
494 1.10 simonb copyin((void *)addr, &data, sizeof(data));
495 1.10 simonb if (instr) {
496 1.10 simonb opc_disasm(addr, data);
497 1.10 simonb } else {
498 1.10 simonb db_printf("%4.4x\n", data);
499 1.10 simonb }
500 1.10 simonb addr += 4;
501 1.10 simonb db_end_line();
502 1.10 simonb }
503 1.10 simonb
504 1.10 simonb }
505 1.10 simonb #endif
506 1.10 simonb
507 1.39 garbled #endif /* DDB */
508 1.39 garbled
509 1.10 simonb #endif /* PPC_IBM4XX */
510