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.s 7.1 (Berkeley) 03/01/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 23REGLIST kdbreglist[] = { 24 /* register_name, address */ 25 "AT", &kdbpcb.pcb_regs[AST], 26 "v0", &kdbpcb.pcb_regs[V0], 27 "v1", &kdbpcb.pcb_regs[V1], 28 "t0", &kdbpcb.pcb_regs[T0], 29 "t1", &kdbpcb.pcb_regs[T1], 30 "t2", &kdbpcb.pcb_regs[T2], 31 "t3", &kdbpcb.pcb_regs[T3], 32 "t4", &kdbpcb.pcb_regs[T4], 33 "t5", &kdbpcb.pcb_regs[T5], 34 "t6", &kdbpcb.pcb_regs[T6], 35 "t7", &kdbpcb.pcb_regs[T7], 36 "t8", &kdbpcb.pcb_regs[T8], 37 "t9", &kdbpcb.pcb_regs[T9], 38 "s0", &kdbpcb.pcb_regs[S0], 39 "s1", &kdbpcb.pcb_regs[S1], 40 "s2", &kdbpcb.pcb_regs[S2], 41 "s3", &kdbpcb.pcb_regs[S3], 42 "s4", &kdbpcb.pcb_regs[S4], 43 "s5", &kdbpcb.pcb_regs[S5], 44 "s6", &kdbpcb.pcb_regs[S6], 45 "s7", &kdbpcb.pcb_regs[S7], 46 "s8", &kdbpcb.pcb_regs[S8], 47 "sp", &kdbpcb.pcb_regs[SP], 48 "gp", &kdbpcb.pcb_regs[GP], 49 "ra", &kdbpcb.pcb_regs[RA], 50 "mullo", &kdbpcb.pcb_regs[MULLO], 51 "mulhi", &kdbpcb.pcb_regs[MULHI], 52 "SR", &kdbpcb.pcb_regs[SR], 53 "pc", &kdbpcb.pcb_regs[PC], 54 "f0", &kdbpcb.pcb_regs[F0], 55 "f1", &kdbpcb.pcb_regs[F1], 56 "f2", &kdbpcb.pcb_regs[F2], 57 "f3", &kdbpcb.pcb_regs[F3], 58 "f4", &kdbpcb.pcb_regs[F4], 59 "f5", &kdbpcb.pcb_regs[F5], 60 "f6", &kdbpcb.pcb_regs[F6], 61 "f7", &kdbpcb.pcb_regs[F7], 62 "f8", &kdbpcb.pcb_regs[F8], 63 "f9", &kdbpcb.pcb_regs[F9], 64 "f10", &kdbpcb.pcb_regs[F10], 65 "f11", &kdbpcb.pcb_regs[F11], 66 "f12", &kdbpcb.pcb_regs[F12], 67 "f13", &kdbpcb.pcb_regs[F13], 68 "f14", &kdbpcb.pcb_regs[F14], 69 "f15", &kdbpcb.pcb_regs[F15], 70 "f16", &kdbpcb.pcb_regs[F16], 71 "f17", &kdbpcb.pcb_regs[F17], 72 "f18", &kdbpcb.pcb_regs[F18], 73 "f19", &kdbpcb.pcb_regs[F19], 74 "f20", &kdbpcb.pcb_regs[F20], 75 "f21", &kdbpcb.pcb_regs[F21], 76 "f22", &kdbpcb.pcb_regs[F22], 77 "f23", &kdbpcb.pcb_regs[F23], 78 "f24", &kdbpcb.pcb_regs[F24], 79 "f25", &kdbpcb.pcb_regs[F25], 80 "f26", &kdbpcb.pcb_regs[F26], 81 "f27", &kdbpcb.pcb_regs[F27], 82 "f28", &kdbpcb.pcb_regs[F28], 83 "f29", &kdbpcb.pcb_regs[F29], 84 "f30", &kdbpcb.pcb_regs[F30], 85 "f31", &kdbpcb.pcb_regs[F31], 86 0, 0 87}; 88 89static char *op_name[64] = { 90/* 0 */ "spec", "bcond","j", "jal", "beq", "bne", "blez", "bgtz", 91/* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori", "xori", "lui", 92/*16 */ "cop0", "cop1", "cop2", "cop3", "op24", "op25", "op26", "op27", 93/*24 */ "op30", "op31", "op32", "op33", "op34", "op35", "op36", "op37", 94/*32 */ "lb", "lh", "lwl", "lw", "lbu", "lhu", "lwr", "ld", 95/*40 */ "sb", "sh", "swl", "sw", "op54", "op55", "swr", "sd", 96/*48 */ "lwc0", "lwc1", "lwc2", "lwc3", "ldc0", "ldc1", "ldc2", "ldc3", 97/*56 */ "swc0", "swc1", "swc2", "swc3", "sdc0", "sdc1", "sdc2", "sdc3" 98}; 99 100static char *spec_name[64] = { 101/* 0 */ "sll", "spec01","srl", "sra", "sllv", "spec05","srlv","srav", 102/* 8 */ "jr", "jalr", "spec12","spec13","syscall","break","spec16","tas", 103/*16 */ "mfhi", "mthi", "mflo", "mtlo", "spec24","spec25","spec26","spec27", 104/*24 */ "mult", "multu","div", "divu", "spec34","spec35","spec36","spec37", 105/*32 */ "add", "addu", "sub", "subu", "and", "or", "xor", "nor", 106/*40 */ "spec50","spec51","slt","sltu", "spec54","spec55","spec56","spec57", 107/*48 */ "spec60","spec61","spec62","spec63","spec64","spec65","spec66","spec67", 108/*56 */ "spec70","spec71","spec72","spec73","spec74","spec75","spec76","spec77" 109}; 110 111static char *bcond_name[32] = { 112/* 0 */ "bltz", "bgez", "?", "?", "?", "?", "?", "?", 113/* 8 */ "?", "?", "?", "?", "?", "?", "?", "?", 114/*16 */ "bltzal", "bgezal", "?", "?", "?", "?", "?", "?", 115/*24 */ "?", "?", "?", "?", "?", "?", "?", "?", 116}; 117 118static char *cop1_name[64] = { 119/* 0 */ "fadd", "fsub", "fmpy", "fdiv", "fsqrt","fabs", "fmov", "fneg", 120/* 8 */ "fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f", 121/*16 */ "fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17", 122/*24 */ "fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f", 123/*32 */ "fcvts","fcvtd","fcvte","fop23","fcvtw","fop25","fop26","fop27", 124/*40 */ "fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f", 125/*48 */ "fcmp.f","fcmp.un","fcmp.eq","fcmp.ueq","fcmp.olt","fcmp.ult", 126 "fcmp.ole","fcmp.ule", 127/*56 */ "fcmp.sf","fcmp.ngle","fcmp.seq","fcmp.ngl","fcmp.lt","fcmp.nge", 128 "fcmp.le","fcmp.ngt" 129}; 130 131static char *fmt_name[16] = { 132 "s", "d", "e", "fmt3", 133 "w", "fmt5", "fmt6", "fmt7", 134 "fmt8", "fmt9", "fmta", "fmtb", 135 "fmtc", "fmtd", "fmte", "fmtf" 136}; 137 138static char *reg_name[32] = { 139 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 140 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 141 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 142 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" 143}; 144 145static char *c0_opname[64] = { 146 "c0op00","tlbr", "tlbwi", "c0op03","c0op04","c0op05","tlbwr", "c0op07", 147 "tlbp", "c0op11","c0op12","c0op13","c0op14","c0op15","c0op16","c0op17", 148 "rfe", "c0op21","c0op22","c0op23","c0op24","c0op25","c0op26","c0op27", 149 "c0op30","c0op31","c0op32","c0op33","c0op34","c0op35","c0op36","c0op37", 150 "c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47", 151 "c0op50","c0op51","c0op52","c0op53","c0op54","c0op55","c0op56","c0op57", 152 "c0op60","c0op61","c0op62","c0op63","c0op64","c0op65","c0op66","c0op67", 153 "c0op70","c0op71","c0op72","c0op73","c0op74","c0op75","c0op77","c0op77", 154}; 155 156static char *c0_reg[32] = { 157 "index","random","tlblo","c0r3","context","c0r5","c0r6","c0r7", 158 "badvaddr","c0r9","tlbhi","c0r11","sr", "cause","epc", "c0r15", 159 "c0r16","c0r17","c0r18","c0r19","c0r20","c0r21","c0r22","c0r23", 160 "c0r24","c0r25","c0r26","c0r27","c0r28","c0r29","c0r30","c0r31" 161}; 162 163/* 164 * Print the cause of the trap to kdb. 165 */ 166void 167kdbprinttrap(causeReg, vadr) 168 unsigned causeReg, vadr; 169{ 170 int type, pc; 171 extern char *trap_type[]; 172 173 type = (causeReg & MACH_CR_EXC_CODE) >> MACH_CR_EXC_CODE_SHIFT; 174 175 /* check to see if we are entering kdb via kdbpanic() */ 176 pc = kdbpcb.pcb_regs[PC]; 177 if (type == T_BREAK && pc < 0) { 178 if (kdbpeek(pc) == MACH_BREAK_KDB) 179 kdbpcb.pcb_regs[PC] = pc + 4; 180 } 181 182 kdbprintf("trap: %s\n", trap_type[type]); 183} 184 185unsigned kdb_ss_addr; 186unsigned kdb_ss_instr; 187 188void 189kdbsetsstep() 190{ 191 register unsigned va; 192 register int *locr0 = kdbpcb.pcb_regs; 193 int i; 194 195 /* compute next address after current location */ 196 va = MachEmulateBranch(locr0, locr0[PC], 0, 1); 197 if (kdb_ss_addr) { 198 kdbprintf("kdbsetsstep: breakpoint already set at %x (va %x)\n", 199 kdb_ss_addr, va); 200 return; 201 } 202 kdb_ss_addr = va; 203 204 if ((int)va < 0) { 205 /* kernel address */ 206 kdb_ss_instr = kdbpeek(va); 207 kdbpoke((caddr_t)va, MACH_BREAK_SSTEP); 208 kdbprintf("SS: breakpoint set at %x: %x (pc %x)\n", 209 kdb_ss_addr, kdb_ss_instr, locr0[PC]); /* XXX */ 210 return; 211 } 212 213 kdb_ss_instr = fuiword(va); 214 i = suiword((caddr_t)va, MACH_BREAK_SSTEP); 215 if (i < 0) { 216 register struct proc *p = curproc; 217 vm_offset_t sa, ea; 218 int rv; 219 220 sa = trunc_page((vm_offset_t)va); 221 ea = round_page((vm_offset_t)va+sizeof(int)-1); 222 rv = vm_map_protect(&p->p_vmspace->vm_map, sa, ea, 223 VM_PROT_DEFAULT, FALSE); 224 if (rv == KERN_SUCCESS) { 225 i = suiword((caddr_t)va, MACH_BREAK_SSTEP); 226 (void) vm_map_protect(&p->p_vmspace->vm_map, 227 sa, ea, VM_PROT_READ|VM_PROT_EXECUTE, FALSE); 228 } 229 } 230 if (i < 0) 231 return; 232 kdbprintf("SS: breakpoint set at %x: %x (pc %x)\n", 233 kdb_ss_addr, kdb_ss_instr, locr0[PC]); /* XXX */ 234} 235 236void 237kdbclrsstep() 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 printf("BREAK %x: %x\n", va, instr); /* XXX */ 261 if (instr != MACH_BREAK_SSTEP) 262 return; 263 264 if ((int)va < 0) { 265 /* kernel address */ 266 kdbpoke((caddr_t)va, kdb_ss_instr); 267 kdb_ss_addr = 0; 268 return; 269 } 270 271 /* restore original instruction and clear BP */ 272 i = suiword((caddr_t)va, kdb_ss_instr); 273 if (i < 0) { 274 register struct proc *p = curproc; 275 vm_offset_t sa, ea; 276 int rv; 277 278 sa = trunc_page((vm_offset_t)va); 279 ea = round_page((vm_offset_t)va+sizeof(int)-1); 280 rv = vm_map_protect(&p->p_vmspace->vm_map, sa, ea, 281 VM_PROT_DEFAULT, FALSE); 282 if (rv == KERN_SUCCESS) { 283 i = suiword((caddr_t)va, p->p_md.md_ss_instr); 284 (void) vm_map_protect(&p->p_vmspace->vm_map, 285 sa, ea, VM_PROT_READ|VM_PROT_EXECUTE, 286 FALSE); 287 } 288 } 289 if (i < 0) 290 kdbprintf("can't clear break at %x\n", va); 291 kdb_ss_addr = 0; 292} 293 294void 295kdbreadc(lp) 296 char *lp; 297{ 298 int c; 299 300 c = cngetc(); 301 if (c == '\r') 302 c = '\n'; 303 *lp = c; 304} 305 306void 307kdbwrite(lp, len) 308 char *lp; 309 int len; 310{ 311 while (len-- > 0) 312 cnputc(*lp++); 313} 314 315/* ARGSUSED */ 316void 317kdbprintins(space, ins) 318 int space; 319 long ins; 320{ 321 InstFmt i; 322 323 i.word = ins; 324 325 switch (i.JType.op) { 326 case OP_SPECIAL: 327 if (i.word == 0) { 328 kdbprintf("nop"); 329 break; 330 } 331 if (i.RType.func == OP_ADDU && i.RType.rt == 0) { 332 kdbprintf("move\t%s,%s", 333 reg_name[i.RType.rd], 334 reg_name[i.RType.rs]); 335 break; 336 } 337 kdbprintf("%s", spec_name[i.RType.func]); 338 switch (i.RType.func) { 339 case OP_SLL: 340 case OP_SRL: 341 case OP_SRA: 342 kdbprintf("\t%s,%s,%d", 343 reg_name[i.RType.rd], 344 reg_name[i.RType.rt], 345 i.RType.shamt); 346 break; 347 348 case OP_SLLV: 349 case OP_SRLV: 350 case OP_SRAV: 351 kdbprintf("\t%s,%s,%s", 352 reg_name[i.RType.rd], 353 reg_name[i.RType.rt], 354 reg_name[i.RType.rs]); 355 break; 356 357 case OP_MFHI: 358 case OP_MFLO: 359 kdbprintf("\t%s", reg_name[i.RType.rd]); 360 break; 361 362 case OP_JR: 363 case OP_JALR: 364 case OP_MTLO: 365 case OP_MTHI: 366 kdbprintf("\t%s", reg_name[i.RType.rs]); 367 break; 368 369 case OP_MULT: 370 case OP_MULTU: 371 case OP_DIV: 372 case OP_DIVU: 373 kdbprintf("\t%s,%s", 374 reg_name[i.RType.rs], 375 reg_name[i.RType.rt]); 376 break; 377 378 case OP_SYSCALL: 379 break; 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/* 551 * Print a stack backtrace. 552 */ 553void 554kdbstacktrace(printlocals) 555 int printlocals; 556{ 557} 558 559/* 560 * Very simple memory allocator for kdb. 561 */ 562char * 563kdbmalloc(size) 564 int size; 565{ 566 static char buffer[4096]; 567 static char *bufp = buffer; 568 char *p; 569 570 /* round size up to sizeof(int) */ 571 size = (size + sizeof(int) - 1) & ~(sizeof(int) - 1); 572 p = bufp; 573 bufp = p + size; 574 return (p); 575} 576 577/* 578 * Machine dependent printing '$'. 579 * Return zero if modif character not recognized. 580 */ 581kdbprintmachdep(modif) 582{ 583 register int i, j; 584 extern int tlbhi, tlblo; 585 586 switch (modif) { 587 case 'p': 588 case 'P': /* print TLB entries */ 589 if (kdbadrflg) { 590 i = kdbadrval; 591 if (i < 0 || i > VMMACH_NUM_TLB_ENTRIES) { 592 extern char *kdbBADMOD; 593 594 kdberror(kdbBADMOD); 595 break; 596 } 597 if (kdbcntflg == 0) 598 j = i + 1; 599 else { 600 j = i + kdbcntval; 601 if (j > VMMACH_NUM_TLB_ENTRIES) 602 j = VMMACH_NUM_TLB_ENTRIES; 603 } 604 } else { 605 i = 0; 606 j = VMMACH_NUM_TLB_ENTRIES; 607 } 608 for (; i < j; i++) { 609 MachTLBRead(i); 610 if (modif == 'p' && !(tlblo & PG_V)) 611 continue; 612 kdbprintf("TLB %2d: hi %8X low %8X\n", i, tlbhi, tlblo); 613 } 614 kdbprintf("TLB PID %x\n", MachTLBGetPID()); 615 break; 616 617 case 'f': /* find a TLB entry by virtaddr */ 618 case 'F': /* find a TLB entry by physaddr */ 619 j = kdbdot & PG_FRAME; 620 for (i = 0; i < VMMACH_NUM_TLB_ENTRIES; i++) { 621 MachTLBRead(i); 622 if (modif == 'f') { 623 if ((tlbhi & PG_FRAME) != j) 624 continue; 625 } else { 626 if ((tlblo & PG_FRAME) != j) 627 continue; 628 } 629 kdbprintf("TLB %2d: hi %8X low %8X\n", i, tlbhi, tlblo); 630 } 631 break; 632 633 default: 634 return (0); 635 } 636 return (1); 637} 638