1 /*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Ralph Campbell. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)kadb.c 8.1 (Berkeley) 06/10/93 11 */ 12 13 /* 14 * Define machine dependent primitives for kdb. 15 */ 16 17 #include <kdb/defs.h> 18 #undef SP 19 #include <machine/reg.h> 20 #include <machine/trap.h> 21 #include <machine/mips_opcode.h> 22 23 REGLIST kdbreglist[] = { 24 /* register_name, address */ 25 "AT", &kdbpcb.pcb_regs[AST], 26 "v0", &kdbpcb.pcb_regs[V0], 27 "v1", &kdbpcb.pcb_regs[V1], 28 "a0", &kdbpcb.pcb_regs[A0], 29 "a1", &kdbpcb.pcb_regs[A1], 30 "a2", &kdbpcb.pcb_regs[A2], 31 "a3", &kdbpcb.pcb_regs[A3], 32 "t0", &kdbpcb.pcb_regs[T0], 33 "t1", &kdbpcb.pcb_regs[T1], 34 "t2", &kdbpcb.pcb_regs[T2], 35 "t3", &kdbpcb.pcb_regs[T3], 36 "t4", &kdbpcb.pcb_regs[T4], 37 "t5", &kdbpcb.pcb_regs[T5], 38 "t6", &kdbpcb.pcb_regs[T6], 39 "t7", &kdbpcb.pcb_regs[T7], 40 "t8", &kdbpcb.pcb_regs[T8], 41 "t9", &kdbpcb.pcb_regs[T9], 42 "s0", &kdbpcb.pcb_regs[S0], 43 "s1", &kdbpcb.pcb_regs[S1], 44 "s2", &kdbpcb.pcb_regs[S2], 45 "s3", &kdbpcb.pcb_regs[S3], 46 "s4", &kdbpcb.pcb_regs[S4], 47 "s5", &kdbpcb.pcb_regs[S5], 48 "s6", &kdbpcb.pcb_regs[S6], 49 "s7", &kdbpcb.pcb_regs[S7], 50 "s8", &kdbpcb.pcb_regs[S8], 51 "sp", &kdbpcb.pcb_regs[SP], 52 "gp", &kdbpcb.pcb_regs[GP], 53 "ra", &kdbpcb.pcb_regs[RA], 54 "mullo", &kdbpcb.pcb_regs[MULLO], 55 "mulhi", &kdbpcb.pcb_regs[MULHI], 56 "SR", &kdbpcb.pcb_regs[SR], 57 "pc", &kdbpcb.pcb_regs[PC], 58 "f0", &kdbpcb.pcb_regs[F0], 59 "f1", &kdbpcb.pcb_regs[F1], 60 "f2", &kdbpcb.pcb_regs[F2], 61 "f3", &kdbpcb.pcb_regs[F3], 62 "f4", &kdbpcb.pcb_regs[F4], 63 "f5", &kdbpcb.pcb_regs[F5], 64 "f6", &kdbpcb.pcb_regs[F6], 65 "f7", &kdbpcb.pcb_regs[F7], 66 "f8", &kdbpcb.pcb_regs[F8], 67 "f9", &kdbpcb.pcb_regs[F9], 68 "f10", &kdbpcb.pcb_regs[F10], 69 "f11", &kdbpcb.pcb_regs[F11], 70 "f12", &kdbpcb.pcb_regs[F12], 71 "f13", &kdbpcb.pcb_regs[F13], 72 "f14", &kdbpcb.pcb_regs[F14], 73 "f15", &kdbpcb.pcb_regs[F15], 74 "f16", &kdbpcb.pcb_regs[F16], 75 "f17", &kdbpcb.pcb_regs[F17], 76 "f18", &kdbpcb.pcb_regs[F18], 77 "f19", &kdbpcb.pcb_regs[F19], 78 "f20", &kdbpcb.pcb_regs[F20], 79 "f21", &kdbpcb.pcb_regs[F21], 80 "f22", &kdbpcb.pcb_regs[F22], 81 "f23", &kdbpcb.pcb_regs[F23], 82 "f24", &kdbpcb.pcb_regs[F24], 83 "f25", &kdbpcb.pcb_regs[F25], 84 "f26", &kdbpcb.pcb_regs[F26], 85 "f27", &kdbpcb.pcb_regs[F27], 86 "f28", &kdbpcb.pcb_regs[F28], 87 "f29", &kdbpcb.pcb_regs[F29], 88 "f30", &kdbpcb.pcb_regs[F30], 89 "f31", &kdbpcb.pcb_regs[F31], 90 0, 0 91 }; 92 93 static char *op_name[64] = { 94 /* 0 */ "spec", "bcond","j", "jal", "beq", "bne", "blez", "bgtz", 95 /* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori", "xori", "lui", 96 /*16 */ "cop0", "cop1", "cop2", "cop3", "op24", "op25", "op26", "op27", 97 /*24 */ "op30", "op31", "op32", "op33", "op34", "op35", "op36", "op37", 98 /*32 */ "lb", "lh", "lwl", "lw", "lbu", "lhu", "lwr", "ld", 99 /*40 */ "sb", "sh", "swl", "sw", "op54", "op55", "swr", "sd", 100 /*48 */ "lwc0", "lwc1", "lwc2", "lwc3", "ldc0", "ldc1", "ldc2", "ldc3", 101 /*56 */ "swc0", "swc1", "swc2", "swc3", "sdc0", "sdc1", "sdc2", "sdc3" 102 }; 103 104 static char *spec_name[64] = { 105 /* 0 */ "sll", "spec01","srl", "sra", "sllv", "spec05","srlv","srav", 106 /* 8 */ "jr", "jalr", "spec12","spec13","syscall","break","spec16","tas", 107 /*16 */ "mfhi", "mthi", "mflo", "mtlo", "spec24","spec25","spec26","spec27", 108 /*24 */ "mult", "multu","div", "divu", "spec34","spec35","spec36","spec37", 109 /*32 */ "add", "addu", "sub", "subu", "and", "or", "xor", "nor", 110 /*40 */ "spec50","spec51","slt","sltu", "spec54","spec55","spec56","spec57", 111 /*48 */ "spec60","spec61","spec62","spec63","spec64","spec65","spec66","spec67", 112 /*56 */ "spec70","spec71","spec72","spec73","spec74","spec75","spec76","spec77" 113 }; 114 115 static char *bcond_name[32] = { 116 /* 0 */ "bltz", "bgez", "?", "?", "?", "?", "?", "?", 117 /* 8 */ "?", "?", "?", "?", "?", "?", "?", "?", 118 /*16 */ "bltzal", "bgezal", "?", "?", "?", "?", "?", "?", 119 /*24 */ "?", "?", "?", "?", "?", "?", "?", "?", 120 }; 121 122 static char *cop1_name[64] = { 123 /* 0 */ "fadd", "fsub", "fmpy", "fdiv", "fsqrt","fabs", "fmov", "fneg", 124 /* 8 */ "fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f", 125 /*16 */ "fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17", 126 /*24 */ "fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f", 127 /*32 */ "fcvts","fcvtd","fcvte","fop23","fcvtw","fop25","fop26","fop27", 128 /*40 */ "fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f", 129 /*48 */ "fcmp.f","fcmp.un","fcmp.eq","fcmp.ueq","fcmp.olt","fcmp.ult", 130 "fcmp.ole","fcmp.ule", 131 /*56 */ "fcmp.sf","fcmp.ngle","fcmp.seq","fcmp.ngl","fcmp.lt","fcmp.nge", 132 "fcmp.le","fcmp.ngt" 133 }; 134 135 static char *fmt_name[16] = { 136 "s", "d", "e", "fmt3", 137 "w", "fmt5", "fmt6", "fmt7", 138 "fmt8", "fmt9", "fmta", "fmtb", 139 "fmtc", "fmtd", "fmte", "fmtf" 140 }; 141 142 static char *reg_name[32] = { 143 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 144 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 145 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 146 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" 147 }; 148 149 static char *c0_opname[64] = { 150 "c0op00","tlbr", "tlbwi", "c0op03","c0op04","c0op05","tlbwr", "c0op07", 151 "tlbp", "c0op11","c0op12","c0op13","c0op14","c0op15","c0op16","c0op17", 152 "rfe", "c0op21","c0op22","c0op23","c0op24","c0op25","c0op26","c0op27", 153 "c0op30","c0op31","c0op32","c0op33","c0op34","c0op35","c0op36","c0op37", 154 "c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47", 155 "c0op50","c0op51","c0op52","c0op53","c0op54","c0op55","c0op56","c0op57", 156 "c0op60","c0op61","c0op62","c0op63","c0op64","c0op65","c0op66","c0op67", 157 "c0op70","c0op71","c0op72","c0op73","c0op74","c0op75","c0op77","c0op77", 158 }; 159 160 static char *c0_reg[32] = { 161 "index","random","tlblo","c0r3","context","c0r5","c0r6","c0r7", 162 "badvaddr","c0r9","tlbhi","c0r11","sr", "cause","epc", "c0r15", 163 "c0r16","c0r17","c0r18","c0r19","c0r20","c0r21","c0r22","c0r23", 164 "c0r24","c0r25","c0r26","c0r27","c0r28","c0r29","c0r30","c0r31" 165 }; 166 167 /* 168 * Print the cause of the trap to kdb. 169 */ 170 void 171 kdbprinttrap(causeReg, vadr) 172 unsigned causeReg, vadr; 173 { 174 int type, pc; 175 extern char *trap_type[]; 176 177 type = (causeReg & MACH_CR_EXC_CODE) >> MACH_CR_EXC_CODE_SHIFT; 178 179 /* check to see if we are entering kdb via kdbpanic() */ 180 pc = kdbpcb.pcb_regs[PC]; 181 if (type == T_BREAK && pc < 0) { 182 if (kdbpeek(pc) == MACH_BREAK_KDB) 183 kdbpcb.pcb_regs[PC] = pc + 4; 184 } 185 186 kdbprintf("trap: %s\n", trap_type[type]); 187 } 188 189 unsigned kdb_ss_addr; 190 unsigned kdb_ss_instr; 191 192 void 193 kdbsetsstep() 194 { 195 register unsigned va; 196 register int *locr0 = kdbpcb.pcb_regs; 197 int i; 198 199 /* compute next address after current location */ 200 va = MachEmulateBranch(locr0, locr0[PC], 0, 1); 201 if (kdb_ss_addr) { 202 kdbprintf("kdbsetsstep: breakpoint already set at %x (va %x)\n", 203 kdb_ss_addr, va); 204 return; 205 } 206 kdb_ss_addr = va; 207 208 if ((int)va < 0) { 209 /* kernel address */ 210 kdb_ss_instr = kdbpeek(va); 211 kdbpoke((caddr_t)va, MACH_BREAK_SSTEP); 212 return; 213 } 214 215 kdb_ss_instr = fuiword(va); 216 i = suiword((caddr_t)va, MACH_BREAK_SSTEP); 217 if (i < 0) { 218 register struct proc *p = curproc; 219 vm_offset_t sa, ea; 220 int rv; 221 222 sa = trunc_page((vm_offset_t)va); 223 ea = round_page((vm_offset_t)va+sizeof(int)-1); 224 rv = vm_map_protect(&p->p_vmspace->vm_map, sa, ea, 225 VM_PROT_DEFAULT, FALSE); 226 if (rv == KERN_SUCCESS) { 227 i = suiword((caddr_t)va, MACH_BREAK_SSTEP); 228 (void) vm_map_protect(&p->p_vmspace->vm_map, 229 sa, ea, VM_PROT_READ|VM_PROT_EXECUTE, FALSE); 230 } 231 } 232 if (i < 0) 233 return; 234 } 235 236 void 237 kdbclrsstep() 238 { 239 register unsigned cr, pc, va; 240 unsigned instr; 241 int i; 242 243 /* ignore this trap if it is not a break trap */ 244 cr = kdbvar[kdbvarchk('t')]; 245 if ((cr & MACH_CR_EXC_CODE) != (T_BREAK << MACH_CR_EXC_CODE_SHIFT)) 246 return; 247 248 /* fix pc if break instruction is in the delay slot */ 249 pc = kdbpcb.pcb_regs[PC]; 250 if ((int)cr < 0) 251 pc += 4; 252 253 /* check to be sure its the one we are expecting */ 254 va = kdb_ss_addr; 255 if (!va || va != pc) 256 return; 257 258 /* read break instruction */ 259 instr = kdbpeek(va); 260 if (instr != MACH_BREAK_SSTEP) 261 return; 262 263 if ((int)va < 0) { 264 /* kernel address */ 265 kdbpoke((caddr_t)va, kdb_ss_instr); 266 kdb_ss_addr = 0; 267 return; 268 } 269 270 /* restore original instruction and clear BP */ 271 i = suiword((caddr_t)va, kdb_ss_instr); 272 if (i < 0) { 273 register struct proc *p = curproc; 274 vm_offset_t sa, ea; 275 int rv; 276 277 sa = trunc_page((vm_offset_t)va); 278 ea = round_page((vm_offset_t)va+sizeof(int)-1); 279 rv = vm_map_protect(&p->p_vmspace->vm_map, sa, ea, 280 VM_PROT_DEFAULT, FALSE); 281 if (rv == KERN_SUCCESS) { 282 i = suiword((caddr_t)va, p->p_md.md_ss_instr); 283 (void) vm_map_protect(&p->p_vmspace->vm_map, 284 sa, ea, VM_PROT_READ|VM_PROT_EXECUTE, 285 FALSE); 286 } 287 } 288 if (i < 0) 289 kdbprintf("can't clear break at %x\n", va); 290 kdb_ss_addr = 0; 291 } 292 293 void 294 kdbreadc(lp) 295 char *lp; 296 { 297 int c; 298 299 c = cngetc(); 300 if (c == '\r') 301 c = '\n'; 302 *lp = c; 303 } 304 305 void 306 kdbwrite(lp, len) 307 char *lp; 308 int len; 309 { 310 while (len-- > 0) 311 cnputc(*lp++); 312 } 313 314 /* ARGSUSED */ 315 void 316 kdbprintins(space, ins) 317 int space; 318 long ins; 319 { 320 InstFmt i; 321 322 i.word = ins; 323 324 switch (i.JType.op) { 325 case OP_SPECIAL: 326 if (i.word == 0) { 327 kdbprintf("nop"); 328 break; 329 } 330 if (i.RType.func == OP_ADDU && i.RType.rt == 0) { 331 kdbprintf("move\t%s,%s", 332 reg_name[i.RType.rd], 333 reg_name[i.RType.rs]); 334 break; 335 } 336 kdbprintf("%s", spec_name[i.RType.func]); 337 switch (i.RType.func) { 338 case OP_SLL: 339 case OP_SRL: 340 case OP_SRA: 341 kdbprintf("\t%s,%s,%d", 342 reg_name[i.RType.rd], 343 reg_name[i.RType.rt], 344 i.RType.shamt); 345 break; 346 347 case OP_SLLV: 348 case OP_SRLV: 349 case OP_SRAV: 350 kdbprintf("\t%s,%s,%s", 351 reg_name[i.RType.rd], 352 reg_name[i.RType.rt], 353 reg_name[i.RType.rs]); 354 break; 355 356 case OP_MFHI: 357 case OP_MFLO: 358 kdbprintf("\t%s", reg_name[i.RType.rd]); 359 break; 360 361 case OP_JR: 362 case OP_JALR: 363 case OP_MTLO: 364 case OP_MTHI: 365 kdbprintf("\t%s", reg_name[i.RType.rs]); 366 break; 367 368 case OP_MULT: 369 case OP_MULTU: 370 case OP_DIV: 371 case OP_DIVU: 372 kdbprintf("\t%s,%s", 373 reg_name[i.RType.rs], 374 reg_name[i.RType.rt]); 375 break; 376 377 case OP_SYSCALL: 378 break; 379 380 case OP_BREAK: 381 kdbprintf("\t%d", (i.RType.rs << 5) | i.RType.rt); 382 break; 383 384 default: 385 kdbprintf("\t%s,%s,%s", 386 reg_name[i.RType.rd], 387 reg_name[i.RType.rs], 388 reg_name[i.RType.rt]); 389 }; 390 break; 391 392 case OP_BCOND: 393 kdbprintf("%s\t%s,", bcond_name[i.IType.rt], 394 reg_name[i.IType.rs]); 395 goto pr_displ; 396 397 case OP_BLEZ: 398 case OP_BGTZ: 399 kdbprintf("%s\t%s,", op_name[i.IType.op], 400 reg_name[i.IType.rs]); 401 goto pr_displ; 402 403 case OP_BEQ: 404 if (i.IType.rs == 0 && i.IType.rt == 0) { 405 kdbprintf("b\t"); 406 goto pr_displ; 407 } 408 /* FALLTHROUGH */ 409 case OP_BNE: 410 kdbprintf("%s\t%s,%s,", op_name[i.IType.op], 411 reg_name[i.IType.rs], 412 reg_name[i.IType.rt]); 413 pr_displ: 414 kdbpsymoff(kdbdot + 4 + ((short)i.IType.imm << 2), ISYM, ""); 415 break; 416 417 case OP_COP0: 418 switch (i.RType.rs) { 419 case OP_BCx: 420 case OP_BCy: 421 kdbprintf("bc0%c\t", 422 "ft"[i.RType.rt & COPz_BC_TF_MASK]); 423 goto pr_displ; 424 425 case OP_MT: 426 kdbprintf("mtc0\t%s,%s", 427 reg_name[i.RType.rt], 428 c0_reg[i.RType.rd]); 429 break; 430 431 case OP_MF: 432 kdbprintf("mfc0\t%s,%s", 433 reg_name[i.RType.rt], 434 c0_reg[i.RType.rd]); 435 break; 436 437 default: 438 kdbprintf("%s", c0_opname[i.FRType.func]); 439 }; 440 break; 441 442 case OP_COP1: 443 switch (i.RType.rs) { 444 case OP_BCx: 445 case OP_BCy: 446 kdbprintf("bc1%c\t", 447 "ft"[i.RType.rt & COPz_BC_TF_MASK]); 448 goto pr_displ; 449 450 case OP_MT: 451 kdbprintf("mtc1\t%s,f%d", 452 reg_name[i.RType.rt], 453 i.RType.rd); 454 break; 455 456 case OP_MF: 457 kdbprintf("mfc1\t%s,f%d", 458 reg_name[i.RType.rt], 459 i.RType.rd); 460 break; 461 462 case OP_CT: 463 kdbprintf("ctc1\t%s,f%d", 464 reg_name[i.RType.rt], 465 i.RType.rd); 466 break; 467 468 case OP_CF: 469 kdbprintf("cfc1\t%s,f%d", 470 reg_name[i.RType.rt], 471 i.RType.rd); 472 break; 473 474 default: 475 kdbprintf("%s.%s\tf%d,f%d,f%d", 476 cop1_name[i.FRType.func], 477 fmt_name[i.FRType.fmt], 478 i.FRType.fd, i.FRType.fs, i.FRType.ft); 479 }; 480 break; 481 482 case OP_J: 483 case OP_JAL: 484 kdbprintf("%s\t", op_name[i.JType.op]); 485 kdbpsymoff((kdbdot & 0xF0000000) | (i.JType.target << 2), 486 ISYM, ""); 487 break; 488 489 case OP_LWC1: 490 case OP_SWC1: 491 kdbprintf("%s\tf%d,", op_name[i.IType.op], 492 i.IType.rt); 493 goto loadstore; 494 495 case OP_LB: 496 case OP_LH: 497 case OP_LW: 498 case OP_LBU: 499 case OP_LHU: 500 case OP_SB: 501 case OP_SH: 502 case OP_SW: 503 kdbprintf("%s\t%s,", op_name[i.IType.op], 504 reg_name[i.IType.rt]); 505 loadstore: 506 kdbprintf("%d(%s)", (short)i.IType.imm, 507 reg_name[i.IType.rs]); 508 break; 509 510 case OP_ORI: 511 case OP_XORI: 512 if (i.IType.rs == 0) { 513 kdbprintf("li\t%s,0x%X", 514 reg_name[i.IType.rt], 515 i.IType.imm); 516 break; 517 } 518 /* FALLTHROUGH */ 519 case OP_ANDI: 520 kdbprintf("%s\t%s,%s,0x%X", op_name[i.IType.op], 521 reg_name[i.IType.rt], 522 reg_name[i.IType.rs], 523 i.IType.imm); 524 break; 525 526 case OP_LUI: 527 kdbprintf("%s\t%s,0x%X", op_name[i.IType.op], 528 reg_name[i.IType.rt], 529 i.IType.imm); 530 break; 531 532 case OP_ADDI: 533 case OP_ADDIU: 534 if (i.IType.rs == 0) { 535 kdbprintf("li\t%s,%D", 536 reg_name[i.IType.rt], 537 (short)i.IType.imm); 538 break; 539 } 540 /* FALLTHROUGH */ 541 default: 542 kdbprintf("%s\t%s,%s,%D", op_name[i.IType.op], 543 reg_name[i.IType.rt], 544 reg_name[i.IType.rs], 545 (short)i.IType.imm); 546 } 547 kdbdotinc = 4; 548 } 549 550 #define MIPS_JR_RA 0x03e00008 /* instruction code for jr ra */ 551 552 /* 553 * Print a stack backtrace. 554 */ 555 void 556 kdbstacktrace(printlocals) 557 int printlocals; 558 { 559 unsigned pc, sp, ra, va, subr; 560 int a0, a1, a2, a3; 561 unsigned instr, mask; 562 InstFmt i; 563 int more, stksize; 564 extern MachKernGenException(); 565 extern MachUserGenException(); 566 extern MachKernIntr(); 567 extern MachUserIntr(); 568 extern setsoftclock(); 569 570 /* get initial values from the exception frame */ 571 sp = kdbpcb.pcb_regs[SP]; 572 pc = kdbpcb.pcb_regs[PC]; 573 ra = kdbpcb.pcb_regs[RA]; 574 a0 = kdbpcb.pcb_regs[A0]; 575 a1 = kdbpcb.pcb_regs[A1]; 576 a2 = kdbpcb.pcb_regs[A2]; 577 a3 = kdbpcb.pcb_regs[A3]; 578 579 loop: 580 /* check for current PC in the kernel interrupt handler code */ 581 if (pc >= (unsigned)MachKernIntr && pc < (unsigned)MachUserIntr) { 582 /* NOTE: the offsets depend on the code in locore.s */ 583 kdbprintf("interupt\n"); 584 a0 = kdbchkget(sp + 36, DSP); 585 a1 = kdbchkget(sp + 40, DSP); 586 a2 = kdbchkget(sp + 44, DSP); 587 a3 = kdbchkget(sp + 48, DSP); 588 pc = kdbchkget(sp + 20, DSP); 589 ra = kdbchkget(sp + 92, DSP); 590 sp = kdbchkget(sp + 100, DSP); 591 } 592 593 /* check for current PC in the exception handler code */ 594 if (pc >= 0x80000000 && pc < (unsigned)setsoftclock) { 595 ra = 0; 596 subr = 0; 597 goto done; 598 } 599 /* 600 * Find the beginning of the current subroutine by scanning backwards 601 * from the current PC for the end of the previous subroutine. 602 */ 603 va = pc - sizeof(int); 604 while ((instr = kdbchkget(va, ISP)) != MIPS_JR_RA) 605 va -= sizeof(int); 606 va += 2 * sizeof(int); /* skip back over branch & delay slot */ 607 /* skip over nulls which might separate .o files */ 608 while ((instr = kdbchkget(va, ISP)) == 0) 609 va += sizeof(int); 610 subr = va; 611 612 /* scan forwards to find stack size and any saved registers */ 613 stksize = 0; 614 more = 3; 615 mask = 0; 616 for (; more; va += sizeof(int), more = (more == 3) ? 3 : more - 1) { 617 /* stop if hit our current position */ 618 if (va >= pc) 619 break; 620 instr = kdbchkget(va, ISP); 621 i.word = instr; 622 switch (i.JType.op) { 623 case OP_SPECIAL: 624 switch (i.RType.func) { 625 case OP_JR: 626 case OP_JALR: 627 more = 2; /* stop after next instruction */ 628 break; 629 630 case OP_SYSCALL: 631 case OP_BREAK: 632 more = 1; /* stop now */ 633 }; 634 break; 635 636 case OP_BCOND: 637 case OP_J: 638 case OP_JAL: 639 case OP_BEQ: 640 case OP_BNE: 641 case OP_BLEZ: 642 case OP_BGTZ: 643 more = 2; /* stop after next instruction */ 644 break; 645 646 case OP_COP0: 647 case OP_COP1: 648 case OP_COP2: 649 case OP_COP3: 650 switch (i.RType.rs) { 651 case OP_BCx: 652 case OP_BCy: 653 more = 2; /* stop after next instruction */ 654 }; 655 break; 656 657 case OP_SW: 658 /* look for saved registers on the stack */ 659 if (i.IType.rs != 29) 660 break; 661 /* only restore the first one */ 662 if (mask & (1 << i.IType.rt)) 663 break; 664 mask |= 1 << i.IType.rt; 665 switch (i.IType.rt) { 666 case 4: /* a0 */ 667 a0 = kdbchkget(sp + (short)i.IType.imm, DSP); 668 break; 669 670 case 5: /* a1 */ 671 a1 = kdbchkget(sp + (short)i.IType.imm, DSP); 672 break; 673 674 case 6: /* a2 */ 675 a2 = kdbchkget(sp + (short)i.IType.imm, DSP); 676 break; 677 678 case 7: /* a3 */ 679 a3 = kdbchkget(sp + (short)i.IType.imm, DSP); 680 break; 681 682 case 31: /* ra */ 683 ra = kdbchkget(sp + (short)i.IType.imm, DSP); 684 } 685 break; 686 687 case OP_ADDI: 688 case OP_ADDIU: 689 /* look for stack pointer adjustment */ 690 if (i.IType.rs != 29 && i.IType.rt != 29) 691 break; 692 stksize = (short)i.IType.imm; 693 } 694 } 695 696 done: 697 #if 0 698 kdbpsymoff((long)pc, ISYM, ""); 699 #else 700 kdbprintf("%X+%X ", subr, pc - subr); /* XXX */ 701 #endif 702 kdbprintf("(%X,%X,%X,%X)\n", a0, a1, a2, a3); 703 704 if (ra) { 705 pc = ra; 706 sp -= stksize; 707 goto loop; 708 } 709 } 710 711 /* 712 * Very simple memory allocator for kdb. 713 */ 714 char * 715 kdbmalloc(size) 716 int size; 717 { 718 static char buffer[4096]; 719 static char *bufp = buffer; 720 char *p; 721 722 /* round size up to sizeof(int) */ 723 size = (size + sizeof(int) - 1) & ~(sizeof(int) - 1); 724 p = bufp; 725 bufp = p + size; 726 return (p); 727 } 728 729 /* 730 * Machine dependent printing '$'. 731 * Return zero if modif character not recognized. 732 */ 733 kdbprintmachdep(modif) 734 { 735 register int i, j; 736 extern int tlbhi, tlblo; 737 738 switch (modif) { 739 case 'p': 740 case 'P': /* print TLB entries */ 741 if (kdbadrflg) { 742 i = kdbadrval; 743 if (i < 0 || i > VMMACH_NUM_TLB_ENTRIES) { 744 extern char *kdbBADMOD; 745 746 kdberror(kdbBADMOD); 747 break; 748 } 749 if (kdbcntflg == 0) 750 j = i + 1; 751 else { 752 j = i + kdbcntval; 753 if (j > VMMACH_NUM_TLB_ENTRIES) 754 j = VMMACH_NUM_TLB_ENTRIES; 755 } 756 } else { 757 i = 0; 758 j = VMMACH_NUM_TLB_ENTRIES; 759 } 760 for (; i < j; i++) { 761 MachTLBRead(i); 762 if (modif == 'p' && !(tlblo & PG_V)) 763 continue; 764 kdbprintf("TLB %2d: hi %8X low %8X\n", i, tlbhi, tlblo); 765 } 766 kdbprintf("TLB PID %x\n", MachTLBGetPID()); 767 break; 768 769 case 'f': /* find a TLB entry by virtaddr */ 770 case 'F': /* find a TLB entry by physaddr */ 771 j = kdbdot & PG_FRAME; 772 for (i = 0; i < VMMACH_NUM_TLB_ENTRIES; i++) { 773 MachTLBRead(i); 774 if (modif == 'f') { 775 if ((tlbhi & PG_FRAME) != j) 776 continue; 777 } else { 778 if ((tlblo & PG_FRAME) != j) 779 continue; 780 } 781 kdbprintf("TLB %2d: hi %8X low %8X\n", i, tlbhi, tlblo); 782 } 783 break; 784 785 default: 786 return (0); 787 } 788 return (1); 789 } 790