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