1*346d7152Ssoda /* $NetBSD: minidebug.c,v 1.6 2000/01/23 20:09:15 soda Exp $ */ 2*346d7152Ssoda 3*346d7152Ssoda /*- 4*346d7152Ssoda * Copyright (c) 1991, 1993 5*346d7152Ssoda * The Regents of the University of California. All rights reserved. 6*346d7152Ssoda * 7*346d7152Ssoda * This code is derived from software contributed to Berkeley by 8*346d7152Ssoda * Ralph Campbell. 9*346d7152Ssoda * 10*346d7152Ssoda * Redistribution and use in source and binary forms, with or without 11*346d7152Ssoda * modification, are permitted provided that the following conditions 12*346d7152Ssoda * are met: 13*346d7152Ssoda * 1. Redistributions of source code must retain the above copyright 14*346d7152Ssoda * notice, this list of conditions and the following disclaimer. 15*346d7152Ssoda * 2. Redistributions in binary form must reproduce the above copyright 16*346d7152Ssoda * notice, this list of conditions and the following disclaimer in the 17*346d7152Ssoda * documentation and/or other materials provided with the distribution. 18*346d7152Ssoda * 3. All advertising materials mentioning features or use of this software 19*346d7152Ssoda * must display the following acknowledgement: 20*346d7152Ssoda * This product includes software developed by the University of 21*346d7152Ssoda * California, Berkeley and its contributors. 22*346d7152Ssoda * 4. Neither the name of the University nor the names of its contributors 23*346d7152Ssoda * may be used to endorse or promote products derived from this software 24*346d7152Ssoda * without specific prior written permission. 25*346d7152Ssoda * 26*346d7152Ssoda * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27*346d7152Ssoda * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28*346d7152Ssoda * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29*346d7152Ssoda * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30*346d7152Ssoda * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31*346d7152Ssoda * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32*346d7152Ssoda * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33*346d7152Ssoda * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34*346d7152Ssoda * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35*346d7152Ssoda * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36*346d7152Ssoda * SUCH DAMAGE. 37*346d7152Ssoda * 38*346d7152Ssoda * from: @(#)kadb.c 8.1 (Berkeley) 6/10/93 39*346d7152Ssoda */ 40*346d7152Ssoda 41*346d7152Ssoda /* 42*346d7152Ssoda * Define machine dependent primitives for mdb. 43*346d7152Ssoda */ 44*346d7152Ssoda 45*346d7152Ssoda #include <sys/types.h> 46*346d7152Ssoda #include <machine/pte.h> 47*346d7152Ssoda #include <vm/vm_prot.h> 48*346d7152Ssoda #undef SP 49*346d7152Ssoda #include <machine/machConst.h> 50*346d7152Ssoda #include <machine/reg.h> 51*346d7152Ssoda #include <machine/pcb.h> 52*346d7152Ssoda #include <machine/trap.h> 53*346d7152Ssoda #include <machine/mips_opcode.h> 54*346d7152Ssoda 55*346d7152Ssoda #ifndef TRUE 56*346d7152Ssoda #define TRUE 1 57*346d7152Ssoda #define FALSE 0 58*346d7152Ssoda #endif 59*346d7152Ssoda 60*346d7152Ssoda void pica_dump_tlb(int, int); 61*346d7152Ssoda 62*346d7152Ssoda static char *op_name[64] = { 63*346d7152Ssoda /* 0 */ "spec", "bcond","j", "jal", "beq", "bne", "blez", "bgtz", 64*346d7152Ssoda /* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori", "xori", "lui", 65*346d7152Ssoda /*16 */ "cop0", "cop1", "cop2", "cop3", "beql", "bnel", "blezl","bgtzl", 66*346d7152Ssoda /*24 */ "daddi","daddiu","ldl", "ldr", "op34", "op35", "op36", "op37", 67*346d7152Ssoda /*32 */ "lb", "lh", "lwl", "lw", "lbu", "lhu", "lwr", "lwu", 68*346d7152Ssoda /*40 */ "sb", "sh", "swl", "sw", "sdl", "sdr", "swr", "cache", 69*346d7152Ssoda /*48 */ "ll", "lwc1", "lwc2", "lwc3", "lld", "ldc1", "ldc2", "ld", 70*346d7152Ssoda /*56 */ "sc", "swc1", "swc2", "swc3", "scd", "sdc1", "sdc2", "sd" 71*346d7152Ssoda }; 72*346d7152Ssoda 73*346d7152Ssoda static char *spec_name[64] = { 74*346d7152Ssoda /* 0 */ "sll", "spec01","srl", "sra", "sllv", "spec05","srlv","srav", 75*346d7152Ssoda /* 8 */ "jr", "jalr", "spec12","spec13","syscall","break","spec16","sync", 76*346d7152Ssoda /*16 */ "mfhi", "mthi", "mflo", "mtlo", "dsllv","spec25","dsrlv","dsrav", 77*346d7152Ssoda /*24 */ "mult", "multu","div", "divu", "dmult","dmultu","ddiv","ddivu", 78*346d7152Ssoda /*32 */ "add", "addu", "sub", "subu", "and", "or", "xor", "nor", 79*346d7152Ssoda /*40 */ "spec50","spec51","slt","sltu", "dadd","daddu","dsub","dsubu", 80*346d7152Ssoda /*48 */ "tge","tgeu","tlt","tltu","teq","spec65","tne","spec67", 81*346d7152Ssoda /*56 */ "dsll","spec71","dsrl","dsra","dsll32","spec75","dsrl32","dsra32" 82*346d7152Ssoda }; 83*346d7152Ssoda 84*346d7152Ssoda static char *bcond_name[32] = { 85*346d7152Ssoda /* 0 */ "bltz", "bgez", "bltzl", "bgezl", "?", "?", "?", "?", 86*346d7152Ssoda /* 8 */ "tgei", "tgeiu", "tlti", "tltiu", "teqi", "?", "tnei", "?", 87*346d7152Ssoda /*16 */ "bltzal", "bgezal", "bltzall", "bgezall", "?", "?", "?", "?", 88*346d7152Ssoda /*24 */ "?", "?", "?", "?", "?", "?", "?", "?", 89*346d7152Ssoda }; 90*346d7152Ssoda 91*346d7152Ssoda static char *cop1_name[64] = { 92*346d7152Ssoda /* 0 */ "fadd", "fsub", "fmpy", "fdiv", "fsqrt","fabs", "fmov", "fneg", 93*346d7152Ssoda /* 8 */ "fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f", 94*346d7152Ssoda /*16 */ "fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17", 95*346d7152Ssoda /*24 */ "fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f", 96*346d7152Ssoda /*32 */ "fcvts","fcvtd","fcvte","fop23","fcvtw","fop25","fop26","fop27", 97*346d7152Ssoda /*40 */ "fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f", 98*346d7152Ssoda /*48 */ "fcmp.f","fcmp.un","fcmp.eq","fcmp.ueq","fcmp.olt","fcmp.ult", 99*346d7152Ssoda "fcmp.ole","fcmp.ule", 100*346d7152Ssoda /*56 */ "fcmp.sf","fcmp.ngle","fcmp.seq","fcmp.ngl","fcmp.lt","fcmp.nge", 101*346d7152Ssoda "fcmp.le","fcmp.ngt" 102*346d7152Ssoda }; 103*346d7152Ssoda 104*346d7152Ssoda static char *fmt_name[16] = { 105*346d7152Ssoda "s", "d", "e", "fmt3", 106*346d7152Ssoda "w", "fmt5", "fmt6", "fmt7", 107*346d7152Ssoda "fmt8", "fmt9", "fmta", "fmtb", 108*346d7152Ssoda "fmtc", "fmtd", "fmte", "fmtf" 109*346d7152Ssoda }; 110*346d7152Ssoda 111*346d7152Ssoda static char *reg_name[32] = { 112*346d7152Ssoda "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 113*346d7152Ssoda "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 114*346d7152Ssoda "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 115*346d7152Ssoda "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" 116*346d7152Ssoda }; 117*346d7152Ssoda 118*346d7152Ssoda static char *c0_opname[64] = { 119*346d7152Ssoda "c0op00","tlbr", "tlbwi", "c0op03","c0op04","c0op05","tlbwr", "c0op07", 120*346d7152Ssoda "tlbp", "c0op11","c0op12","c0op13","c0op14","c0op15","c0op16","c0op17", 121*346d7152Ssoda "rfe", "c0op21","c0op22","c0op23","c0op24","c0op25","c0op26","c0op27", 122*346d7152Ssoda "eret","c0op31","c0op32","c0op33","c0op34","c0op35","c0op36","c0op37", 123*346d7152Ssoda "c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47", 124*346d7152Ssoda "c0op50","c0op51","c0op52","c0op53","c0op54","c0op55","c0op56","c0op57", 125*346d7152Ssoda "c0op60","c0op61","c0op62","c0op63","c0op64","c0op65","c0op66","c0op67", 126*346d7152Ssoda "c0op70","c0op71","c0op72","c0op73","c0op74","c0op75","c0op77","c0op77", 127*346d7152Ssoda }; 128*346d7152Ssoda 129*346d7152Ssoda static char *c0_reg[32] = { 130*346d7152Ssoda "index","random","tlblo0","tlblo1","context","tlbmask","wired","c0r7", 131*346d7152Ssoda "badvaddr","count","tlbhi","c0r11","sr","cause","epc", "prid", 132*346d7152Ssoda "config","lladr","watchlo","watchhi","xcontext","c0r21","c0r22","c0r23", 133*346d7152Ssoda "c0r24","c0r25","ecc","cacheerr","taglo","taghi","errepc","c0r31" 134*346d7152Ssoda }; 135*346d7152Ssoda 136*346d7152Ssoda extern char *trap_type[]; 137*346d7152Ssoda 138*346d7152Ssoda struct pcb mdbpcb; 139*346d7152Ssoda int mdbmkfault; 140*346d7152Ssoda 141*346d7152Ssoda #define MAXBRK 10 142*346d7152Ssoda struct brk { 143*346d7152Ssoda int inst; 144*346d7152Ssoda int addr; 145*346d7152Ssoda } brk_tab[MAXBRK]; 146*346d7152Ssoda 147*346d7152Ssoda /* 148*346d7152Ssoda * Mini debugger for kernel. 149*346d7152Ssoda */ 150*346d7152Ssoda int gethex(u_int *val, u_int dotval) 151*346d7152Ssoda { 152*346d7152Ssoda u_int c; 153*346d7152Ssoda 154*346d7152Ssoda *val = 0; 155*346d7152Ssoda while((c = cngetc()) != '\e' && c != '\n') { 156*346d7152Ssoda if(c >= '0' && c <= '9') { 157*346d7152Ssoda *val = (*val << 4) + c - '0'; 158*346d7152Ssoda cnputc(c); 159*346d7152Ssoda } 160*346d7152Ssoda else if(c >= 'a' && c <= 'f') { 161*346d7152Ssoda *val = (*val << 4) + c - 'a' + 10; 162*346d7152Ssoda cnputc(c); 163*346d7152Ssoda } 164*346d7152Ssoda else if(c == '\b') { 165*346d7152Ssoda *val = *val >> 4; 166*346d7152Ssoda printf("\b \b"); 167*346d7152Ssoda } 168*346d7152Ssoda else if(c == ',') { 169*346d7152Ssoda cnputc(c); 170*346d7152Ssoda return(c); 171*346d7152Ssoda } 172*346d7152Ssoda else if(c == '.') { 173*346d7152Ssoda *val = dotval;; 174*346d7152Ssoda cnputc(c); 175*346d7152Ssoda } 176*346d7152Ssoda } 177*346d7152Ssoda return(c); 178*346d7152Ssoda } 179*346d7152Ssoda 180*346d7152Ssoda void dump(u_int *addr, u_int size) 181*346d7152Ssoda { 182*346d7152Ssoda int cnt; 183*346d7152Ssoda 184*346d7152Ssoda cnt = 0; 185*346d7152Ssoda 186*346d7152Ssoda size = (size + 3) / 4; 187*346d7152Ssoda while(size--) { 188*346d7152Ssoda if((cnt++ & 3) == 0) 189*346d7152Ssoda printf("\n%08x: ",(int)addr); 190*346d7152Ssoda printf("%08x ",*addr++); 191*346d7152Ssoda } 192*346d7152Ssoda } 193*346d7152Ssoda 194*346d7152Ssoda void print_regs() 195*346d7152Ssoda { 196*346d7152Ssoda printf("\n"); 197*346d7152Ssoda printf("T0-7 %08x %08x %08x %08x %08x %08x %08x %08x\n", 198*346d7152Ssoda mdbpcb.pcb_regs[T0],mdbpcb.pcb_regs[T1], 199*346d7152Ssoda mdbpcb.pcb_regs[T2],mdbpcb.pcb_regs[T3], 200*346d7152Ssoda mdbpcb.pcb_regs[T4],mdbpcb.pcb_regs[T5], 201*346d7152Ssoda mdbpcb.pcb_regs[T6],mdbpcb.pcb_regs[T7]); 202*346d7152Ssoda printf("T8-9 %08x %08x A0-4 %08x %08x %08x %08x\n", 203*346d7152Ssoda mdbpcb.pcb_regs[T8],mdbpcb.pcb_regs[T9], 204*346d7152Ssoda mdbpcb.pcb_regs[A0],mdbpcb.pcb_regs[A1], 205*346d7152Ssoda mdbpcb.pcb_regs[A2],mdbpcb.pcb_regs[A3]); 206*346d7152Ssoda printf("S0-7 %08x %08x %08x %08x %08x %08x %08x %08x\n", 207*346d7152Ssoda mdbpcb.pcb_regs[S0],mdbpcb.pcb_regs[S1], 208*346d7152Ssoda mdbpcb.pcb_regs[S2],mdbpcb.pcb_regs[S3], 209*346d7152Ssoda mdbpcb.pcb_regs[S4],mdbpcb.pcb_regs[S5], 210*346d7152Ssoda mdbpcb.pcb_regs[S6],mdbpcb.pcb_regs[S7]); 211*346d7152Ssoda printf(" S8 %08x V0-1 %08x %08x GP %08x SP %08x\n", 212*346d7152Ssoda mdbpcb.pcb_regs[S8],mdbpcb.pcb_regs[V0], 213*346d7152Ssoda mdbpcb.pcb_regs[V1],mdbpcb.pcb_regs[GP], 214*346d7152Ssoda mdbpcb.pcb_regs[SP]); 215*346d7152Ssoda printf(" AT %08x PC %08x RA %08x SR %08x", 216*346d7152Ssoda mdbpcb.pcb_regs[AST],mdbpcb.pcb_regs[PC], 217*346d7152Ssoda mdbpcb.pcb_regs[RA],mdbpcb.pcb_regs[SR]); 218*346d7152Ssoda } 219*346d7152Ssoda 220*346d7152Ssoda set_break(va) 221*346d7152Ssoda { 222*346d7152Ssoda int i; 223*346d7152Ssoda 224*346d7152Ssoda va = va & ~3; 225*346d7152Ssoda for(i = 0; i < MAXBRK; i++) { 226*346d7152Ssoda if(brk_tab[i].addr == 0) { 227*346d7152Ssoda brk_tab[i].addr = va; 228*346d7152Ssoda brk_tab[i].inst = *(u_int *)va; 229*346d7152Ssoda return; 230*346d7152Ssoda } 231*346d7152Ssoda } 232*346d7152Ssoda printf(" Break table full!!"); 233*346d7152Ssoda } 234*346d7152Ssoda 235*346d7152Ssoda del_break(va) 236*346d7152Ssoda { 237*346d7152Ssoda int i; 238*346d7152Ssoda 239*346d7152Ssoda va = va & ~3; 240*346d7152Ssoda for(i = 0; i < MAXBRK; i++) { 241*346d7152Ssoda if(brk_tab[i].addr == va) { 242*346d7152Ssoda brk_tab[i].addr = 0; 243*346d7152Ssoda return; 244*346d7152Ssoda } 245*346d7152Ssoda } 246*346d7152Ssoda printf(" Break to remove not found!!"); 247*346d7152Ssoda } 248*346d7152Ssoda 249*346d7152Ssoda break_insert() 250*346d7152Ssoda { 251*346d7152Ssoda int i; 252*346d7152Ssoda 253*346d7152Ssoda for(i = 0; i < MAXBRK; i++) { 254*346d7152Ssoda if(brk_tab[i].addr != 0) { 255*346d7152Ssoda brk_tab[i].inst = *(u_int *)brk_tab[i].addr; 256*346d7152Ssoda *(u_int *)brk_tab[i].addr = MIPS_BREAK_BRKPT; 257*346d7152Ssoda MachFlushDCache(brk_tab[i].addr,4); 258*346d7152Ssoda MachFlushICache(brk_tab[i].addr,4); 259*346d7152Ssoda } 260*346d7152Ssoda } 261*346d7152Ssoda } 262*346d7152Ssoda 263*346d7152Ssoda break_restore() 264*346d7152Ssoda { 265*346d7152Ssoda int i; 266*346d7152Ssoda 267*346d7152Ssoda for(i = 0; i < MAXBRK; i++) { 268*346d7152Ssoda if(brk_tab[i].addr != 0) { 269*346d7152Ssoda *(u_int *)brk_tab[i].addr = brk_tab[i].inst; 270*346d7152Ssoda MachFlushDCache(brk_tab[i].addr,4); 271*346d7152Ssoda MachFlushICache(brk_tab[i].addr,4); 272*346d7152Ssoda } 273*346d7152Ssoda } 274*346d7152Ssoda } 275*346d7152Ssoda 276*346d7152Ssoda break_find(va) 277*346d7152Ssoda { 278*346d7152Ssoda int i; 279*346d7152Ssoda 280*346d7152Ssoda for(i = 0; i < MAXBRK; i++) { 281*346d7152Ssoda if(brk_tab[i].addr == va) { 282*346d7152Ssoda return(i); 283*346d7152Ssoda } 284*346d7152Ssoda } 285*346d7152Ssoda return(-1); 286*346d7152Ssoda } 287*346d7152Ssoda 288*346d7152Ssoda prt_break() 289*346d7152Ssoda { 290*346d7152Ssoda int i; 291*346d7152Ssoda 292*346d7152Ssoda for(i = 0; i < MAXBRK; i++) { 293*346d7152Ssoda if(brk_tab[i].addr != 0) { 294*346d7152Ssoda printf("\n %08x\t", brk_tab[i].addr); 295*346d7152Ssoda mdbprintins(brk_tab[i].inst, brk_tab[i].addr); 296*346d7152Ssoda } 297*346d7152Ssoda } 298*346d7152Ssoda } 299*346d7152Ssoda mdb(causeReg, vadr, p, kernelmode) 300*346d7152Ssoda { 301*346d7152Ssoda int c; 302*346d7152Ssoda int newaddr; 303*346d7152Ssoda int size; 304*346d7152Ssoda int cause; 305*346d7152Ssoda static int ssandrun; /* Single step and run flag (when cont at brk) */ 306*346d7152Ssoda 307*346d7152Ssoda splhigh(); 308*346d7152Ssoda cause = (causeReg & MIPS_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT; 309*346d7152Ssoda newaddr = (int)(mdbpcb.pcb_regs[PC]); 310*346d7152Ssoda switch(cause) { 311*346d7152Ssoda case T_BREAK: 312*346d7152Ssoda if(*(int *)newaddr == MIPS_BREAK_SOVER) { 313*346d7152Ssoda break_restore(); 314*346d7152Ssoda mdbpcb.pcb_regs[PC] += 4; 315*346d7152Ssoda printf("\nStop break (panic)\n# "); 316*346d7152Ssoda printf(" %08x\t",newaddr); 317*346d7152Ssoda mdbprintins(*(int *)newaddr, newaddr); 318*346d7152Ssoda printf("\n# "); 319*346d7152Ssoda break; 320*346d7152Ssoda } 321*346d7152Ssoda if(*(int *)newaddr == MIPS_BREAK_BRKPT) { 322*346d7152Ssoda break_restore(); 323*346d7152Ssoda printf("\rBRK %08x\t",newaddr); 324*346d7152Ssoda if(mdbprintins(*(int *)newaddr, newaddr)) { 325*346d7152Ssoda newaddr += 4; 326*346d7152Ssoda printf("\n %08x\t",newaddr); 327*346d7152Ssoda mdbprintins(*(int *)newaddr, newaddr); 328*346d7152Ssoda } 329*346d7152Ssoda printf("\n# "); 330*346d7152Ssoda break; 331*346d7152Ssoda } 332*346d7152Ssoda if(mdbclrsstep(causeReg)) { 333*346d7152Ssoda if(ssandrun) { /* Step over bp before free run */ 334*346d7152Ssoda ssandrun = 0; 335*346d7152Ssoda break_insert(); 336*346d7152Ssoda return(TRUE); 337*346d7152Ssoda } 338*346d7152Ssoda printf("\r %08x\t",newaddr); 339*346d7152Ssoda if(mdbprintins(*(int *)newaddr, newaddr)) { 340*346d7152Ssoda newaddr += 4; 341*346d7152Ssoda printf("\n %08x\t",newaddr); 342*346d7152Ssoda mdbprintins(*(int *)newaddr, newaddr); 343*346d7152Ssoda } 344*346d7152Ssoda printf("\n# "); 345*346d7152Ssoda } 346*346d7152Ssoda break; 347*346d7152Ssoda 348*346d7152Ssoda default: 349*346d7152Ssoda printf("\n-- %s --\n# ",trap_type[cause]); 350*346d7152Ssoda } 351*346d7152Ssoda ssandrun = 0; 352*346d7152Ssoda break_restore(); 353*346d7152Ssoda 354*346d7152Ssoda while(c = cngetc()) { 355*346d7152Ssoda switch(c) { 356*346d7152Ssoda case 'T': 357*346d7152Ssoda trapDump("Debugger"); 358*346d7152Ssoda break; 359*346d7152Ssoda case 'b': 360*346d7152Ssoda printf("break-"); 361*346d7152Ssoda c = cngetc(); 362*346d7152Ssoda switch(c) { 363*346d7152Ssoda case 's': 364*346d7152Ssoda printf("set at "); 365*346d7152Ssoda c = gethex(&newaddr, newaddr); 366*346d7152Ssoda if(c != '\e') { 367*346d7152Ssoda set_break(newaddr); 368*346d7152Ssoda } 369*346d7152Ssoda break; 370*346d7152Ssoda 371*346d7152Ssoda case 'd': 372*346d7152Ssoda printf("delete at "); 373*346d7152Ssoda c = gethex(&newaddr, newaddr); 374*346d7152Ssoda if(c != '\e') { 375*346d7152Ssoda del_break(newaddr); 376*346d7152Ssoda } 377*346d7152Ssoda break; 378*346d7152Ssoda 379*346d7152Ssoda case 'p': 380*346d7152Ssoda printf("print"); 381*346d7152Ssoda prt_break(); 382*346d7152Ssoda break; 383*346d7152Ssoda } 384*346d7152Ssoda break; 385*346d7152Ssoda 386*346d7152Ssoda case 'r': 387*346d7152Ssoda print_regs(); 388*346d7152Ssoda break; 389*346d7152Ssoda 390*346d7152Ssoda case 'I': 391*346d7152Ssoda printf("Instruction at "); 392*346d7152Ssoda c = gethex(&newaddr, newaddr); 393*346d7152Ssoda while(c != '\e') { 394*346d7152Ssoda printf("\n %08x\t",newaddr); 395*346d7152Ssoda mdbprintins(*(int *)newaddr, newaddr); 396*346d7152Ssoda newaddr += 4; 397*346d7152Ssoda c = cngetc(); 398*346d7152Ssoda } 399*346d7152Ssoda break; 400*346d7152Ssoda 401*346d7152Ssoda case 'c': 402*346d7152Ssoda printf("continue"); 403*346d7152Ssoda if(break_find((int)(mdbpcb.pcb_regs[PC])) >= 0) { 404*346d7152Ssoda ssandrun = 1; 405*346d7152Ssoda mdbsetsstep(); 406*346d7152Ssoda } 407*346d7152Ssoda else { 408*346d7152Ssoda break_insert(); 409*346d7152Ssoda } 410*346d7152Ssoda return(TRUE); 411*346d7152Ssoda 412*346d7152Ssoda case 's': 413*346d7152Ssoda set_break(mdbpcb.pcb_regs[PC] + 8); 414*346d7152Ssoda return(TRUE); 415*346d7152Ssoda case ' ': 416*346d7152Ssoda mdbsetsstep(); 417*346d7152Ssoda return(TRUE); 418*346d7152Ssoda 419*346d7152Ssoda case 'd': 420*346d7152Ssoda printf("dump "); 421*346d7152Ssoda c = gethex(&newaddr, newaddr); 422*346d7152Ssoda if(c == ',') { 423*346d7152Ssoda c = gethex(&size,256); 424*346d7152Ssoda } 425*346d7152Ssoda else { 426*346d7152Ssoda size = 16; 427*346d7152Ssoda } 428*346d7152Ssoda if(c == '\n' && newaddr != 0) { 429*346d7152Ssoda dump((u_int *)newaddr, size); 430*346d7152Ssoda newaddr += size; 431*346d7152Ssoda } 432*346d7152Ssoda break; 433*346d7152Ssoda 434*346d7152Ssoda case 'm': 435*346d7152Ssoda printf("mod "); 436*346d7152Ssoda c = gethex(&newaddr, newaddr); 437*346d7152Ssoda while(c == ',') { 438*346d7152Ssoda c = gethex(&size, 0); 439*346d7152Ssoda if(c != '\e') 440*346d7152Ssoda *((u_int *)newaddr)++ = size; 441*346d7152Ssoda } 442*346d7152Ssoda break; 443*346d7152Ssoda 444*346d7152Ssoda case 'i': 445*346d7152Ssoda printf("in-"); 446*346d7152Ssoda c = cngetc(); 447*346d7152Ssoda switch(c) { 448*346d7152Ssoda case 'b': 449*346d7152Ssoda printf("byte "); 450*346d7152Ssoda c = gethex(&newaddr, newaddr); 451*346d7152Ssoda if(c == '\n') { 452*346d7152Ssoda printf("= %02x", 453*346d7152Ssoda *(u_char *)newaddr); 454*346d7152Ssoda } 455*346d7152Ssoda break; 456*346d7152Ssoda case 'h': 457*346d7152Ssoda printf("halfword "); 458*346d7152Ssoda c = gethex(&newaddr, newaddr); 459*346d7152Ssoda if(c == '\n') { 460*346d7152Ssoda printf("= %04x", 461*346d7152Ssoda *(u_short *)newaddr); 462*346d7152Ssoda } 463*346d7152Ssoda break; 464*346d7152Ssoda case 'w': 465*346d7152Ssoda printf("word "); 466*346d7152Ssoda c = gethex(&newaddr, newaddr); 467*346d7152Ssoda if(c == '\n') { 468*346d7152Ssoda printf("= %08x", 469*346d7152Ssoda *(u_int *)newaddr); 470*346d7152Ssoda } 471*346d7152Ssoda break; 472*346d7152Ssoda } 473*346d7152Ssoda break; 474*346d7152Ssoda 475*346d7152Ssoda case 'o': 476*346d7152Ssoda printf("out-"); 477*346d7152Ssoda c = cngetc(); 478*346d7152Ssoda switch(c) { 479*346d7152Ssoda case 'b': 480*346d7152Ssoda printf("byte "); 481*346d7152Ssoda c = gethex(&newaddr, newaddr); 482*346d7152Ssoda if(c == ',') { 483*346d7152Ssoda c = gethex(&size, 0); 484*346d7152Ssoda if(c == '\n') { 485*346d7152Ssoda *(u_char *)newaddr = size; 486*346d7152Ssoda } 487*346d7152Ssoda } 488*346d7152Ssoda break; 489*346d7152Ssoda case 'h': 490*346d7152Ssoda printf("halfword "); 491*346d7152Ssoda c = gethex(&newaddr, newaddr); 492*346d7152Ssoda if(c == ',') { 493*346d7152Ssoda c = gethex(&size, 0); 494*346d7152Ssoda if(c == '\n') { 495*346d7152Ssoda *(u_short *)newaddr = size; 496*346d7152Ssoda } 497*346d7152Ssoda } 498*346d7152Ssoda break; 499*346d7152Ssoda case 'w': 500*346d7152Ssoda printf("word "); 501*346d7152Ssoda c = gethex(&newaddr, newaddr); 502*346d7152Ssoda if(c == ',') { 503*346d7152Ssoda c = gethex(&size, 0); 504*346d7152Ssoda if(c == '\n') { 505*346d7152Ssoda *(u_int *)newaddr = size; 506*346d7152Ssoda } 507*346d7152Ssoda } 508*346d7152Ssoda break; 509*346d7152Ssoda } 510*346d7152Ssoda break; 511*346d7152Ssoda 512*346d7152Ssoda case 't': 513*346d7152Ssoda printf("tlb-dump\n"); 514*346d7152Ssoda pica_dump_tlb(0,23); 515*346d7152Ssoda (void)cngetc(); 516*346d7152Ssoda pica_dump_tlb(24,47); 517*346d7152Ssoda break; 518*346d7152Ssoda 519*346d7152Ssoda case 'f': 520*346d7152Ssoda printf("flush-"); 521*346d7152Ssoda c = cngetc(); 522*346d7152Ssoda switch(c) { 523*346d7152Ssoda case 't': 524*346d7152Ssoda printf("tlb"); 525*346d7152Ssoda MachTLBFlush(); 526*346d7152Ssoda break; 527*346d7152Ssoda 528*346d7152Ssoda case 'c': 529*346d7152Ssoda printf("cache"); 530*346d7152Ssoda MachFlushCache(); 531*346d7152Ssoda break; 532*346d7152Ssoda } 533*346d7152Ssoda break; 534*346d7152Ssoda 535*346d7152Ssoda default: 536*346d7152Ssoda cnputc('\a'); 537*346d7152Ssoda break; 538*346d7152Ssoda } 539*346d7152Ssoda printf("\n# "); 540*346d7152Ssoda } 541*346d7152Ssoda } 542*346d7152Ssoda 543*346d7152Ssoda u_int mdb_ss_addr; 544*346d7152Ssoda u_int mdb_ss_instr; 545*346d7152Ssoda 546*346d7152Ssoda mdbsetsstep() 547*346d7152Ssoda { 548*346d7152Ssoda register u_int va; 549*346d7152Ssoda register int *locr0 = mdbpcb.pcb_regs; 550*346d7152Ssoda int i; 551*346d7152Ssoda 552*346d7152Ssoda /* compute next address after current location */ 553*346d7152Ssoda if(mdbpeek(locr0[PC]) != 0) { 554*346d7152Ssoda va = MachEmulateBranch(locr0, locr0[PC], 0, mdbpeek(locr0[PC])); 555*346d7152Ssoda } 556*346d7152Ssoda else { 557*346d7152Ssoda va = locr0[PC] + 4; 558*346d7152Ssoda } 559*346d7152Ssoda if (mdb_ss_addr) { 560*346d7152Ssoda printf("mdbsetsstep: breakpoint already set at %x (va %x)\n", 561*346d7152Ssoda mdb_ss_addr, va); 562*346d7152Ssoda return; 563*346d7152Ssoda } 564*346d7152Ssoda mdb_ss_addr = va; 565*346d7152Ssoda 566*346d7152Ssoda if ((int)va < 0) { 567*346d7152Ssoda /* kernel address */ 568*346d7152Ssoda mdb_ss_instr = mdbpeek(va); 569*346d7152Ssoda mdbpoke((caddr_t)va, MIPS_BREAK_SSTEP); 570*346d7152Ssoda MachFlushDCache(va,4); 571*346d7152Ssoda MachFlushICache(va,4); 572*346d7152Ssoda return; 573*346d7152Ssoda } 574*346d7152Ssoda } 575*346d7152Ssoda 576*346d7152Ssoda mdbclrsstep(cr) 577*346d7152Ssoda int cr; 578*346d7152Ssoda { 579*346d7152Ssoda register u_int pc, va; 580*346d7152Ssoda u_int instr; 581*346d7152Ssoda 582*346d7152Ssoda /* fix pc if break instruction is in the delay slot */ 583*346d7152Ssoda pc = mdbpcb.pcb_regs[PC]; 584*346d7152Ssoda if (cr < 0) 585*346d7152Ssoda pc += 4; 586*346d7152Ssoda 587*346d7152Ssoda /* check to be sure its the one we are expecting */ 588*346d7152Ssoda va = mdb_ss_addr; 589*346d7152Ssoda if (!va || va != pc) 590*346d7152Ssoda return(FALSE); 591*346d7152Ssoda 592*346d7152Ssoda /* read break instruction */ 593*346d7152Ssoda instr = mdbpeek(va); 594*346d7152Ssoda if (instr != MIPS_BREAK_SSTEP) 595*346d7152Ssoda return(FALSE); 596*346d7152Ssoda 597*346d7152Ssoda if ((int)va < 0) { 598*346d7152Ssoda /* kernel address */ 599*346d7152Ssoda mdbpoke((caddr_t)va, mdb_ss_instr); 600*346d7152Ssoda MachFlushDCache(va,4); 601*346d7152Ssoda MachFlushICache(va,4); 602*346d7152Ssoda mdb_ss_addr = 0; 603*346d7152Ssoda return(TRUE); 604*346d7152Ssoda } 605*346d7152Ssoda 606*346d7152Ssoda printf("can't clear break at %x\n", va); 607*346d7152Ssoda mdb_ss_addr = 0; 608*346d7152Ssoda return(FALSE); 609*346d7152Ssoda } 610*346d7152Ssoda 611*346d7152Ssoda void 612*346d7152Ssoda mdbreadc(lp) 613*346d7152Ssoda char *lp; 614*346d7152Ssoda { 615*346d7152Ssoda int c; 616*346d7152Ssoda 617*346d7152Ssoda c = cngetc(); 618*346d7152Ssoda if (c == '\r') 619*346d7152Ssoda c = '\n'; 620*346d7152Ssoda *lp = c; 621*346d7152Ssoda } 622*346d7152Ssoda 623*346d7152Ssoda void 624*346d7152Ssoda mdbwrite(lp, len) 625*346d7152Ssoda char *lp; 626*346d7152Ssoda int len; 627*346d7152Ssoda { 628*346d7152Ssoda while (len-- > 0) 629*346d7152Ssoda cnputc(*lp++); 630*346d7152Ssoda } 631*346d7152Ssoda 632*346d7152Ssoda /* ARGSUSED */ 633*346d7152Ssoda mdbprintins(ins, mdbdot) 634*346d7152Ssoda { 635*346d7152Ssoda InstFmt i; 636*346d7152Ssoda int delay = 0; 637*346d7152Ssoda 638*346d7152Ssoda i.word = ins; 639*346d7152Ssoda 640*346d7152Ssoda switch (i.JType.op) { 641*346d7152Ssoda case OP_SPECIAL: 642*346d7152Ssoda if (i.word == 0) { 643*346d7152Ssoda printf("nop"); 644*346d7152Ssoda break; 645*346d7152Ssoda } 646*346d7152Ssoda if (i.RType.func == OP_ADDU && i.RType.rt == 0) { 647*346d7152Ssoda printf("move\t%s,%s", 648*346d7152Ssoda reg_name[i.RType.rd], 649*346d7152Ssoda reg_name[i.RType.rs]); 650*346d7152Ssoda break; 651*346d7152Ssoda } 652*346d7152Ssoda printf("%s", spec_name[i.RType.func]); 653*346d7152Ssoda switch (i.RType.func) { 654*346d7152Ssoda case OP_SLL: 655*346d7152Ssoda case OP_SRL: 656*346d7152Ssoda case OP_SRA: 657*346d7152Ssoda case OP_DSLL: 658*346d7152Ssoda case OP_DSRL: 659*346d7152Ssoda case OP_DSRA: 660*346d7152Ssoda case OP_DSLL32: 661*346d7152Ssoda case OP_DSRL32: 662*346d7152Ssoda case OP_DSRA32: 663*346d7152Ssoda printf("\t%s,%s,%d", 664*346d7152Ssoda reg_name[i.RType.rd], 665*346d7152Ssoda reg_name[i.RType.rt], 666*346d7152Ssoda i.RType.shamt); 667*346d7152Ssoda break; 668*346d7152Ssoda 669*346d7152Ssoda case OP_SLLV: 670*346d7152Ssoda case OP_SRLV: 671*346d7152Ssoda case OP_SRAV: 672*346d7152Ssoda case OP_DSLLV: 673*346d7152Ssoda case OP_DSRLV: 674*346d7152Ssoda case OP_DSRAV: 675*346d7152Ssoda printf("\t%s,%s,%s", 676*346d7152Ssoda reg_name[i.RType.rd], 677*346d7152Ssoda reg_name[i.RType.rt], 678*346d7152Ssoda reg_name[i.RType.rs]); 679*346d7152Ssoda break; 680*346d7152Ssoda 681*346d7152Ssoda case OP_MFHI: 682*346d7152Ssoda case OP_MFLO: 683*346d7152Ssoda printf("\t%s", reg_name[i.RType.rd]); 684*346d7152Ssoda break; 685*346d7152Ssoda 686*346d7152Ssoda case OP_JR: 687*346d7152Ssoda case OP_JALR: 688*346d7152Ssoda delay = 1; 689*346d7152Ssoda /* FALLTHROUGH */ 690*346d7152Ssoda case OP_MTLO: 691*346d7152Ssoda case OP_MTHI: 692*346d7152Ssoda printf("\t%s", reg_name[i.RType.rs]); 693*346d7152Ssoda break; 694*346d7152Ssoda 695*346d7152Ssoda case OP_MULT: 696*346d7152Ssoda case OP_MULTU: 697*346d7152Ssoda case OP_DMULT: 698*346d7152Ssoda case OP_DMULTU: 699*346d7152Ssoda case OP_DIV: 700*346d7152Ssoda case OP_DIVU: 701*346d7152Ssoda case OP_DDIV: 702*346d7152Ssoda case OP_DDIVU: 703*346d7152Ssoda printf("\t%s,%s", 704*346d7152Ssoda reg_name[i.RType.rs], 705*346d7152Ssoda reg_name[i.RType.rt]); 706*346d7152Ssoda break; 707*346d7152Ssoda 708*346d7152Ssoda case OP_SYSCALL: 709*346d7152Ssoda case OP_SYNC: 710*346d7152Ssoda break; 711*346d7152Ssoda 712*346d7152Ssoda case OP_BREAK: 713*346d7152Ssoda printf("\t%d", (i.RType.rs << 5) | i.RType.rt); 714*346d7152Ssoda break; 715*346d7152Ssoda 716*346d7152Ssoda default: 717*346d7152Ssoda printf("\t%s,%s,%s", 718*346d7152Ssoda reg_name[i.RType.rd], 719*346d7152Ssoda reg_name[i.RType.rs], 720*346d7152Ssoda reg_name[i.RType.rt]); 721*346d7152Ssoda }; 722*346d7152Ssoda break; 723*346d7152Ssoda 724*346d7152Ssoda case OP_BCOND: 725*346d7152Ssoda printf("%s\t%s,", bcond_name[i.IType.rt], 726*346d7152Ssoda reg_name[i.IType.rs]); 727*346d7152Ssoda goto pr_displ; 728*346d7152Ssoda 729*346d7152Ssoda case OP_BLEZ: 730*346d7152Ssoda case OP_BLEZL: 731*346d7152Ssoda case OP_BGTZ: 732*346d7152Ssoda case OP_BGTZL: 733*346d7152Ssoda printf("%s\t%s,", op_name[i.IType.op], 734*346d7152Ssoda reg_name[i.IType.rs]); 735*346d7152Ssoda goto pr_displ; 736*346d7152Ssoda 737*346d7152Ssoda case OP_BEQ: 738*346d7152Ssoda case OP_BEQL: 739*346d7152Ssoda if (i.IType.rs == 0 && i.IType.rt == 0) { 740*346d7152Ssoda printf("b\t"); 741*346d7152Ssoda goto pr_displ; 742*346d7152Ssoda } 743*346d7152Ssoda /* FALLTHROUGH */ 744*346d7152Ssoda case OP_BNE: 745*346d7152Ssoda case OP_BNEL: 746*346d7152Ssoda printf("%s\t%s,%s,", op_name[i.IType.op], 747*346d7152Ssoda reg_name[i.IType.rs], 748*346d7152Ssoda reg_name[i.IType.rt]); 749*346d7152Ssoda pr_displ: 750*346d7152Ssoda delay = 1; 751*346d7152Ssoda printf("0x%08x", mdbdot + 4 + ((short)i.IType.imm << 2)); 752*346d7152Ssoda break; 753*346d7152Ssoda 754*346d7152Ssoda case OP_COP0: 755*346d7152Ssoda switch (i.RType.rs) { 756*346d7152Ssoda case OP_BCx: 757*346d7152Ssoda case OP_BCy: 758*346d7152Ssoda printf("bc0%c\t", 759*346d7152Ssoda "ft"[i.RType.rt & COPz_BC_TF_MASK]); 760*346d7152Ssoda goto pr_displ; 761*346d7152Ssoda 762*346d7152Ssoda case OP_MT: 763*346d7152Ssoda printf("mtc0\t%s,%s", 764*346d7152Ssoda reg_name[i.RType.rt], 765*346d7152Ssoda c0_reg[i.RType.rd]); 766*346d7152Ssoda break; 767*346d7152Ssoda 768*346d7152Ssoda case OP_DMT: 769*346d7152Ssoda printf("dmtc0\t%s,%s", 770*346d7152Ssoda reg_name[i.RType.rt], 771*346d7152Ssoda c0_reg[i.RType.rd]); 772*346d7152Ssoda break; 773*346d7152Ssoda 774*346d7152Ssoda case OP_MF: 775*346d7152Ssoda printf("mfc0\t%s,%s", 776*346d7152Ssoda reg_name[i.RType.rt], 777*346d7152Ssoda c0_reg[i.RType.rd]); 778*346d7152Ssoda break; 779*346d7152Ssoda 780*346d7152Ssoda case OP_DMF: 781*346d7152Ssoda printf("dmfc0\t%s,%s", 782*346d7152Ssoda reg_name[i.RType.rt], 783*346d7152Ssoda c0_reg[i.RType.rd]); 784*346d7152Ssoda break; 785*346d7152Ssoda 786*346d7152Ssoda default: 787*346d7152Ssoda printf("%s", c0_opname[i.FRType.func]); 788*346d7152Ssoda }; 789*346d7152Ssoda break; 790*346d7152Ssoda 791*346d7152Ssoda case OP_COP1: 792*346d7152Ssoda switch (i.RType.rs) { 793*346d7152Ssoda case OP_BCx: 794*346d7152Ssoda case OP_BCy: 795*346d7152Ssoda printf("bc1%c\t", 796*346d7152Ssoda "ft"[i.RType.rt & COPz_BC_TF_MASK]); 797*346d7152Ssoda goto pr_displ; 798*346d7152Ssoda 799*346d7152Ssoda case OP_MT: 800*346d7152Ssoda printf("mtc1\t%s,f%d", 801*346d7152Ssoda reg_name[i.RType.rt], 802*346d7152Ssoda i.RType.rd); 803*346d7152Ssoda break; 804*346d7152Ssoda 805*346d7152Ssoda case OP_MF: 806*346d7152Ssoda printf("mfc1\t%s,f%d", 807*346d7152Ssoda reg_name[i.RType.rt], 808*346d7152Ssoda i.RType.rd); 809*346d7152Ssoda break; 810*346d7152Ssoda 811*346d7152Ssoda case OP_CT: 812*346d7152Ssoda printf("ctc1\t%s,f%d", 813*346d7152Ssoda reg_name[i.RType.rt], 814*346d7152Ssoda i.RType.rd); 815*346d7152Ssoda break; 816*346d7152Ssoda 817*346d7152Ssoda case OP_CF: 818*346d7152Ssoda printf("cfc1\t%s,f%d", 819*346d7152Ssoda reg_name[i.RType.rt], 820*346d7152Ssoda i.RType.rd); 821*346d7152Ssoda break; 822*346d7152Ssoda 823*346d7152Ssoda default: 824*346d7152Ssoda printf("%s.%s\tf%d,f%d,f%d", 825*346d7152Ssoda cop1_name[i.FRType.func], 826*346d7152Ssoda fmt_name[i.FRType.fmt], 827*346d7152Ssoda i.FRType.fd, i.FRType.fs, i.FRType.ft); 828*346d7152Ssoda }; 829*346d7152Ssoda break; 830*346d7152Ssoda 831*346d7152Ssoda case OP_J: 832*346d7152Ssoda case OP_JAL: 833*346d7152Ssoda printf("%s\t", op_name[i.JType.op]); 834*346d7152Ssoda printf("0x%8x",(mdbdot & 0xF0000000) | (i.JType.target << 2)); 835*346d7152Ssoda delay = 1; 836*346d7152Ssoda break; 837*346d7152Ssoda 838*346d7152Ssoda case OP_LWC1: 839*346d7152Ssoda case OP_SWC1: 840*346d7152Ssoda printf("%s\tf%d,", op_name[i.IType.op], 841*346d7152Ssoda i.IType.rt); 842*346d7152Ssoda goto loadstore; 843*346d7152Ssoda 844*346d7152Ssoda case OP_LB: 845*346d7152Ssoda case OP_LH: 846*346d7152Ssoda case OP_LW: 847*346d7152Ssoda case OP_LD: 848*346d7152Ssoda case OP_LBU: 849*346d7152Ssoda case OP_LHU: 850*346d7152Ssoda case OP_LWU: 851*346d7152Ssoda case OP_SB: 852*346d7152Ssoda case OP_SH: 853*346d7152Ssoda case OP_SW: 854*346d7152Ssoda case OP_SD: 855*346d7152Ssoda printf("%s\t%s,", op_name[i.IType.op], 856*346d7152Ssoda reg_name[i.IType.rt]); 857*346d7152Ssoda loadstore: 858*346d7152Ssoda printf("%d(%s)", (short)i.IType.imm, 859*346d7152Ssoda reg_name[i.IType.rs]); 860*346d7152Ssoda break; 861*346d7152Ssoda 862*346d7152Ssoda case OP_ORI: 863*346d7152Ssoda case OP_XORI: 864*346d7152Ssoda if (i.IType.rs == 0) { 865*346d7152Ssoda printf("li\t%s,0x%x", 866*346d7152Ssoda reg_name[i.IType.rt], 867*346d7152Ssoda i.IType.imm); 868*346d7152Ssoda break; 869*346d7152Ssoda } 870*346d7152Ssoda /* FALLTHROUGH */ 871*346d7152Ssoda case OP_ANDI: 872*346d7152Ssoda printf("%s\t%s,%s,0x%x", op_name[i.IType.op], 873*346d7152Ssoda reg_name[i.IType.rt], 874*346d7152Ssoda reg_name[i.IType.rs], 875*346d7152Ssoda i.IType.imm); 876*346d7152Ssoda break; 877*346d7152Ssoda 878*346d7152Ssoda case OP_LUI: 879*346d7152Ssoda printf("%s\t%s,0x%x", op_name[i.IType.op], 880*346d7152Ssoda reg_name[i.IType.rt], 881*346d7152Ssoda i.IType.imm); 882*346d7152Ssoda break; 883*346d7152Ssoda 884*346d7152Ssoda case OP_ADDI: 885*346d7152Ssoda case OP_DADDI: 886*346d7152Ssoda case OP_ADDIU: 887*346d7152Ssoda case OP_DADDIU: 888*346d7152Ssoda if (i.IType.rs == 0) { 889*346d7152Ssoda printf("li\t%s,%d", 890*346d7152Ssoda reg_name[i.IType.rt], 891*346d7152Ssoda (short)i.IType.imm); 892*346d7152Ssoda break; 893*346d7152Ssoda } 894*346d7152Ssoda /* FALLTHROUGH */ 895*346d7152Ssoda default: 896*346d7152Ssoda printf("%s\t%s,%s,%d", op_name[i.IType.op], 897*346d7152Ssoda reg_name[i.IType.rt], 898*346d7152Ssoda reg_name[i.IType.rs], 899*346d7152Ssoda (short)i.IType.imm); 900*346d7152Ssoda } 901*346d7152Ssoda return(delay); 902*346d7152Ssoda } 903*346d7152Ssoda 904*346d7152Ssoda #define MIPS_JR_RA 0x03e00008 /* instruction code for jr ra */ 905*346d7152Ssoda 906*346d7152Ssoda #if 0 907*346d7152Ssoda /* 908*346d7152Ssoda * Print a stack backtrace. 909*346d7152Ssoda */ 910*346d7152Ssoda void 911*346d7152Ssoda mdbstacktrace(printlocals) 912*346d7152Ssoda int printlocals; 913*346d7152Ssoda { 914*346d7152Ssoda u_int pc, sp, ra, va, subr; 915*346d7152Ssoda int a0, a1, a2, a3; 916*346d7152Ssoda u_int instr, mask; 917*346d7152Ssoda InstFmt i; 918*346d7152Ssoda int more, stksize; 919*346d7152Ssoda extern MachKernGenException(); 920*346d7152Ssoda extern MachUserGenException(); 921*346d7152Ssoda extern MachKernIntr(); 922*346d7152Ssoda extern MachUserIntr(); 923*346d7152Ssoda extern setsoftclock(); 924*346d7152Ssoda 925*346d7152Ssoda /* get initial values from the exception frame */ 926*346d7152Ssoda sp = mdbpcb.pcb_regs[SP]; 927*346d7152Ssoda pc = mdbpcb.pcb_regs[PC]; 928*346d7152Ssoda ra = mdbpcb.pcb_regs[RA]; 929*346d7152Ssoda a0 = mdbpcb.pcb_regs[A0]; 930*346d7152Ssoda a1 = mdbpcb.pcb_regs[A1]; 931*346d7152Ssoda a2 = mdbpcb.pcb_regs[A2]; 932*346d7152Ssoda a3 = mdbpcb.pcb_regs[A3]; 933*346d7152Ssoda 934*346d7152Ssoda loop: 935*346d7152Ssoda /* check for current PC in the kernel interrupt handler code */ 936*346d7152Ssoda if (pc >= (u_int)MachKernIntr && pc < (u_int)MachUserIntr) { 937*346d7152Ssoda /* NOTE: the offsets depend on the code in locore.s */ 938*346d7152Ssoda printf("interupt\n"); 939*346d7152Ssoda a0 = mdbchkget(sp + 36, DSP); 940*346d7152Ssoda a1 = mdbchkget(sp + 40, DSP); 941*346d7152Ssoda a2 = mdbchkget(sp + 44, DSP); 942*346d7152Ssoda a3 = mdbchkget(sp + 48, DSP); 943*346d7152Ssoda pc = mdbchkget(sp + 20, DSP); 944*346d7152Ssoda ra = mdbchkget(sp + 92, DSP); 945*346d7152Ssoda sp = mdbchkget(sp + 100, DSP); 946*346d7152Ssoda } 947*346d7152Ssoda 948*346d7152Ssoda /* check for current PC in the exception handler code */ 949*346d7152Ssoda if (pc >= 0x80000000 && pc < (u_int)setsoftclock) { 950*346d7152Ssoda ra = 0; 951*346d7152Ssoda subr = 0; 952*346d7152Ssoda goto done; 953*346d7152Ssoda } 954*346d7152Ssoda /* 955*346d7152Ssoda * Find the beginning of the current subroutine by scanning backwards 956*346d7152Ssoda * from the current PC for the end of the previous subroutine. 957*346d7152Ssoda */ 958*346d7152Ssoda va = pc - sizeof(int); 959*346d7152Ssoda while ((instr = mdbchkget(va, ISP)) != MIPS_JR_RA) 960*346d7152Ssoda va -= sizeof(int); 961*346d7152Ssoda va += 2 * sizeof(int); /* skip back over branch & delay slot */ 962*346d7152Ssoda /* skip over nulls which might separate .o files */ 963*346d7152Ssoda while ((instr = mdbchkget(va, ISP)) == 0) 964*346d7152Ssoda va += sizeof(int); 965*346d7152Ssoda subr = va; 966*346d7152Ssoda 967*346d7152Ssoda /* scan forwards to find stack size and any saved registers */ 968*346d7152Ssoda stksize = 0; 969*346d7152Ssoda more = 3; 970*346d7152Ssoda mask = 0; 971*346d7152Ssoda for (; more; va += sizeof(int), more = (more == 3) ? 3 : more - 1) { 972*346d7152Ssoda /* stop if hit our current position */ 973*346d7152Ssoda if (va >= pc) 974*346d7152Ssoda break; 975*346d7152Ssoda instr = mdbchkget(va, ISP); 976*346d7152Ssoda i.word = instr; 977*346d7152Ssoda switch (i.JType.op) { 978*346d7152Ssoda case OP_SPECIAL: 979*346d7152Ssoda switch (i.RType.func) { 980*346d7152Ssoda case OP_JR: 981*346d7152Ssoda case OP_JALR: 982*346d7152Ssoda more = 2; /* stop after next instruction */ 983*346d7152Ssoda break; 984*346d7152Ssoda 985*346d7152Ssoda case OP_SYSCALL: 986*346d7152Ssoda case OP_BREAK: 987*346d7152Ssoda more = 1; /* stop now */ 988*346d7152Ssoda }; 989*346d7152Ssoda break; 990*346d7152Ssoda 991*346d7152Ssoda case OP_BCOND: 992*346d7152Ssoda case OP_J: 993*346d7152Ssoda case OP_JAL: 994*346d7152Ssoda case OP_BEQ: 995*346d7152Ssoda case OP_BNE: 996*346d7152Ssoda case OP_BLEZ: 997*346d7152Ssoda case OP_BGTZ: 998*346d7152Ssoda more = 2; /* stop after next instruction */ 999*346d7152Ssoda break; 1000*346d7152Ssoda 1001*346d7152Ssoda case OP_COP0: 1002*346d7152Ssoda case OP_COP1: 1003*346d7152Ssoda case OP_COP2: 1004*346d7152Ssoda case OP_COP3: 1005*346d7152Ssoda switch (i.RType.rs) { 1006*346d7152Ssoda case OP_BCx: 1007*346d7152Ssoda case OP_BCy: 1008*346d7152Ssoda more = 2; /* stop after next instruction */ 1009*346d7152Ssoda }; 1010*346d7152Ssoda break; 1011*346d7152Ssoda 1012*346d7152Ssoda case OP_SW: 1013*346d7152Ssoda /* look for saved registers on the stack */ 1014*346d7152Ssoda if (i.IType.rs != 29) 1015*346d7152Ssoda break; 1016*346d7152Ssoda /* only restore the first one */ 1017*346d7152Ssoda if (mask & (1 << i.IType.rt)) 1018*346d7152Ssoda break; 1019*346d7152Ssoda mask |= 1 << i.IType.rt; 1020*346d7152Ssoda switch (i.IType.rt) { 1021*346d7152Ssoda case 4: /* a0 */ 1022*346d7152Ssoda a0 = mdbchkget(sp + (short)i.IType.imm, DSP); 1023*346d7152Ssoda break; 1024*346d7152Ssoda 1025*346d7152Ssoda case 5: /* a1 */ 1026*346d7152Ssoda a1 = mdbchkget(sp + (short)i.IType.imm, DSP); 1027*346d7152Ssoda break; 1028*346d7152Ssoda 1029*346d7152Ssoda case 6: /* a2 */ 1030*346d7152Ssoda a2 = mdbchkget(sp + (short)i.IType.imm, DSP); 1031*346d7152Ssoda break; 1032*346d7152Ssoda 1033*346d7152Ssoda case 7: /* a3 */ 1034*346d7152Ssoda a3 = mdbchkget(sp + (short)i.IType.imm, DSP); 1035*346d7152Ssoda break; 1036*346d7152Ssoda 1037*346d7152Ssoda case 31: /* ra */ 1038*346d7152Ssoda ra = mdbchkget(sp + (short)i.IType.imm, DSP); 1039*346d7152Ssoda } 1040*346d7152Ssoda break; 1041*346d7152Ssoda 1042*346d7152Ssoda case OP_ADDI: 1043*346d7152Ssoda case OP_ADDIU: 1044*346d7152Ssoda /* look for stack pointer adjustment */ 1045*346d7152Ssoda if (i.IType.rs != 29 && i.IType.rt != 29) 1046*346d7152Ssoda break; 1047*346d7152Ssoda stksize = (short)i.IType.imm; 1048*346d7152Ssoda } 1049*346d7152Ssoda } 1050*346d7152Ssoda 1051*346d7152Ssoda done: 1052*346d7152Ssoda printf("%x+%x ", subr, pc - subr); /* XXX */ 1053*346d7152Ssoda printf("(%x,%x,%x,%x)\n", a0, a1, a2, a3); 1054*346d7152Ssoda 1055*346d7152Ssoda if (ra) { 1056*346d7152Ssoda pc = ra; 1057*346d7152Ssoda sp -= stksize; 1058*346d7152Ssoda goto loop; 1059*346d7152Ssoda } 1060*346d7152Ssoda } 1061*346d7152Ssoda #endif 1062*346d7152Ssoda 1063*346d7152Ssoda /* 1064*346d7152Ssoda * Very simple memory allocator for mdb. 1065*346d7152Ssoda */ 1066*346d7152Ssoda char * 1067*346d7152Ssoda mdbmalloc(size) 1068*346d7152Ssoda int size; 1069*346d7152Ssoda { 1070*346d7152Ssoda static char buffer[4096]; 1071*346d7152Ssoda static char *bufp = buffer; 1072*346d7152Ssoda char *p; 1073*346d7152Ssoda 1074*346d7152Ssoda /* round size up to sizeof(int) */ 1075*346d7152Ssoda size = (size + sizeof(int) - 1) & ~(sizeof(int) - 1); 1076*346d7152Ssoda p = bufp; 1077*346d7152Ssoda bufp = p + size; 1078*346d7152Ssoda return (p); 1079*346d7152Ssoda } 1080*346d7152Ssoda 1081*346d7152Ssoda /* 1082*346d7152Ssoda * Dump TLB contents. 1083*346d7152Ssoda */ 1084*346d7152Ssoda void pica_dump_tlb(int first,int last) 1085*346d7152Ssoda { 1086*346d7152Ssoda int tlbno; 1087*346d7152Ssoda struct tlb tlb; 1088*346d7152Ssoda 1089*346d7152Ssoda tlbno = first; 1090*346d7152Ssoda 1091*346d7152Ssoda while(tlbno <= last) { 1092*346d7152Ssoda MachTLBRead(tlbno, &tlb); 1093*346d7152Ssoda if(tlb.tlb_lo0 & PG_V || tlb.tlb_lo1 & PG_V) { 1094*346d7152Ssoda printf("TLB %2d vad 0x%08x ", tlbno, tlb.tlb_hi); 1095*346d7152Ssoda } 1096*346d7152Ssoda else { 1097*346d7152Ssoda printf("TLB*%2d vad 0x%08x ", tlbno, tlb.tlb_hi); 1098*346d7152Ssoda } 1099*346d7152Ssoda printf("0=0x%08x ", pfn_to_vad(tlb.tlb_lo0)); 1100*346d7152Ssoda printf("%c", tlb.tlb_lo0 & PG_M ? 'M' : ' '); 1101*346d7152Ssoda printf("%c", tlb.tlb_lo0 & PG_G ? 'G' : ' '); 1102*346d7152Ssoda printf(" atr %x ", (tlb.tlb_lo0 >> 3) & 7); 1103*346d7152Ssoda printf("1=0x%08x ", pfn_to_vad(tlb.tlb_lo1)); 1104*346d7152Ssoda printf("%c", tlb.tlb_lo1 & PG_M ? 'M' : ' '); 1105*346d7152Ssoda printf("%c", tlb.tlb_lo1 & PG_G ? 'G' : ' '); 1106*346d7152Ssoda printf(" atr %x ", (tlb.tlb_lo1 >> 3) & 7); 1107*346d7152Ssoda printf(" sz=%x\n", tlb.tlb_mask); 1108*346d7152Ssoda 1109*346d7152Ssoda tlbno++; 1110*346d7152Ssoda } 1111*346d7152Ssoda } 1112