Annotation of sys/arch/sparc64/sparc64/db_interface.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: db_interface.c,v 1.23 2007/05/02 18:46:07 kettenis Exp $ */
2: /* $NetBSD: db_interface.c,v 1.61 2001/07/31 06:55:47 eeh Exp $ */
3:
4: /*
5: * Mach Operating System
6: * Copyright (c) 1991,1990 Carnegie Mellon University
7: * All Rights Reserved.
8: *
9: * Permission to use, copy, modify and distribute this software and its
10: * documentation is hereby granted, provided that both the copyright
11: * notice and this permission notice appear in all copies of the
12: * software, derivative works or modified versions, and any portions
13: * thereof, and that both notices appear in supporting documentation.
14: *
15: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
17: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18: *
19: * Carnegie Mellon requests users of this software to return to
20: *
21: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
22: * School of Computer Science
23: * Carnegie Mellon University
24: * Pittsburgh PA 15213-3890
25: *
26: * any improvements or extensions that they make and grant Carnegie the
27: * rights to redistribute these changes.
28: *
29: * From: db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
30: */
31:
32: #include <sys/param.h>
33: #include <sys/proc.h>
34: #include <sys/user.h>
35: #include <sys/reboot.h>
36: #include <sys/systm.h>
37:
38: #include <uvm/uvm_extern.h>
39:
40: #include <dev/cons.h>
41:
42: #include <machine/db_machdep.h>
43: #include <ddb/db_command.h>
44: #include <ddb/db_sym.h>
45: #include <ddb/db_variables.h>
46: #include <ddb/db_extern.h>
47: #include <ddb/db_access.h>
48: #include <ddb/db_output.h>
49: #include <ddb/db_interface.h>
50:
51: #include <machine/instr.h>
52: #include <machine/cpu.h>
53: #include <machine/openfirm.h>
54: #include <machine/ctlreg.h>
55: #include <machine/pmap.h>
56:
57: #ifdef notyet
58: #include "fb.h"
59: #include "esp_sbus.h"
60: #endif
61:
62: db_regs_t ddb_regs; /* register state */
63:
64: extern void OF_enter(void);
65:
66: extern struct traptrace {
67: unsigned short tl:3, /* Trap level */
68: ns:4, /* PCB nsaved */
69: tt:9; /* Trap type */
70: unsigned short pid; /* PID */
71: u_int tstate; /* tstate */
72: u_int tsp; /* sp */
73: u_int tpc; /* pc */
74: u_int tfault; /* MMU tag access */
75: } trap_trace[], trap_trace_end[];
76:
77: static long nil;
78:
79: static int
80: db__char_value(struct db_variable *var, db_expr_t *expr, int mode)
81: {
82:
83: switch (mode) {
84: case DB_VAR_SET:
85: *var->valuep = *(char *)expr;
86: break;
87: case DB_VAR_GET:
88: *expr = *(char *)var->valuep;
89: break;
90: #ifdef DIAGNOSTIC
91: default:
92: printf("db__char_value: mode %d\n", mode);
93: break;
94: #endif
95: }
96:
97: return 0;
98: }
99:
100: #ifdef notdef_yet
101: static int
102: db__short_value(struct db_variable *var, db_expr_t *expr, int mode)
103: {
104:
105: switch (mode) {
106: case DB_VAR_SET:
107: *var->valuep = *(short *)expr;
108: break;
109: case DB_VAR_GET:
110: *expr = *(short *)var->valuep;
111: break;
112: #ifdef DIAGNOSTIC
113: default:
114: printf("db__short_value: mode %d\n", mode);
115: break;
116: #endif
117: }
118:
119: return 0;
120: }
121: #endif
122:
123: struct db_variable db_regs[] = {
124: { "tstate", (long *)&DDB_TF->tf_tstate, FCN_NULL, },
125: { "pc", (long *)&DDB_TF->tf_pc, FCN_NULL, },
126: { "npc", (long *)&DDB_TF->tf_npc, FCN_NULL, },
127: { "ipl", (long *)&DDB_TF->tf_oldpil, db__char_value, },
128: { "y", (long *)&DDB_TF->tf_y, db_var_rw_int, },
129: { "g0", (long *)&nil, FCN_NULL, },
130: { "g1", (long *)&DDB_TF->tf_global[1], FCN_NULL, },
131: { "g2", (long *)&DDB_TF->tf_global[2], FCN_NULL, },
132: { "g3", (long *)&DDB_TF->tf_global[3], FCN_NULL, },
133: { "g4", (long *)&DDB_TF->tf_global[4], FCN_NULL, },
134: { "g5", (long *)&DDB_TF->tf_global[5], FCN_NULL, },
135: { "g6", (long *)&DDB_TF->tf_global[6], FCN_NULL, },
136: { "g7", (long *)&DDB_TF->tf_global[7], FCN_NULL, },
137: { "o0", (long *)&DDB_TF->tf_out[0], FCN_NULL, },
138: { "o1", (long *)&DDB_TF->tf_out[1], FCN_NULL, },
139: { "o2", (long *)&DDB_TF->tf_out[2], FCN_NULL, },
140: { "o3", (long *)&DDB_TF->tf_out[3], FCN_NULL, },
141: { "o4", (long *)&DDB_TF->tf_out[4], FCN_NULL, },
142: { "o5", (long *)&DDB_TF->tf_out[5], FCN_NULL, },
143: { "o6", (long *)&DDB_TF->tf_out[6], FCN_NULL, },
144: { "o7", (long *)&DDB_TF->tf_out[7], FCN_NULL, },
145: { "l0", (long *)&DDB_TF->tf_local[0], FCN_NULL, },
146: { "l1", (long *)&DDB_TF->tf_local[1], FCN_NULL, },
147: { "l2", (long *)&DDB_TF->tf_local[2], FCN_NULL, },
148: { "l3", (long *)&DDB_TF->tf_local[3], FCN_NULL, },
149: { "l4", (long *)&DDB_TF->tf_local[4], FCN_NULL, },
150: { "l5", (long *)&DDB_TF->tf_local[5], FCN_NULL, },
151: { "l6", (long *)&DDB_TF->tf_local[6], FCN_NULL, },
152: { "l7", (long *)&DDB_TF->tf_local[7], FCN_NULL, },
153: { "i0", (long *)&DDB_FR->fr_arg[0], FCN_NULL, },
154: { "i1", (long *)&DDB_FR->fr_arg[1], FCN_NULL, },
155: { "i2", (long *)&DDB_FR->fr_arg[2], FCN_NULL, },
156: { "i3", (long *)&DDB_FR->fr_arg[3], FCN_NULL, },
157: { "i4", (long *)&DDB_FR->fr_arg[4], FCN_NULL, },
158: { "i5", (long *)&DDB_FR->fr_arg[5], FCN_NULL, },
159: { "i6", (long *)&DDB_FR->fr_arg[6], FCN_NULL, },
160: { "i7", (long *)&DDB_FR->fr_arg[7], FCN_NULL, },
161: { "f0", (long *)&DDB_FP->fs_regs[0], FCN_NULL, },
162: { "f2", (long *)&DDB_FP->fs_regs[2], FCN_NULL, },
163: { "f4", (long *)&DDB_FP->fs_regs[4], FCN_NULL, },
164: { "f6", (long *)&DDB_FP->fs_regs[6], FCN_NULL, },
165: { "f8", (long *)&DDB_FP->fs_regs[8], FCN_NULL, },
166: { "f10", (long *)&DDB_FP->fs_regs[10], FCN_NULL, },
167: { "f12", (long *)&DDB_FP->fs_regs[12], FCN_NULL, },
168: { "f14", (long *)&DDB_FP->fs_regs[14], FCN_NULL, },
169: { "f16", (long *)&DDB_FP->fs_regs[16], FCN_NULL, },
170: { "f18", (long *)&DDB_FP->fs_regs[18], FCN_NULL, },
171: { "f20", (long *)&DDB_FP->fs_regs[20], FCN_NULL, },
172: { "f22", (long *)&DDB_FP->fs_regs[22], FCN_NULL, },
173: { "f24", (long *)&DDB_FP->fs_regs[24], FCN_NULL, },
174: { "f26", (long *)&DDB_FP->fs_regs[26], FCN_NULL, },
175: { "f28", (long *)&DDB_FP->fs_regs[28], FCN_NULL, },
176: { "f30", (long *)&DDB_FP->fs_regs[30], FCN_NULL, },
177: { "f32", (long *)&DDB_FP->fs_regs[32], FCN_NULL, },
178: { "f34", (long *)&DDB_FP->fs_regs[34], FCN_NULL, },
179: { "f36", (long *)&DDB_FP->fs_regs[36], FCN_NULL, },
180: { "f38", (long *)&DDB_FP->fs_regs[38], FCN_NULL, },
181: { "f40", (long *)&DDB_FP->fs_regs[40], FCN_NULL, },
182: { "f42", (long *)&DDB_FP->fs_regs[42], FCN_NULL, },
183: { "f44", (long *)&DDB_FP->fs_regs[44], FCN_NULL, },
184: { "f46", (long *)&DDB_FP->fs_regs[46], FCN_NULL, },
185: { "f48", (long *)&DDB_FP->fs_regs[48], FCN_NULL, },
186: { "f50", (long *)&DDB_FP->fs_regs[50], FCN_NULL, },
187: { "f52", (long *)&DDB_FP->fs_regs[52], FCN_NULL, },
188: { "f54", (long *)&DDB_FP->fs_regs[54], FCN_NULL, },
189: { "f56", (long *)&DDB_FP->fs_regs[56], FCN_NULL, },
190: { "f58", (long *)&DDB_FP->fs_regs[58], FCN_NULL, },
191: { "f60", (long *)&DDB_FP->fs_regs[60], FCN_NULL, },
192: { "f62", (long *)&DDB_FP->fs_regs[62], FCN_NULL, },
193: { "fsr", (long *)&DDB_FP->fs_fsr, FCN_NULL, },
194: { "gsr", (long *)&DDB_FP->fs_gsr, FCN_NULL, },
195:
196: };
197: struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
198:
199: extern label_t *db_recover;
200:
201: int db_active = 0;
202:
203: extern char *trap_type[];
204:
205: void kdb_kbd_trap(struct trapframe64 *);
206: void db_prom_cmd(db_expr_t, int, db_expr_t, char *);
207: void db_proc_cmd(db_expr_t, int, db_expr_t, char *);
208: void db_ctx_cmd(db_expr_t, int, db_expr_t, char *);
209: void db_dump_window(db_expr_t, int, db_expr_t, char *);
210: void db_dump_stack(db_expr_t, int, db_expr_t, char *);
211: void db_dump_trap(db_expr_t, int, db_expr_t, char *);
212: void db_dump_fpstate(db_expr_t, int, db_expr_t, char *);
213: void db_dump_ts(db_expr_t, int, db_expr_t, char *);
214: void db_dump_pcb(db_expr_t, int, db_expr_t, char *);
215: void db_dump_pv(db_expr_t, int, db_expr_t, char *);
216: void db_setpcb(db_expr_t, int, db_expr_t, char *);
217: void db_dump_dtlb(db_expr_t, int, db_expr_t, char *);
218: void db_dump_itlb(db_expr_t, int, db_expr_t, char *);
219: void db_dump_dtsb(db_expr_t, int, db_expr_t, char *);
220: void db_pmap_kernel(db_expr_t, int, db_expr_t, char *);
221: void db_pload_cmd(db_expr_t, int, db_expr_t, char *);
222: void db_pmap_cmd(db_expr_t, int, db_expr_t, char *);
223: void db_lock(db_expr_t, int, db_expr_t, char *);
224: void db_traptrace(db_expr_t, int, db_expr_t, char *);
225: void db_dump_buf(db_expr_t, int, db_expr_t, char *);
226: void db_dump_espcmd(db_expr_t, int, db_expr_t, char *);
227: void db_watch(db_expr_t, int, db_expr_t, char *);
228:
229: static void db_dump_pmap(struct pmap*);
230: static void db_print_trace_entry(struct traptrace *, int);
231:
232:
233: /*
234: * Received keyboard interrupt sequence.
235: */
236: void
237: kdb_kbd_trap(tf)
238: struct trapframe64 *tf;
239: {
240: if (db_active == 0 /* && (boothowto & RB_KDB) */) {
241: printf("\n\nkernel: keyboard interrupt tf=%p\n", tf);
242: kdb_trap(-1, tf);
243: }
244: }
245:
246: /*
247: * kdb_trap - field a TRACE or BPT trap
248: */
249: int
250: kdb_trap(type, tf)
251: int type;
252: register struct trapframe64 *tf;
253: {
254: int s, tl;
255: struct trapstate *ts = &ddb_regs.ddb_ts[0];
256: extern int savetstate(struct trapstate *ts);
257: extern void restoretstate(int tl, struct trapstate *ts);
258: extern int trap_trace_dis;
259:
260: trap_trace_dis++;
261:
262: fb_unblank();
263:
264: switch (type) {
265: case T_BREAKPOINT: /* breakpoint */
266: printf("kdb breakpoint at %llx\n",
267: (unsigned long long)tf->tf_pc);
268: break;
269: case -1: /* keyboard interrupt */
270: printf("kdb tf=%p\n", tf);
271: break;
272: default:
273: printf("kernel trap %x: %s\n", type, trap_type[type & 0x1ff]);
274: if (db_recover != 0) {
275: OF_enter();
276: db_error("Faulted in DDB; continuing...\n");
277: OF_enter();
278: /*NOTREACHED*/
279: }
280: db_recover = (label_t *)1;
281: }
282:
283: /* Should switch to kdb`s own stack here. */
284: write_all_windows();
285:
286: ddb_regs.ddb_tf = *tf;
287: if (fpproc) {
288: savefpstate(fpproc->p_md.md_fpstate);
289: ddb_regs.ddb_fpstate = *fpproc->p_md.md_fpstate;
290: loadfpstate(fpproc->p_md.md_fpstate);
291: }
292: /* We should do a proper copyin and xlate 64-bit stack frames, but... */
293: /* if (tf->tf_tstate & TSTATE_PRIV) { */
294:
295: #if 0
296: /* make sure this is not causing ddb problems. */
297: if (tf->tf_out[6] & 1) {
298: if ((unsigned)(tf->tf_out[6] + BIAS) > (unsigned)KERNBASE)
299: ddb_regs.ddb_fr = *(struct frame64 *)(tf->tf_out[6] + BIAS);
300: else
301: copyin((caddr_t)(tf->tf_out[6] + BIAS), &ddb_regs.ddb_fr, sizeof(struct frame64));
302: } else {
303: struct frame32 tfr;
304:
305: /* First get a local copy of the frame32 */
306: if ((unsigned)(tf->tf_out[6]) > (unsigned)KERNBASE)
307: tfr = *(struct frame32 *)tf->tf_out[6];
308: else
309: copyin((caddr_t)(tf->tf_out[6]), &tfr, sizeof(struct frame32));
310: /* Now copy each field from the 32-bit value to the 64-bit value */
311: for (i=0; i<8; i++)
312: ddb_regs.ddb_fr.fr_local[i] = tfr.fr_local[i];
313: for (i=0; i<6; i++)
314: ddb_regs.ddb_fr.fr_arg[i] = tfr.fr_arg[i];
315: ddb_regs.ddb_fr.fr_fp = (long)tfr.fr_fp;
316: ddb_regs.ddb_fr.fr_pc = tfr.fr_pc;
317: }
318: #endif
319:
320: s = splhigh();
321: db_active++;
322: cnpollc(TRUE);
323: /* Need to do spl stuff till cnpollc works */
324: tl = ddb_regs.ddb_tl = savetstate(ts);
325: db_dump_ts(0, 0, 0, 0);
326: db_trap(type, 0/*code*/);
327: restoretstate(tl,ts);
328: cnpollc(FALSE);
329: db_active--;
330: splx(s);
331:
332: if (fpproc) {
333: *fpproc->p_md.md_fpstate = ddb_regs.ddb_fpstate;
334: loadfpstate(fpproc->p_md.md_fpstate);
335: }
336: #if 0
337: /* We will not alter the machine's running state until we get everything else working */
338: *(struct frame *)tf->tf_out[6] = ddb_regs.ddb_fr;
339: #endif
340: *tf = ddb_regs.ddb_tf;
341: trap_trace_dis--;
342:
343: return (1);
344: }
345:
346: /*
347: * Read bytes from kernel address space for debugger.
348: */
349: void
350: db_read_bytes(addr, size, data)
351: vaddr_t addr;
352: register size_t size;
353: register char *data;
354: {
355: register char *src;
356:
357: src = (char *)addr;
358: while (size-- > 0) {
359: if (src >= (char *)VM_MIN_KERNEL_ADDRESS)
360: *data++ = probeget((paddr_t)(u_long)src++, ASI_P, 1);
361: else
362: copyin(src++, data++, sizeof(u_char));
363: }
364: }
365:
366:
367: /*
368: * Write bytes to kernel address space for debugger.
369: */
370: void
371: db_write_bytes(addr, size, data)
372: vaddr_t addr;
373: register size_t size;
374: register char *data;
375: {
376: register char *dst;
377: extern vaddr_t ktext;
378: extern paddr_t ktextp;
379:
380: dst = (char *)addr;
381: while (size-- > 0) {
382: if ((dst >= (char *)VM_MIN_KERNEL_ADDRESS+0x400000))
383: *dst = *data;
384: else if ((dst >= (char *)VM_MIN_KERNEL_ADDRESS) &&
385: (dst < (char *)VM_MIN_KERNEL_ADDRESS+0x400000))
386: /* Read Only mapping -- need to do a bypass access */
387: stba((u_long)dst - ktext + ktextp, ASI_PHYS_CACHED, *data);
388: else
389: copyout(data, dst, sizeof(char));
390: dst++, data++;
391: }
392:
393: }
394:
395: void
396: Debugger()
397: {
398: /* We use the breakpoint to trap into DDB */
399: asm("ta 1; nop");
400: }
401:
402: void
403: db_prom_cmd(addr, have_addr, count, modif)
404: db_expr_t addr;
405: int have_addr;
406: db_expr_t count;
407: char *modif;
408: {
409: OF_enter();
410: }
411:
412: #define CHEETAHP (((getver()>>32) & 0x1ff) >= 0x14)
413: unsigned long db_get_dtlb_data(int entry), db_get_dtlb_tag(int entry),
414: db_get_itlb_data(int entry), db_get_itlb_tag(int entry);
415: void db_print_itlb_entry(int entry, int i, int endc);
416: void db_print_dtlb_entry(int entry, int i, int endc);
417:
418: extern __inline__ unsigned long db_get_dtlb_data(int entry)
419: {
420: unsigned long r;
421: __asm__ __volatile__("ldxa [%1] %2,%0"
422: : "=r" (r)
423: : "r" (entry <<3), "i" (ASI_DMMU_TLB_DATA));
424: return r;
425: }
426: extern __inline__ unsigned long db_get_dtlb_tag(int entry)
427: {
428: unsigned long r;
429: __asm__ __volatile__("ldxa [%1] %2,%0"
430: : "=r" (r)
431: : "r" (entry <<3), "i" (ASI_DMMU_TLB_TAG));
432: return r;
433: }
434: extern __inline__ unsigned long db_get_itlb_data(int entry)
435: {
436: unsigned long r;
437: __asm__ __volatile__("ldxa [%1] %2,%0"
438: : "=r" (r)
439: : "r" (entry <<3), "i" (ASI_IMMU_TLB_DATA));
440: return r;
441: }
442: extern __inline__ unsigned long db_get_itlb_tag(int entry)
443: {
444: unsigned long r;
445: __asm__ __volatile__("ldxa [%1] %2,%0"
446: : "=r" (r)
447: : "r" (entry <<3), "i" (ASI_IMMU_TLB_TAG));
448: return r;
449: }
450:
451: void db_print_dtlb_entry(int entry, int i, int endc)
452: {
453: unsigned long tag, data;
454: tag = db_get_dtlb_tag(entry);
455: data = db_get_dtlb_data(entry);
456: db_printf("%2d:%16.16lx %16.16lx%c", i, tag, data, endc);
457: }
458:
459: void db_print_itlb_entry(int entry, int i, int endc)
460: {
461: unsigned long tag, data;
462: tag = db_get_itlb_tag(entry);
463: data = db_get_itlb_data(entry);
464: db_printf("%2d:%16.16lx %16.16lx%c", i, tag, data, endc);
465: }
466:
467: void
468: db_dump_dtlb(addr, have_addr, count, modif)
469: db_expr_t addr;
470: int have_addr;
471: db_expr_t count;
472: char *modif;
473: {
474: /* extern void print_dtlb(void); -- locore.s; no longer used here */
475:
476: if (have_addr) {
477: int i;
478: int64_t* p = (int64_t*)addr;
479: static int64_t buf[128];
480: extern void dump_dtlb(int64_t *);
481:
482: if (CHEETAHP) {
483: db_printf("DTLB %ld\n", addr);
484: switch(addr)
485: {
486: case 0:
487: for (i = 0; i < 16; ++i)
488: db_print_dtlb_entry(i, i, (i&1)?'\n':' ');
489: break;
490: case 2:
491: for (i = 0; i < 512; ++i)
492: db_print_dtlb_entry(i+16384, i, (i&1)?'\n':' ');
493: break;
494: }
495: } else {
496: dump_dtlb(buf);
497: p = buf;
498: for (i=0; i<64;) {
499: db_printf("%2d:%16.16llx %16.16llx ", i++, p[0], p[1]);
500: p += 2;
501: db_printf("%2d:%16.16llx %16.16llx\n", i++, p[0], p[1]);
502: p += 2;
503: }
504: }
505: } else {
506: printf ("Usage: mach dtlb 0,2\n");
507: }
508: }
509:
510: void
511: db_dump_itlb(addr, have_addr, count, modif)
512: db_expr_t addr;
513: int have_addr;
514: db_expr_t count;
515: char *modif;
516: {
517: int i;
518: if (!have_addr) {
519: db_printf("Usage: mach itlb 0,1,2\n");
520: return;
521: }
522: if (CHEETAHP) {
523: db_printf("ITLB %ld\n", addr);
524: switch(addr)
525: {
526: case 0:
527: for (i = 0; i < 16; ++i)
528: db_print_itlb_entry(i, i, (i&1)?'\n':' ');
529: break;
530: case 2:
531: for (i = 0; i < 128; ++i)
532: db_print_itlb_entry(i+16384, i, (i&1)?'\n':' ');
533: break;
534: }
535: } else {
536: for (i = 0; i < 63; ++i)
537: db_print_itlb_entry(i, i, (i&1)?'\n':' ');
538: }
539: }
540:
541: void
542: db_pload_cmd(addr, have_addr, count, modif)
543: db_expr_t addr;
544: int have_addr;
545: db_expr_t count;
546: char *modif;
547: {
548: static paddr_t oldaddr = -1;
549: int asi = ASI_PHYS_CACHED;
550:
551: if (!have_addr) {
552: addr = oldaddr;
553: }
554: if (addr == -1) {
555: db_printf("no address\n");
556: return;
557: }
558: addr &= ~0x7; /* align */
559: {
560: register char c, *cp = modif;
561: while ((c = *cp++) != 0)
562: if (c == 'u')
563: asi = ASI_AIUS;
564: }
565: while (count--) {
566: if (db_print_position() == 0) {
567: /* Always print the address. */
568: db_printf("%16.16lx:\t", addr);
569: }
570: oldaddr=addr;
571: db_printf("%8.8lx\n", (long)ldxa(addr, asi));
572: addr += 8;
573: if (db_print_position() != 0)
574: db_end_line(0);
575: }
576: }
577:
578: int64_t pseg_get(struct pmap *, vaddr_t);
579:
580: void
581: db_dump_pmap(pm)
582: struct pmap* pm;
583: {
584: /* print all valid pages in the kernel pmap */
585: long i, j, k, n;
586: paddr_t *pdir, *ptbl;
587: /* Almost the same as pmap_collect() */
588:
589: n = 0;
590: for (i=0; i<STSZ; i++) {
591: if((pdir = (paddr_t *)(u_long)ldxa((vaddr_t)&pm->pm_segs[i], ASI_PHYS_CACHED))) {
592: db_printf("pdir %ld at %lx:\n", i, (long)pdir);
593: for (k=0; k<PDSZ; k++) {
594: if ((ptbl = (paddr_t *)(u_long)ldxa((vaddr_t)&pdir[k], ASI_PHYS_CACHED))) {
595: db_printf("\tptable %ld:%ld at %lx:\n", i, k, (long)ptbl);
596: for (j=0; j<PTSZ; j++) {
597: int64_t data0, data1;
598: data0 = ldxa((vaddr_t)&ptbl[j], ASI_PHYS_CACHED);
599: j++;
600: data1 = ldxa((vaddr_t)&ptbl[j], ASI_PHYS_CACHED);
601: if (data0 || data1) {
602: db_printf("%llx: %llx\t",
603: (unsigned long long)(((u_int64_t)i<<STSHIFT)|(k<<PDSHIFT)|((j-1)<<PTSHIFT)),
604: (unsigned long long)(data0));
605: db_printf("%llx: %llx\n",
606: (unsigned long long)(((u_int64_t)i<<STSHIFT)|(k<<PDSHIFT)|(j<<PTSHIFT)),
607: (unsigned long long)(data1));
608: }
609: }
610: }
611: }
612: }
613: }
614: }
615:
616: void
617: db_pmap_kernel(addr, have_addr, count, modif)
618: db_expr_t addr;
619: int have_addr;
620: db_expr_t count;
621: char *modif;
622: {
623: extern struct pmap kernel_pmap_;
624: int i, j, full = 0;
625: u_int64_t data;
626:
627: {
628: register char c, *cp = modif;
629: while ((c = *cp++) != 0)
630: if (c == 'f')
631: full = 1;
632: }
633: if (have_addr) {
634: /* lookup an entry for this VA */
635:
636: if ((data = pseg_get(&kernel_pmap_, (vaddr_t)addr))) {
637: db_printf("pmap_kernel(%p)->pm_segs[%lx][%lx][%lx]=>%qx\n",
638: (void *)addr, (u_long)va_to_seg(addr),
639: (u_long)va_to_dir(addr), (u_long)va_to_pte(addr),
640: (unsigned long long)data);
641: } else {
642: db_printf("No mapping for %p\n", (void *)addr);
643: }
644: return;
645: }
646:
647: db_printf("pmap_kernel(%p) psegs %p phys %llx\n",
648: &kernel_pmap_, kernel_pmap_.pm_segs,
649: (unsigned long long)kernel_pmap_.pm_physaddr);
650: if (full) {
651: db_dump_pmap(&kernel_pmap_);
652: } else {
653: for (j=i=0; i<STSZ; i++) {
654: long seg = (long)ldxa((vaddr_t)&kernel_pmap_.pm_segs[i], ASI_PHYS_CACHED);
655: if (seg)
656: db_printf("seg %d => %lx%c", i, seg, (j++%4)?'\t':'\n');
657: }
658: }
659: }
660:
661:
662: void
663: db_pmap_cmd(addr, have_addr, count, modif)
664: db_expr_t addr;
665: int have_addr;
666: db_expr_t count;
667: char *modif;
668: {
669: struct pmap* pm=NULL;
670: int i, j=0, full = 0;
671:
672: {
673: register char c, *cp = modif;
674: if (modif)
675: while ((c = *cp++) != 0)
676: if (c == 'f')
677: full = 1;
678: }
679: if (curproc && curproc->p_vmspace)
680: pm = curproc->p_vmspace->vm_map.pmap;
681: if (have_addr) {
682: pm = (struct pmap*)addr;
683: }
684:
685: db_printf("pmap %p: ctx %x refs %d physaddr %llx psegs %p\n",
686: pm, pm->pm_ctx, pm->pm_refs,
687: (unsigned long long)pm->pm_physaddr, pm->pm_segs);
688:
689: if (full) {
690: db_dump_pmap(pm);
691: } else {
692: for (i=0; i<STSZ; i++) {
693: long seg = (long)ldxa((vaddr_t)&kernel_pmap_.pm_segs[i], ASI_PHYS_CACHED);
694: if (seg)
695: db_printf("seg %d => %lx%c", i, seg, (j++%4)?'\t':'\n');
696: }
697: }
698: }
699:
700:
701: void
702: db_lock(addr, have_addr, count, modif)
703: db_expr_t addr;
704: int have_addr;
705: db_expr_t count;
706: char *modif;
707: {
708: #if 0
709: struct lock *l;
710:
711: if (!have_addr) {
712: db_printf("What lock address?\n");
713: return;
714: }
715:
716: l = (struct lock *)addr;
717: db_printf("flags=%x\n waitcount=%x sharecount=%x "
718: "exclusivecount=%x\n wmesg=%s recurselevel=%x\n",
719: l->lk_flags, l->lk_waitcount,
720: l->lk_sharecount, l->lk_exclusivecount, l->lk_wmesg,
721: l->lk_recurselevel);
722: #else
723: db_printf("locks unsupported\n");
724: #endif
725: }
726:
727: void
728: db_dump_dtsb(addr, have_addr, count, modif)
729: db_expr_t addr;
730: int have_addr;
731: db_expr_t count;
732: char *modif;
733: {
734: extern pte_t *tsb_dmmu;
735: extern int tsbsize;
736: #define TSBENTS (512<<tsbsize)
737: int i;
738:
739: db_printf("TSB:\n");
740: for (i=0; i<TSBENTS; i++) {
741: db_printf("%4d:%4d:%08x %08x:%08x ", i,
742: (int)((tsb_dmmu[i].tag&TSB_TAG_G)?-1:TSB_TAG_CTX(tsb_dmmu[i].tag)),
743: (int)((i<<13)|TSB_TAG_VA(tsb_dmmu[i].tag)),
744: (int)(tsb_dmmu[i].data>>32), (int)tsb_dmmu[i].data);
745: i++;
746: db_printf("%4d:%4d:%08x %08x:%08x\n", i,
747: (int)((tsb_dmmu[i].tag&TSB_TAG_G)?-1:TSB_TAG_CTX(tsb_dmmu[i].tag)),
748: (int)((i<<13)|TSB_TAG_VA(tsb_dmmu[i].tag)),
749: (int)(tsb_dmmu[i].data>>32), (int)tsb_dmmu[i].data);
750: }
751: }
752:
753: void db_page_cmd(db_expr_t, int, db_expr_t, char *);
754: void
755: db_page_cmd(addr, have_addr, count, modif)
756: db_expr_t addr;
757: int have_addr;
758: db_expr_t count;
759: char *modif;
760: {
761:
762: if (!have_addr) {
763: db_printf("Need paddr for page\n");
764: return;
765: }
766:
767: db_printf("pa %llx pg %p\n", (unsigned long long)addr,
768: PHYS_TO_VM_PAGE(addr));
769: }
770:
771:
772: void
773: db_proc_cmd(addr, have_addr, count, modif)
774: db_expr_t addr;
775: int have_addr;
776: db_expr_t count;
777: char *modif;
778: {
779: struct proc *p;
780:
781: p = curproc;
782: if (have_addr)
783: p = (struct proc*) addr;
784: if (p == NULL) {
785: db_printf("no current process\n");
786: return;
787: }
788: db_printf("process %p:", p);
789: db_printf("pid:%d vmspace:%p pmap:%p ctx:%x wchan:%p pri:%d upri:%d\n",
790: p->p_pid, p->p_vmspace, p->p_vmspace->vm_map.pmap,
791: p->p_vmspace->vm_map.pmap->pm_ctx,
792: p->p_wchan, p->p_priority, p->p_usrpri);
793: db_printf("maxsaddr:%p ssiz:%dpg or %llxB\n",
794: p->p_vmspace->vm_maxsaddr, p->p_vmspace->vm_ssize,
795: (unsigned long long)ctob(p->p_vmspace->vm_ssize));
796: db_printf("profile timer: %ld sec %ld usec\n",
797: p->p_stats->p_timer[ITIMER_PROF].it_value.tv_sec,
798: p->p_stats->p_timer[ITIMER_PROF].it_value.tv_usec);
799: db_printf("pcb: %p fpstate: %p\n", &p->p_addr->u_pcb,
800: p->p_md.md_fpstate);
801: return;
802: }
803:
804: void
805: db_ctx_cmd(addr, have_addr, count, modif)
806: db_expr_t addr;
807: int have_addr;
808: db_expr_t count;
809: char *modif;
810: {
811: struct proc *p;
812:
813: /* XXX LOCKING XXX */
814: LIST_FOREACH(p, &allproc, p_list) {
815: if (p->p_stat) {
816: db_printf("process %p:", p);
817: db_printf("pid:%d pmap:%p ctx:%x tf:%p fpstate %p "
818: "lastcall:%s\n",
819: p->p_pid, p->p_vmspace->vm_map.pmap,
820: p->p_vmspace->vm_map.pmap->pm_ctx,
821: p->p_md.md_tf, p->p_md.md_fpstate,
822: (p->p_addr->u_pcb.lastcall)?
823: p->p_addr->u_pcb.lastcall : "Null");
824: }
825: }
826: return;
827: }
828:
829: void
830: db_dump_pcb(addr, have_addr, count, modif)
831: db_expr_t addr;
832: int have_addr;
833: db_expr_t count;
834: char *modif;
835: {
836: struct pcb *pcb;
837: int i;
838:
839: pcb = curpcb;
840: if (have_addr)
841: pcb = (struct pcb*) addr;
842:
843: db_printf("pcb@%p sp:%p pc:%p cwp:%d pil:%d nsaved:%x onfault:%p\nlastcall:%s\nfull windows:\n",
844: pcb, (void *)(long)pcb->pcb_sp, (void *)(long)pcb->pcb_pc, pcb->pcb_cwp,
845: pcb->pcb_pil, pcb->pcb_nsaved, (void *)pcb->pcb_onfault,
846: (pcb->lastcall)?pcb->lastcall:"Null");
847:
848: for (i=0; i<pcb->pcb_nsaved; i++) {
849: db_printf("win %d: at %llx local, in\n", i,
850: (unsigned long long)pcb->pcb_rw[i+1].rw_in[6]);
851: db_printf("%16llx %16llx %16llx %16llx\n",
852: (unsigned long long)pcb->pcb_rw[i].rw_local[0],
853: (unsigned long long)pcb->pcb_rw[i].rw_local[1],
854: (unsigned long long)pcb->pcb_rw[i].rw_local[2],
855: (unsigned long long)pcb->pcb_rw[i].rw_local[3]);
856: db_printf("%16llx %16llx %16llx %16llx\n",
857: (unsigned long long)pcb->pcb_rw[i].rw_local[4],
858: (unsigned long long)pcb->pcb_rw[i].rw_local[5],
859: (unsigned long long)pcb->pcb_rw[i].rw_local[6],
860: (unsigned long long)pcb->pcb_rw[i].rw_local[7]);
861: db_printf("%16llx %16llx %16llx %16llx\n",
862: (unsigned long long)pcb->pcb_rw[i].rw_in[0],
863: (unsigned long long)pcb->pcb_rw[i].rw_in[1],
864: (unsigned long long)pcb->pcb_rw[i].rw_in[2],
865: (unsigned long long)pcb->pcb_rw[i].rw_in[3]);
866: db_printf("%16llx %16llx %16llx %16llx\n",
867: (unsigned long long)pcb->pcb_rw[i].rw_in[4],
868: (unsigned long long)pcb->pcb_rw[i].rw_in[5],
869: (unsigned long long)pcb->pcb_rw[i].rw_in[6],
870: (unsigned long long)pcb->pcb_rw[i].rw_in[7]);
871: }
872: }
873:
874:
875: void
876: db_setpcb(addr, have_addr, count, modif)
877: db_expr_t addr;
878: int have_addr;
879: db_expr_t count;
880: char *modif;
881: {
882: struct proc *p, *pp;
883:
884: if (!have_addr) {
885: db_printf("What PID do you want to map in?\n");
886: return;
887: }
888:
889: LIST_FOREACH(p, &allproc, p_list) {
890: pp = p->p_pptr;
891: if (p->p_stat && p->p_pid == addr) {
892: curproc = p;
893: curpcb = (struct pcb*)p->p_addr;
894: if (p->p_vmspace->vm_map.pmap->pm_ctx) {
895: switchtoctx(p->p_vmspace->vm_map.pmap->pm_ctx);
896: return;
897: }
898: db_printf("PID %ld has a null context.\n", addr);
899: return;
900: }
901: }
902: db_printf("PID %ld not found.\n", addr);
903: }
904:
905: static void
906: db_print_trace_entry(te, i)
907: struct traptrace *te;
908: int i;
909: {
910: db_printf("%d:%d p:%d tt:%d:%llx:%llx %llx:%llx ", i,
911: (int)te->tl, (int)te->pid,
912: (int)te->tt, (unsigned long long)te->tstate,
913: (unsigned long long)te->tfault, (unsigned long long)te->tsp,
914: (unsigned long long)te->tpc);
915: db_printsym((u_long)te->tpc, DB_STGY_PROC, db_printf);
916: db_printf(": ");
917: if ((te->tpc && !(te->tpc&0x3)) &&
918: curproc &&
919: (curproc->p_pid == te->pid)) {
920: db_disasm((u_long)te->tpc, 0);
921: } else db_printf("\n");
922: }
923:
924: void
925: db_traptrace(addr, have_addr, count, modif)
926: db_expr_t addr;
927: int have_addr;
928: db_expr_t count;
929: char *modif;
930: {
931: int i, start = 0, full = 0, reverse = 0;
932: struct traptrace *end;
933:
934: start = 0;
935: end = &trap_trace_end[0];
936:
937: {
938: register char c, *cp = modif;
939: if (modif)
940: while ((c = *cp++) != 0) {
941: if (c == 'f')
942: full = 1;
943: if (c == 'r')
944: reverse = 1;
945: }
946: }
947:
948: if (have_addr) {
949: start = addr / (sizeof (struct traptrace));
950: if (&trap_trace[start] > &trap_trace_end[0]) {
951: db_printf("Address out of range.\n");
952: return;
953: }
954: if (!full) end = &trap_trace[start+1];
955: }
956:
957: db_printf("#:tl p:pid tt:tt:tstate:tfault sp:pc\n");
958: if (reverse) {
959: if (full && start)
960: for (i=start; --i;) {
961: db_print_trace_entry(&trap_trace[i], i);
962: }
963: i = (end - &trap_trace[0]);
964: while(--i > start) {
965: db_print_trace_entry(&trap_trace[i], i);
966: }
967: } else {
968: for (i=start; &trap_trace[i] < end ; i++) {
969: db_print_trace_entry(&trap_trace[i], i);
970: }
971: if (full && start)
972: for (i=0; i < start ; i++) {
973: db_print_trace_entry(&trap_trace[i], i);
974: }
975: }
976: }
977:
978: /*
979: * Use physical or virtual watchpoint registers -- ugh
980: */
981: void
982: db_watch(addr, have_addr, count, modif)
983: db_expr_t addr;
984: int have_addr;
985: db_expr_t count;
986: char *modif;
987: {
988: int phys = 0;
989:
990: #define WATCH_VR (1L<<22)
991: #define WATCH_VW (1L<<21)
992: #define WATCH_PR (1L<<24)
993: #define WATCH_PW (1L<<23)
994: #define WATCH_PM (((u_int64_t)0xffffL)<<33)
995: #define WATCH_VM (((u_int64_t)0xffffL)<<25)
996:
997: {
998: register char c, *cp = modif;
999: if (modif)
1000: while ((c = *cp++) != 0)
1001: if (c == 'p')
1002: phys = 1;
1003: }
1004: if (have_addr) {
1005: /* turn on the watchpoint */
1006: int64_t tmp = ldxa(0, ASI_MCCR);
1007:
1008: if (phys) {
1009: tmp &= ~(WATCH_PM|WATCH_PR|WATCH_PW);
1010: stxa(PHYSICAL_WATCHPOINT, ASI_DMMU, addr);
1011: } else {
1012: tmp &= ~(WATCH_VM|WATCH_VR|WATCH_VW);
1013: stxa(VIRTUAL_WATCHPOINT, ASI_DMMU, addr);
1014: }
1015: stxa(0, ASI_MCCR, tmp);
1016: } else {
1017: /* turn off the watchpoint */
1018: int64_t tmp = ldxa(0, ASI_MCCR);
1019: if (phys) tmp &= ~(WATCH_PM);
1020: else tmp &= ~(WATCH_VM);
1021: stxa(0, ASI_MCCR, tmp);
1022: }
1023: }
1024:
1025:
1026: #include <uvm/uvm.h>
1027:
1028: #ifdef UVMHIST
1029: void db_uvmhistdump(db_expr_t, int, db_expr_t, char *);
1030: extern void uvmhist_dump(struct uvm_history *);
1031: extern struct uvm_history_head uvm_histories;
1032:
1033: void
1034: db_uvmhistdump(addr, have_addr, count, modif)
1035: db_expr_t addr;
1036: int have_addr;
1037: db_expr_t count;
1038: char *modif;
1039: {
1040:
1041: uvmhist_dump(LIST_FIRST(&uvm_histories));
1042: }
1043: #endif
1044:
1045: #if NESP_SBUS
1046: extern void db_esp(db_expr_t, int, db_expr_t, char *);
1047: #endif
1048:
1049: struct db_command db_machine_command_table[] = {
1050: { "ctx", db_ctx_cmd, 0, 0 },
1051: { "dtlb", db_dump_dtlb, 0, 0 },
1052: { "dtsb", db_dump_dtsb, 0, 0 },
1053: #if NESP_SBUS
1054: { "esp", db_esp, 0, 0 },
1055: #endif
1056: { "fpstate", db_dump_fpstate,0, 0 },
1057: { "itlb", db_dump_itlb, 0, 0 },
1058: { "kmap", db_pmap_kernel, 0, 0 },
1059: { "lock", db_lock, 0, 0 },
1060: { "pcb", db_dump_pcb, 0, 0 },
1061: { "pctx", db_setpcb, 0, 0 },
1062: { "page", db_page_cmd, 0, 0 },
1063: { "phys", db_pload_cmd, 0, 0 },
1064: { "pmap", db_pmap_cmd, 0, 0 },
1065: { "proc", db_proc_cmd, 0, 0 },
1066: { "prom", db_prom_cmd, 0, 0 },
1067: { "pv", db_dump_pv, 0, 0 },
1068: { "stack", db_dump_stack, 0, 0 },
1069: { "tf", db_dump_trap, 0, 0 },
1070: { "ts", db_dump_ts, 0, 0 },
1071: { "traptrace", db_traptrace, 0, 0 },
1072: #ifdef UVMHIST
1073: { "uvmdump", db_uvmhistdump, 0, 0 },
1074: #endif
1075: { "watch", db_watch, 0, 0 },
1076: { "window", db_dump_window, 0, 0 },
1077: { (char *)0, }
1078: };
1079:
1080: /*
1081: * support for SOFTWARE_SSTEP:
1082: * return the next pc if the given branch is taken.
1083: *
1084: * note: in the case of conditional branches with annul,
1085: * this actually returns the next pc in the "not taken" path,
1086: * but in that case next_instr_address() will return the
1087: * next pc in the "taken" path. so even tho the breakpoints
1088: * are backwards, everything will still work, and the logic is
1089: * much simpler this way.
1090: */
1091: db_addr_t
1092: db_branch_taken(inst, pc, regs)
1093: int inst;
1094: db_addr_t pc;
1095: db_regs_t *regs;
1096: {
1097: union instr insn;
1098: db_addr_t npc = ddb_regs.ddb_tf.tf_npc;
1099:
1100: insn.i_int = inst;
1101:
1102: /* the fancy union just gets in the way of this: */
1103: switch(inst & 0xffc00000) {
1104: case 0x30400000: /* branch always, annul, with prediction */
1105: return pc + ((inst<<(32-19))>>((32-19)-2));
1106: case 0x30800000: /* branch always, annul */
1107: return pc + ((inst<<(32-22))>>((32-22)-2));
1108: }
1109:
1110: /*
1111: * if this is not an annulled conditional branch, the next pc is "npc".
1112: */
1113:
1114: if (insn.i_any.i_op != IOP_OP2 || insn.i_branch.i_annul != 1)
1115: return npc;
1116:
1117: switch (insn.i_op2.i_op2) {
1118: case IOP2_Bicc:
1119: case IOP2_FBfcc:
1120: case IOP2_BPcc:
1121: case IOP2_FBPfcc:
1122: case IOP2_CBccc:
1123: /* branch on some condition-code */
1124: switch (insn.i_branch.i_cond)
1125: {
1126: case Icc_A: /* always */
1127: return pc + ((inst << 10) >> 8);
1128:
1129: default: /* all other conditions */
1130: return npc + 4;
1131: }
1132:
1133: case IOP2_BPr:
1134: /* branch on register, always conditional */
1135: return npc + 4;
1136:
1137: default:
1138: /* not a branch */
1139: panic("branch_taken() on non-branch");
1140: }
1141: }
1142:
1143: boolean_t
1144: db_inst_branch(inst)
1145: int inst;
1146: {
1147: union instr insn;
1148:
1149: insn.i_int = inst;
1150:
1151: /* the fancy union just gets in the way of this: */
1152: switch(inst & 0xffc00000) {
1153: case 0x30400000: /* branch always, annul, with prediction */
1154: return TRUE;
1155: case 0x30800000: /* branch always, annul */
1156: return TRUE;
1157: }
1158:
1159: if (insn.i_any.i_op != IOP_OP2)
1160: return FALSE;
1161:
1162: switch (insn.i_op2.i_op2) {
1163: case IOP2_BPcc:
1164: case IOP2_Bicc:
1165: case IOP2_BPr:
1166: case IOP2_FBPfcc:
1167: case IOP2_FBfcc:
1168: case IOP2_CBccc:
1169: return TRUE;
1170:
1171: default:
1172: return FALSE;
1173: }
1174: }
1175:
1176:
1177: boolean_t
1178: db_inst_call(inst)
1179: int inst;
1180: {
1181: union instr insn;
1182:
1183: insn.i_int = inst;
1184:
1185: switch (insn.i_any.i_op) {
1186: case IOP_CALL:
1187: return TRUE;
1188:
1189: case IOP_reg:
1190: return (insn.i_op3.i_op3 == IOP3_JMPL) && !db_inst_return(inst);
1191:
1192: default:
1193: return FALSE;
1194: }
1195: }
1196:
1197:
1198: boolean_t
1199: db_inst_unconditional_flow_transfer(inst)
1200: int inst;
1201: {
1202: union instr insn;
1203:
1204: insn.i_int = inst;
1205:
1206: if (db_inst_call(inst))
1207: return TRUE;
1208:
1209: if (insn.i_any.i_op != IOP_OP2)
1210: return FALSE;
1211:
1212: switch (insn.i_op2.i_op2)
1213: {
1214: case IOP2_BPcc:
1215: case IOP2_Bicc:
1216: case IOP2_FBPfcc:
1217: case IOP2_FBfcc:
1218: case IOP2_CBccc:
1219: return insn.i_branch.i_cond == Icc_A;
1220:
1221: default:
1222: return FALSE;
1223: }
1224: }
1225:
1226:
1227: boolean_t
1228: db_inst_return(inst)
1229: int inst;
1230: {
1231: return (inst == I_JMPLri(I_G0, I_O7, 8) || /* ret */
1232: inst == I_JMPLri(I_G0, I_I7, 8)); /* retl */
1233: }
1234:
1235: boolean_t
1236: db_inst_trap_return(inst)
1237: int inst;
1238: {
1239: union instr insn;
1240:
1241: insn.i_int = inst;
1242:
1243: return (insn.i_any.i_op == IOP_reg &&
1244: insn.i_op3.i_op3 == IOP3_RETT);
1245: }
1246:
1247:
1248: int
1249: db_inst_load(inst)
1250: int inst;
1251: {
1252: union instr insn;
1253:
1254: insn.i_int = inst;
1255:
1256: if (insn.i_any.i_op != IOP_mem)
1257: return 0;
1258:
1259: switch (insn.i_op3.i_op3) {
1260: case IOP3_LD:
1261: case IOP3_LDUB:
1262: case IOP3_LDUH:
1263: case IOP3_LDD:
1264: case IOP3_LDSB:
1265: case IOP3_LDSH:
1266: case IOP3_LDSTUB:
1267: case IOP3_SWAP:
1268: case IOP3_LDA:
1269: case IOP3_LDUBA:
1270: case IOP3_LDUHA:
1271: case IOP3_LDDA:
1272: case IOP3_LDSBA:
1273: case IOP3_LDSHA:
1274: case IOP3_LDSTUBA:
1275: case IOP3_SWAPA:
1276: case IOP3_LDF:
1277: case IOP3_LDFSR:
1278: case IOP3_LDDF:
1279: case IOP3_LFC:
1280: case IOP3_LDCSR:
1281: case IOP3_LDDC:
1282: return 1;
1283:
1284: default:
1285: return 0;
1286: }
1287: }
1288:
1289: int
1290: db_inst_store(inst)
1291: int inst;
1292: {
1293: union instr insn;
1294:
1295: insn.i_int = inst;
1296:
1297: if (insn.i_any.i_op != IOP_mem)
1298: return 0;
1299:
1300: switch (insn.i_op3.i_op3) {
1301: case IOP3_ST:
1302: case IOP3_STB:
1303: case IOP3_STH:
1304: case IOP3_STD:
1305: case IOP3_LDSTUB:
1306: case IOP3_SWAP:
1307: case IOP3_STA:
1308: case IOP3_STBA:
1309: case IOP3_STHA:
1310: case IOP3_STDA:
1311: case IOP3_LDSTUBA:
1312: case IOP3_SWAPA:
1313: case IOP3_STF:
1314: case IOP3_STFSR:
1315: case IOP3_STQF:
1316: case IOP3_STDF:
1317: case IOP3_STC:
1318: case IOP3_STCSR:
1319: case IOP3_STQFA:
1320: case IOP3_STDC:
1321: return 1;
1322:
1323: default:
1324: return 0;
1325: }
1326: }
1327:
1328: void
1329: db_machine_init()
1330: {
1331: db_machine_commands_install(db_machine_command_table);
1332: }
CVSweb