xref: /netbsd/sys/arch/arc/arc/minidebug.c (revision eea86dc2)
1*eea86dc2Smatt /*	$NetBSD: minidebug.c,v 1.21 2011/08/18 21:04:23 matt Exp $	*/
271f6ef9eSsoda /*	$OpenBSD: minidebug.c,v 1.2 1998/03/16 09:03:36 pefo Exp $	*/
3346d7152Ssoda 
4346d7152Ssoda /*-
5346d7152Ssoda  * Copyright (c) 1991, 1993
6346d7152Ssoda  *	The Regents of the University of California.  All rights reserved.
7346d7152Ssoda  *
8346d7152Ssoda  * This code is derived from software contributed to Berkeley by
9346d7152Ssoda  * Ralph Campbell.
10346d7152Ssoda  *
11346d7152Ssoda  * Redistribution and use in source and binary forms, with or without
12346d7152Ssoda  * modification, are permitted provided that the following conditions
13346d7152Ssoda  * are met:
14346d7152Ssoda  * 1. Redistributions of source code must retain the above copyright
15346d7152Ssoda  *    notice, this list of conditions and the following disclaimer.
16346d7152Ssoda  * 2. Redistributions in binary form must reproduce the above copyright
17346d7152Ssoda  *    notice, this list of conditions and the following disclaimer in the
18346d7152Ssoda  *    documentation and/or other materials provided with the distribution.
19aad01611Sagc  * 3. Neither the name of the University nor the names of its contributors
20346d7152Ssoda  *    may be used to endorse or promote products derived from this software
21346d7152Ssoda  *    without specific prior written permission.
22346d7152Ssoda  *
23346d7152Ssoda  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24346d7152Ssoda  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25346d7152Ssoda  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26346d7152Ssoda  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27346d7152Ssoda  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28346d7152Ssoda  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29346d7152Ssoda  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30346d7152Ssoda  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31346d7152Ssoda  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32346d7152Ssoda  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33346d7152Ssoda  * SUCH DAMAGE.
34346d7152Ssoda  *
35346d7152Ssoda  *	from: @(#)kadb.c	8.1 (Berkeley) 6/10/93
36346d7152Ssoda  */
37346d7152Ssoda 
38346d7152Ssoda /*
39346d7152Ssoda  * Define machine dependent primitives for mdb.
40346d7152Ssoda  */
41346d7152Ssoda 
42a4183603Slukem #include <sys/cdefs.h>
43*eea86dc2Smatt __KERNEL_RCSID(0, "$NetBSD: minidebug.c,v 1.21 2011/08/18 21:04:23 matt Exp $");
44a4183603Slukem 
45564df9b6Ssoda #include <sys/param.h>
46564df9b6Ssoda #include <sys/systm.h>
47564df9b6Ssoda #include <sys/proc.h>
48564df9b6Ssoda #include <dev/cons.h>
4947ef8ee9Smrg #include <uvm/uvm_extern.h>
50346d7152Ssoda #undef SP
51564df9b6Ssoda #include <machine/pte.h>
52564df9b6Ssoda #include <mips/locore.h>
53564df9b6Ssoda #include <machine/cpu.h>
54346d7152Ssoda #include <machine/reg.h>
55564df9b6Ssoda #include <machine/regnum.h>
56564df9b6Ssoda #include <machine/intr.h>
57346d7152Ssoda #include <machine/trap.h>
58346d7152Ssoda #include <machine/mips_opcode.h>
59346d7152Ssoda 
60346d7152Ssoda static char *op_name[64] = {
61346d7152Ssoda /* 0 */	"spec",	"bcond","j",	"jal",	"beq",	"bne",	"blez",	"bgtz",
62346d7152Ssoda /* 8 */	"addi",	"addiu","slti",	"sltiu","andi",	"ori",	"xori",	"lui",
63346d7152Ssoda /*16 */	"cop0",	"cop1",	"cop2",	"cop3",	"beql",	"bnel",	"blezl","bgtzl",
64346d7152Ssoda /*24 */	"daddi","daddiu","ldl",	"ldr",	"op34",	"op35",	"op36",	"op37",
65346d7152Ssoda /*32 */	"lb",	"lh",	"lwl",	"lw",	"lbu",	"lhu",	"lwr",	"lwu",
66346d7152Ssoda /*40 */	"sb",	"sh",	"swl",	"sw",	"sdl",	"sdr",	"swr",	"cache",
67346d7152Ssoda /*48 */	"ll",	"lwc1",	"lwc2",	"lwc3",	"lld",	"ldc1",	"ldc2",	"ld",
68346d7152Ssoda /*56 */	"sc",	"swc1",	"swc2",	"swc3",	"scd",	"sdc1",	"sdc2",	"sd"
69346d7152Ssoda };
70346d7152Ssoda 
71346d7152Ssoda static char *spec_name[64] = {
72346d7152Ssoda /* 0 */	"sll",	"spec01","srl",	"sra",	"sllv",	"spec05","srlv","srav",
73346d7152Ssoda /* 8 */	"jr",	"jalr",	"spec12","spec13","syscall","break","spec16","sync",
74346d7152Ssoda /*16 */	"mfhi",	"mthi",	"mflo",	"mtlo",	"dsllv","spec25","dsrlv","dsrav",
75346d7152Ssoda /*24 */	"mult",	"multu","div",	"divu",	"dmult","dmultu","ddiv","ddivu",
76346d7152Ssoda /*32 */	"add",	"addu",	"sub",	"subu",	"and",	"or",	"xor",	"nor",
77346d7152Ssoda /*40 */	"spec50","spec51","slt","sltu",	"dadd","daddu","dsub","dsubu",
78346d7152Ssoda /*48 */	"tge","tgeu","tlt","tltu","teq","spec65","tne","spec67",
79346d7152Ssoda /*56 */	"dsll","spec71","dsrl","dsra","dsll32","spec75","dsrl32","dsra32"
80346d7152Ssoda };
81346d7152Ssoda 
82*eea86dc2Smatt static char *regimm_name[32] = {
83346d7152Ssoda /* 0 */	"bltz",	"bgez", "bltzl", "bgezl", "?", "?", "?", "?",
84346d7152Ssoda /* 8 */	"tgei", "tgeiu", "tlti", "tltiu", "teqi", "?", "tnei", "?",
85346d7152Ssoda /*16 */	"bltzal", "bgezal", "bltzall", "bgezall", "?", "?", "?", "?",
86346d7152Ssoda /*24 */	"?", "?", "?", "?", "?", "?", "?", "?",
87346d7152Ssoda };
88346d7152Ssoda 
89346d7152Ssoda static char *cop1_name[64] = {
90346d7152Ssoda /* 0 */	"fadd",	"fsub",	"fmpy",	"fdiv",	"fsqrt","fabs",	"fmov",	"fneg",
91346d7152Ssoda /* 8 */	"fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f",
92346d7152Ssoda /*16 */	"fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17",
93346d7152Ssoda /*24 */	"fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f",
94346d7152Ssoda /*32 */	"fcvts","fcvtd","fcvte","fop23","fcvtw","fop25","fop26","fop27",
95346d7152Ssoda /*40 */	"fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f",
96346d7152Ssoda /*48 */	"fcmp.f","fcmp.un","fcmp.eq","fcmp.ueq","fcmp.olt","fcmp.ult",
97346d7152Ssoda 	"fcmp.ole","fcmp.ule",
98346d7152Ssoda /*56 */	"fcmp.sf","fcmp.ngle","fcmp.seq","fcmp.ngl","fcmp.lt","fcmp.nge",
99346d7152Ssoda 	"fcmp.le","fcmp.ngt"
100346d7152Ssoda };
101346d7152Ssoda 
102346d7152Ssoda static char *fmt_name[16] = {
103346d7152Ssoda 	"s",	"d",	"e",	"fmt3",
104346d7152Ssoda 	"w",	"fmt5",	"fmt6",	"fmt7",
105346d7152Ssoda 	"fmt8",	"fmt9",	"fmta",	"fmtb",
106346d7152Ssoda 	"fmtc",	"fmtd",	"fmte",	"fmtf"
107346d7152Ssoda };
108346d7152Ssoda 
109346d7152Ssoda static char *reg_name[32] = {
110346d7152Ssoda 	"zero",	"at",	"v0",	"v1",	"a0",	"a1",	"a2",	"a3",
111346d7152Ssoda 	"t0",	"t1",	"t2",	"t3",	"t4",	"t5",	"t6",	"t7",
112346d7152Ssoda 	"s0",	"s1",	"s2",	"s3",	"s4",	"s5",	"s6",	"s7",
113346d7152Ssoda 	"t8",	"t9",	"k0",	"k1",	"gp",	"sp",	"s8",	"ra"
114346d7152Ssoda };
115346d7152Ssoda 
116346d7152Ssoda static char *c0_opname[64] = {
117346d7152Ssoda 	"c0op00","tlbr",  "tlbwi", "c0op03","c0op04","c0op05","tlbwr", "c0op07",
118346d7152Ssoda 	"tlbp",  "c0op11","c0op12","c0op13","c0op14","c0op15","c0op16","c0op17",
119346d7152Ssoda 	"rfe",   "c0op21","c0op22","c0op23","c0op24","c0op25","c0op26","c0op27",
120346d7152Ssoda 	"eret","c0op31","c0op32","c0op33","c0op34","c0op35","c0op36","c0op37",
121346d7152Ssoda 	"c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47",
122346d7152Ssoda 	"c0op50","c0op51","c0op52","c0op53","c0op54","c0op55","c0op56","c0op57",
123346d7152Ssoda 	"c0op60","c0op61","c0op62","c0op63","c0op64","c0op65","c0op66","c0op67",
124346d7152Ssoda 	"c0op70","c0op71","c0op72","c0op73","c0op74","c0op75","c0op77","c0op77",
125346d7152Ssoda };
126346d7152Ssoda 
127346d7152Ssoda static char *c0_reg[32] = {
128346d7152Ssoda 	"index","random","tlblo0","tlblo1","context","tlbmask","wired","c0r7",
129346d7152Ssoda 	"badvaddr","count","tlbhi","c0r11","sr","cause","epc",	"prid",
130346d7152Ssoda 	"config","lladr","watchlo","watchhi","xcontext","c0r21","c0r22","c0r23",
131346d7152Ssoda 	"c0r24","c0r25","ecc","cacheerr","taglo","taghi","errepc","c0r31"
132346d7152Ssoda };
133346d7152Ssoda 
1347fe2a5a0Stsutsui extern u_int mdbpeek(int);
1357fe2a5a0Stsutsui extern void mdbpoke(int, int);
13671f6ef9eSsoda #ifdef __OpenBSD__
1377fe2a5a0Stsutsui extern void cpu_setwatch(int, int);
13871f6ef9eSsoda #endif
1397fe2a5a0Stsutsui extern void trapDump(char *);
1407fe2a5a0Stsutsui extern void stacktrace(void);
1417fe2a5a0Stsutsui extern u_int MachEmulateBranch(int *, int, int, u_int);
142346d7152Ssoda extern char *trap_type[];
143564df9b6Ssoda extern int num_tlbentries;
1447fe2a5a0Stsutsui static void arc_dump_tlb(int,int);
1457fe2a5a0Stsutsui static void prt_break(void);
1467fe2a5a0Stsutsui static int mdbprintins(int, int);
1477fe2a5a0Stsutsui static void mdbsetsstep(void);
1487fe2a5a0Stsutsui static int mdbclrsstep(int);
1497fe2a5a0Stsutsui static void print_regs(void);
1507fe2a5a0Stsutsui static void break_insert(void);
1517fe2a5a0Stsutsui static void break_restore(void);
1527fe2a5a0Stsutsui static int break_find(int);
153564df9b6Ssoda 
1547fe2a5a0Stsutsui void set_break(int va);
1557fe2a5a0Stsutsui void del_break(int va);
1567fe2a5a0Stsutsui int mdb(int causeReg, int vadr, int p, int kernelmode);
157564df9b6Ssoda 
158346d7152Ssoda 
159346d7152Ssoda struct pcb mdbpcb;
160346d7152Ssoda int mdbmkfault;
161346d7152Ssoda 
162346d7152Ssoda #define MAXBRK 10
163346d7152Ssoda struct brk {
164346d7152Ssoda 	int	inst;
165346d7152Ssoda 	int	addr;
166346d7152Ssoda } brk_tab[MAXBRK];
167346d7152Ssoda 
168346d7152Ssoda /*
169346d7152Ssoda  * Mini debugger for kernel.
170346d7152Ssoda  */
171564df9b6Ssoda static int
gethex(u_int * val,u_int dotval)172564df9b6Ssoda gethex(u_int *val, u_int dotval)
173346d7152Ssoda {
174346d7152Ssoda 	u_int c;
175346d7152Ssoda 
176346d7152Ssoda 	*val = 0;
177564df9b6Ssoda 	while((c = cngetc()) != '\e' && c != '\n' && c != '\r') {
178346d7152Ssoda 		if(c >= '0' && c <= '9') {
179346d7152Ssoda 			*val = (*val << 4) + c - '0';
180346d7152Ssoda 			cnputc(c);
181346d7152Ssoda 		}
182346d7152Ssoda 		else if(c >= 'a' && c <= 'f') {
183346d7152Ssoda 			*val = (*val << 4) + c - 'a' + 10;
184346d7152Ssoda 			cnputc(c);
185346d7152Ssoda 		}
186346d7152Ssoda 		else if(c == '\b') {
187346d7152Ssoda 			*val = *val >> 4;
188346d7152Ssoda 			printf("\b \b");
189346d7152Ssoda 		}
190346d7152Ssoda 		else if(c == ',') {
191346d7152Ssoda 			cnputc(c);
1927fe2a5a0Stsutsui 			return c;
193346d7152Ssoda 		}
194346d7152Ssoda 		else if(c == '.') {
195276fd166Ssimonb 			*val = dotval;
196346d7152Ssoda 			cnputc(c);
197346d7152Ssoda 		}
198346d7152Ssoda 	}
199564df9b6Ssoda 	if(c == '\r')
200564df9b6Ssoda 		c = '\n';
2017fe2a5a0Stsutsui 	return c;
202346d7152Ssoda }
203346d7152Ssoda 
204564df9b6Ssoda static
dump(u_int * addr,u_int size)205346d7152Ssoda void dump(u_int *addr, u_int size)
206346d7152Ssoda {
207346d7152Ssoda 	int	cnt;
208346d7152Ssoda 
209346d7152Ssoda 	cnt = 0;
210346d7152Ssoda 
211346d7152Ssoda 	size = (size + 3) / 4;
212346d7152Ssoda 	while (size--) {
213346d7152Ssoda 		if ((cnt++ & 3) == 0)
214346d7152Ssoda 			printf("\n%08x: ",(int)addr);
215346d7152Ssoda 		printf("%08x ",*addr++);
216346d7152Ssoda 	}
217346d7152Ssoda }
218346d7152Ssoda 
219564df9b6Ssoda static void
print_regs(void)2207fe2a5a0Stsutsui print_regs(void)
221346d7152Ssoda {
222346d7152Ssoda 	printf("\n");
223346d7152Ssoda 	printf("T0-7 %08x %08x %08x %08x %08x %08x %08x %08x\n",
224346d7152Ssoda 	    mdbpcb.pcb_regs[T0],mdbpcb.pcb_regs[T1],
225346d7152Ssoda 	    mdbpcb.pcb_regs[T2],mdbpcb.pcb_regs[T3],
226346d7152Ssoda 	    mdbpcb.pcb_regs[T4],mdbpcb.pcb_regs[T5],
227346d7152Ssoda 	    mdbpcb.pcb_regs[T6],mdbpcb.pcb_regs[T7]);
228346d7152Ssoda 	printf("T8-9 %08x %08x     A0-4 %08x %08x %08x %08x\n",
229346d7152Ssoda 	    mdbpcb.pcb_regs[T8],mdbpcb.pcb_regs[T9],
230346d7152Ssoda 	    mdbpcb.pcb_regs[A0],mdbpcb.pcb_regs[A1],
231346d7152Ssoda 	    mdbpcb.pcb_regs[A2],mdbpcb.pcb_regs[A3]);
232346d7152Ssoda 	printf("S0-7 %08x %08x %08x %08x %08x %08x %08x %08x\n",
233346d7152Ssoda 	    mdbpcb.pcb_regs[S0],mdbpcb.pcb_regs[S1],
234346d7152Ssoda 	    mdbpcb.pcb_regs[S2],mdbpcb.pcb_regs[S3],
235346d7152Ssoda 	    mdbpcb.pcb_regs[S4],mdbpcb.pcb_regs[S5],
236346d7152Ssoda 	    mdbpcb.pcb_regs[S6],mdbpcb.pcb_regs[S7]);
237346d7152Ssoda 	printf("  S8 %08x     V0-1 %08x %08x       GP %08x       SP %08x\n",
238346d7152Ssoda 	    mdbpcb.pcb_regs[S8],mdbpcb.pcb_regs[V0],
239346d7152Ssoda 	    mdbpcb.pcb_regs[V1],mdbpcb.pcb_regs[GP],
240346d7152Ssoda 	    mdbpcb.pcb_regs[SP]);
241346d7152Ssoda 	printf("  AT %08x       PC %08x       RA %08x       SR %08x",
242346d7152Ssoda 	    mdbpcb.pcb_regs[AST],mdbpcb.pcb_regs[PC],
243346d7152Ssoda 	    mdbpcb.pcb_regs[RA],mdbpcb.pcb_regs[SR]);
244346d7152Ssoda }
245346d7152Ssoda 
246564df9b6Ssoda void
set_break(int va)247564df9b6Ssoda set_break(int va)
248346d7152Ssoda {
249346d7152Ssoda 	int i;
250346d7152Ssoda 
251346d7152Ssoda 	va = va & ~3;
252346d7152Ssoda 	for (i = 0; i < MAXBRK; i++) {
253346d7152Ssoda 		if (brk_tab[i].addr == 0) {
254346d7152Ssoda 			brk_tab[i].addr = va;
255346d7152Ssoda 			brk_tab[i].inst = *(u_int *)va;
256346d7152Ssoda 			return;
257346d7152Ssoda 		}
258346d7152Ssoda 	}
259346d7152Ssoda 	printf(" Break table full!!");
260346d7152Ssoda }
261346d7152Ssoda 
262564df9b6Ssoda void
del_break(int va)263564df9b6Ssoda del_break(int va)
264346d7152Ssoda {
265346d7152Ssoda 	int i;
266346d7152Ssoda 
267346d7152Ssoda 	va = va & ~3;
268346d7152Ssoda 	for (i = 0; i < MAXBRK; i++) {
269346d7152Ssoda 		if (brk_tab[i].addr == va) {
270346d7152Ssoda 			brk_tab[i].addr = 0;
271346d7152Ssoda 			return;
272346d7152Ssoda 		}
273346d7152Ssoda 	}
274346d7152Ssoda 	printf(" Break to remove not found!!");
275346d7152Ssoda }
276346d7152Ssoda 
277564df9b6Ssoda static void
break_insert(void)2787fe2a5a0Stsutsui break_insert(void)
279346d7152Ssoda {
280346d7152Ssoda 	int i;
281346d7152Ssoda 
282346d7152Ssoda 	for (i = 0; i < MAXBRK; i++) {
283346d7152Ssoda 		if (brk_tab[i].addr != 0) {
284346d7152Ssoda 			brk_tab[i].inst = *(u_int *)brk_tab[i].addr;
285346d7152Ssoda 			*(u_int *)brk_tab[i].addr = MIPS_BREAK_BRKPT;
286564df9b6Ssoda 			mips3_FlushDCache(brk_tab[i].addr,4);
287564df9b6Ssoda 			mips3_FlushICache(brk_tab[i].addr,4);
288346d7152Ssoda 		}
289346d7152Ssoda 	}
290346d7152Ssoda }
291346d7152Ssoda 
292564df9b6Ssoda static void
break_restore(void)2937fe2a5a0Stsutsui break_restore(void)
294346d7152Ssoda {
295346d7152Ssoda 	int i;
296346d7152Ssoda 
297346d7152Ssoda 	for (i = 0; i < MAXBRK; i++) {
298346d7152Ssoda 		if (brk_tab[i].addr != 0) {
299346d7152Ssoda 			*(u_int *)brk_tab[i].addr = brk_tab[i].inst;
300564df9b6Ssoda 			mips3_FlushDCache(brk_tab[i].addr,4);
301564df9b6Ssoda 			mips3_FlushICache(brk_tab[i].addr,4);
302346d7152Ssoda 		}
303346d7152Ssoda 	}
304346d7152Ssoda }
305346d7152Ssoda 
306564df9b6Ssoda static int
break_find(int va)30782357f6dSdsl break_find(int va)
308346d7152Ssoda {
309346d7152Ssoda 	int i;
310346d7152Ssoda 
311346d7152Ssoda 	for (i = 0; i < MAXBRK; i++) {
312346d7152Ssoda 		if (brk_tab[i].addr == va) {
3137fe2a5a0Stsutsui 			return i;
314346d7152Ssoda 		}
315346d7152Ssoda 	}
3167fe2a5a0Stsutsui 	return -1;
317346d7152Ssoda }
318346d7152Ssoda 
319564df9b6Ssoda void
prt_break(void)3207fe2a5a0Stsutsui prt_break(void)
321346d7152Ssoda {
322346d7152Ssoda 	int i;
323346d7152Ssoda 
324346d7152Ssoda 	for (i = 0; i < MAXBRK; i++) {
325346d7152Ssoda 		if (brk_tab[i].addr != 0) {
326346d7152Ssoda 			printf("\n    %08x\t", brk_tab[i].addr);
327346d7152Ssoda 			mdbprintins(brk_tab[i].inst, brk_tab[i].addr);
328346d7152Ssoda 		}
329346d7152Ssoda 	}
330346d7152Ssoda }
331564df9b6Ssoda 
332564df9b6Ssoda int
mdb(int causeReg,int vadr,int p,int kernelmode)333564df9b6Ssoda mdb(int causeReg, int vadr, int p, int kernelmode)
334346d7152Ssoda {
335346d7152Ssoda 	int c;
336346d7152Ssoda 	int newaddr;
337346d7152Ssoda 	int size;
338346d7152Ssoda 	int cause;
339346d7152Ssoda static int ssandrun;	/* Single step and run flag (when cont at brk) */
340346d7152Ssoda 
341346d7152Ssoda 	splhigh();
342564df9b6Ssoda 	cause = (causeReg & MIPS3_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT;
343346d7152Ssoda 	newaddr = (int)(mdbpcb.pcb_regs[PC]);
344346d7152Ssoda 	switch (cause) {
345346d7152Ssoda 	case T_BREAK:
346346d7152Ssoda 		if (*(int *)newaddr == MIPS_BREAK_SOVER) {
347346d7152Ssoda 			break_restore();
348346d7152Ssoda 			mdbpcb.pcb_regs[PC] += 4;
349346d7152Ssoda 			printf("\nStop break (panic)\n# ");
350346d7152Ssoda 			printf("    %08x\t",newaddr);
351346d7152Ssoda 			mdbprintins(*(int *)newaddr, newaddr);
352346d7152Ssoda 			printf("\n# ");
353346d7152Ssoda 			break;
354346d7152Ssoda 		}
355346d7152Ssoda 		if (*(int *)newaddr == MIPS_BREAK_BRKPT) {
356346d7152Ssoda 			break_restore();
357346d7152Ssoda 			printf("\rBRK %08x\t",newaddr);
358346d7152Ssoda 			if(mdbprintins(*(int *)newaddr, newaddr)) {
359346d7152Ssoda 				newaddr += 4;
360346d7152Ssoda 				printf("\n    %08x\t",newaddr);
361346d7152Ssoda 				mdbprintins(*(int *)newaddr, newaddr);
362346d7152Ssoda 			}
363346d7152Ssoda 			printf("\n# ");
364346d7152Ssoda 			break;
365346d7152Ssoda 		}
366346d7152Ssoda 		if (mdbclrsstep(causeReg)) {
367346d7152Ssoda 			if (ssandrun) { /* Step over bp before free run */
368346d7152Ssoda 				ssandrun = 0;
369346d7152Ssoda 				break_insert();
370cfc07219Sthorpej 				return true;
371346d7152Ssoda 			}
372346d7152Ssoda 			printf("\r    %08x\t",newaddr);
373346d7152Ssoda 			if(mdbprintins(*(int *)newaddr, newaddr)) {
374346d7152Ssoda 				newaddr += 4;
375346d7152Ssoda 				printf("\n    %08x\t",newaddr);
376346d7152Ssoda 				mdbprintins(*(int *)newaddr, newaddr);
377346d7152Ssoda 			}
378346d7152Ssoda 			printf("\n# ");
379346d7152Ssoda 		}
380346d7152Ssoda 		break;
381346d7152Ssoda 
382346d7152Ssoda 	default:
383346d7152Ssoda 		printf("\n-- %s --\n# ",trap_type[cause]);
384346d7152Ssoda 	}
385346d7152Ssoda 	ssandrun = 0;
386346d7152Ssoda 	break_restore();
387346d7152Ssoda 
388564df9b6Ssoda 	while (1) {
389564df9b6Ssoda 		c = cngetc();
390346d7152Ssoda 		switch (c) {
391346d7152Ssoda 		case 'T':
392346d7152Ssoda 			trapDump("Debugger");
393346d7152Ssoda 			break;
394346d7152Ssoda 		case 'b':
395346d7152Ssoda 			printf("break-");
396346d7152Ssoda 			c = cngetc();
397346d7152Ssoda 			switch (c) {
398346d7152Ssoda 			case 's':
399346d7152Ssoda 				printf("set at ");
400346d7152Ssoda 				c = gethex(&newaddr, newaddr);
401346d7152Ssoda 				if(c != '\e') {
402346d7152Ssoda 					set_break(newaddr);
403346d7152Ssoda 				}
404346d7152Ssoda 				break;
405346d7152Ssoda 
406346d7152Ssoda 			case 'd':
407346d7152Ssoda 				printf("delete at ");
408346d7152Ssoda 				c = gethex(&newaddr, newaddr);
409346d7152Ssoda 				if(c != '\e') {
410346d7152Ssoda 					del_break(newaddr);
411346d7152Ssoda 				}
412346d7152Ssoda 				break;
413346d7152Ssoda 
414346d7152Ssoda 			case 'p':
415346d7152Ssoda 				printf("print");
416346d7152Ssoda 				prt_break();
417346d7152Ssoda 				break;
418346d7152Ssoda 			}
419346d7152Ssoda 			break;
420346d7152Ssoda 
421346d7152Ssoda 		case 'r':
422346d7152Ssoda 			print_regs();
423346d7152Ssoda 			break;
424346d7152Ssoda 
425346d7152Ssoda 		case 'I':
426346d7152Ssoda 			printf("Instruction at ");
427346d7152Ssoda 			c = gethex(&newaddr, newaddr);
428346d7152Ssoda 			while (c != '\e') {
429346d7152Ssoda 				printf("\n    %08x\t",newaddr);
430346d7152Ssoda 				mdbprintins(*(int *)newaddr, newaddr);
431346d7152Ssoda 				newaddr += 4;
432346d7152Ssoda 				c = cngetc();
433346d7152Ssoda 			}
434346d7152Ssoda 			break;
435346d7152Ssoda 
436346d7152Ssoda 		case 'c':
437346d7152Ssoda 			printf("continue");
438346d7152Ssoda 			if(break_find((int)(mdbpcb.pcb_regs[PC])) >= 0) {
439346d7152Ssoda 				ssandrun = 1;
440346d7152Ssoda 				mdbsetsstep();
441346d7152Ssoda 			}
442346d7152Ssoda 			else {
443346d7152Ssoda 				break_insert();
444346d7152Ssoda 			}
445cfc07219Sthorpej 			return true;
446564df9b6Ssoda 		case 'S':
447564df9b6Ssoda 			printf("Stack traceback:\n");
448564df9b6Ssoda 			stacktrace();
449cfc07219Sthorpej 			return true;
450346d7152Ssoda 		case 's':
451346d7152Ssoda 			set_break(mdbpcb.pcb_regs[PC] + 8);
452cfc07219Sthorpej 			return true;
453346d7152Ssoda 		case ' ':
454346d7152Ssoda 			mdbsetsstep();
455cfc07219Sthorpej 			return true;
456346d7152Ssoda 
457346d7152Ssoda 		case 'd':
458346d7152Ssoda 			printf("dump ");
459346d7152Ssoda 			c = gethex(&newaddr, newaddr);
460346d7152Ssoda 			if(c == ',') {
461346d7152Ssoda 				c = gethex(&size,256);
462346d7152Ssoda 			}
463346d7152Ssoda 			else {
464346d7152Ssoda 				size = 16;
465346d7152Ssoda 			}
466346d7152Ssoda 			if(c == '\n' && newaddr != 0) {
467346d7152Ssoda 				dump((u_int *)newaddr, size);
468346d7152Ssoda 				newaddr += size;
469346d7152Ssoda 			}
470346d7152Ssoda 			break;
471346d7152Ssoda 
472346d7152Ssoda 		case 'm':
473346d7152Ssoda 			printf("mod ");
474346d7152Ssoda 			c = gethex(&newaddr, newaddr);
475346d7152Ssoda 			while(c == ',') {
476346d7152Ssoda 				c = gethex(&size, 0);
477346d7152Ssoda 				if(c != '\e')
478346d7152Ssoda 					*((u_int *)newaddr)++ = size;
479346d7152Ssoda 			}
480346d7152Ssoda 			break;
481346d7152Ssoda 
482346d7152Ssoda 		case 'i':
483346d7152Ssoda 			printf("in-");
484346d7152Ssoda 			c = cngetc();
485346d7152Ssoda 			switch (c) {
486346d7152Ssoda 			case 'b':
487346d7152Ssoda 				printf("byte ");
488346d7152Ssoda 				c = gethex(&newaddr, newaddr);
489346d7152Ssoda 				if(c == '\n') {
490346d7152Ssoda 					printf("= %02x",
491346d7152Ssoda 						*(u_char *)newaddr);
492346d7152Ssoda 				}
493346d7152Ssoda 				break;
494346d7152Ssoda 			case 'h':
495346d7152Ssoda 				printf("halfword ");
496346d7152Ssoda 				c = gethex(&newaddr, newaddr);
497346d7152Ssoda 				if(c == '\n') {
498346d7152Ssoda 					printf("= %04x",
499346d7152Ssoda 						*(u_short *)newaddr);
500346d7152Ssoda 				}
501346d7152Ssoda 				break;
502346d7152Ssoda 			case 'w':
503346d7152Ssoda 				printf("word ");
504346d7152Ssoda 				c = gethex(&newaddr, newaddr);
505346d7152Ssoda 				if(c == '\n') {
506346d7152Ssoda 					printf("= %08x",
507346d7152Ssoda 						*(u_int *)newaddr);
508346d7152Ssoda 				}
509346d7152Ssoda 				break;
510346d7152Ssoda 			}
511346d7152Ssoda 			break;
512346d7152Ssoda 
513346d7152Ssoda 		case 'o':
514346d7152Ssoda 			printf("out-");
515346d7152Ssoda 			c = cngetc();
516346d7152Ssoda 			switch (c) {
517346d7152Ssoda 			case 'b':
518346d7152Ssoda 				printf("byte ");
519346d7152Ssoda 				c = gethex(&newaddr, newaddr);
520346d7152Ssoda 				if(c == ',') {
521346d7152Ssoda 					c = gethex(&size, 0);
522346d7152Ssoda 					if(c == '\n') {
523346d7152Ssoda 						*(u_char *)newaddr = size;
524346d7152Ssoda 					}
525346d7152Ssoda 				}
526346d7152Ssoda 				break;
527346d7152Ssoda 			case 'h':
528346d7152Ssoda 				printf("halfword ");
529346d7152Ssoda 				c = gethex(&newaddr, newaddr);
530346d7152Ssoda 				if(c == ',') {
531346d7152Ssoda 					c = gethex(&size, 0);
532346d7152Ssoda 					if(c == '\n') {
533346d7152Ssoda 						*(u_short *)newaddr = size;
534346d7152Ssoda 					}
535346d7152Ssoda 				}
536346d7152Ssoda 				break;
537346d7152Ssoda 			case 'w':
538346d7152Ssoda 				printf("word ");
539346d7152Ssoda 				c = gethex(&newaddr, newaddr);
540346d7152Ssoda 				if(c == ',') {
541346d7152Ssoda 					c = gethex(&size, 0);
542346d7152Ssoda 					if(c == '\n') {
543346d7152Ssoda 						*(u_int *)newaddr = size;
544346d7152Ssoda 					}
545346d7152Ssoda 				}
546346d7152Ssoda 				break;
547346d7152Ssoda 			}
548346d7152Ssoda 			break;
549346d7152Ssoda 
550346d7152Ssoda 		case 't':
551346d7152Ssoda 			printf("tlb-dump\n");
552564df9b6Ssoda 			arc_dump_tlb(0,23);
553346d7152Ssoda 			(void)cngetc();
554564df9b6Ssoda 			arc_dump_tlb(24,47);
555346d7152Ssoda 			break;
556346d7152Ssoda 
557346d7152Ssoda 		case 'f':
558346d7152Ssoda 			printf("flush-");
559346d7152Ssoda 			c = cngetc();
560346d7152Ssoda 			switch (c) {
561346d7152Ssoda 			case 't':
562346d7152Ssoda 				printf("tlb");
563564df9b6Ssoda 				mips3_TLBFlush(num_tlbentries);
564346d7152Ssoda 				break;
565346d7152Ssoda 
566346d7152Ssoda 			case 'c':
567346d7152Ssoda 				printf("cache");
568564df9b6Ssoda 				mips3_FlushCache();
569346d7152Ssoda 				break;
570346d7152Ssoda 			}
571346d7152Ssoda 			break;
572346d7152Ssoda 
57371f6ef9eSsoda #ifdef __OpenBSD__
57471f6ef9eSsoda 		case 'w':
57571f6ef9eSsoda 			printf("watch ");
57671f6ef9eSsoda 			c = gethex(&newaddr, newaddr);
57771f6ef9eSsoda 			size = 3;
57871f6ef9eSsoda 			if(c == ',') {
57971f6ef9eSsoda 				c = cngetc();
58071f6ef9eSsoda 				cnputc(c);
58171f6ef9eSsoda 				if(c == 'r')
58271f6ef9eSsoda 					size = 2;
58371f6ef9eSsoda 				else if(c == 'w')
58471f6ef9eSsoda 					size = 1;
58571f6ef9eSsoda 				else
58671f6ef9eSsoda 					size = 0;
58771f6ef9eSsoda 			}
58871f6ef9eSsoda 			cpu_setwatch(0, (newaddr & ~7) | size);
58971f6ef9eSsoda 			break;
59071f6ef9eSsoda #endif
59171f6ef9eSsoda 
592346d7152Ssoda 		default:
593346d7152Ssoda 			cnputc('\a');
594346d7152Ssoda 			break;
595346d7152Ssoda 		}
596346d7152Ssoda 		printf("\n# ");
597346d7152Ssoda 	}
598346d7152Ssoda }
599346d7152Ssoda 
600346d7152Ssoda u_int mdb_ss_addr;
601346d7152Ssoda u_int mdb_ss_instr;
602346d7152Ssoda 
603564df9b6Ssoda static void
mdbsetsstep(void)6047fe2a5a0Stsutsui mdbsetsstep(void)
605346d7152Ssoda {
6068e19dfb2Stsutsui 	u_int va;
6078e19dfb2Stsutsui 	int *locr0 = mdbpcb.pcb_regs;
608346d7152Ssoda 
609346d7152Ssoda 	/* compute next address after current location */
610346d7152Ssoda 	if (mdbpeek(locr0[PC]) != 0) {
611346d7152Ssoda 		va = MachEmulateBranch(locr0, locr0[PC], 0, mdbpeek(locr0[PC]));
612346d7152Ssoda 	}
613346d7152Ssoda 	else {
614346d7152Ssoda 		va = locr0[PC] + 4;
615346d7152Ssoda 	}
616346d7152Ssoda 	if (mdb_ss_addr) {
617346d7152Ssoda 		printf("mdbsetsstep: breakpoint already set at %x (va %x)\n",
618346d7152Ssoda 		    mdb_ss_addr, va);
619346d7152Ssoda 		return;
620346d7152Ssoda 	}
621346d7152Ssoda 	mdb_ss_addr = va;
622346d7152Ssoda 
623346d7152Ssoda 	if ((int)va < 0) {
624346d7152Ssoda 		/* kernel address */
625346d7152Ssoda 		mdb_ss_instr = mdbpeek(va);
626564df9b6Ssoda 		mdbpoke(va, MIPS_BREAK_SSTEP);
627564df9b6Ssoda 		mips3_FlushDCache(va,4);
628564df9b6Ssoda 		mips3_FlushICache(va,4);
629346d7152Ssoda 		return;
630346d7152Ssoda 	}
631346d7152Ssoda }
632346d7152Ssoda 
633564df9b6Ssoda static int
mdbclrsstep(int cr)634564df9b6Ssoda mdbclrsstep(int cr)
635346d7152Ssoda {
6368e19dfb2Stsutsui 	u_int pc, va;
637346d7152Ssoda 	u_int instr;
638346d7152Ssoda 
639346d7152Ssoda 	/* fix pc if break instruction is in the delay slot */
640346d7152Ssoda 	pc = mdbpcb.pcb_regs[PC];
641346d7152Ssoda 	if (cr < 0)
642346d7152Ssoda 		pc += 4;
643346d7152Ssoda 
644346d7152Ssoda 	/* check to be sure its the one we are expecting */
645346d7152Ssoda 	va = mdb_ss_addr;
646346d7152Ssoda 	if (!va || va != pc)
647cfc07219Sthorpej 		return false;
648346d7152Ssoda 
649346d7152Ssoda 	/* read break instruction */
650346d7152Ssoda 	instr = mdbpeek(va);
651346d7152Ssoda 	if (instr != MIPS_BREAK_SSTEP)
652cfc07219Sthorpej 		return false;
653346d7152Ssoda 
654346d7152Ssoda 	if ((int)va < 0) {
655346d7152Ssoda 		/* kernel address */
656564df9b6Ssoda 		mdbpoke(va, mdb_ss_instr);
657564df9b6Ssoda 		mips3_FlushDCache(va,4);
658564df9b6Ssoda 		mips3_FlushICache(va,4);
659346d7152Ssoda 		mdb_ss_addr = 0;
660cfc07219Sthorpej 		return true;
661346d7152Ssoda 	}
662346d7152Ssoda 
663346d7152Ssoda 	printf("can't clear break at %x\n", va);
664346d7152Ssoda 	mdb_ss_addr = 0;
665cfc07219Sthorpej 	return false;
666346d7152Ssoda }
667346d7152Ssoda 
668346d7152Ssoda 
669346d7152Ssoda /* ARGSUSED */
670564df9b6Ssoda static int
mdbprintins(int ins,int mdbdot)671564df9b6Ssoda mdbprintins(int ins, int mdbdot)
672346d7152Ssoda {
673346d7152Ssoda 	InstFmt i;
674346d7152Ssoda 	int delay = 0;
675346d7152Ssoda 
676346d7152Ssoda 	i.word = ins;
677346d7152Ssoda 
678346d7152Ssoda 	switch (i.JType.op) {
679346d7152Ssoda 	case OP_SPECIAL:
680346d7152Ssoda 		if (i.word == 0) {
681346d7152Ssoda 			printf("nop");
682346d7152Ssoda 			break;
683346d7152Ssoda 		}
684346d7152Ssoda 		if (i.RType.func == OP_ADDU && i.RType.rt == 0) {
685346d7152Ssoda 			printf("move\t%s,%s",
686346d7152Ssoda 			    reg_name[i.RType.rd],
687346d7152Ssoda 			    reg_name[i.RType.rs]);
688346d7152Ssoda 			break;
689346d7152Ssoda 		}
690346d7152Ssoda 		printf("%s", spec_name[i.RType.func]);
691346d7152Ssoda 		switch (i.RType.func) {
692346d7152Ssoda 		case OP_SLL:
693346d7152Ssoda 		case OP_SRL:
694346d7152Ssoda 		case OP_SRA:
695346d7152Ssoda 		case OP_DSLL:
696346d7152Ssoda 		case OP_DSRL:
697346d7152Ssoda 		case OP_DSRA:
698346d7152Ssoda 		case OP_DSLL32:
699346d7152Ssoda 		case OP_DSRL32:
700346d7152Ssoda 		case OP_DSRA32:
701346d7152Ssoda 			printf("\t%s,%s,%d",
702346d7152Ssoda 			    reg_name[i.RType.rd],
703346d7152Ssoda 			    reg_name[i.RType.rt],
704346d7152Ssoda 			    i.RType.shamt);
705346d7152Ssoda 			break;
706346d7152Ssoda 
707346d7152Ssoda 		case OP_SLLV:
708346d7152Ssoda 		case OP_SRLV:
709346d7152Ssoda 		case OP_SRAV:
710346d7152Ssoda 		case OP_DSLLV:
711346d7152Ssoda 		case OP_DSRLV:
712346d7152Ssoda 		case OP_DSRAV:
713346d7152Ssoda 			printf("\t%s,%s,%s",
714346d7152Ssoda 			    reg_name[i.RType.rd],
715346d7152Ssoda 			    reg_name[i.RType.rt],
716346d7152Ssoda 			    reg_name[i.RType.rs]);
717346d7152Ssoda 			break;
718346d7152Ssoda 
719346d7152Ssoda 		case OP_MFHI:
720346d7152Ssoda 		case OP_MFLO:
721346d7152Ssoda 			printf("\t%s", reg_name[i.RType.rd]);
722346d7152Ssoda 			break;
723346d7152Ssoda 
724346d7152Ssoda 		case OP_JR:
725346d7152Ssoda 		case OP_JALR:
726346d7152Ssoda 			delay = 1;
727346d7152Ssoda 			/* FALLTHROUGH */
728346d7152Ssoda 		case OP_MTLO:
729346d7152Ssoda 		case OP_MTHI:
730346d7152Ssoda 			printf("\t%s", reg_name[i.RType.rs]);
731346d7152Ssoda 			break;
732346d7152Ssoda 
733346d7152Ssoda 		case OP_MULT:
734346d7152Ssoda 		case OP_MULTU:
735346d7152Ssoda 		case OP_DMULT:
736346d7152Ssoda 		case OP_DMULTU:
737346d7152Ssoda 		case OP_DIV:
738346d7152Ssoda 		case OP_DIVU:
739346d7152Ssoda 		case OP_DDIV:
740346d7152Ssoda 		case OP_DDIVU:
741346d7152Ssoda 			printf("\t%s,%s",
742346d7152Ssoda 				reg_name[i.RType.rs],
743346d7152Ssoda 				reg_name[i.RType.rt]);
744346d7152Ssoda 			break;
745346d7152Ssoda 
746346d7152Ssoda 		case OP_SYSCALL:
747346d7152Ssoda 		case OP_SYNC:
748346d7152Ssoda 			break;
749346d7152Ssoda 
750346d7152Ssoda 		case OP_BREAK:
751346d7152Ssoda 			printf("\t%d", (i.RType.rs << 5) | i.RType.rt);
752346d7152Ssoda 			break;
753346d7152Ssoda 
754346d7152Ssoda 		default:
755346d7152Ssoda 			printf("\t%s,%s,%s",
756346d7152Ssoda 			    reg_name[i.RType.rd],
757346d7152Ssoda 			    reg_name[i.RType.rs],
758346d7152Ssoda 			    reg_name[i.RType.rt]);
759346d7152Ssoda 		};
760346d7152Ssoda 		break;
761346d7152Ssoda 
762*eea86dc2Smatt 	case OP_REGIMM:
763*eea86dc2Smatt 		printf("%s\t%s,", regimm_name[i.IType.rt],
764346d7152Ssoda 		    reg_name[i.IType.rs]);
765346d7152Ssoda 		goto pr_displ;
766346d7152Ssoda 
767346d7152Ssoda 	case OP_BLEZ:
768346d7152Ssoda 	case OP_BLEZL:
769346d7152Ssoda 	case OP_BGTZ:
770346d7152Ssoda 	case OP_BGTZL:
771346d7152Ssoda 		printf("%s\t%s,", op_name[i.IType.op],
772346d7152Ssoda 		    reg_name[i.IType.rs]);
773346d7152Ssoda 		goto pr_displ;
774346d7152Ssoda 
775346d7152Ssoda 	case OP_BEQ:
776346d7152Ssoda 	case OP_BEQL:
777346d7152Ssoda 		if (i.IType.rs == 0 && i.IType.rt == 0) {
778346d7152Ssoda 			printf("b\t");
779346d7152Ssoda 			goto pr_displ;
780346d7152Ssoda 		}
781346d7152Ssoda 		/* FALLTHROUGH */
782346d7152Ssoda 	case OP_BNE:
783346d7152Ssoda 	case OP_BNEL:
784346d7152Ssoda 		printf("%s\t%s,%s,", op_name[i.IType.op],
785346d7152Ssoda 		    reg_name[i.IType.rs],
786346d7152Ssoda 		    reg_name[i.IType.rt]);
787346d7152Ssoda 	pr_displ:
788346d7152Ssoda 		delay = 1;
789346d7152Ssoda 		printf("0x%08x", mdbdot + 4 + ((short)i.IType.imm << 2));
790346d7152Ssoda 		break;
791346d7152Ssoda 
792346d7152Ssoda 	case OP_COP0:
793346d7152Ssoda 		switch (i.RType.rs) {
794346d7152Ssoda 		case OP_BCx:
795346d7152Ssoda 		case OP_BCy:
796346d7152Ssoda 			printf("bc0%c\t",
797346d7152Ssoda 			    "ft"[i.RType.rt & COPz_BC_TF_MASK]);
798346d7152Ssoda 			goto pr_displ;
799346d7152Ssoda 
800346d7152Ssoda 		case OP_MT:
801346d7152Ssoda 			printf("mtc0\t%s,%s",
802346d7152Ssoda 			    reg_name[i.RType.rt],
803346d7152Ssoda 			    c0_reg[i.RType.rd]);
804346d7152Ssoda 			break;
805346d7152Ssoda 
806346d7152Ssoda 		case OP_DMT:
807346d7152Ssoda 			printf("dmtc0\t%s,%s",
808346d7152Ssoda 			    reg_name[i.RType.rt],
809346d7152Ssoda 			    c0_reg[i.RType.rd]);
810346d7152Ssoda 			break;
811346d7152Ssoda 
812346d7152Ssoda 		case OP_MF:
813346d7152Ssoda 			printf("mfc0\t%s,%s",
814346d7152Ssoda 			    reg_name[i.RType.rt],
815346d7152Ssoda 			    c0_reg[i.RType.rd]);
816346d7152Ssoda 			break;
817346d7152Ssoda 
818346d7152Ssoda 		case OP_DMF:
819346d7152Ssoda 			printf("dmfc0\t%s,%s",
820346d7152Ssoda 			    reg_name[i.RType.rt],
821346d7152Ssoda 			    c0_reg[i.RType.rd]);
822346d7152Ssoda 			break;
823346d7152Ssoda 
824346d7152Ssoda 		default:
825346d7152Ssoda 			printf("%s", c0_opname[i.FRType.func]);
826346d7152Ssoda 		};
827346d7152Ssoda 		break;
828346d7152Ssoda 
829346d7152Ssoda 	case OP_COP1:
830346d7152Ssoda 		switch (i.RType.rs) {
831346d7152Ssoda 		case OP_BCx:
832346d7152Ssoda 		case OP_BCy:
833346d7152Ssoda 			printf("bc1%c\t",
834346d7152Ssoda 			    "ft"[i.RType.rt & COPz_BC_TF_MASK]);
835346d7152Ssoda 			goto pr_displ;
836346d7152Ssoda 
837346d7152Ssoda 		case OP_MT:
838346d7152Ssoda 			printf("mtc1\t%s,f%d",
839346d7152Ssoda 			    reg_name[i.RType.rt],
840346d7152Ssoda 			    i.RType.rd);
841346d7152Ssoda 			break;
842346d7152Ssoda 
843346d7152Ssoda 		case OP_MF:
844346d7152Ssoda 			printf("mfc1\t%s,f%d",
845346d7152Ssoda 			    reg_name[i.RType.rt],
846346d7152Ssoda 			    i.RType.rd);
847346d7152Ssoda 			break;
848346d7152Ssoda 
849346d7152Ssoda 		case OP_CT:
850346d7152Ssoda 			printf("ctc1\t%s,f%d",
851346d7152Ssoda 			    reg_name[i.RType.rt],
852346d7152Ssoda 			    i.RType.rd);
853346d7152Ssoda 			break;
854346d7152Ssoda 
855346d7152Ssoda 		case OP_CF:
856346d7152Ssoda 			printf("cfc1\t%s,f%d",
857346d7152Ssoda 			    reg_name[i.RType.rt],
858346d7152Ssoda 			    i.RType.rd);
859346d7152Ssoda 			break;
860346d7152Ssoda 
861346d7152Ssoda 		default:
862346d7152Ssoda 			printf("%s.%s\tf%d,f%d,f%d",
863346d7152Ssoda 			    cop1_name[i.FRType.func],
864346d7152Ssoda 			    fmt_name[i.FRType.fmt],
865346d7152Ssoda 			    i.FRType.fd, i.FRType.fs, i.FRType.ft);
866346d7152Ssoda 		};
867346d7152Ssoda 		break;
868346d7152Ssoda 
869346d7152Ssoda 	case OP_J:
870346d7152Ssoda 	case OP_JAL:
871346d7152Ssoda 		printf("%s\t", op_name[i.JType.op]);
872346d7152Ssoda 		printf("0x%8x",(mdbdot & 0xF0000000) | (i.JType.target << 2));
873346d7152Ssoda 		delay = 1;
874346d7152Ssoda 		break;
875346d7152Ssoda 
876346d7152Ssoda 	case OP_LWC1:
877346d7152Ssoda 	case OP_SWC1:
878346d7152Ssoda 		printf("%s\tf%d,", op_name[i.IType.op],
879346d7152Ssoda 		    i.IType.rt);
880346d7152Ssoda 		goto loadstore;
881346d7152Ssoda 
882346d7152Ssoda 	case OP_LB:
883346d7152Ssoda 	case OP_LH:
884346d7152Ssoda 	case OP_LW:
885346d7152Ssoda 	case OP_LD:
886346d7152Ssoda 	case OP_LBU:
887346d7152Ssoda 	case OP_LHU:
888346d7152Ssoda 	case OP_LWU:
889346d7152Ssoda 	case OP_SB:
890346d7152Ssoda 	case OP_SH:
891346d7152Ssoda 	case OP_SW:
892346d7152Ssoda 	case OP_SD:
893346d7152Ssoda 		printf("%s\t%s,", op_name[i.IType.op],
894346d7152Ssoda 		    reg_name[i.IType.rt]);
895346d7152Ssoda 	loadstore:
896346d7152Ssoda 		printf("%d(%s)", (short)i.IType.imm,
897346d7152Ssoda 		    reg_name[i.IType.rs]);
898346d7152Ssoda 		break;
899346d7152Ssoda 
900346d7152Ssoda 	case OP_ORI:
901346d7152Ssoda 	case OP_XORI:
902346d7152Ssoda 		if (i.IType.rs == 0) {
903346d7152Ssoda 			printf("li\t%s,0x%x",
904346d7152Ssoda 			    reg_name[i.IType.rt],
905346d7152Ssoda 			    i.IType.imm);
906346d7152Ssoda 			break;
907346d7152Ssoda 		}
908346d7152Ssoda 		/* FALLTHROUGH */
909346d7152Ssoda 	case OP_ANDI:
910346d7152Ssoda 		printf("%s\t%s,%s,0x%x", op_name[i.IType.op],
911346d7152Ssoda 		    reg_name[i.IType.rt],
912346d7152Ssoda 		    reg_name[i.IType.rs],
913346d7152Ssoda 		    i.IType.imm);
914346d7152Ssoda 		break;
915346d7152Ssoda 
916346d7152Ssoda 	case OP_LUI:
917346d7152Ssoda 		printf("%s\t%s,0x%x", op_name[i.IType.op],
918346d7152Ssoda 		    reg_name[i.IType.rt],
919346d7152Ssoda 		    i.IType.imm);
920346d7152Ssoda 		break;
921346d7152Ssoda 
922346d7152Ssoda 	case OP_ADDI:
923346d7152Ssoda 	case OP_DADDI:
924346d7152Ssoda 	case OP_ADDIU:
925346d7152Ssoda 	case OP_DADDIU:
926346d7152Ssoda 		if (i.IType.rs == 0) {
927346d7152Ssoda  			printf("li\t%s,%d",
928346d7152Ssoda 			    reg_name[i.IType.rt],
929346d7152Ssoda 			    (short)i.IType.imm);
930346d7152Ssoda 			break;
931346d7152Ssoda 		}
932346d7152Ssoda 		/* FALLTHROUGH */
933346d7152Ssoda 	default:
934346d7152Ssoda 		printf("%s\t%s,%s,%d", op_name[i.IType.op],
935346d7152Ssoda 		    reg_name[i.IType.rt],
936346d7152Ssoda 		    reg_name[i.IType.rs],
937346d7152Ssoda 		    (short)i.IType.imm);
938346d7152Ssoda 	}
9397fe2a5a0Stsutsui 	return delay;
940346d7152Ssoda }
941346d7152Ssoda 
942346d7152Ssoda 
943346d7152Ssoda /*
944346d7152Ssoda  *	Dump TLB contents.
945346d7152Ssoda  */
946564df9b6Ssoda static void
arc_dump_tlb(int first,int last)947564df9b6Ssoda arc_dump_tlb(int first,int last)
948346d7152Ssoda {
949346d7152Ssoda 	int tlbno;
950346d7152Ssoda 	struct tlb tlb;
951346d7152Ssoda 
952346d7152Ssoda 	tlbno = first;
953346d7152Ssoda 
954346d7152Ssoda 	while (tlbno <= last) {
955564df9b6Ssoda 		mips3_TLBRead(tlbno, &tlb);
956564df9b6Ssoda 		if (tlb.tlb_lo0 & MIPS3_PG_V || tlb.tlb_lo1 & MIPS3_PG_V) {
957346d7152Ssoda 			printf("TLB %2d vad 0x%08x ", tlbno, tlb.tlb_hi);
9587fe2a5a0Stsutsui 		} else {
959346d7152Ssoda 			printf("TLB*%2d vad 0x%08x ", tlbno, tlb.tlb_hi);
960346d7152Ssoda 		}
96126c2cf79Ssoda 		printf("0=0x%08x ", mips_tlbpfn_to_paddr(tlb.tlb_lo0));
962564df9b6Ssoda 		printf("%c", tlb.tlb_lo0 & MIPS3_PG_M ? 'M' : ' ');
963564df9b6Ssoda 		printf("%c", tlb.tlb_lo0 & MIPS3_PG_G ? 'G' : ' ');
964346d7152Ssoda 		printf(" atr %x ", (tlb.tlb_lo0 >> 3) & 7);
96526c2cf79Ssoda 		printf("1=0x%08x ", mips_tlbpfn_to_paddr(tlb.tlb_lo1));
966564df9b6Ssoda 		printf("%c", tlb.tlb_lo1 & MIPS3_PG_M ? 'M' : ' ');
967564df9b6Ssoda 		printf("%c", tlb.tlb_lo1 & MIPS3_PG_G ? 'G' : ' ');
968346d7152Ssoda 		printf(" atr %x ", (tlb.tlb_lo1 >> 3) & 7);
969346d7152Ssoda 		printf(" sz=%x\n", tlb.tlb_mask);
970346d7152Ssoda 
971346d7152Ssoda 		tlbno++;
972346d7152Ssoda 	}
973346d7152Ssoda }
974