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