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