1 /* $NetBSD: db_interface.c,v 1.45 2002/11/04 20:02:09 thorpej Exp $ */ 2 3 /* 4 * Mach Operating System 5 * Copyright (c) 1991,1990 Carnegie Mellon University 6 * All Rights Reserved. 7 * 8 * Permission to use, copy, modify and distribute this software and its 9 * documentation is hereby granted, provided that both the copyright 10 * notice and this permission notice appear in all copies of the 11 * software, derivative works or modified versions, and any portions 12 * thereof, and that both notices appear in supporting documentation. 13 * 14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 * 18 * Carnegie Mellon requests users of this software to return to 19 * 20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 21 * School of Computer Science 22 * Carnegie Mellon University 23 * Pittsburgh PA 15213-3890 24 * 25 * any improvements or extensions that they make and grant Carnegie Mellon 26 * the rights to redistribute these changes. 27 */ 28 29 #include "opt_cputype.h" /* which mips CPUs do we support? */ 30 #include "opt_ddb.h" 31 #include "opt_kgdb.h" 32 33 #include <sys/types.h> 34 #include <sys/systm.h> 35 #include <sys/param.h> 36 #include <sys/proc.h> 37 #include <sys/user.h> 38 #include <sys/reboot.h> 39 40 #include <uvm/uvm_extern.h> 41 42 #include <mips/cache.h> 43 #include <mips/pte.h> 44 #include <mips/cpu.h> 45 #include <mips/locore.h> 46 #include <mips/mips_opcode.h> 47 #include <dev/cons.h> 48 49 #include <machine/db_machdep.h> 50 #include <ddb/db_access.h> 51 #ifndef KGDB 52 #include <ddb/db_command.h> 53 #include <ddb/db_output.h> 54 #include <ddb/db_sym.h> 55 #include <ddb/db_extern.h> 56 #include <ddb/db_interface.h> 57 #endif 58 59 int db_active = 0; 60 db_regs_t ddb_regs; 61 mips_reg_t kdbaux[11]; /* XXX struct switchframe: better inside curpcb? XXX */ 62 63 void db_tlbdump_cmd(db_expr_t, int, db_expr_t, char *); 64 void db_kvtophys_cmd(db_expr_t, int, db_expr_t, char *); 65 void db_cp0dump_cmd(db_expr_t, int, db_expr_t, char *); 66 67 static void kdbpoke_4(vaddr_t addr, int newval); 68 static void kdbpoke_2(vaddr_t addr, short newval); 69 static void kdbpoke_1(vaddr_t addr, char newval); 70 static short kdbpeek_2(vaddr_t addr); 71 static char kdbpeek_1(vaddr_t addr); 72 extern vaddr_t MachEmulateBranch(struct frame *, vaddr_t, unsigned, int); 73 74 extern paddr_t kvtophys(vaddr_t); 75 76 #ifdef DDB_TRACE 77 int 78 kdbpeek(vaddr_t addr) 79 { 80 81 if (addr == 0 || (addr & 3)) 82 return 0; 83 return *(int *)addr; 84 } 85 #endif 86 87 static short 88 kdbpeek_2(vaddr_t addr) 89 { 90 91 return *(short *)addr; 92 } 93 94 static char 95 kdbpeek_1(vaddr_t addr) 96 { 97 98 return *(char *)addr; 99 } 100 101 /* 102 * kdbpoke -- write a value to a kernel virtual address. 103 * XXX should handle KSEG2 addresses and check for unmapped pages. 104 * XXX user-space addresess? 105 */ 106 static void 107 kdbpoke_4(vaddr_t addr, int newval) 108 { 109 110 *(int*) addr = newval; 111 wbflush(); 112 } 113 114 static void 115 kdbpoke_2(vaddr_t addr, short newval) 116 { 117 118 *(short*) addr = newval; 119 wbflush(); 120 } 121 122 static void 123 kdbpoke_1(vaddr_t addr, char newval) 124 { 125 *(char*) addr = newval; 126 wbflush(); 127 } 128 129 #if 0 /* UNUSED */ 130 /* 131 * Received keyboard interrupt sequence. 132 */ 133 void 134 kdb_kbd_trap(int *tf) 135 { 136 137 if (db_active == 0 && (boothowto & RB_KDB)) { 138 printf("\n\nkernel: keyboard interrupt\n"); 139 ddb_trap(-1, tf); 140 } 141 } 142 #endif 143 144 #ifndef KGDB 145 int 146 kdb_trap(int type, mips_reg_t /* struct trapframe */ *tfp) 147 { 148 149 struct frame *f = (struct frame *)&ddb_regs; 150 151 #ifdef notyet 152 switch (type) { 153 case T_BREAK: /* breakpoint */ 154 case -1: /* keyboard interrupt */ 155 break; 156 default: 157 printf("kernel: %s trap", trap_type[type & 0xff]); 158 if (db_recover != 0) { 159 db_error("Faulted in DDB; continuing...\n"); 160 /*NOTREACHED*/ 161 } 162 break; 163 } 164 #endif 165 /* Should switch to kdb`s own stack here. */ 166 db_set_ddb_regs(type, tfp); 167 168 db_active++; 169 cnpollc(1); 170 db_trap(type & ~T_USER, 0 /*code*/); 171 cnpollc(0); 172 db_active--; 173 174 if (type & T_USER) 175 *(struct frame *)curproc->p_md.md_regs = *f; 176 else { 177 /* Synthetic full scale register context when trap happens */ 178 tfp[TF_AST] = f->f_regs[AST]; 179 tfp[TF_V0] = f->f_regs[V0]; 180 tfp[TF_V1] = f->f_regs[V1]; 181 tfp[TF_A0] = f->f_regs[A0]; 182 tfp[TF_A1] = f->f_regs[A1]; 183 tfp[TF_A2] = f->f_regs[A2]; 184 tfp[TF_A3] = f->f_regs[A3]; 185 tfp[TF_T0] = f->f_regs[T0]; 186 tfp[TF_T1] = f->f_regs[T1]; 187 tfp[TF_T2] = f->f_regs[T2]; 188 tfp[TF_T3] = f->f_regs[T3]; 189 tfp[TF_TA0] = f->f_regs[TA0]; 190 tfp[TF_TA1] = f->f_regs[TA1]; 191 tfp[TF_TA2] = f->f_regs[TA2]; 192 tfp[TF_TA3] = f->f_regs[TA3]; 193 tfp[TF_T8] = f->f_regs[T8]; 194 tfp[TF_T9] = f->f_regs[T9]; 195 tfp[TF_RA] = f->f_regs[RA]; 196 tfp[TF_SR] = f->f_regs[SR]; 197 tfp[TF_MULLO] = f->f_regs[MULLO]; 198 tfp[TF_MULHI] = f->f_regs[MULHI]; 199 tfp[TF_EPC] = f->f_regs[PC]; 200 kdbaux[0] = f->f_regs[S0]; 201 kdbaux[1] = f->f_regs[S1]; 202 kdbaux[2] = f->f_regs[S2]; 203 kdbaux[3] = f->f_regs[S3]; 204 kdbaux[4] = f->f_regs[S4]; 205 kdbaux[5] = f->f_regs[S5]; 206 kdbaux[6] = f->f_regs[S6]; 207 kdbaux[7] = f->f_regs[S7]; 208 kdbaux[8] = f->f_regs[SP]; 209 kdbaux[9] = f->f_regs[S8]; 210 kdbaux[10] = f->f_regs[GP]; 211 } 212 213 return (1); 214 } 215 216 void 217 cpu_Debugger(void) 218 { 219 220 asm("break"); 221 } 222 #endif /* !KGDB */ 223 224 void 225 db_set_ddb_regs(int type, mips_reg_t *tfp) 226 { 227 struct frame *f = (struct frame *)&ddb_regs; 228 229 /* Should switch to kdb`s own stack here. */ 230 231 if (type & T_USER) 232 *f = *(struct frame *)curproc->p_md.md_regs; 233 else { 234 /* Synthetic full scale register context when trap happens */ 235 f->f_regs[AST] = tfp[TF_AST]; 236 f->f_regs[V0] = tfp[TF_V0]; 237 f->f_regs[V1] = tfp[TF_V1]; 238 f->f_regs[A0] = tfp[TF_A0]; 239 f->f_regs[A1] = tfp[TF_A1]; 240 f->f_regs[A2] = tfp[TF_A2]; 241 f->f_regs[A3] = tfp[TF_A3]; 242 f->f_regs[T0] = tfp[TF_T0]; 243 f->f_regs[T1] = tfp[TF_T1]; 244 f->f_regs[T2] = tfp[TF_T2]; 245 f->f_regs[T3] = tfp[TF_T3]; 246 f->f_regs[TA0] = tfp[TF_TA0]; 247 f->f_regs[TA1] = tfp[TF_TA1]; 248 f->f_regs[TA2] = tfp[TF_TA2]; 249 f->f_regs[TA3] = tfp[TF_TA3]; 250 f->f_regs[T8] = tfp[TF_T8]; 251 f->f_regs[T9] = tfp[TF_T9]; 252 f->f_regs[RA] = tfp[TF_RA]; 253 f->f_regs[SR] = tfp[TF_SR]; 254 f->f_regs[MULLO] = tfp[TF_MULLO]; 255 f->f_regs[MULHI] = tfp[TF_MULHI]; 256 f->f_regs[PC] = tfp[TF_EPC]; 257 f->f_regs[S0] = kdbaux[0]; 258 f->f_regs[S1] = kdbaux[1]; 259 f->f_regs[S2] = kdbaux[2]; 260 f->f_regs[S3] = kdbaux[3]; 261 f->f_regs[S4] = kdbaux[4]; 262 f->f_regs[S5] = kdbaux[5]; 263 f->f_regs[S6] = kdbaux[6]; 264 f->f_regs[S7] = kdbaux[7]; 265 f->f_regs[SP] = kdbaux[8]; 266 f->f_regs[S8] = kdbaux[9]; 267 f->f_regs[GP] = kdbaux[10]; 268 } 269 } 270 271 /* 272 * Read bytes from kernel address space for debugger. 273 */ 274 void 275 db_read_bytes(vaddr_t addr, size_t size, char *data) 276 { 277 278 while (size >= 4) 279 *((int*)data)++ = kdbpeek(addr), addr += 4, size -= 4; 280 while (size >= 2) 281 *((short*)data)++ = kdbpeek_2(addr), addr += 2, size -= 2; 282 if (size == 1) 283 *((char*)data)++ = kdbpeek_1(addr); 284 } 285 286 /* 287 * Write bytes to kernel address space for debugger. 288 */ 289 void 290 db_write_bytes(vaddr_t addr, size_t size, char *data) 291 { 292 vaddr_t p = addr; 293 size_t n = size; 294 295 #ifdef DEBUG_DDB 296 printf("db_write_bytes(%lx, %d, %p, val %x)\n", addr, size, data, 297 (addr &3 ) == 0? *(u_int*)addr: -1); 298 #endif 299 300 while (n >= 4) { 301 kdbpoke_4(p, *(int*)data); 302 p += 4; 303 data += 4; 304 n -= 4; 305 } 306 if (n >= 2) { 307 kdbpoke_2(p, *(short*)data); 308 p += 2; 309 data += 2; 310 n -= 2; 311 } 312 if (n == 1) { 313 kdbpoke_1(p, *(char*)data); 314 } 315 316 mips_icache_sync_range((vaddr_t) addr, size); 317 } 318 319 #ifndef KGDB 320 void 321 db_tlbdump_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) 322 { 323 324 #ifdef MIPS1 325 if (!MIPS_HAS_R4K_MMU) { 326 struct mips1_tlb { 327 u_int32_t tlb_hi; 328 u_int32_t tlb_lo; 329 } tlb; 330 int i; 331 void mips1_TLBRead(int, struct mips1_tlb *); 332 333 for (i = 0; i < mips_num_tlb_entries; i++) { 334 mips1_TLBRead(i, &tlb); 335 db_printf("TLB%c%2d Hi 0x%08x Lo 0x%08x", 336 (tlb.tlb_lo & MIPS1_PG_V) ? ' ' : '*', 337 i, tlb.tlb_hi, 338 tlb.tlb_lo & MIPS1_PG_FRAME); 339 db_printf(" %c%c%c\n", 340 (tlb.tlb_lo & MIPS1_PG_D) ? 'D' : ' ', 341 (tlb.tlb_lo & MIPS1_PG_G) ? 'G' : ' ', 342 (tlb.tlb_lo & MIPS1_PG_N) ? 'N' : ' '); 343 } 344 } 345 #endif 346 #ifdef MIPS3_PLUS 347 if (MIPS_HAS_R4K_MMU) { 348 struct tlb tlb; 349 int i; 350 351 for (i = 0; i < mips_num_tlb_entries; i++) { 352 #if defined(MIPS3) 353 #if defined(MIPS3_5900) 354 mips5900_TLBRead(i, &tlb); 355 #else 356 mips3_TLBRead(i, &tlb); 357 #endif 358 #elif defined(MIPS32) 359 mips32_TLBRead(i, &tlb); 360 #elif defined(MIPS64) 361 mips64_TLBRead(i, &tlb); 362 #endif 363 db_printf("TLB%c%2d Hi 0x%08x ", 364 (tlb.tlb_lo0 | tlb.tlb_lo1) & MIPS3_PG_V ? ' ' : '*', 365 i, tlb.tlb_hi); 366 db_printf("Lo0=0x%08x %c%c attr %x ", 367 (unsigned)mips_tlbpfn_to_paddr(tlb.tlb_lo0), 368 (tlb.tlb_lo0 & MIPS3_PG_D) ? 'D' : ' ', 369 (tlb.tlb_lo0 & MIPS3_PG_G) ? 'G' : ' ', 370 (tlb.tlb_lo0 >> 3) & 7); 371 db_printf("Lo1=0x%08x %c%c attr %x sz=%x\n", 372 (unsigned)mips_tlbpfn_to_paddr(tlb.tlb_lo1), 373 (tlb.tlb_lo1 & MIPS3_PG_D) ? 'D' : ' ', 374 (tlb.tlb_lo1 & MIPS3_PG_G) ? 'G' : ' ', 375 (tlb.tlb_lo1 >> 3) & 7, 376 tlb.tlb_mask); 377 } 378 } 379 #endif 380 } 381 382 void 383 db_kvtophys_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) 384 { 385 386 if (!have_addr) 387 return; 388 if (MIPS_KSEG2_START <= addr) { 389 /* 390 * Cast the physical address -- some platforms, while 391 * being ILP32, may be using 64-bit paddr_t's. 392 */ 393 db_printf("0x%lx -> 0x%qx\n", addr, 394 (unsigned long long) kvtophys(addr)); 395 } else 396 printf("not a kernel virtual address\n"); 397 } 398 399 #define FLDWIDTH 10 400 #define SHOW32(reg, name) \ 401 do { \ 402 uint32_t __val; \ 403 \ 404 asm volatile("mfc0 %0,$" ___STRING(reg) : "=r"(__val)); \ 405 printf(" %s:%*s %#x\n", name, FLDWIDTH - (int) strlen(name), \ 406 "", __val); \ 407 } while (0) 408 409 /* XXX not 64-bit ABI safe! */ 410 #define SHOW64(reg, name) \ 411 do { \ 412 uint64_t __val; \ 413 \ 414 asm volatile( \ 415 ".set push \n\t" \ 416 ".set mips3 \n\t" \ 417 ".set noat \n\t" \ 418 "dmfc0 $1,$" ___STRING(reg) " \n\t" \ 419 "dsll %L0,$1,32 \n\t" \ 420 "dsrl %L0,%L0,32 \n\t" \ 421 "dsrl %M0,$1,32 \n\t" \ 422 ".set pop" \ 423 : "=r"(__val)); \ 424 printf(" %s:%*s %#llx\n", name, FLDWIDTH - (int) strlen(name), \ 425 "", __val); \ 426 } while (0) 427 428 void 429 db_cp0dump_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) 430 { 431 432 SHOW32(MIPS_COP_0_TLB_INDEX, "index"); 433 SHOW32(MIPS_COP_0_TLB_RANDOM, "random"); 434 435 if (!MIPS_HAS_R4K_MMU) { 436 SHOW32(MIPS_COP_0_TLB_LOW, "entrylow"); 437 } else { 438 if (CPUIS64BITS) { 439 SHOW64(MIPS_COP_0_TLB_LO0, "entrylo0"); 440 SHOW64(MIPS_COP_0_TLB_LO1, "entrylo1"); 441 } else { 442 SHOW32(MIPS_COP_0_TLB_LO0, "entrylo0"); 443 SHOW32(MIPS_COP_0_TLB_LO1, "entrylo1"); 444 } 445 } 446 447 if (CPUIS64BITS) { 448 SHOW64(MIPS_COP_0_TLB_CONTEXT, "context"); 449 } else { 450 SHOW32(MIPS_COP_0_TLB_CONTEXT, "context"); 451 } 452 453 if (MIPS_HAS_R4K_MMU) { 454 SHOW32(MIPS_COP_0_TLB_PG_MASK, "pagemask"); 455 SHOW32(MIPS_COP_0_TLB_WIRED, "wired"); 456 } 457 458 if (CPUIS64BITS) { 459 SHOW64(MIPS_COP_0_BAD_VADDR, "badvaddr"); 460 } else { 461 SHOW32(MIPS_COP_0_BAD_VADDR, "badvaddr"); 462 } 463 464 if (cpu_arch >= CPU_ARCH_MIPS3) { 465 SHOW32(MIPS_COP_0_COUNT, "count"); 466 } 467 468 if (CPUIS64BITS) { 469 SHOW64(MIPS_COP_0_TLB_HI, "entryhi"); 470 } else { 471 SHOW32(MIPS_COP_0_TLB_HI, "entryhi"); 472 } 473 474 if (cpu_arch >= CPU_ARCH_MIPS3) { 475 SHOW32(MIPS_COP_0_COMPARE, "compare"); 476 } 477 478 SHOW32(MIPS_COP_0_STATUS, "status"); 479 SHOW32(MIPS_COP_0_CAUSE, "cause"); 480 481 if (CPUIS64BITS) { 482 SHOW64(MIPS_COP_0_EXC_PC, "epc"); 483 } else { 484 SHOW32(MIPS_COP_0_EXC_PC, "epc"); 485 } 486 487 SHOW32(MIPS_COP_0_PRID, "prid"); 488 SHOW32(MIPS_COP_0_CONFIG, "config"); 489 490 #if defined(MIPS32) || defined(MIPS64) 491 if (CPUISMIPSNN) { 492 uint32_t val; 493 494 val = mipsNN_cp0_config1_read(); 495 printf(" config1: %#x\n", val); 496 } 497 #endif 498 499 if (MIPS_HAS_LLSC) { 500 if (CPUISMIPS64) { 501 SHOW64(MIPS_COP_0_LLADDR, "lladdr"); 502 SHOW64(MIPS_COP_0_WATCH_LO, "watchlo"); 503 } else { 504 SHOW32(MIPS_COP_0_LLADDR, "lladdr"); 505 SHOW32(MIPS_COP_0_WATCH_LO, "watchlo"); 506 } 507 508 SHOW32(MIPS_COP_0_WATCH_HI, "watchhi"); 509 510 if (CPUIS64BITS) { 511 SHOW64(MIPS_COP_0_TLB_XCONTEXT, "xcontext"); 512 } 513 514 if (CPUISMIPSNN) { 515 if (CPUISMIPS64) { 516 SHOW64(MIPS_COP_0_PERFCNT, "perfcnt"); 517 } else { 518 SHOW32(MIPS_COP_0_PERFCNT, "perfcnt"); 519 } 520 } 521 522 SHOW32(MIPS_COP_0_ECC, "ecc"); 523 SHOW32(MIPS_COP_0_CACHE_ERR, "cacherr"); 524 SHOW32(MIPS_COP_0_TAG_LO, "cachelo"); 525 SHOW32(MIPS_COP_0_TAG_HI, "cachehi"); 526 527 if (CPUIS64BITS) { 528 SHOW64(MIPS_COP_0_ERROR_PC, "errorpc"); 529 } else { 530 SHOW32(MIPS_COP_0_ERROR_PC, "errorpc"); 531 } 532 } 533 } 534 535 const struct db_command db_machine_command_table[] = { 536 { "kvtop", db_kvtophys_cmd, 0, 0 }, 537 { "tlb", db_tlbdump_cmd, 0, 0 }, 538 { "cp0", db_cp0dump_cmd, 0, 0 }, 539 { (char *)0, } 540 }; 541 #endif /* !KGDB */ 542 543 /* 544 * Determine whether the instruction involves a delay slot. 545 */ 546 boolean_t 547 inst_branch(int inst) 548 { 549 InstFmt i; 550 int delay; 551 552 i.word = inst; 553 delay = 0; 554 switch (i.JType.op) { 555 case OP_BCOND: 556 case OP_J: 557 case OP_JAL: 558 case OP_BEQ: 559 case OP_BNE: 560 case OP_BLEZ: 561 case OP_BGTZ: 562 case OP_BEQL: 563 case OP_BNEL: 564 case OP_BLEZL: 565 case OP_BGTZL: 566 delay = 1; 567 break; 568 569 case OP_COP0: 570 case OP_COP1: 571 switch (i.RType.rs) { 572 case OP_BCx: 573 case OP_BCy: 574 delay = 1; 575 } 576 break; 577 578 case OP_SPECIAL: 579 if (i.RType.op == OP_JR || i.RType.op == OP_JALR) 580 delay = 1; 581 break; 582 } 583 return delay; 584 } 585 586 /* 587 * Determine whether the instruction calls a function. 588 */ 589 boolean_t 590 inst_call(int inst) 591 { 592 boolean_t call; 593 InstFmt i; 594 595 i.word = inst; 596 if (i.JType.op == OP_SPECIAL 597 && ((i.RType.func == OP_JR && i.RType.rs != 31) || 598 i.RType.func == OP_JALR)) 599 call = 1; 600 else if (i.JType.op == OP_JAL) 601 call = 1; 602 else 603 call = 0; 604 return call; 605 } 606 607 /* 608 * Determine whether the instruction returns from a function (j ra). The 609 * compiler can use this construct for other jumps, but usually will not. 610 * This lets the ddb "next" command to work (also need inst_trap_return()). 611 */ 612 boolean_t 613 inst_return(int inst) 614 { 615 InstFmt i; 616 617 i.word = inst; 618 619 return (i.JType.op == OP_SPECIAL && i.RType.func == OP_JR && 620 i.RType.rs == 31); 621 } 622 623 /* 624 * Determine whether the instruction makes a jump. 625 */ 626 boolean_t 627 inst_unconditional_flow_transfer(int inst) 628 { 629 InstFmt i; 630 boolean_t jump; 631 632 i.word = inst; 633 jump = (i.JType.op == OP_J) || 634 (i.JType.op == OP_SPECIAL && i.RType.func == OP_JR); 635 return jump; 636 } 637 638 /* 639 * Determine whether the instruction is a load/store as appropriate. 640 */ 641 boolean_t 642 inst_load(int inst) 643 { 644 InstFmt i; 645 646 i.word = inst; 647 648 switch (i.JType.op) { 649 case OP_LWC1: 650 case OP_LB: 651 case OP_LH: 652 case OP_LW: 653 case OP_LD: 654 case OP_LBU: 655 case OP_LHU: 656 case OP_LWU: 657 case OP_LDL: 658 case OP_LDR: 659 case OP_LWL: 660 case OP_LWR: 661 case OP_LL: 662 return 1; 663 default: 664 return 0; 665 } 666 } 667 668 boolean_t 669 inst_store(int inst) 670 { 671 InstFmt i; 672 673 i.word = inst; 674 675 switch (i.JType.op) { 676 case OP_SWC1: 677 case OP_SB: 678 case OP_SH: 679 case OP_SW: 680 case OP_SD: 681 case OP_SDL: 682 case OP_SDR: 683 case OP_SWL: 684 case OP_SWR: 685 case OP_SCD: 686 return 1; 687 default: 688 return 0; 689 } 690 } 691 692 /* 693 * Return the next pc if the given branch is taken. 694 * MachEmulateBranch() runs analysis for branch delay slot. 695 */ 696 db_addr_t 697 branch_taken(int inst, db_addr_t pc, db_regs_t *regs) 698 { 699 vaddr_t ra; 700 unsigned fpucsr; 701 702 fpucsr = curproc ? PCB_FSR(&curproc->p_addr->u_pcb) : 0; 703 ra = MachEmulateBranch((struct frame *)regs, pc, fpucsr, 0); 704 return ra; 705 } 706 707 /* 708 * Return the next pc of an arbitrary instruction. 709 */ 710 db_addr_t 711 next_instr_address(db_addr_t pc, boolean_t bd) 712 { 713 unsigned ins; 714 715 if (bd == FALSE) 716 return (pc + 4); 717 718 if (pc < MIPS_KSEG0_START) 719 ins = fuiword((void *)pc); 720 else 721 ins = *(unsigned *)pc; 722 723 if (inst_branch(ins) || inst_call(ins) || inst_return(ins)) 724 return (pc + 4); 725 726 return (pc); 727 } 728