xref: /netbsd/sys/arch/arc/arc/minidebug.c (revision 47ef8ee9)
1*47ef8ee9Smrg /*	$NetBSD: minidebug.c,v 1.10 2000/06/29 08:34:09 mrg 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.
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 
46564df9b6Ssoda #include <sys/param.h>
47564df9b6Ssoda #include <sys/systm.h>
48564df9b6Ssoda #include <sys/proc.h>
49564df9b6Ssoda #include <sys/user.h>
50564df9b6Ssoda #include <dev/cons.h>
51*47ef8ee9Smrg #include <uvm/uvm_extern.h>
52346d7152Ssoda #undef SP
53564df9b6Ssoda #include <machine/pte.h>
54564df9b6Ssoda #include <mips/locore.h>
55564df9b6Ssoda #include <machine/cpu.h>
56346d7152Ssoda #include <machine/reg.h>
57564df9b6Ssoda #include <machine/regnum.h>
58564df9b6Ssoda #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 
142564df9b6Ssoda extern u_int mdbpeek __P((int));
143564df9b6Ssoda extern void mdbpoke __P((int, int));
14471f6ef9eSsoda #ifdef __OpenBSD__
14571f6ef9eSsoda extern void cpu_setwatch __P((int, int));
14671f6ef9eSsoda #endif
147564df9b6Ssoda extern void trapDump __P((char *));
148564df9b6Ssoda extern void stacktrace __P((void));
149564df9b6Ssoda extern u_int MachEmulateBranch __P((int *, int, int, u_int));
150346d7152Ssoda extern char *trap_type[];
151564df9b6Ssoda extern int num_tlbentries;
152564df9b6Ssoda static void arc_dump_tlb __P((int,int));
153564df9b6Ssoda static void prt_break __P((void));
154564df9b6Ssoda static int mdbprintins __P((int, int));
155564df9b6Ssoda static void mdbsetsstep __P((void));
156564df9b6Ssoda static int mdbclrsstep __P((int));
157564df9b6Ssoda static void print_regs __P((void));
158564df9b6Ssoda static void break_insert __P((void));
159564df9b6Ssoda static void break_restore __P((void));
160564df9b6Ssoda static int break_find __P((int));
161564df9b6Ssoda 
162564df9b6Ssoda void set_break __P((int va));
163564df9b6Ssoda void del_break __P((int va));
164564df9b6Ssoda int mdb __P((int causeReg, int vadr, int p, int kernelmode));
165564df9b6Ssoda 
166346d7152Ssoda 
167346d7152Ssoda struct pcb mdbpcb;
168346d7152Ssoda int mdbmkfault;
169346d7152Ssoda 
170346d7152Ssoda #define MAXBRK 10
171346d7152Ssoda struct brk {
172346d7152Ssoda 	int	inst;
173346d7152Ssoda 	int	addr;
174346d7152Ssoda } brk_tab[MAXBRK];
175346d7152Ssoda 
176346d7152Ssoda /*
177346d7152Ssoda  * Mini debugger for kernel.
178346d7152Ssoda  */
179564df9b6Ssoda static int
180564df9b6Ssoda gethex(u_int *val, u_int dotval)
181346d7152Ssoda {
182346d7152Ssoda 	u_int c;
183346d7152Ssoda 
184346d7152Ssoda 	*val = 0;
185564df9b6Ssoda 	while((c = cngetc()) != '\e' && c != '\n' && c != '\r') {
186346d7152Ssoda 		if(c >= '0' && c <= '9') {
187346d7152Ssoda 			*val = (*val << 4) + c - '0';
188346d7152Ssoda 			cnputc(c);
189346d7152Ssoda 		}
190346d7152Ssoda 		else if(c >= 'a' && c <= 'f') {
191346d7152Ssoda 			*val = (*val << 4) + c - 'a' + 10;
192346d7152Ssoda 			cnputc(c);
193346d7152Ssoda 		}
194346d7152Ssoda 		else if(c == '\b') {
195346d7152Ssoda 			*val = *val >> 4;
196346d7152Ssoda 			printf("\b \b");
197346d7152Ssoda 		}
198346d7152Ssoda 		else if(c == ',') {
199346d7152Ssoda 			cnputc(c);
200346d7152Ssoda 			return(c);
201346d7152Ssoda 		}
202346d7152Ssoda 		else if(c == '.') {
203346d7152Ssoda 			*val = dotval;;
204346d7152Ssoda 			cnputc(c);
205346d7152Ssoda 		}
206346d7152Ssoda 	}
207564df9b6Ssoda 	if(c == '\r')
208564df9b6Ssoda 		c = '\n';
209346d7152Ssoda 	return(c);
210346d7152Ssoda }
211346d7152Ssoda 
212564df9b6Ssoda static
213346d7152Ssoda void dump(u_int *addr, u_int size)
214346d7152Ssoda {
215346d7152Ssoda 	int	cnt;
216346d7152Ssoda 
217346d7152Ssoda 	cnt = 0;
218346d7152Ssoda 
219346d7152Ssoda 	size = (size + 3) / 4;
220346d7152Ssoda 	while(size--) {
221346d7152Ssoda 		if((cnt++ & 3) == 0)
222346d7152Ssoda 			printf("\n%08x: ",(int)addr);
223346d7152Ssoda 		printf("%08x ",*addr++);
224346d7152Ssoda 	}
225346d7152Ssoda }
226346d7152Ssoda 
227564df9b6Ssoda static void
228564df9b6Ssoda print_regs()
229346d7152Ssoda {
230346d7152Ssoda 	printf("\n");
231346d7152Ssoda 	printf("T0-7 %08x %08x %08x %08x %08x %08x %08x %08x\n",
232346d7152Ssoda 		mdbpcb.pcb_regs[T0],mdbpcb.pcb_regs[T1],
233346d7152Ssoda 		mdbpcb.pcb_regs[T2],mdbpcb.pcb_regs[T3],
234346d7152Ssoda 		mdbpcb.pcb_regs[T4],mdbpcb.pcb_regs[T5],
235346d7152Ssoda 		mdbpcb.pcb_regs[T6],mdbpcb.pcb_regs[T7]);
236346d7152Ssoda 	printf("T8-9 %08x %08x     A0-4 %08x %08x %08x %08x\n",
237346d7152Ssoda 		mdbpcb.pcb_regs[T8],mdbpcb.pcb_regs[T9],
238346d7152Ssoda 		mdbpcb.pcb_regs[A0],mdbpcb.pcb_regs[A1],
239346d7152Ssoda 		mdbpcb.pcb_regs[A2],mdbpcb.pcb_regs[A3]);
240346d7152Ssoda 	printf("S0-7 %08x %08x %08x %08x %08x %08x %08x %08x\n",
241346d7152Ssoda 		mdbpcb.pcb_regs[S0],mdbpcb.pcb_regs[S1],
242346d7152Ssoda 		mdbpcb.pcb_regs[S2],mdbpcb.pcb_regs[S3],
243346d7152Ssoda 		mdbpcb.pcb_regs[S4],mdbpcb.pcb_regs[S5],
244346d7152Ssoda 		mdbpcb.pcb_regs[S6],mdbpcb.pcb_regs[S7]);
245346d7152Ssoda 	printf("  S8 %08x     V0-1 %08x %08x       GP %08x       SP %08x\n",
246346d7152Ssoda 		mdbpcb.pcb_regs[S8],mdbpcb.pcb_regs[V0],
247346d7152Ssoda 		mdbpcb.pcb_regs[V1],mdbpcb.pcb_regs[GP],
248346d7152Ssoda 		mdbpcb.pcb_regs[SP]);
249346d7152Ssoda 	printf("  AT %08x       PC %08x       RA %08x       SR %08x",
250346d7152Ssoda 		mdbpcb.pcb_regs[AST],mdbpcb.pcb_regs[PC],
251346d7152Ssoda 		mdbpcb.pcb_regs[RA],mdbpcb.pcb_regs[SR]);
252346d7152Ssoda }
253346d7152Ssoda 
254564df9b6Ssoda void
255564df9b6Ssoda set_break(int va)
256346d7152Ssoda {
257346d7152Ssoda 	int i;
258346d7152Ssoda 
259346d7152Ssoda 	va = va & ~3;
260346d7152Ssoda 	for(i = 0; i < MAXBRK; i++) {
261346d7152Ssoda 		if(brk_tab[i].addr == 0) {
262346d7152Ssoda 			brk_tab[i].addr = va;
263346d7152Ssoda 			brk_tab[i].inst = *(u_int *)va;
264346d7152Ssoda 			return;
265346d7152Ssoda 		}
266346d7152Ssoda 	}
267346d7152Ssoda 	printf(" Break table full!!");
268346d7152Ssoda }
269346d7152Ssoda 
270564df9b6Ssoda void
271564df9b6Ssoda del_break(int va)
272346d7152Ssoda {
273346d7152Ssoda 	int i;
274346d7152Ssoda 
275346d7152Ssoda 	va = va & ~3;
276346d7152Ssoda 	for(i = 0; i < MAXBRK; i++) {
277346d7152Ssoda 		if(brk_tab[i].addr == va) {
278346d7152Ssoda 			brk_tab[i].addr = 0;
279346d7152Ssoda 			return;
280346d7152Ssoda 		}
281346d7152Ssoda 	}
282346d7152Ssoda 	printf(" Break to remove not found!!");
283346d7152Ssoda }
284346d7152Ssoda 
285564df9b6Ssoda static void
286346d7152Ssoda break_insert()
287346d7152Ssoda {
288346d7152Ssoda 	int i;
289346d7152Ssoda 
290346d7152Ssoda 	for(i = 0; i < MAXBRK; i++) {
291346d7152Ssoda 		if(brk_tab[i].addr != 0) {
292346d7152Ssoda 			brk_tab[i].inst = *(u_int *)brk_tab[i].addr;
293346d7152Ssoda 			*(u_int *)brk_tab[i].addr = MIPS_BREAK_BRKPT;
294564df9b6Ssoda 			mips3_FlushDCache(brk_tab[i].addr,4);
295564df9b6Ssoda 			mips3_FlushICache(brk_tab[i].addr,4);
296346d7152Ssoda 		}
297346d7152Ssoda 	}
298346d7152Ssoda }
299346d7152Ssoda 
300564df9b6Ssoda static void
301346d7152Ssoda break_restore()
302346d7152Ssoda {
303346d7152Ssoda 	int i;
304346d7152Ssoda 
305346d7152Ssoda 	for(i = 0; i < MAXBRK; i++) {
306346d7152Ssoda 		if(brk_tab[i].addr != 0) {
307346d7152Ssoda 			*(u_int *)brk_tab[i].addr = brk_tab[i].inst;
308564df9b6Ssoda 			mips3_FlushDCache(brk_tab[i].addr,4);
309564df9b6Ssoda 			mips3_FlushICache(brk_tab[i].addr,4);
310346d7152Ssoda 		}
311346d7152Ssoda 	}
312346d7152Ssoda }
313346d7152Ssoda 
314564df9b6Ssoda static int
315346d7152Ssoda break_find(va)
316564df9b6Ssoda 	int va;
317346d7152Ssoda {
318346d7152Ssoda 	int i;
319346d7152Ssoda 
320346d7152Ssoda 	for(i = 0; i < MAXBRK; i++) {
321346d7152Ssoda 		if(brk_tab[i].addr == va) {
322346d7152Ssoda 			return(i);
323346d7152Ssoda 		}
324346d7152Ssoda 	}
325346d7152Ssoda 	return(-1);
326346d7152Ssoda }
327346d7152Ssoda 
328564df9b6Ssoda void
329346d7152Ssoda prt_break()
330346d7152Ssoda {
331346d7152Ssoda 	int i;
332346d7152Ssoda 
333346d7152Ssoda 	for(i = 0; i < MAXBRK; i++) {
334346d7152Ssoda 		if(brk_tab[i].addr != 0) {
335346d7152Ssoda 			printf("\n    %08x\t", brk_tab[i].addr);
336346d7152Ssoda 			mdbprintins(brk_tab[i].inst, brk_tab[i].addr);
337346d7152Ssoda 		}
338346d7152Ssoda 	}
339346d7152Ssoda }
340564df9b6Ssoda 
341564df9b6Ssoda int
342564df9b6Ssoda mdb(int causeReg, int vadr, int p, int kernelmode)
343346d7152Ssoda {
344346d7152Ssoda 	int c;
345346d7152Ssoda 	int newaddr;
346346d7152Ssoda 	int size;
347346d7152Ssoda 	int cause;
348346d7152Ssoda static int ssandrun;	/* Single step and run flag (when cont at brk) */
349346d7152Ssoda 
350346d7152Ssoda 	splhigh();
351564df9b6Ssoda 	cause = (causeReg & MIPS3_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT;
352346d7152Ssoda 	newaddr = (int)(mdbpcb.pcb_regs[PC]);
353346d7152Ssoda 	switch(cause) {
354346d7152Ssoda 	case T_BREAK:
355346d7152Ssoda 		if(*(int *)newaddr == MIPS_BREAK_SOVER) {
356346d7152Ssoda 			break_restore();
357346d7152Ssoda 			mdbpcb.pcb_regs[PC] += 4;
358346d7152Ssoda 			printf("\nStop break (panic)\n# ");
359346d7152Ssoda 			printf("    %08x\t",newaddr);
360346d7152Ssoda 			mdbprintins(*(int *)newaddr, newaddr);
361346d7152Ssoda 			printf("\n# ");
362346d7152Ssoda 			break;
363346d7152Ssoda 		}
364346d7152Ssoda 		if(*(int *)newaddr == MIPS_BREAK_BRKPT) {
365346d7152Ssoda 			break_restore();
366346d7152Ssoda 			printf("\rBRK %08x\t",newaddr);
367346d7152Ssoda 			if(mdbprintins(*(int *)newaddr, newaddr)) {
368346d7152Ssoda 				newaddr += 4;
369346d7152Ssoda 				printf("\n    %08x\t",newaddr);
370346d7152Ssoda 				mdbprintins(*(int *)newaddr, newaddr);
371346d7152Ssoda 			}
372346d7152Ssoda 			printf("\n# ");
373346d7152Ssoda 			break;
374346d7152Ssoda 		}
375346d7152Ssoda 		if(mdbclrsstep(causeReg)) {
376346d7152Ssoda 			if(ssandrun) { /* Step over bp before free run */
377346d7152Ssoda 				ssandrun = 0;
378346d7152Ssoda 				break_insert();
379346d7152Ssoda 				return(TRUE);
380346d7152Ssoda 			}
381346d7152Ssoda 			printf("\r    %08x\t",newaddr);
382346d7152Ssoda 			if(mdbprintins(*(int *)newaddr, newaddr)) {
383346d7152Ssoda 				newaddr += 4;
384346d7152Ssoda 				printf("\n    %08x\t",newaddr);
385346d7152Ssoda 				mdbprintins(*(int *)newaddr, newaddr);
386346d7152Ssoda 			}
387346d7152Ssoda 			printf("\n# ");
388346d7152Ssoda 		}
389346d7152Ssoda 		break;
390346d7152Ssoda 
391346d7152Ssoda 	default:
392346d7152Ssoda 		printf("\n-- %s --\n# ",trap_type[cause]);
393346d7152Ssoda 	}
394346d7152Ssoda 	ssandrun = 0;
395346d7152Ssoda 	break_restore();
396346d7152Ssoda 
397564df9b6Ssoda 	while(1) {
398564df9b6Ssoda 		c = cngetc();
399346d7152Ssoda 		switch(c) {
400346d7152Ssoda 		case 'T':
401346d7152Ssoda 			trapDump("Debugger");
402346d7152Ssoda 			break;
403346d7152Ssoda 		case 'b':
404346d7152Ssoda 			printf("break-");
405346d7152Ssoda 			c = cngetc();
406346d7152Ssoda 			switch(c) {
407346d7152Ssoda 			case 's':
408346d7152Ssoda 				printf("set at ");
409346d7152Ssoda 				c = gethex(&newaddr, newaddr);
410346d7152Ssoda 				if(c != '\e') {
411346d7152Ssoda 					set_break(newaddr);
412346d7152Ssoda 				}
413346d7152Ssoda 				break;
414346d7152Ssoda 
415346d7152Ssoda 			case 'd':
416346d7152Ssoda 				printf("delete at ");
417346d7152Ssoda 				c = gethex(&newaddr, newaddr);
418346d7152Ssoda 				if(c != '\e') {
419346d7152Ssoda 					del_break(newaddr);
420346d7152Ssoda 				}
421346d7152Ssoda 				break;
422346d7152Ssoda 
423346d7152Ssoda 			case 'p':
424346d7152Ssoda 				printf("print");
425346d7152Ssoda 				prt_break();
426346d7152Ssoda 				break;
427346d7152Ssoda 			}
428346d7152Ssoda 			break;
429346d7152Ssoda 
430346d7152Ssoda 		case 'r':
431346d7152Ssoda 			print_regs();
432346d7152Ssoda 			break;
433346d7152Ssoda 
434346d7152Ssoda 		case 'I':
435346d7152Ssoda 			printf("Instruction at ");
436346d7152Ssoda 			c = gethex(&newaddr, newaddr);
437346d7152Ssoda 			while(c != '\e') {
438346d7152Ssoda 				printf("\n    %08x\t",newaddr);
439346d7152Ssoda 				mdbprintins(*(int *)newaddr, newaddr);
440346d7152Ssoda 				newaddr += 4;
441346d7152Ssoda 				c = cngetc();
442346d7152Ssoda 			}
443346d7152Ssoda 			break;
444346d7152Ssoda 
445346d7152Ssoda 		case 'c':
446346d7152Ssoda 			printf("continue");
447346d7152Ssoda 			if(break_find((int)(mdbpcb.pcb_regs[PC])) >= 0) {
448346d7152Ssoda 				ssandrun = 1;
449346d7152Ssoda 				mdbsetsstep();
450346d7152Ssoda 			}
451346d7152Ssoda 			else {
452346d7152Ssoda 				break_insert();
453346d7152Ssoda 			}
454346d7152Ssoda 			return(TRUE);
455564df9b6Ssoda 		case 'S':
456564df9b6Ssoda 			printf("Stack traceback:\n");
457564df9b6Ssoda 			stacktrace();
458564df9b6Ssoda 			return(TRUE);
459346d7152Ssoda 		case 's':
460346d7152Ssoda 			set_break(mdbpcb.pcb_regs[PC] + 8);
461346d7152Ssoda 			return(TRUE);
462346d7152Ssoda 		case ' ':
463346d7152Ssoda 			mdbsetsstep();
464346d7152Ssoda 			return(TRUE);
465346d7152Ssoda 
466346d7152Ssoda 		case 'd':
467346d7152Ssoda 			printf("dump ");
468346d7152Ssoda 			c = gethex(&newaddr, newaddr);
469346d7152Ssoda 			if(c == ',') {
470346d7152Ssoda 				c = gethex(&size,256);
471346d7152Ssoda 			}
472346d7152Ssoda 			else {
473346d7152Ssoda 				size = 16;
474346d7152Ssoda 			}
475346d7152Ssoda 			if(c == '\n' && newaddr != 0) {
476346d7152Ssoda 				dump((u_int *)newaddr, size);
477346d7152Ssoda 				newaddr += size;
478346d7152Ssoda 			}
479346d7152Ssoda 			break;
480346d7152Ssoda 
481346d7152Ssoda 		case 'm':
482346d7152Ssoda 			printf("mod ");
483346d7152Ssoda 			c = gethex(&newaddr, newaddr);
484346d7152Ssoda 			while(c == ',') {
485346d7152Ssoda 				c = gethex(&size, 0);
486346d7152Ssoda 				if(c != '\e')
487346d7152Ssoda 					*((u_int *)newaddr)++ = size;
488346d7152Ssoda 			}
489346d7152Ssoda 			break;
490346d7152Ssoda 
491346d7152Ssoda 		case 'i':
492346d7152Ssoda 			printf("in-");
493346d7152Ssoda 			c = cngetc();
494346d7152Ssoda 			switch(c) {
495346d7152Ssoda 			case 'b':
496346d7152Ssoda 				printf("byte ");
497346d7152Ssoda 				c = gethex(&newaddr, newaddr);
498346d7152Ssoda 				if(c == '\n') {
499346d7152Ssoda 					printf("= %02x",
500346d7152Ssoda 						*(u_char *)newaddr);
501346d7152Ssoda 				}
502346d7152Ssoda 				break;
503346d7152Ssoda 			case 'h':
504346d7152Ssoda 				printf("halfword ");
505346d7152Ssoda 				c = gethex(&newaddr, newaddr);
506346d7152Ssoda 				if(c == '\n') {
507346d7152Ssoda 					printf("= %04x",
508346d7152Ssoda 						*(u_short *)newaddr);
509346d7152Ssoda 				}
510346d7152Ssoda 				break;
511346d7152Ssoda 			case 'w':
512346d7152Ssoda 				printf("word ");
513346d7152Ssoda 				c = gethex(&newaddr, newaddr);
514346d7152Ssoda 				if(c == '\n') {
515346d7152Ssoda 					printf("= %08x",
516346d7152Ssoda 						*(u_int *)newaddr);
517346d7152Ssoda 				}
518346d7152Ssoda 				break;
519346d7152Ssoda 			}
520346d7152Ssoda 			break;
521346d7152Ssoda 
522346d7152Ssoda 		case 'o':
523346d7152Ssoda 			printf("out-");
524346d7152Ssoda 			c = cngetc();
525346d7152Ssoda 			switch(c) {
526346d7152Ssoda 			case 'b':
527346d7152Ssoda 				printf("byte ");
528346d7152Ssoda 				c = gethex(&newaddr, newaddr);
529346d7152Ssoda 				if(c == ',') {
530346d7152Ssoda 					c = gethex(&size, 0);
531346d7152Ssoda 					if(c == '\n') {
532346d7152Ssoda 						*(u_char *)newaddr = size;
533346d7152Ssoda 					}
534346d7152Ssoda 				}
535346d7152Ssoda 				break;
536346d7152Ssoda 			case 'h':
537346d7152Ssoda 				printf("halfword ");
538346d7152Ssoda 				c = gethex(&newaddr, newaddr);
539346d7152Ssoda 				if(c == ',') {
540346d7152Ssoda 					c = gethex(&size, 0);
541346d7152Ssoda 					if(c == '\n') {
542346d7152Ssoda 						*(u_short *)newaddr = size;
543346d7152Ssoda 					}
544346d7152Ssoda 				}
545346d7152Ssoda 				break;
546346d7152Ssoda 			case 'w':
547346d7152Ssoda 				printf("word ");
548346d7152Ssoda 				c = gethex(&newaddr, newaddr);
549346d7152Ssoda 				if(c == ',') {
550346d7152Ssoda 					c = gethex(&size, 0);
551346d7152Ssoda 					if(c == '\n') {
552346d7152Ssoda 						*(u_int *)newaddr = size;
553346d7152Ssoda 					}
554346d7152Ssoda 				}
555346d7152Ssoda 				break;
556346d7152Ssoda 			}
557346d7152Ssoda 			break;
558346d7152Ssoda 
559346d7152Ssoda 		case 't':
560346d7152Ssoda 			printf("tlb-dump\n");
561564df9b6Ssoda 			arc_dump_tlb(0,23);
562346d7152Ssoda 			(void)cngetc();
563564df9b6Ssoda 			arc_dump_tlb(24,47);
564346d7152Ssoda 			break;
565346d7152Ssoda 
566346d7152Ssoda 		case 'f':
567346d7152Ssoda 			printf("flush-");
568346d7152Ssoda 			c = cngetc();
569346d7152Ssoda 			switch(c) {
570346d7152Ssoda 			case 't':
571346d7152Ssoda 				printf("tlb");
572564df9b6Ssoda 				mips3_TLBFlush(num_tlbentries);
573346d7152Ssoda 				break;
574346d7152Ssoda 
575346d7152Ssoda 			case 'c':
576346d7152Ssoda 				printf("cache");
577564df9b6Ssoda 				mips3_FlushCache();
578346d7152Ssoda 				break;
579346d7152Ssoda 			}
580346d7152Ssoda 			break;
581346d7152Ssoda 
58271f6ef9eSsoda #ifdef __OpenBSD__
58371f6ef9eSsoda 		case 'w':
58471f6ef9eSsoda 			printf("watch ");
58571f6ef9eSsoda 			c = gethex(&newaddr, newaddr);
58671f6ef9eSsoda 			size = 3;
58771f6ef9eSsoda 			if(c == ',') {
58871f6ef9eSsoda 				c = cngetc();
58971f6ef9eSsoda 				cnputc(c);
59071f6ef9eSsoda 				if(c == 'r')
59171f6ef9eSsoda 					size = 2;
59271f6ef9eSsoda 				else if(c == 'w')
59371f6ef9eSsoda 					size = 1;
59471f6ef9eSsoda 				else
59571f6ef9eSsoda 					size = 0;
59671f6ef9eSsoda 			}
59771f6ef9eSsoda 			cpu_setwatch(0, (newaddr & ~7) | size);
59871f6ef9eSsoda 			break;
59971f6ef9eSsoda #endif
60071f6ef9eSsoda 
601346d7152Ssoda 		default:
602346d7152Ssoda 			cnputc('\a');
603346d7152Ssoda 			break;
604346d7152Ssoda 		}
605346d7152Ssoda 		printf("\n# ");
606346d7152Ssoda 	}
607346d7152Ssoda }
608346d7152Ssoda 
609346d7152Ssoda u_int mdb_ss_addr;
610346d7152Ssoda u_int mdb_ss_instr;
611346d7152Ssoda 
612564df9b6Ssoda static void
613346d7152Ssoda mdbsetsstep()
614346d7152Ssoda {
615346d7152Ssoda 	register u_int va;
616346d7152Ssoda 	register int *locr0 = mdbpcb.pcb_regs;
617346d7152Ssoda 
618346d7152Ssoda 	/* compute next address after current location */
619346d7152Ssoda 	if(mdbpeek(locr0[PC]) != 0) {
620346d7152Ssoda 		va = MachEmulateBranch(locr0, locr0[PC], 0, mdbpeek(locr0[PC]));
621346d7152Ssoda 	}
622346d7152Ssoda 	else {
623346d7152Ssoda 		va = locr0[PC] + 4;
624346d7152Ssoda 	}
625346d7152Ssoda 	if (mdb_ss_addr) {
626346d7152Ssoda 		printf("mdbsetsstep: breakpoint already set at %x (va %x)\n",
627346d7152Ssoda 			mdb_ss_addr, va);
628346d7152Ssoda 		return;
629346d7152Ssoda 	}
630346d7152Ssoda 	mdb_ss_addr = va;
631346d7152Ssoda 
632346d7152Ssoda 	if ((int)va < 0) {
633346d7152Ssoda 		/* kernel address */
634346d7152Ssoda 		mdb_ss_instr = mdbpeek(va);
635564df9b6Ssoda 		mdbpoke(va, MIPS_BREAK_SSTEP);
636564df9b6Ssoda 		mips3_FlushDCache(va,4);
637564df9b6Ssoda 		mips3_FlushICache(va,4);
638346d7152Ssoda 		return;
639346d7152Ssoda 	}
640346d7152Ssoda }
641346d7152Ssoda 
642564df9b6Ssoda static int
643564df9b6Ssoda mdbclrsstep(int cr)
644346d7152Ssoda {
645346d7152Ssoda 	register u_int pc, va;
646346d7152Ssoda 	u_int instr;
647346d7152Ssoda 
648346d7152Ssoda 	/* fix pc if break instruction is in the delay slot */
649346d7152Ssoda 	pc = mdbpcb.pcb_regs[PC];
650346d7152Ssoda 	if (cr < 0)
651346d7152Ssoda 		pc += 4;
652346d7152Ssoda 
653346d7152Ssoda 	/* check to be sure its the one we are expecting */
654346d7152Ssoda 	va = mdb_ss_addr;
655346d7152Ssoda 	if (!va || va != pc)
656346d7152Ssoda 		return(FALSE);
657346d7152Ssoda 
658346d7152Ssoda 	/* read break instruction */
659346d7152Ssoda 	instr = mdbpeek(va);
660346d7152Ssoda 	if (instr != MIPS_BREAK_SSTEP)
661346d7152Ssoda 		return(FALSE);
662346d7152Ssoda 
663346d7152Ssoda 	if ((int)va < 0) {
664346d7152Ssoda 		/* kernel address */
665564df9b6Ssoda 		mdbpoke(va, mdb_ss_instr);
666564df9b6Ssoda 		mips3_FlushDCache(va,4);
667564df9b6Ssoda 		mips3_FlushICache(va,4);
668346d7152Ssoda 		mdb_ss_addr = 0;
669346d7152Ssoda 		return(TRUE);
670346d7152Ssoda 	}
671346d7152Ssoda 
672346d7152Ssoda 	printf("can't clear break at %x\n", va);
673346d7152Ssoda 	mdb_ss_addr = 0;
674346d7152Ssoda 	return(FALSE);
675346d7152Ssoda }
676346d7152Ssoda 
677346d7152Ssoda 
678346d7152Ssoda /* ARGSUSED */
679564df9b6Ssoda static int
680564df9b6Ssoda mdbprintins(int ins, int mdbdot)
681346d7152Ssoda {
682346d7152Ssoda 	InstFmt i;
683346d7152Ssoda 	int delay = 0;
684346d7152Ssoda 
685346d7152Ssoda 	i.word = ins;
686346d7152Ssoda 
687346d7152Ssoda 	switch (i.JType.op) {
688346d7152Ssoda 	case OP_SPECIAL:
689346d7152Ssoda 		if (i.word == 0) {
690346d7152Ssoda 			printf("nop");
691346d7152Ssoda 			break;
692346d7152Ssoda 		}
693346d7152Ssoda 		if (i.RType.func == OP_ADDU && i.RType.rt == 0) {
694346d7152Ssoda 			printf("move\t%s,%s",
695346d7152Ssoda 				reg_name[i.RType.rd],
696346d7152Ssoda 				reg_name[i.RType.rs]);
697346d7152Ssoda 			break;
698346d7152Ssoda 		}
699346d7152Ssoda 		printf("%s", spec_name[i.RType.func]);
700346d7152Ssoda 		switch (i.RType.func) {
701346d7152Ssoda 		case OP_SLL:
702346d7152Ssoda 		case OP_SRL:
703346d7152Ssoda 		case OP_SRA:
704346d7152Ssoda 		case OP_DSLL:
705346d7152Ssoda 		case OP_DSRL:
706346d7152Ssoda 		case OP_DSRA:
707346d7152Ssoda 		case OP_DSLL32:
708346d7152Ssoda 		case OP_DSRL32:
709346d7152Ssoda 		case OP_DSRA32:
710346d7152Ssoda 			printf("\t%s,%s,%d",
711346d7152Ssoda 				reg_name[i.RType.rd],
712346d7152Ssoda 				reg_name[i.RType.rt],
713346d7152Ssoda 				i.RType.shamt);
714346d7152Ssoda 			break;
715346d7152Ssoda 
716346d7152Ssoda 		case OP_SLLV:
717346d7152Ssoda 		case OP_SRLV:
718346d7152Ssoda 		case OP_SRAV:
719346d7152Ssoda 		case OP_DSLLV:
720346d7152Ssoda 		case OP_DSRLV:
721346d7152Ssoda 		case OP_DSRAV:
722346d7152Ssoda 			printf("\t%s,%s,%s",
723346d7152Ssoda 				reg_name[i.RType.rd],
724346d7152Ssoda 				reg_name[i.RType.rt],
725346d7152Ssoda 				reg_name[i.RType.rs]);
726346d7152Ssoda 			break;
727346d7152Ssoda 
728346d7152Ssoda 		case OP_MFHI:
729346d7152Ssoda 		case OP_MFLO:
730346d7152Ssoda 			printf("\t%s", reg_name[i.RType.rd]);
731346d7152Ssoda 			break;
732346d7152Ssoda 
733346d7152Ssoda 		case OP_JR:
734346d7152Ssoda 		case OP_JALR:
735346d7152Ssoda 			delay = 1;
736346d7152Ssoda 			/* FALLTHROUGH */
737346d7152Ssoda 		case OP_MTLO:
738346d7152Ssoda 		case OP_MTHI:
739346d7152Ssoda 			printf("\t%s", reg_name[i.RType.rs]);
740346d7152Ssoda 			break;
741346d7152Ssoda 
742346d7152Ssoda 		case OP_MULT:
743346d7152Ssoda 		case OP_MULTU:
744346d7152Ssoda 		case OP_DMULT:
745346d7152Ssoda 		case OP_DMULTU:
746346d7152Ssoda 		case OP_DIV:
747346d7152Ssoda 		case OP_DIVU:
748346d7152Ssoda 		case OP_DDIV:
749346d7152Ssoda 		case OP_DDIVU:
750346d7152Ssoda 			printf("\t%s,%s",
751346d7152Ssoda 				reg_name[i.RType.rs],
752346d7152Ssoda 				reg_name[i.RType.rt]);
753346d7152Ssoda 			break;
754346d7152Ssoda 
755346d7152Ssoda 		case OP_SYSCALL:
756346d7152Ssoda 		case OP_SYNC:
757346d7152Ssoda 			break;
758346d7152Ssoda 
759346d7152Ssoda 		case OP_BREAK:
760346d7152Ssoda 			printf("\t%d", (i.RType.rs << 5) | i.RType.rt);
761346d7152Ssoda 			break;
762346d7152Ssoda 
763346d7152Ssoda 		default:
764346d7152Ssoda 			printf("\t%s,%s,%s",
765346d7152Ssoda 				reg_name[i.RType.rd],
766346d7152Ssoda 				reg_name[i.RType.rs],
767346d7152Ssoda 				reg_name[i.RType.rt]);
768346d7152Ssoda 		};
769346d7152Ssoda 		break;
770346d7152Ssoda 
771346d7152Ssoda 	case OP_BCOND:
772346d7152Ssoda 		printf("%s\t%s,", bcond_name[i.IType.rt],
773346d7152Ssoda 			reg_name[i.IType.rs]);
774346d7152Ssoda 		goto pr_displ;
775346d7152Ssoda 
776346d7152Ssoda 	case OP_BLEZ:
777346d7152Ssoda 	case OP_BLEZL:
778346d7152Ssoda 	case OP_BGTZ:
779346d7152Ssoda 	case OP_BGTZL:
780346d7152Ssoda 		printf("%s\t%s,", op_name[i.IType.op],
781346d7152Ssoda 			reg_name[i.IType.rs]);
782346d7152Ssoda 		goto pr_displ;
783346d7152Ssoda 
784346d7152Ssoda 	case OP_BEQ:
785346d7152Ssoda 	case OP_BEQL:
786346d7152Ssoda 		if (i.IType.rs == 0 && i.IType.rt == 0) {
787346d7152Ssoda 			printf("b\t");
788346d7152Ssoda 			goto pr_displ;
789346d7152Ssoda 		}
790346d7152Ssoda 		/* FALLTHROUGH */
791346d7152Ssoda 	case OP_BNE:
792346d7152Ssoda 	case OP_BNEL:
793346d7152Ssoda 		printf("%s\t%s,%s,", op_name[i.IType.op],
794346d7152Ssoda 			reg_name[i.IType.rs],
795346d7152Ssoda 			reg_name[i.IType.rt]);
796346d7152Ssoda 	pr_displ:
797346d7152Ssoda 		delay = 1;
798346d7152Ssoda 		printf("0x%08x", mdbdot + 4 + ((short)i.IType.imm << 2));
799346d7152Ssoda 		break;
800346d7152Ssoda 
801346d7152Ssoda 	case OP_COP0:
802346d7152Ssoda 		switch (i.RType.rs) {
803346d7152Ssoda 		case OP_BCx:
804346d7152Ssoda 		case OP_BCy:
805346d7152Ssoda 			printf("bc0%c\t",
806346d7152Ssoda 				"ft"[i.RType.rt & COPz_BC_TF_MASK]);
807346d7152Ssoda 			goto pr_displ;
808346d7152Ssoda 
809346d7152Ssoda 		case OP_MT:
810346d7152Ssoda 			printf("mtc0\t%s,%s",
811346d7152Ssoda 				reg_name[i.RType.rt],
812346d7152Ssoda 				c0_reg[i.RType.rd]);
813346d7152Ssoda 			break;
814346d7152Ssoda 
815346d7152Ssoda 		case OP_DMT:
816346d7152Ssoda 			printf("dmtc0\t%s,%s",
817346d7152Ssoda 				reg_name[i.RType.rt],
818346d7152Ssoda 				c0_reg[i.RType.rd]);
819346d7152Ssoda 			break;
820346d7152Ssoda 
821346d7152Ssoda 		case OP_MF:
822346d7152Ssoda 			printf("mfc0\t%s,%s",
823346d7152Ssoda 				reg_name[i.RType.rt],
824346d7152Ssoda 				c0_reg[i.RType.rd]);
825346d7152Ssoda 			break;
826346d7152Ssoda 
827346d7152Ssoda 		case OP_DMF:
828346d7152Ssoda 			printf("dmfc0\t%s,%s",
829346d7152Ssoda 				reg_name[i.RType.rt],
830346d7152Ssoda 				c0_reg[i.RType.rd]);
831346d7152Ssoda 			break;
832346d7152Ssoda 
833346d7152Ssoda 		default:
834346d7152Ssoda 			printf("%s", c0_opname[i.FRType.func]);
835346d7152Ssoda 		};
836346d7152Ssoda 		break;
837346d7152Ssoda 
838346d7152Ssoda 	case OP_COP1:
839346d7152Ssoda 		switch (i.RType.rs) {
840346d7152Ssoda 		case OP_BCx:
841346d7152Ssoda 		case OP_BCy:
842346d7152Ssoda 			printf("bc1%c\t",
843346d7152Ssoda 				"ft"[i.RType.rt & COPz_BC_TF_MASK]);
844346d7152Ssoda 			goto pr_displ;
845346d7152Ssoda 
846346d7152Ssoda 		case OP_MT:
847346d7152Ssoda 			printf("mtc1\t%s,f%d",
848346d7152Ssoda 				reg_name[i.RType.rt],
849346d7152Ssoda 				i.RType.rd);
850346d7152Ssoda 			break;
851346d7152Ssoda 
852346d7152Ssoda 		case OP_MF:
853346d7152Ssoda 			printf("mfc1\t%s,f%d",
854346d7152Ssoda 				reg_name[i.RType.rt],
855346d7152Ssoda 				i.RType.rd);
856346d7152Ssoda 			break;
857346d7152Ssoda 
858346d7152Ssoda 		case OP_CT:
859346d7152Ssoda 			printf("ctc1\t%s,f%d",
860346d7152Ssoda 				reg_name[i.RType.rt],
861346d7152Ssoda 				i.RType.rd);
862346d7152Ssoda 			break;
863346d7152Ssoda 
864346d7152Ssoda 		case OP_CF:
865346d7152Ssoda 			printf("cfc1\t%s,f%d",
866346d7152Ssoda 				reg_name[i.RType.rt],
867346d7152Ssoda 				i.RType.rd);
868346d7152Ssoda 			break;
869346d7152Ssoda 
870346d7152Ssoda 		default:
871346d7152Ssoda 			printf("%s.%s\tf%d,f%d,f%d",
872346d7152Ssoda 				cop1_name[i.FRType.func],
873346d7152Ssoda 				fmt_name[i.FRType.fmt],
874346d7152Ssoda 				i.FRType.fd, i.FRType.fs, i.FRType.ft);
875346d7152Ssoda 		};
876346d7152Ssoda 		break;
877346d7152Ssoda 
878346d7152Ssoda 	case OP_J:
879346d7152Ssoda 	case OP_JAL:
880346d7152Ssoda 		printf("%s\t", op_name[i.JType.op]);
881346d7152Ssoda 		printf("0x%8x",(mdbdot & 0xF0000000) | (i.JType.target << 2));
882346d7152Ssoda 		delay = 1;
883346d7152Ssoda 		break;
884346d7152Ssoda 
885346d7152Ssoda 	case OP_LWC1:
886346d7152Ssoda 	case OP_SWC1:
887346d7152Ssoda 		printf("%s\tf%d,", op_name[i.IType.op],
888346d7152Ssoda 			i.IType.rt);
889346d7152Ssoda 		goto loadstore;
890346d7152Ssoda 
891346d7152Ssoda 	case OP_LB:
892346d7152Ssoda 	case OP_LH:
893346d7152Ssoda 	case OP_LW:
894346d7152Ssoda 	case OP_LD:
895346d7152Ssoda 	case OP_LBU:
896346d7152Ssoda 	case OP_LHU:
897346d7152Ssoda 	case OP_LWU:
898346d7152Ssoda 	case OP_SB:
899346d7152Ssoda 	case OP_SH:
900346d7152Ssoda 	case OP_SW:
901346d7152Ssoda 	case OP_SD:
902346d7152Ssoda 		printf("%s\t%s,", op_name[i.IType.op],
903346d7152Ssoda 			reg_name[i.IType.rt]);
904346d7152Ssoda 	loadstore:
905346d7152Ssoda 		printf("%d(%s)", (short)i.IType.imm,
906346d7152Ssoda 			reg_name[i.IType.rs]);
907346d7152Ssoda 		break;
908346d7152Ssoda 
909346d7152Ssoda 	case OP_ORI:
910346d7152Ssoda 	case OP_XORI:
911346d7152Ssoda 		if (i.IType.rs == 0) {
912346d7152Ssoda 			printf("li\t%s,0x%x",
913346d7152Ssoda 				reg_name[i.IType.rt],
914346d7152Ssoda 				i.IType.imm);
915346d7152Ssoda 			break;
916346d7152Ssoda 		}
917346d7152Ssoda 		/* FALLTHROUGH */
918346d7152Ssoda 	case OP_ANDI:
919346d7152Ssoda 		printf("%s\t%s,%s,0x%x", op_name[i.IType.op],
920346d7152Ssoda 			reg_name[i.IType.rt],
921346d7152Ssoda 			reg_name[i.IType.rs],
922346d7152Ssoda 			i.IType.imm);
923346d7152Ssoda 		break;
924346d7152Ssoda 
925346d7152Ssoda 	case OP_LUI:
926346d7152Ssoda 		printf("%s\t%s,0x%x", op_name[i.IType.op],
927346d7152Ssoda 			reg_name[i.IType.rt],
928346d7152Ssoda 			i.IType.imm);
929346d7152Ssoda 		break;
930346d7152Ssoda 
931346d7152Ssoda 	case OP_ADDI:
932346d7152Ssoda 	case OP_DADDI:
933346d7152Ssoda 	case OP_ADDIU:
934346d7152Ssoda 	case OP_DADDIU:
935346d7152Ssoda 		if (i.IType.rs == 0) {
936346d7152Ssoda  			printf("li\t%s,%d",
937346d7152Ssoda 				reg_name[i.IType.rt],
938346d7152Ssoda 				(short)i.IType.imm);
939346d7152Ssoda 			break;
940346d7152Ssoda 		}
941346d7152Ssoda 		/* FALLTHROUGH */
942346d7152Ssoda 	default:
943346d7152Ssoda 		printf("%s\t%s,%s,%d", op_name[i.IType.op],
944346d7152Ssoda 			reg_name[i.IType.rt],
945346d7152Ssoda 			reg_name[i.IType.rs],
946346d7152Ssoda 			(short)i.IType.imm);
947346d7152Ssoda 	}
948346d7152Ssoda 	return(delay);
949346d7152Ssoda }
950346d7152Ssoda 
951346d7152Ssoda 
952346d7152Ssoda /*
953346d7152Ssoda  *	Dump TLB contents.
954346d7152Ssoda  */
955564df9b6Ssoda static void
956564df9b6Ssoda arc_dump_tlb(int first,int last)
957346d7152Ssoda {
958346d7152Ssoda 	int tlbno;
959346d7152Ssoda 	struct tlb tlb;
960346d7152Ssoda 
961346d7152Ssoda 	tlbno = first;
962346d7152Ssoda 
963346d7152Ssoda 	while(tlbno <= last) {
964564df9b6Ssoda 		mips3_TLBRead(tlbno, &tlb);
965564df9b6Ssoda 		if(tlb.tlb_lo0 & MIPS3_PG_V || tlb.tlb_lo1 & MIPS3_PG_V) {
966346d7152Ssoda 			printf("TLB %2d vad 0x%08x ", tlbno, tlb.tlb_hi);
967346d7152Ssoda 		}
968346d7152Ssoda 		else {
969346d7152Ssoda 			printf("TLB*%2d vad 0x%08x ", tlbno, tlb.tlb_hi);
970346d7152Ssoda 		}
97126c2cf79Ssoda 		printf("0=0x%08x ", mips_tlbpfn_to_paddr(tlb.tlb_lo0));
972564df9b6Ssoda 		printf("%c", tlb.tlb_lo0 & MIPS3_PG_M ? 'M' : ' ');
973564df9b6Ssoda 		printf("%c", tlb.tlb_lo0 & MIPS3_PG_G ? 'G' : ' ');
974346d7152Ssoda 		printf(" atr %x ", (tlb.tlb_lo0 >> 3) & 7);
97526c2cf79Ssoda 		printf("1=0x%08x ", mips_tlbpfn_to_paddr(tlb.tlb_lo1));
976564df9b6Ssoda 		printf("%c", tlb.tlb_lo1 & MIPS3_PG_M ? 'M' : ' ');
977564df9b6Ssoda 		printf("%c", tlb.tlb_lo1 & MIPS3_PG_G ? 'G' : ' ');
978346d7152Ssoda 		printf(" atr %x ", (tlb.tlb_lo1 >> 3) & 7);
979346d7152Ssoda 		printf(" sz=%x\n", tlb.tlb_mask);
980346d7152Ssoda 
981346d7152Ssoda 		tlbno++;
982346d7152Ssoda 	}
983346d7152Ssoda }
984