1 /*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * 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 7.2 (Berkeley) 03/14/92 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; 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 && 582 pc < (unsigned)MachUserIntr) { 583 /* NOTE: the offsets depend on the code in locore.s */ 584 kdbprintf("interupt\n"); 585 a0 = kdbchkget(sp + 36, DSP); 586 a1 = kdbchkget(sp + 40, DSP); 587 a2 = kdbchkget(sp + 44, DSP); 588 a3 = kdbchkget(sp + 48, DSP); 589 pc = kdbchkget(sp + 20, DSP); 590 ra = kdbchkget(sp + 92, DSP); 591 sp = kdbchkget(sp + 100, DSP); 592 } 593 594 /* check for current PC in the exception handler code */ 595 if (pc >= 0x80000000 && 596 pc < (unsigned)setsoftclock) { 597 ra = 0; 598 goto done; 599 } 600 /* 601 * Find the beginning of the current subroutine by scanning backwards 602 * from the current PC for the end of the previous subroutine. 603 */ 604 va = pc - sizeof(int); 605 while ((instr = kdbchkget(va, ISP)) != MIPS_JR_RA) 606 va -= sizeof(int); 607 va += 2 * sizeof(int); /* skip back over branch & delay slot */ 608 /* skip over nulls which might separate .o files */ 609 while ((instr = kdbchkget(va, ISP)) == 0) 610 va += sizeof(int); 611 subr = va; 612 613 /* scan forwards to find stack size and any saved registers */ 614 stksize = 0; 615 more = 3; 616 for (; more; va += sizeof(int), more = (more == 3) ? 3 : more - 1) { 617 instr = kdbchkget(va, ISP); 618 i.word = instr; 619 switch (i.JType.op) { 620 case OP_SPECIAL: 621 switch (i.RType.func) { 622 case OP_JR: 623 case OP_JALR: 624 more = 2; /* stop after next instruction */ 625 break; 626 627 case OP_SYSCALL: 628 case OP_BREAK: 629 more = 1; /* stop now */ 630 }; 631 break; 632 633 case OP_BCOND: 634 case OP_J: 635 case OP_JAL: 636 case OP_BEQ: 637 case OP_BNE: 638 case OP_BLEZ: 639 case OP_BGTZ: 640 more = 2; /* stop after next instruction */ 641 break; 642 643 case OP_COP0: 644 case OP_COP1: 645 case OP_COP2: 646 case OP_COP3: 647 switch (i.RType.rs) { 648 case OP_BCx: 649 case OP_BCy: 650 more = 2; /* stop after next instruction */ 651 }; 652 break; 653 654 case OP_SW: 655 /* look for saved registers on the stack */ 656 if (i.IType.rs != 29) 657 break; 658 switch (i.IType.rt) { 659 case 4: /* a0 */ 660 a0 = kdbchkget(sp + (short)i.IType.imm, DSP); 661 break; 662 663 case 5: /* a1 */ 664 a1 = kdbchkget(sp + (short)i.IType.imm, DSP); 665 break; 666 667 case 6: /* a2 */ 668 a2 = kdbchkget(sp + (short)i.IType.imm, DSP); 669 break; 670 671 case 7: /* a3 */ 672 a3 = kdbchkget(sp + (short)i.IType.imm, DSP); 673 break; 674 675 case 31: /* ra */ 676 ra = kdbchkget(sp + (short)i.IType.imm, DSP); 677 } 678 break; 679 680 case OP_ADDI: 681 case OP_ADDIU: 682 /* look for stack pointer adjustment */ 683 if (i.IType.rs != 29 && i.IType.rt != 29) 684 break; 685 stksize = (short)i.IType.imm; 686 } 687 } 688 689 done: 690 #if 0 691 kdbpsymoff((long)pc, ISYM, ""); 692 #else 693 kdbprintf("%X+%X ", subr, pc - subr); /* XXX */ 694 #endif 695 kdbprintf("(%X,%X,%X,%X)\n", a0, a1, a2, a3); 696 697 if (ra) { 698 pc = ra; 699 sp -= stksize; 700 goto loop; 701 } 702 } 703 704 /* 705 * Very simple memory allocator for kdb. 706 */ 707 char * 708 kdbmalloc(size) 709 int size; 710 { 711 static char buffer[4096]; 712 static char *bufp = buffer; 713 char *p; 714 715 /* round size up to sizeof(int) */ 716 size = (size + sizeof(int) - 1) & ~(sizeof(int) - 1); 717 p = bufp; 718 bufp = p + size; 719 return (p); 720 } 721 722 /* 723 * Machine dependent printing '$'. 724 * Return zero if modif character not recognized. 725 */ 726 kdbprintmachdep(modif) 727 { 728 register int i, j; 729 extern int tlbhi, tlblo; 730 731 switch (modif) { 732 case 'p': 733 case 'P': /* print TLB entries */ 734 if (kdbadrflg) { 735 i = kdbadrval; 736 if (i < 0 || i > VMMACH_NUM_TLB_ENTRIES) { 737 extern char *kdbBADMOD; 738 739 kdberror(kdbBADMOD); 740 break; 741 } 742 if (kdbcntflg == 0) 743 j = i + 1; 744 else { 745 j = i + kdbcntval; 746 if (j > VMMACH_NUM_TLB_ENTRIES) 747 j = VMMACH_NUM_TLB_ENTRIES; 748 } 749 } else { 750 i = 0; 751 j = VMMACH_NUM_TLB_ENTRIES; 752 } 753 for (; i < j; i++) { 754 MachTLBRead(i); 755 if (modif == 'p' && !(tlblo & PG_V)) 756 continue; 757 kdbprintf("TLB %2d: hi %8X low %8X\n", i, tlbhi, tlblo); 758 } 759 kdbprintf("TLB PID %x\n", MachTLBGetPID()); 760 break; 761 762 case 'f': /* find a TLB entry by virtaddr */ 763 case 'F': /* find a TLB entry by physaddr */ 764 j = kdbdot & PG_FRAME; 765 for (i = 0; i < VMMACH_NUM_TLB_ENTRIES; i++) { 766 MachTLBRead(i); 767 if (modif == 'f') { 768 if ((tlbhi & PG_FRAME) != j) 769 continue; 770 } else { 771 if ((tlblo & PG_FRAME) != j) 772 continue; 773 } 774 kdbprintf("TLB %2d: hi %8X low %8X\n", i, tlbhi, tlblo); 775 } 776 break; 777 778 default: 779 return (0); 780 } 781 return (1); 782 } 783