xref: /netbsd/sys/arch/arc/arc/minidebug.c (revision 564df9b6)
1*564df9b6Ssoda /*	$NetBSD: minidebug.c,v 1.7 2000/01/23 21:01:52 soda Exp $	*/
2*564df9b6Ssoda /*	$OpenBSD: minidebug.c,v 1.5 1997/04/19 17:19:46 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.
19346d7152Ssoda  * 3. All advertising materials mentioning features or use of this software
20346d7152Ssoda  *    must display the following acknowledgement:
21346d7152Ssoda  *	This product includes software developed by the University of
22346d7152Ssoda  *	California, Berkeley and its contributors.
23346d7152Ssoda  * 4. Neither the name of the University nor the names of its contributors
24346d7152Ssoda  *    may be used to endorse or promote products derived from this software
25346d7152Ssoda  *    without specific prior written permission.
26346d7152Ssoda  *
27346d7152Ssoda  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28346d7152Ssoda  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29346d7152Ssoda  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30346d7152Ssoda  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31346d7152Ssoda  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32346d7152Ssoda  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33346d7152Ssoda  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34346d7152Ssoda  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35346d7152Ssoda  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36346d7152Ssoda  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37346d7152Ssoda  * SUCH DAMAGE.
38346d7152Ssoda  *
39346d7152Ssoda  *	from: @(#)kadb.c	8.1 (Berkeley) 6/10/93
40346d7152Ssoda  */
41346d7152Ssoda 
42346d7152Ssoda /*
43346d7152Ssoda  * Define machine dependent primitives for mdb.
44346d7152Ssoda  */
45346d7152Ssoda 
46*564df9b6Ssoda #include <sys/param.h>
47*564df9b6Ssoda #include <sys/systm.h>
48*564df9b6Ssoda #include <sys/proc.h>
49*564df9b6Ssoda #include <sys/user.h>
50*564df9b6Ssoda #include <dev/cons.h>
51*564df9b6Ssoda #include <vm/vm.h>
52346d7152Ssoda #undef SP
53*564df9b6Ssoda #include <machine/pte.h>
54*564df9b6Ssoda #include <mips/locore.h>
55*564df9b6Ssoda #include <machine/cpu.h>
56346d7152Ssoda #include <machine/reg.h>
57*564df9b6Ssoda #include <machine/regnum.h>
58*564df9b6Ssoda #include <machine/intr.h>
59346d7152Ssoda #include <machine/trap.h>
60346d7152Ssoda #include <machine/mips_opcode.h>
61346d7152Ssoda 
62346d7152Ssoda #ifndef TRUE
63346d7152Ssoda #define TRUE 1
64346d7152Ssoda #define FALSE 0
65346d7152Ssoda #endif
66346d7152Ssoda 
67346d7152Ssoda 
68346d7152Ssoda static char *op_name[64] = {
69346d7152Ssoda /* 0 */	"spec",	"bcond","j",	"jal",	"beq",	"bne",	"blez",	"bgtz",
70346d7152Ssoda /* 8 */	"addi",	"addiu","slti",	"sltiu","andi",	"ori",	"xori",	"lui",
71346d7152Ssoda /*16 */	"cop0",	"cop1",	"cop2",	"cop3",	"beql",	"bnel",	"blezl","bgtzl",
72346d7152Ssoda /*24 */	"daddi","daddiu","ldl",	"ldr",	"op34",	"op35",	"op36",	"op37",
73346d7152Ssoda /*32 */	"lb",	"lh",	"lwl",	"lw",	"lbu",	"lhu",	"lwr",	"lwu",
74346d7152Ssoda /*40 */	"sb",	"sh",	"swl",	"sw",	"sdl",	"sdr",	"swr",	"cache",
75346d7152Ssoda /*48 */	"ll",	"lwc1",	"lwc2",	"lwc3",	"lld",	"ldc1",	"ldc2",	"ld",
76346d7152Ssoda /*56 */	"sc",	"swc1",	"swc2",	"swc3",	"scd",	"sdc1",	"sdc2",	"sd"
77346d7152Ssoda };
78346d7152Ssoda 
79346d7152Ssoda static char *spec_name[64] = {
80346d7152Ssoda /* 0 */	"sll",	"spec01","srl",	"sra",	"sllv",	"spec05","srlv","srav",
81346d7152Ssoda /* 8 */	"jr",	"jalr",	"spec12","spec13","syscall","break","spec16","sync",
82346d7152Ssoda /*16 */	"mfhi",	"mthi",	"mflo",	"mtlo",	"dsllv","spec25","dsrlv","dsrav",
83346d7152Ssoda /*24 */	"mult",	"multu","div",	"divu",	"dmult","dmultu","ddiv","ddivu",
84346d7152Ssoda /*32 */	"add",	"addu",	"sub",	"subu",	"and",	"or",	"xor",	"nor",
85346d7152Ssoda /*40 */	"spec50","spec51","slt","sltu",	"dadd","daddu","dsub","dsubu",
86346d7152Ssoda /*48 */	"tge","tgeu","tlt","tltu","teq","spec65","tne","spec67",
87346d7152Ssoda /*56 */	"dsll","spec71","dsrl","dsra","dsll32","spec75","dsrl32","dsra32"
88346d7152Ssoda };
89346d7152Ssoda 
90346d7152Ssoda static char *bcond_name[32] = {
91346d7152Ssoda /* 0 */	"bltz",	"bgez", "bltzl", "bgezl", "?", "?", "?", "?",
92346d7152Ssoda /* 8 */	"tgei", "tgeiu", "tlti", "tltiu", "teqi", "?", "tnei", "?",
93346d7152Ssoda /*16 */	"bltzal", "bgezal", "bltzall", "bgezall", "?", "?", "?", "?",
94346d7152Ssoda /*24 */	"?", "?", "?", "?", "?", "?", "?", "?",
95346d7152Ssoda };
96346d7152Ssoda 
97346d7152Ssoda static char *cop1_name[64] = {
98346d7152Ssoda /* 0 */	"fadd",	"fsub",	"fmpy",	"fdiv",	"fsqrt","fabs",	"fmov",	"fneg",
99346d7152Ssoda /* 8 */	"fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f",
100346d7152Ssoda /*16 */	"fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17",
101346d7152Ssoda /*24 */	"fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f",
102346d7152Ssoda /*32 */	"fcvts","fcvtd","fcvte","fop23","fcvtw","fop25","fop26","fop27",
103346d7152Ssoda /*40 */	"fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f",
104346d7152Ssoda /*48 */	"fcmp.f","fcmp.un","fcmp.eq","fcmp.ueq","fcmp.olt","fcmp.ult",
105346d7152Ssoda 	"fcmp.ole","fcmp.ule",
106346d7152Ssoda /*56 */	"fcmp.sf","fcmp.ngle","fcmp.seq","fcmp.ngl","fcmp.lt","fcmp.nge",
107346d7152Ssoda 	"fcmp.le","fcmp.ngt"
108346d7152Ssoda };
109346d7152Ssoda 
110346d7152Ssoda static char *fmt_name[16] = {
111346d7152Ssoda 	"s",	"d",	"e",	"fmt3",
112346d7152Ssoda 	"w",	"fmt5",	"fmt6",	"fmt7",
113346d7152Ssoda 	"fmt8",	"fmt9",	"fmta",	"fmtb",
114346d7152Ssoda 	"fmtc",	"fmtd",	"fmte",	"fmtf"
115346d7152Ssoda };
116346d7152Ssoda 
117346d7152Ssoda static char *reg_name[32] = {
118346d7152Ssoda 	"zero",	"at",	"v0",	"v1",	"a0",	"a1",	"a2",	"a3",
119346d7152Ssoda 	"t0",	"t1",	"t2",	"t3",	"t4",	"t5",	"t6",	"t7",
120346d7152Ssoda 	"s0",	"s1",	"s2",	"s3",	"s4",	"s5",	"s6",	"s7",
121346d7152Ssoda 	"t8",	"t9",	"k0",	"k1",	"gp",	"sp",	"s8",	"ra"
122346d7152Ssoda };
123346d7152Ssoda 
124346d7152Ssoda static char *c0_opname[64] = {
125346d7152Ssoda 	"c0op00","tlbr",  "tlbwi", "c0op03","c0op04","c0op05","tlbwr", "c0op07",
126346d7152Ssoda 	"tlbp",  "c0op11","c0op12","c0op13","c0op14","c0op15","c0op16","c0op17",
127346d7152Ssoda 	"rfe",   "c0op21","c0op22","c0op23","c0op24","c0op25","c0op26","c0op27",
128346d7152Ssoda 	"eret","c0op31","c0op32","c0op33","c0op34","c0op35","c0op36","c0op37",
129346d7152Ssoda 	"c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47",
130346d7152Ssoda 	"c0op50","c0op51","c0op52","c0op53","c0op54","c0op55","c0op56","c0op57",
131346d7152Ssoda 	"c0op60","c0op61","c0op62","c0op63","c0op64","c0op65","c0op66","c0op67",
132346d7152Ssoda 	"c0op70","c0op71","c0op72","c0op73","c0op74","c0op75","c0op77","c0op77",
133346d7152Ssoda };
134346d7152Ssoda 
135346d7152Ssoda static char *c0_reg[32] = {
136346d7152Ssoda 	"index","random","tlblo0","tlblo1","context","tlbmask","wired","c0r7",
137346d7152Ssoda 	"badvaddr","count","tlbhi","c0r11","sr","cause","epc",	"prid",
138346d7152Ssoda 	"config","lladr","watchlo","watchhi","xcontext","c0r21","c0r22","c0r23",
139346d7152Ssoda 	"c0r24","c0r25","ecc","cacheerr","taglo","taghi","errepc","c0r31"
140346d7152Ssoda };
141346d7152Ssoda 
142*564df9b6Ssoda extern u_int mdbpeek __P((int));
143*564df9b6Ssoda extern void mdbpoke __P((int, int));
144*564df9b6Ssoda extern void trapDump __P((char *));
145*564df9b6Ssoda extern void stacktrace __P((void));
146*564df9b6Ssoda extern u_int MachEmulateBranch __P((int *, int, int, u_int));
147346d7152Ssoda extern char *trap_type[];
148*564df9b6Ssoda extern int num_tlbentries;
149*564df9b6Ssoda static void arc_dump_tlb __P((int,int));
150*564df9b6Ssoda static void prt_break __P((void));
151*564df9b6Ssoda static int mdbprintins __P((int, int));
152*564df9b6Ssoda static void mdbsetsstep __P((void));
153*564df9b6Ssoda static int mdbclrsstep __P((int));
154*564df9b6Ssoda static void print_regs __P((void));
155*564df9b6Ssoda static void break_insert __P((void));
156*564df9b6Ssoda static void break_restore __P((void));
157*564df9b6Ssoda static int break_find __P((int));
158*564df9b6Ssoda 
159*564df9b6Ssoda void set_break __P((int va));
160*564df9b6Ssoda void del_break __P((int va));
161*564df9b6Ssoda int mdb __P((int causeReg, int vadr, int p, int kernelmode));
162*564df9b6Ssoda 
163346d7152Ssoda 
164346d7152Ssoda struct pcb mdbpcb;
165346d7152Ssoda int mdbmkfault;
166346d7152Ssoda 
167346d7152Ssoda #define MAXBRK 10
168346d7152Ssoda struct brk {
169346d7152Ssoda 	int	inst;
170346d7152Ssoda 	int	addr;
171346d7152Ssoda } brk_tab[MAXBRK];
172346d7152Ssoda 
173346d7152Ssoda /*
174346d7152Ssoda  * Mini debugger for kernel.
175346d7152Ssoda  */
176*564df9b6Ssoda static int
177*564df9b6Ssoda gethex(u_int *val, u_int dotval)
178346d7152Ssoda {
179346d7152Ssoda 	u_int c;
180346d7152Ssoda 
181346d7152Ssoda 	*val = 0;
182*564df9b6Ssoda 	while((c = cngetc()) != '\e' && c != '\n' && c != '\r') {
183346d7152Ssoda 		if(c >= '0' && c <= '9') {
184346d7152Ssoda 			*val = (*val << 4) + c - '0';
185346d7152Ssoda 			cnputc(c);
186346d7152Ssoda 		}
187346d7152Ssoda 		else if(c >= 'a' && c <= 'f') {
188346d7152Ssoda 			*val = (*val << 4) + c - 'a' + 10;
189346d7152Ssoda 			cnputc(c);
190346d7152Ssoda 		}
191346d7152Ssoda 		else if(c == '\b') {
192346d7152Ssoda 			*val = *val >> 4;
193346d7152Ssoda 			printf("\b \b");
194346d7152Ssoda 		}
195346d7152Ssoda 		else if(c == ',') {
196346d7152Ssoda 			cnputc(c);
197346d7152Ssoda 			return(c);
198346d7152Ssoda 		}
199346d7152Ssoda 		else if(c == '.') {
200346d7152Ssoda 			*val = dotval;;
201346d7152Ssoda 			cnputc(c);
202346d7152Ssoda 		}
203346d7152Ssoda 	}
204*564df9b6Ssoda 	if(c == '\r')
205*564df9b6Ssoda 		c = '\n';
206346d7152Ssoda 	return(c);
207346d7152Ssoda }
208346d7152Ssoda 
209*564df9b6Ssoda static
210346d7152Ssoda void dump(u_int *addr, u_int size)
211346d7152Ssoda {
212346d7152Ssoda 	int	cnt;
213346d7152Ssoda 
214346d7152Ssoda 	cnt = 0;
215346d7152Ssoda 
216346d7152Ssoda 	size = (size + 3) / 4;
217346d7152Ssoda 	while(size--) {
218346d7152Ssoda 		if((cnt++ & 3) == 0)
219346d7152Ssoda 			printf("\n%08x: ",(int)addr);
220346d7152Ssoda 		printf("%08x ",*addr++);
221346d7152Ssoda 	}
222346d7152Ssoda }
223346d7152Ssoda 
224*564df9b6Ssoda static void
225*564df9b6Ssoda print_regs()
226346d7152Ssoda {
227346d7152Ssoda 	printf("\n");
228346d7152Ssoda 	printf("T0-7 %08x %08x %08x %08x %08x %08x %08x %08x\n",
229346d7152Ssoda 		mdbpcb.pcb_regs[T0],mdbpcb.pcb_regs[T1],
230346d7152Ssoda 		mdbpcb.pcb_regs[T2],mdbpcb.pcb_regs[T3],
231346d7152Ssoda 		mdbpcb.pcb_regs[T4],mdbpcb.pcb_regs[T5],
232346d7152Ssoda 		mdbpcb.pcb_regs[T6],mdbpcb.pcb_regs[T7]);
233346d7152Ssoda 	printf("T8-9 %08x %08x     A0-4 %08x %08x %08x %08x\n",
234346d7152Ssoda 		mdbpcb.pcb_regs[T8],mdbpcb.pcb_regs[T9],
235346d7152Ssoda 		mdbpcb.pcb_regs[A0],mdbpcb.pcb_regs[A1],
236346d7152Ssoda 		mdbpcb.pcb_regs[A2],mdbpcb.pcb_regs[A3]);
237346d7152Ssoda 	printf("S0-7 %08x %08x %08x %08x %08x %08x %08x %08x\n",
238346d7152Ssoda 		mdbpcb.pcb_regs[S0],mdbpcb.pcb_regs[S1],
239346d7152Ssoda 		mdbpcb.pcb_regs[S2],mdbpcb.pcb_regs[S3],
240346d7152Ssoda 		mdbpcb.pcb_regs[S4],mdbpcb.pcb_regs[S5],
241346d7152Ssoda 		mdbpcb.pcb_regs[S6],mdbpcb.pcb_regs[S7]);
242346d7152Ssoda 	printf("  S8 %08x     V0-1 %08x %08x       GP %08x       SP %08x\n",
243346d7152Ssoda 		mdbpcb.pcb_regs[S8],mdbpcb.pcb_regs[V0],
244346d7152Ssoda 		mdbpcb.pcb_regs[V1],mdbpcb.pcb_regs[GP],
245346d7152Ssoda 		mdbpcb.pcb_regs[SP]);
246346d7152Ssoda 	printf("  AT %08x       PC %08x       RA %08x       SR %08x",
247346d7152Ssoda 		mdbpcb.pcb_regs[AST],mdbpcb.pcb_regs[PC],
248346d7152Ssoda 		mdbpcb.pcb_regs[RA],mdbpcb.pcb_regs[SR]);
249346d7152Ssoda }
250346d7152Ssoda 
251*564df9b6Ssoda void
252*564df9b6Ssoda set_break(int va)
253346d7152Ssoda {
254346d7152Ssoda 	int i;
255346d7152Ssoda 
256346d7152Ssoda 	va = va & ~3;
257346d7152Ssoda 	for(i = 0; i < MAXBRK; i++) {
258346d7152Ssoda 		if(brk_tab[i].addr == 0) {
259346d7152Ssoda 			brk_tab[i].addr = va;
260346d7152Ssoda 			brk_tab[i].inst = *(u_int *)va;
261346d7152Ssoda 			return;
262346d7152Ssoda 		}
263346d7152Ssoda 	}
264346d7152Ssoda 	printf(" Break table full!!");
265346d7152Ssoda }
266346d7152Ssoda 
267*564df9b6Ssoda void
268*564df9b6Ssoda del_break(int va)
269346d7152Ssoda {
270346d7152Ssoda 	int i;
271346d7152Ssoda 
272346d7152Ssoda 	va = va & ~3;
273346d7152Ssoda 	for(i = 0; i < MAXBRK; i++) {
274346d7152Ssoda 		if(brk_tab[i].addr == va) {
275346d7152Ssoda 			brk_tab[i].addr = 0;
276346d7152Ssoda 			return;
277346d7152Ssoda 		}
278346d7152Ssoda 	}
279346d7152Ssoda 	printf(" Break to remove not found!!");
280346d7152Ssoda }
281346d7152Ssoda 
282*564df9b6Ssoda static void
283346d7152Ssoda break_insert()
284346d7152Ssoda {
285346d7152Ssoda 	int i;
286346d7152Ssoda 
287346d7152Ssoda 	for(i = 0; i < MAXBRK; i++) {
288346d7152Ssoda 		if(brk_tab[i].addr != 0) {
289346d7152Ssoda 			brk_tab[i].inst = *(u_int *)brk_tab[i].addr;
290346d7152Ssoda 			*(u_int *)brk_tab[i].addr = MIPS_BREAK_BRKPT;
291*564df9b6Ssoda 			mips3_FlushDCache(brk_tab[i].addr,4);
292*564df9b6Ssoda 			mips3_FlushICache(brk_tab[i].addr,4);
293346d7152Ssoda 		}
294346d7152Ssoda 	}
295346d7152Ssoda }
296346d7152Ssoda 
297*564df9b6Ssoda static void
298346d7152Ssoda break_restore()
299346d7152Ssoda {
300346d7152Ssoda 	int i;
301346d7152Ssoda 
302346d7152Ssoda 	for(i = 0; i < MAXBRK; i++) {
303346d7152Ssoda 		if(brk_tab[i].addr != 0) {
304346d7152Ssoda 			*(u_int *)brk_tab[i].addr = brk_tab[i].inst;
305*564df9b6Ssoda 			mips3_FlushDCache(brk_tab[i].addr,4);
306*564df9b6Ssoda 			mips3_FlushICache(brk_tab[i].addr,4);
307346d7152Ssoda 		}
308346d7152Ssoda 	}
309346d7152Ssoda }
310346d7152Ssoda 
311*564df9b6Ssoda static int
312346d7152Ssoda break_find(va)
313*564df9b6Ssoda 	int va;
314346d7152Ssoda {
315346d7152Ssoda 	int i;
316346d7152Ssoda 
317346d7152Ssoda 	for(i = 0; i < MAXBRK; i++) {
318346d7152Ssoda 		if(brk_tab[i].addr == va) {
319346d7152Ssoda 			return(i);
320346d7152Ssoda 		}
321346d7152Ssoda 	}
322346d7152Ssoda 	return(-1);
323346d7152Ssoda }
324346d7152Ssoda 
325*564df9b6Ssoda void
326346d7152Ssoda prt_break()
327346d7152Ssoda {
328346d7152Ssoda 	int i;
329346d7152Ssoda 
330346d7152Ssoda 	for(i = 0; i < MAXBRK; i++) {
331346d7152Ssoda 		if(brk_tab[i].addr != 0) {
332346d7152Ssoda 			printf("\n    %08x\t", brk_tab[i].addr);
333346d7152Ssoda 			mdbprintins(brk_tab[i].inst, brk_tab[i].addr);
334346d7152Ssoda 		}
335346d7152Ssoda 	}
336346d7152Ssoda }
337*564df9b6Ssoda 
338*564df9b6Ssoda int
339*564df9b6Ssoda mdb(int causeReg, int vadr, int p, int kernelmode)
340346d7152Ssoda {
341346d7152Ssoda 	int c;
342346d7152Ssoda 	int newaddr;
343346d7152Ssoda 	int size;
344346d7152Ssoda 	int cause;
345346d7152Ssoda static int ssandrun;	/* Single step and run flag (when cont at brk) */
346346d7152Ssoda 
347346d7152Ssoda 	splhigh();
348*564df9b6Ssoda 	cause = (causeReg & MIPS3_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT;
349346d7152Ssoda 	newaddr = (int)(mdbpcb.pcb_regs[PC]);
350346d7152Ssoda 	switch(cause) {
351346d7152Ssoda 	case T_BREAK:
352346d7152Ssoda 		if(*(int *)newaddr == MIPS_BREAK_SOVER) {
353346d7152Ssoda 			break_restore();
354346d7152Ssoda 			mdbpcb.pcb_regs[PC] += 4;
355346d7152Ssoda 			printf("\nStop break (panic)\n# ");
356346d7152Ssoda 			printf("    %08x\t",newaddr);
357346d7152Ssoda 			mdbprintins(*(int *)newaddr, newaddr);
358346d7152Ssoda 			printf("\n# ");
359346d7152Ssoda 			break;
360346d7152Ssoda 		}
361346d7152Ssoda 		if(*(int *)newaddr == MIPS_BREAK_BRKPT) {
362346d7152Ssoda 			break_restore();
363346d7152Ssoda 			printf("\rBRK %08x\t",newaddr);
364346d7152Ssoda 			if(mdbprintins(*(int *)newaddr, newaddr)) {
365346d7152Ssoda 				newaddr += 4;
366346d7152Ssoda 				printf("\n    %08x\t",newaddr);
367346d7152Ssoda 				mdbprintins(*(int *)newaddr, newaddr);
368346d7152Ssoda 			}
369346d7152Ssoda 			printf("\n# ");
370346d7152Ssoda 			break;
371346d7152Ssoda 		}
372346d7152Ssoda 		if(mdbclrsstep(causeReg)) {
373346d7152Ssoda 			if(ssandrun) { /* Step over bp before free run */
374346d7152Ssoda 				ssandrun = 0;
375346d7152Ssoda 				break_insert();
376346d7152Ssoda 				return(TRUE);
377346d7152Ssoda 			}
378346d7152Ssoda 			printf("\r    %08x\t",newaddr);
379346d7152Ssoda 			if(mdbprintins(*(int *)newaddr, newaddr)) {
380346d7152Ssoda 				newaddr += 4;
381346d7152Ssoda 				printf("\n    %08x\t",newaddr);
382346d7152Ssoda 				mdbprintins(*(int *)newaddr, newaddr);
383346d7152Ssoda 			}
384346d7152Ssoda 			printf("\n# ");
385346d7152Ssoda 		}
386346d7152Ssoda 		break;
387346d7152Ssoda 
388346d7152Ssoda 	default:
389346d7152Ssoda 		printf("\n-- %s --\n# ",trap_type[cause]);
390346d7152Ssoda 	}
391346d7152Ssoda 	ssandrun = 0;
392346d7152Ssoda 	break_restore();
393346d7152Ssoda 
394*564df9b6Ssoda 	while(1) {
395*564df9b6Ssoda 		c = cngetc();
396346d7152Ssoda 		switch(c) {
397346d7152Ssoda 		case 'T':
398346d7152Ssoda 			trapDump("Debugger");
399346d7152Ssoda 			break;
400346d7152Ssoda 		case 'b':
401346d7152Ssoda 			printf("break-");
402346d7152Ssoda 			c = cngetc();
403346d7152Ssoda 			switch(c) {
404346d7152Ssoda 			case 's':
405346d7152Ssoda 				printf("set at ");
406346d7152Ssoda 				c = gethex(&newaddr, newaddr);
407346d7152Ssoda 				if(c != '\e') {
408346d7152Ssoda 					set_break(newaddr);
409346d7152Ssoda 				}
410346d7152Ssoda 				break;
411346d7152Ssoda 
412346d7152Ssoda 			case 'd':
413346d7152Ssoda 				printf("delete at ");
414346d7152Ssoda 				c = gethex(&newaddr, newaddr);
415346d7152Ssoda 				if(c != '\e') {
416346d7152Ssoda 					del_break(newaddr);
417346d7152Ssoda 				}
418346d7152Ssoda 				break;
419346d7152Ssoda 
420346d7152Ssoda 			case 'p':
421346d7152Ssoda 				printf("print");
422346d7152Ssoda 				prt_break();
423346d7152Ssoda 				break;
424346d7152Ssoda 			}
425346d7152Ssoda 			break;
426346d7152Ssoda 
427346d7152Ssoda 		case 'r':
428346d7152Ssoda 			print_regs();
429346d7152Ssoda 			break;
430346d7152Ssoda 
431346d7152Ssoda 		case 'I':
432346d7152Ssoda 			printf("Instruction at ");
433346d7152Ssoda 			c = gethex(&newaddr, newaddr);
434346d7152Ssoda 			while(c != '\e') {
435346d7152Ssoda 				printf("\n    %08x\t",newaddr);
436346d7152Ssoda 				mdbprintins(*(int *)newaddr, newaddr);
437346d7152Ssoda 				newaddr += 4;
438346d7152Ssoda 				c = cngetc();
439346d7152Ssoda 			}
440346d7152Ssoda 			break;
441346d7152Ssoda 
442346d7152Ssoda 		case 'c':
443346d7152Ssoda 			printf("continue");
444346d7152Ssoda 			if(break_find((int)(mdbpcb.pcb_regs[PC])) >= 0) {
445346d7152Ssoda 				ssandrun = 1;
446346d7152Ssoda 				mdbsetsstep();
447346d7152Ssoda 			}
448346d7152Ssoda 			else {
449346d7152Ssoda 				break_insert();
450346d7152Ssoda 			}
451346d7152Ssoda 			return(TRUE);
452*564df9b6Ssoda 		case 'S':
453*564df9b6Ssoda 			printf("Stack traceback:\n");
454*564df9b6Ssoda 			stacktrace();
455*564df9b6Ssoda 			return(TRUE);
456346d7152Ssoda 		case 's':
457346d7152Ssoda 			set_break(mdbpcb.pcb_regs[PC] + 8);
458346d7152Ssoda 			return(TRUE);
459346d7152Ssoda 		case ' ':
460346d7152Ssoda 			mdbsetsstep();
461346d7152Ssoda 			return(TRUE);
462346d7152Ssoda 
463346d7152Ssoda 		case 'd':
464346d7152Ssoda 			printf("dump ");
465346d7152Ssoda 			c = gethex(&newaddr, newaddr);
466346d7152Ssoda 			if(c == ',') {
467346d7152Ssoda 				c = gethex(&size,256);
468346d7152Ssoda 			}
469346d7152Ssoda 			else {
470346d7152Ssoda 				size = 16;
471346d7152Ssoda 			}
472346d7152Ssoda 			if(c == '\n' && newaddr != 0) {
473346d7152Ssoda 				dump((u_int *)newaddr, size);
474346d7152Ssoda 				newaddr += size;
475346d7152Ssoda 			}
476346d7152Ssoda 			break;
477346d7152Ssoda 
478346d7152Ssoda 		case 'm':
479346d7152Ssoda 			printf("mod ");
480346d7152Ssoda 			c = gethex(&newaddr, newaddr);
481346d7152Ssoda 			while(c == ',') {
482346d7152Ssoda 				c = gethex(&size, 0);
483346d7152Ssoda 				if(c != '\e')
484346d7152Ssoda 					*((u_int *)newaddr)++ = size;
485346d7152Ssoda 			}
486346d7152Ssoda 			break;
487346d7152Ssoda 
488346d7152Ssoda 		case 'i':
489346d7152Ssoda 			printf("in-");
490346d7152Ssoda 			c = cngetc();
491346d7152Ssoda 			switch(c) {
492346d7152Ssoda 			case 'b':
493346d7152Ssoda 				printf("byte ");
494346d7152Ssoda 				c = gethex(&newaddr, newaddr);
495346d7152Ssoda 				if(c == '\n') {
496346d7152Ssoda 					printf("= %02x",
497346d7152Ssoda 						*(u_char *)newaddr);
498346d7152Ssoda 				}
499346d7152Ssoda 				break;
500346d7152Ssoda 			case 'h':
501346d7152Ssoda 				printf("halfword ");
502346d7152Ssoda 				c = gethex(&newaddr, newaddr);
503346d7152Ssoda 				if(c == '\n') {
504346d7152Ssoda 					printf("= %04x",
505346d7152Ssoda 						*(u_short *)newaddr);
506346d7152Ssoda 				}
507346d7152Ssoda 				break;
508346d7152Ssoda 			case 'w':
509346d7152Ssoda 				printf("word ");
510346d7152Ssoda 				c = gethex(&newaddr, newaddr);
511346d7152Ssoda 				if(c == '\n') {
512346d7152Ssoda 					printf("= %08x",
513346d7152Ssoda 						*(u_int *)newaddr);
514346d7152Ssoda 				}
515346d7152Ssoda 				break;
516346d7152Ssoda 			}
517346d7152Ssoda 			break;
518346d7152Ssoda 
519346d7152Ssoda 		case 'o':
520346d7152Ssoda 			printf("out-");
521346d7152Ssoda 			c = cngetc();
522346d7152Ssoda 			switch(c) {
523346d7152Ssoda 			case 'b':
524346d7152Ssoda 				printf("byte ");
525346d7152Ssoda 				c = gethex(&newaddr, newaddr);
526346d7152Ssoda 				if(c == ',') {
527346d7152Ssoda 					c = gethex(&size, 0);
528346d7152Ssoda 					if(c == '\n') {
529346d7152Ssoda 						*(u_char *)newaddr = size;
530346d7152Ssoda 					}
531346d7152Ssoda 				}
532346d7152Ssoda 				break;
533346d7152Ssoda 			case 'h':
534346d7152Ssoda 				printf("halfword ");
535346d7152Ssoda 				c = gethex(&newaddr, newaddr);
536346d7152Ssoda 				if(c == ',') {
537346d7152Ssoda 					c = gethex(&size, 0);
538346d7152Ssoda 					if(c == '\n') {
539346d7152Ssoda 						*(u_short *)newaddr = size;
540346d7152Ssoda 					}
541346d7152Ssoda 				}
542346d7152Ssoda 				break;
543346d7152Ssoda 			case 'w':
544346d7152Ssoda 				printf("word ");
545346d7152Ssoda 				c = gethex(&newaddr, newaddr);
546346d7152Ssoda 				if(c == ',') {
547346d7152Ssoda 					c = gethex(&size, 0);
548346d7152Ssoda 					if(c == '\n') {
549346d7152Ssoda 						*(u_int *)newaddr = size;
550346d7152Ssoda 					}
551346d7152Ssoda 				}
552346d7152Ssoda 				break;
553346d7152Ssoda 			}
554346d7152Ssoda 			break;
555346d7152Ssoda 
556346d7152Ssoda 		case 't':
557346d7152Ssoda 			printf("tlb-dump\n");
558*564df9b6Ssoda 			arc_dump_tlb(0,23);
559346d7152Ssoda 			(void)cngetc();
560*564df9b6Ssoda 			arc_dump_tlb(24,47);
561346d7152Ssoda 			break;
562346d7152Ssoda 
563346d7152Ssoda 		case 'f':
564346d7152Ssoda 			printf("flush-");
565346d7152Ssoda 			c = cngetc();
566346d7152Ssoda 			switch(c) {
567346d7152Ssoda 			case 't':
568346d7152Ssoda 				printf("tlb");
569*564df9b6Ssoda 				mips3_TLBFlush(num_tlbentries);
570346d7152Ssoda 				break;
571346d7152Ssoda 
572346d7152Ssoda 			case 'c':
573346d7152Ssoda 				printf("cache");
574*564df9b6Ssoda 				mips3_FlushCache();
575346d7152Ssoda 				break;
576346d7152Ssoda 			}
577346d7152Ssoda 			break;
578346d7152Ssoda 
579346d7152Ssoda 		default:
580346d7152Ssoda 			cnputc('\a');
581346d7152Ssoda 			break;
582346d7152Ssoda 		}
583346d7152Ssoda 		printf("\n# ");
584346d7152Ssoda 	}
585346d7152Ssoda }
586346d7152Ssoda 
587346d7152Ssoda u_int mdb_ss_addr;
588346d7152Ssoda u_int mdb_ss_instr;
589346d7152Ssoda 
590*564df9b6Ssoda static void
591346d7152Ssoda mdbsetsstep()
592346d7152Ssoda {
593346d7152Ssoda 	register u_int va;
594346d7152Ssoda 	register int *locr0 = mdbpcb.pcb_regs;
595346d7152Ssoda 
596346d7152Ssoda 	/* compute next address after current location */
597346d7152Ssoda 	if(mdbpeek(locr0[PC]) != 0) {
598346d7152Ssoda 		va = MachEmulateBranch(locr0, locr0[PC], 0, mdbpeek(locr0[PC]));
599346d7152Ssoda 	}
600346d7152Ssoda 	else {
601346d7152Ssoda 		va = locr0[PC] + 4;
602346d7152Ssoda 	}
603346d7152Ssoda 	if (mdb_ss_addr) {
604346d7152Ssoda 		printf("mdbsetsstep: breakpoint already set at %x (va %x)\n",
605346d7152Ssoda 			mdb_ss_addr, va);
606346d7152Ssoda 		return;
607346d7152Ssoda 	}
608346d7152Ssoda 	mdb_ss_addr = va;
609346d7152Ssoda 
610346d7152Ssoda 	if ((int)va < 0) {
611346d7152Ssoda 		/* kernel address */
612346d7152Ssoda 		mdb_ss_instr = mdbpeek(va);
613*564df9b6Ssoda 		mdbpoke(va, MIPS_BREAK_SSTEP);
614*564df9b6Ssoda 		mips3_FlushDCache(va,4);
615*564df9b6Ssoda 		mips3_FlushICache(va,4);
616346d7152Ssoda 		return;
617346d7152Ssoda 	}
618346d7152Ssoda }
619346d7152Ssoda 
620*564df9b6Ssoda static int
621*564df9b6Ssoda mdbclrsstep(int cr)
622346d7152Ssoda {
623346d7152Ssoda 	register u_int pc, va;
624346d7152Ssoda 	u_int instr;
625346d7152Ssoda 
626346d7152Ssoda 	/* fix pc if break instruction is in the delay slot */
627346d7152Ssoda 	pc = mdbpcb.pcb_regs[PC];
628346d7152Ssoda 	if (cr < 0)
629346d7152Ssoda 		pc += 4;
630346d7152Ssoda 
631346d7152Ssoda 	/* check to be sure its the one we are expecting */
632346d7152Ssoda 	va = mdb_ss_addr;
633346d7152Ssoda 	if (!va || va != pc)
634346d7152Ssoda 		return(FALSE);
635346d7152Ssoda 
636346d7152Ssoda 	/* read break instruction */
637346d7152Ssoda 	instr = mdbpeek(va);
638346d7152Ssoda 	if (instr != MIPS_BREAK_SSTEP)
639346d7152Ssoda 		return(FALSE);
640346d7152Ssoda 
641346d7152Ssoda 	if ((int)va < 0) {
642346d7152Ssoda 		/* kernel address */
643*564df9b6Ssoda 		mdbpoke(va, mdb_ss_instr);
644*564df9b6Ssoda 		mips3_FlushDCache(va,4);
645*564df9b6Ssoda 		mips3_FlushICache(va,4);
646346d7152Ssoda 		mdb_ss_addr = 0;
647346d7152Ssoda 		return(TRUE);
648346d7152Ssoda 	}
649346d7152Ssoda 
650346d7152Ssoda 	printf("can't clear break at %x\n", va);
651346d7152Ssoda 	mdb_ss_addr = 0;
652346d7152Ssoda 	return(FALSE);
653346d7152Ssoda }
654346d7152Ssoda 
655346d7152Ssoda 
656346d7152Ssoda /* ARGSUSED */
657*564df9b6Ssoda static int
658*564df9b6Ssoda mdbprintins(int ins, int mdbdot)
659346d7152Ssoda {
660346d7152Ssoda 	InstFmt i;
661346d7152Ssoda 	int delay = 0;
662346d7152Ssoda 
663346d7152Ssoda 	i.word = ins;
664346d7152Ssoda 
665346d7152Ssoda 	switch (i.JType.op) {
666346d7152Ssoda 	case OP_SPECIAL:
667346d7152Ssoda 		if (i.word == 0) {
668346d7152Ssoda 			printf("nop");
669346d7152Ssoda 			break;
670346d7152Ssoda 		}
671346d7152Ssoda 		if (i.RType.func == OP_ADDU && i.RType.rt == 0) {
672346d7152Ssoda 			printf("move\t%s,%s",
673346d7152Ssoda 				reg_name[i.RType.rd],
674346d7152Ssoda 				reg_name[i.RType.rs]);
675346d7152Ssoda 			break;
676346d7152Ssoda 		}
677346d7152Ssoda 		printf("%s", spec_name[i.RType.func]);
678346d7152Ssoda 		switch (i.RType.func) {
679346d7152Ssoda 		case OP_SLL:
680346d7152Ssoda 		case OP_SRL:
681346d7152Ssoda 		case OP_SRA:
682346d7152Ssoda 		case OP_DSLL:
683346d7152Ssoda 		case OP_DSRL:
684346d7152Ssoda 		case OP_DSRA:
685346d7152Ssoda 		case OP_DSLL32:
686346d7152Ssoda 		case OP_DSRL32:
687346d7152Ssoda 		case OP_DSRA32:
688346d7152Ssoda 			printf("\t%s,%s,%d",
689346d7152Ssoda 				reg_name[i.RType.rd],
690346d7152Ssoda 				reg_name[i.RType.rt],
691346d7152Ssoda 				i.RType.shamt);
692346d7152Ssoda 			break;
693346d7152Ssoda 
694346d7152Ssoda 		case OP_SLLV:
695346d7152Ssoda 		case OP_SRLV:
696346d7152Ssoda 		case OP_SRAV:
697346d7152Ssoda 		case OP_DSLLV:
698346d7152Ssoda 		case OP_DSRLV:
699346d7152Ssoda 		case OP_DSRAV:
700346d7152Ssoda 			printf("\t%s,%s,%s",
701346d7152Ssoda 				reg_name[i.RType.rd],
702346d7152Ssoda 				reg_name[i.RType.rt],
703346d7152Ssoda 				reg_name[i.RType.rs]);
704346d7152Ssoda 			break;
705346d7152Ssoda 
706346d7152Ssoda 		case OP_MFHI:
707346d7152Ssoda 		case OP_MFLO:
708346d7152Ssoda 			printf("\t%s", reg_name[i.RType.rd]);
709346d7152Ssoda 			break;
710346d7152Ssoda 
711346d7152Ssoda 		case OP_JR:
712346d7152Ssoda 		case OP_JALR:
713346d7152Ssoda 			delay = 1;
714346d7152Ssoda 			/* FALLTHROUGH */
715346d7152Ssoda 		case OP_MTLO:
716346d7152Ssoda 		case OP_MTHI:
717346d7152Ssoda 			printf("\t%s", reg_name[i.RType.rs]);
718346d7152Ssoda 			break;
719346d7152Ssoda 
720346d7152Ssoda 		case OP_MULT:
721346d7152Ssoda 		case OP_MULTU:
722346d7152Ssoda 		case OP_DMULT:
723346d7152Ssoda 		case OP_DMULTU:
724346d7152Ssoda 		case OP_DIV:
725346d7152Ssoda 		case OP_DIVU:
726346d7152Ssoda 		case OP_DDIV:
727346d7152Ssoda 		case OP_DDIVU:
728346d7152Ssoda 			printf("\t%s,%s",
729346d7152Ssoda 				reg_name[i.RType.rs],
730346d7152Ssoda 				reg_name[i.RType.rt]);
731346d7152Ssoda 			break;
732346d7152Ssoda 
733346d7152Ssoda 		case OP_SYSCALL:
734346d7152Ssoda 		case OP_SYNC:
735346d7152Ssoda 			break;
736346d7152Ssoda 
737346d7152Ssoda 		case OP_BREAK:
738346d7152Ssoda 			printf("\t%d", (i.RType.rs << 5) | i.RType.rt);
739346d7152Ssoda 			break;
740346d7152Ssoda 
741346d7152Ssoda 		default:
742346d7152Ssoda 			printf("\t%s,%s,%s",
743346d7152Ssoda 				reg_name[i.RType.rd],
744346d7152Ssoda 				reg_name[i.RType.rs],
745346d7152Ssoda 				reg_name[i.RType.rt]);
746346d7152Ssoda 		};
747346d7152Ssoda 		break;
748346d7152Ssoda 
749346d7152Ssoda 	case OP_BCOND:
750346d7152Ssoda 		printf("%s\t%s,", bcond_name[i.IType.rt],
751346d7152Ssoda 			reg_name[i.IType.rs]);
752346d7152Ssoda 		goto pr_displ;
753346d7152Ssoda 
754346d7152Ssoda 	case OP_BLEZ:
755346d7152Ssoda 	case OP_BLEZL:
756346d7152Ssoda 	case OP_BGTZ:
757346d7152Ssoda 	case OP_BGTZL:
758346d7152Ssoda 		printf("%s\t%s,", op_name[i.IType.op],
759346d7152Ssoda 			reg_name[i.IType.rs]);
760346d7152Ssoda 		goto pr_displ;
761346d7152Ssoda 
762346d7152Ssoda 	case OP_BEQ:
763346d7152Ssoda 	case OP_BEQL:
764346d7152Ssoda 		if (i.IType.rs == 0 && i.IType.rt == 0) {
765346d7152Ssoda 			printf("b\t");
766346d7152Ssoda 			goto pr_displ;
767346d7152Ssoda 		}
768346d7152Ssoda 		/* FALLTHROUGH */
769346d7152Ssoda 	case OP_BNE:
770346d7152Ssoda 	case OP_BNEL:
771346d7152Ssoda 		printf("%s\t%s,%s,", op_name[i.IType.op],
772346d7152Ssoda 			reg_name[i.IType.rs],
773346d7152Ssoda 			reg_name[i.IType.rt]);
774346d7152Ssoda 	pr_displ:
775346d7152Ssoda 		delay = 1;
776346d7152Ssoda 		printf("0x%08x", mdbdot + 4 + ((short)i.IType.imm << 2));
777346d7152Ssoda 		break;
778346d7152Ssoda 
779346d7152Ssoda 	case OP_COP0:
780346d7152Ssoda 		switch (i.RType.rs) {
781346d7152Ssoda 		case OP_BCx:
782346d7152Ssoda 		case OP_BCy:
783346d7152Ssoda 			printf("bc0%c\t",
784346d7152Ssoda 				"ft"[i.RType.rt & COPz_BC_TF_MASK]);
785346d7152Ssoda 			goto pr_displ;
786346d7152Ssoda 
787346d7152Ssoda 		case OP_MT:
788346d7152Ssoda 			printf("mtc0\t%s,%s",
789346d7152Ssoda 				reg_name[i.RType.rt],
790346d7152Ssoda 				c0_reg[i.RType.rd]);
791346d7152Ssoda 			break;
792346d7152Ssoda 
793346d7152Ssoda 		case OP_DMT:
794346d7152Ssoda 			printf("dmtc0\t%s,%s",
795346d7152Ssoda 				reg_name[i.RType.rt],
796346d7152Ssoda 				c0_reg[i.RType.rd]);
797346d7152Ssoda 			break;
798346d7152Ssoda 
799346d7152Ssoda 		case OP_MF:
800346d7152Ssoda 			printf("mfc0\t%s,%s",
801346d7152Ssoda 				reg_name[i.RType.rt],
802346d7152Ssoda 				c0_reg[i.RType.rd]);
803346d7152Ssoda 			break;
804346d7152Ssoda 
805346d7152Ssoda 		case OP_DMF:
806346d7152Ssoda 			printf("dmfc0\t%s,%s",
807346d7152Ssoda 				reg_name[i.RType.rt],
808346d7152Ssoda 				c0_reg[i.RType.rd]);
809346d7152Ssoda 			break;
810346d7152Ssoda 
811346d7152Ssoda 		default:
812346d7152Ssoda 			printf("%s", c0_opname[i.FRType.func]);
813346d7152Ssoda 		};
814346d7152Ssoda 		break;
815346d7152Ssoda 
816346d7152Ssoda 	case OP_COP1:
817346d7152Ssoda 		switch (i.RType.rs) {
818346d7152Ssoda 		case OP_BCx:
819346d7152Ssoda 		case OP_BCy:
820346d7152Ssoda 			printf("bc1%c\t",
821346d7152Ssoda 				"ft"[i.RType.rt & COPz_BC_TF_MASK]);
822346d7152Ssoda 			goto pr_displ;
823346d7152Ssoda 
824346d7152Ssoda 		case OP_MT:
825346d7152Ssoda 			printf("mtc1\t%s,f%d",
826346d7152Ssoda 				reg_name[i.RType.rt],
827346d7152Ssoda 				i.RType.rd);
828346d7152Ssoda 			break;
829346d7152Ssoda 
830346d7152Ssoda 		case OP_MF:
831346d7152Ssoda 			printf("mfc1\t%s,f%d",
832346d7152Ssoda 				reg_name[i.RType.rt],
833346d7152Ssoda 				i.RType.rd);
834346d7152Ssoda 			break;
835346d7152Ssoda 
836346d7152Ssoda 		case OP_CT:
837346d7152Ssoda 			printf("ctc1\t%s,f%d",
838346d7152Ssoda 				reg_name[i.RType.rt],
839346d7152Ssoda 				i.RType.rd);
840346d7152Ssoda 			break;
841346d7152Ssoda 
842346d7152Ssoda 		case OP_CF:
843346d7152Ssoda 			printf("cfc1\t%s,f%d",
844346d7152Ssoda 				reg_name[i.RType.rt],
845346d7152Ssoda 				i.RType.rd);
846346d7152Ssoda 			break;
847346d7152Ssoda 
848346d7152Ssoda 		default:
849346d7152Ssoda 			printf("%s.%s\tf%d,f%d,f%d",
850346d7152Ssoda 				cop1_name[i.FRType.func],
851346d7152Ssoda 				fmt_name[i.FRType.fmt],
852346d7152Ssoda 				i.FRType.fd, i.FRType.fs, i.FRType.ft);
853346d7152Ssoda 		};
854346d7152Ssoda 		break;
855346d7152Ssoda 
856346d7152Ssoda 	case OP_J:
857346d7152Ssoda 	case OP_JAL:
858346d7152Ssoda 		printf("%s\t", op_name[i.JType.op]);
859346d7152Ssoda 		printf("0x%8x",(mdbdot & 0xF0000000) | (i.JType.target << 2));
860346d7152Ssoda 		delay = 1;
861346d7152Ssoda 		break;
862346d7152Ssoda 
863346d7152Ssoda 	case OP_LWC1:
864346d7152Ssoda 	case OP_SWC1:
865346d7152Ssoda 		printf("%s\tf%d,", op_name[i.IType.op],
866346d7152Ssoda 			i.IType.rt);
867346d7152Ssoda 		goto loadstore;
868346d7152Ssoda 
869346d7152Ssoda 	case OP_LB:
870346d7152Ssoda 	case OP_LH:
871346d7152Ssoda 	case OP_LW:
872346d7152Ssoda 	case OP_LD:
873346d7152Ssoda 	case OP_LBU:
874346d7152Ssoda 	case OP_LHU:
875346d7152Ssoda 	case OP_LWU:
876346d7152Ssoda 	case OP_SB:
877346d7152Ssoda 	case OP_SH:
878346d7152Ssoda 	case OP_SW:
879346d7152Ssoda 	case OP_SD:
880346d7152Ssoda 		printf("%s\t%s,", op_name[i.IType.op],
881346d7152Ssoda 			reg_name[i.IType.rt]);
882346d7152Ssoda 	loadstore:
883346d7152Ssoda 		printf("%d(%s)", (short)i.IType.imm,
884346d7152Ssoda 			reg_name[i.IType.rs]);
885346d7152Ssoda 		break;
886346d7152Ssoda 
887346d7152Ssoda 	case OP_ORI:
888346d7152Ssoda 	case OP_XORI:
889346d7152Ssoda 		if (i.IType.rs == 0) {
890346d7152Ssoda 			printf("li\t%s,0x%x",
891346d7152Ssoda 				reg_name[i.IType.rt],
892346d7152Ssoda 				i.IType.imm);
893346d7152Ssoda 			break;
894346d7152Ssoda 		}
895346d7152Ssoda 		/* FALLTHROUGH */
896346d7152Ssoda 	case OP_ANDI:
897346d7152Ssoda 		printf("%s\t%s,%s,0x%x", op_name[i.IType.op],
898346d7152Ssoda 			reg_name[i.IType.rt],
899346d7152Ssoda 			reg_name[i.IType.rs],
900346d7152Ssoda 			i.IType.imm);
901346d7152Ssoda 		break;
902346d7152Ssoda 
903346d7152Ssoda 	case OP_LUI:
904346d7152Ssoda 		printf("%s\t%s,0x%x", op_name[i.IType.op],
905346d7152Ssoda 			reg_name[i.IType.rt],
906346d7152Ssoda 			i.IType.imm);
907346d7152Ssoda 		break;
908346d7152Ssoda 
909346d7152Ssoda 	case OP_ADDI:
910346d7152Ssoda 	case OP_DADDI:
911346d7152Ssoda 	case OP_ADDIU:
912346d7152Ssoda 	case OP_DADDIU:
913346d7152Ssoda 		if (i.IType.rs == 0) {
914346d7152Ssoda  			printf("li\t%s,%d",
915346d7152Ssoda 				reg_name[i.IType.rt],
916346d7152Ssoda 				(short)i.IType.imm);
917346d7152Ssoda 			break;
918346d7152Ssoda 		}
919346d7152Ssoda 		/* FALLTHROUGH */
920346d7152Ssoda 	default:
921346d7152Ssoda 		printf("%s\t%s,%s,%d", op_name[i.IType.op],
922346d7152Ssoda 			reg_name[i.IType.rt],
923346d7152Ssoda 			reg_name[i.IType.rs],
924346d7152Ssoda 			(short)i.IType.imm);
925346d7152Ssoda 	}
926346d7152Ssoda 	return(delay);
927346d7152Ssoda }
928346d7152Ssoda 
929346d7152Ssoda 
930346d7152Ssoda /*
931346d7152Ssoda  *	Dump TLB contents.
932346d7152Ssoda  */
933*564df9b6Ssoda static void
934*564df9b6Ssoda arc_dump_tlb(int first,int last)
935346d7152Ssoda {
936346d7152Ssoda 	int tlbno;
937346d7152Ssoda 	struct tlb tlb;
938346d7152Ssoda 
939346d7152Ssoda 	tlbno = first;
940346d7152Ssoda 
941346d7152Ssoda 	while(tlbno <= last) {
942*564df9b6Ssoda 		mips3_TLBRead(tlbno, &tlb);
943*564df9b6Ssoda 		if(tlb.tlb_lo0 & MIPS3_PG_V || tlb.tlb_lo1 & MIPS3_PG_V) {
944346d7152Ssoda 			printf("TLB %2d vad 0x%08x ", tlbno, tlb.tlb_hi);
945346d7152Ssoda 		}
946346d7152Ssoda 		else {
947346d7152Ssoda 			printf("TLB*%2d vad 0x%08x ", tlbno, tlb.tlb_hi);
948346d7152Ssoda 		}
949346d7152Ssoda 		printf("0=0x%08x ", pfn_to_vad(tlb.tlb_lo0));
950*564df9b6Ssoda 		printf("%c", tlb.tlb_lo0 & MIPS3_PG_M ? 'M' : ' ');
951*564df9b6Ssoda 		printf("%c", tlb.tlb_lo0 & MIPS3_PG_G ? 'G' : ' ');
952346d7152Ssoda 		printf(" atr %x ", (tlb.tlb_lo0 >> 3) & 7);
953346d7152Ssoda 		printf("1=0x%08x ", pfn_to_vad(tlb.tlb_lo1));
954*564df9b6Ssoda 		printf("%c", tlb.tlb_lo1 & MIPS3_PG_M ? 'M' : ' ');
955*564df9b6Ssoda 		printf("%c", tlb.tlb_lo1 & MIPS3_PG_G ? 'G' : ' ');
956346d7152Ssoda 		printf(" atr %x ", (tlb.tlb_lo1 >> 3) & 7);
957346d7152Ssoda 		printf(" sz=%x\n", tlb.tlb_mask);
958346d7152Ssoda 
959346d7152Ssoda 		tlbno++;
960346d7152Ssoda 	}
961346d7152Ssoda }
962