1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * isa-dependent portions of the kmdb target 31 */ 32 33 #include <mdb/mdb_kreg_impl.h> 34 #include <mdb/mdb_debug.h> 35 #include <mdb/mdb_modapi.h> 36 #include <mdb/mdb_v9util.h> 37 #include <mdb/mdb_target_impl.h> 38 #include <mdb/mdb_err.h> 39 #include <mdb/mdb_umem.h> 40 #include <kmdb/kmdb_kdi.h> 41 #include <kmdb/kmdb_dpi.h> 42 #include <kmdb/kmdb_promif.h> 43 #include <kmdb/kmdb_asmutil.h> 44 #include <kmdb/kvm.h> 45 #include <mdb/mdb.h> 46 47 #include <sys/types.h> 48 #include <sys/stack.h> 49 #include <sys/regset.h> 50 #include <sys/sysmacros.h> 51 #include <sys/bitmap.h> 52 #include <sys/machtrap.h> 53 #include <sys/trap.h> 54 55 /* Higher than the highest trap number for which we have a specific specifier */ 56 #define KMT_MAXTRAPNO 0x1ff 57 58 #define OP(x) ((x) >> 30) 59 #define OP3(x) (((x) >> 19) & 0x3f) 60 #define RD(x) (((x) >> 25) & 0x1f) 61 #define RS1(x) (((x) >> 14) & 0x1f) 62 #define RS2(x) ((x) & 0x1f) 63 64 #define OP_ARITH 0x2 65 66 #define OP3_OR 0x02 67 #define OP3_SAVE 0x3c 68 #define OP3_RESTORE 0x3d 69 70 static int 71 kmt_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp, 72 mdb_tgt_stack_f *func, void *arg, int cpu) 73 { 74 mdb_tgt_gregset_t gregs; 75 kreg_t *kregs = &gregs.kregs[0]; 76 long nwin, stopwin, canrestore, wp, i, sp; 77 long argv[6]; 78 79 /* 80 * If gsp isn't null, we were asked to dump a trace from a 81 * specific location. The normal iterator can handle that. 82 */ 83 if (gsp != NULL) { 84 if (cpu != DPI_MASTER_CPUID) 85 warn("register set provided - ignoring cpu argument\n"); 86 return (mdb_kvm_v9stack_iter(t, gsp, func, arg)); 87 } 88 89 if (kmdb_dpi_get_cpu_state(cpu) < 0) { 90 warn("failed to iterate through stack for cpu %u", cpu); 91 return (DCMD_ERR); 92 } 93 94 /* 95 * We're being asked to dump the trace for the current CPU. 96 * To do that, we need to iterate first through the saved 97 * register windors. If there's more to the trace than that, 98 * we'll hand off to the normal iterator. 99 */ 100 bcopy(kmdb_dpi_get_gregs(cpu), &gregs, sizeof (mdb_tgt_gregset_t)); 101 102 wp = kregs[KREG_CWP]; 103 canrestore = kregs[KREG_CANRESTORE]; 104 nwin = kmdb_dpi_get_nwin(cpu); 105 stopwin = ((wp + nwin) - canrestore - 1) % nwin; 106 107 mdb_dprintf(MDB_DBG_KMOD, "dumping cwp = %lu, canrestore = %lu, " 108 "stopwin = %lu\n", wp, canrestore, stopwin); 109 110 for (;;) { 111 struct rwindow rwin; 112 113 for (i = 0; i < 6; i++) 114 argv[i] = kregs[KREG_I0 + i]; 115 116 if (kregs[KREG_PC] != 0 && 117 func(arg, kregs[KREG_PC], 6, argv, &gregs) != 0) 118 return (0); 119 120 kregs[KREG_PC] = kregs[KREG_I7]; 121 kregs[KREG_NPC] = kregs[KREG_PC] + 4; 122 123 if ((sp = kregs[KREG_FP] + STACK_BIAS) == STACK_BIAS || sp == 0) 124 return (0); /* Stop if we're at the end of stack */ 125 126 if (sp & (STACK_ALIGN - 1)) 127 return (set_errno(EMDB_STKALIGN)); 128 129 wp = (wp + nwin - 1) % nwin; 130 131 if (wp == stopwin) 132 break; 133 134 bcopy(&kregs[KREG_I0], &kregs[KREG_O0], 8 * sizeof (kreg_t)); 135 136 if (kmdb_dpi_get_rwin(cpu, wp, &rwin) < 0) { 137 warn("unable to get registers from window %ld\n", wp); 138 return (-1); 139 } 140 141 for (i = 0; i < 8; i++) 142 kregs[KREG_L0 + i] = (uintptr_t)rwin.rw_local[i]; 143 for (i = 0; i < 8; i++) 144 kregs[KREG_I0 + i] = (uintptr_t)rwin.rw_in[i]; 145 } 146 147 mdb_dprintf(MDB_DBG_KMOD, "dumping wp %ld and beyond normally\n", wp); 148 149 /* 150 * hack - if we null out pc here, iterator won't print the frame 151 * that corresponds to the current set of registers. That's what we 152 * want because we just printed them above. 153 */ 154 kregs[KREG_PC] = 0; 155 return (mdb_kvm_v9stack_iter(t, &gregs, func, arg)); 156 } 157 158 void 159 kmt_printregs(const mdb_tgt_gregset_t *gregs) 160 { 161 mdb_v9printregs(gregs); 162 } 163 164 static int 165 kmt_stack_common(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv, 166 int cpuid, mdb_tgt_stack_f *func, kreg_t saved_pc) 167 { 168 mdb_tgt_gregset_t *grp = NULL; 169 mdb_tgt_gregset_t gregs; 170 void *arg = (void *)mdb.m_nargs; 171 172 if (flags & DCMD_ADDRSPEC) { 173 bzero(&gregs, sizeof (gregs)); 174 gregs.kregs[KREG_FP] = addr; 175 gregs.kregs[KREG_I7] = saved_pc; 176 grp = &gregs; 177 } 178 179 if (argc != 0) { 180 if (argv->a_type == MDB_TYPE_CHAR || argc > 1) 181 return (DCMD_USAGE); 182 183 if (argv->a_type == MDB_TYPE_STRING) 184 arg = (void *)(uint_t)mdb_strtoull(argv->a_un.a_str); 185 else 186 arg = (void *)(uint_t)argv->a_un.a_val; 187 } 188 189 (void) kmt_stack_iter(mdb.m_target, grp, func, arg, cpuid); 190 191 return (DCMD_OK); 192 } 193 194 int 195 kmt_cpustack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv, 196 int cpuid, int verbose) 197 { 198 return (kmt_stack_common(addr, flags, argc, argv, cpuid, 199 (verbose ? mdb_kvm_v9framev : mdb_kvm_v9frame), 0)); 200 } 201 202 int 203 kmt_stack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 204 { 205 return (kmt_stack_common(addr, flags, argc, argv, DPI_MASTER_CPUID, 206 mdb_kvm_v9frame, 0)); 207 } 208 209 int 210 kmt_stackv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 211 { 212 return (kmt_stack_common(addr, flags, argc, argv, DPI_MASTER_CPUID, 213 mdb_kvm_v9framev, 0)); 214 } 215 216 int 217 kmt_stackr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 218 { 219 /* 220 * Force printing of the first register window by setting the saved 221 * pc (%i7) to PC_FAKE. 222 */ 223 return (kmt_stack_common(addr, flags, argc, argv, DPI_MASTER_CPUID, 224 mdb_kvm_v9framer, PC_FAKE)); 225 } 226 227 ssize_t 228 kmt_write_page(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr) 229 { 230 jmp_buf *oldpcb = NULL; 231 jmp_buf pcb; 232 physaddr_t pa; 233 234 /* 235 * Can we write to this page? 236 */ 237 if (!(t->t_flags & MDB_TGT_F_ALLOWIO) && 238 (nbytes = kmdb_kdi_range_is_nontoxic(addr, nbytes, 1)) == 0) 239 return (set_errno(EMDB_NOMAP)); 240 241 /* 242 * The OBP va>pa call returns a protection value that's right only some 243 * of the time. We can, however, tell if we failed a write due to a 244 * protection violation. If we get such an error, we'll retry the 245 * write using pwrite. 246 */ 247 if (setjmp(pcb) != 0) { 248 /* We failed the write */ 249 kmdb_dpi_restore_fault_hdlr(oldpcb); 250 251 if (errno == EACCES && kmdb_prom_vtop(addr, &pa) == 0) 252 return (kmt_pwrite(t, buf, nbytes, pa)); 253 return (-1); /* errno is set for us */ 254 } 255 256 mdb_dprintf(MDB_DBG_KMOD, "copying %lu bytes from %p to %p\n", nbytes, 257 buf, (void *)addr); 258 259 oldpcb = kmdb_dpi_set_fault_hdlr(&pcb); 260 (void) kmt_writer((void *)buf, nbytes, addr); 261 kmdb_dpi_restore_fault_hdlr(oldpcb); 262 263 return (nbytes); 264 } 265 266 /*ARGSUSED*/ 267 ssize_t 268 kmt_write(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr) 269 { 270 size_t ntowrite, nwritten, n; 271 int rc; 272 273 kmdb_prom_check_interrupt(); 274 275 if (nbytes == 0) 276 return (0); 277 278 /* 279 * Break the writes up into page-sized chunks. First, the leading page 280 * fragment (if any), then the subsequent pages. 281 */ 282 283 if ((n = (addr & (mdb.m_pagesize - 1))) != 0) { 284 ntowrite = MIN(mdb.m_pagesize - n, nbytes); 285 286 if ((rc = kmt_write_page(t, buf, ntowrite, addr)) != ntowrite) 287 return (rc); 288 289 addr = roundup(addr, mdb.m_pagesize); 290 nbytes -= ntowrite; 291 nwritten = ntowrite; 292 buf = ((caddr_t)buf + ntowrite); 293 } 294 295 while (nbytes > 0) { 296 ntowrite = MIN(mdb.m_pagesize, nbytes); 297 298 if ((rc = kmt_write_page(t, buf, ntowrite, addr)) != ntowrite) 299 return (rc < 0 ? rc : rc + nwritten); 300 301 addr += mdb.m_pagesize; 302 nbytes -= ntowrite; 303 nwritten += ntowrite; 304 buf = ((caddr_t)buf + ntowrite); 305 } 306 307 return (rc); 308 } 309 310 /*ARGSUSED*/ 311 ssize_t 312 kmt_ioread(mdb_tgt_t *t, void *buf, size_t nbytes, uintptr_t addr) 313 { 314 return (set_errno(EMDB_TGTHWNOTSUP)); 315 } 316 317 /*ARGSUSED*/ 318 ssize_t 319 kmt_iowrite(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr) 320 { 321 return (set_errno(EMDB_TGTHWNOTSUP)); 322 } 323 324 const char * 325 kmt_def_dismode(void) 326 { 327 #ifdef __sparcv9 328 return ("v9plus"); 329 #else 330 return ("v8"); 331 #endif 332 } 333 334 /* 335 * If we are stopped on a save instruction or at the first instruction of a 336 * known function, return %o7 as the step-out address; otherwise return the 337 * current frame's return address (%i7). Significantly better handling of 338 * step out in leaf routines could be accomplished by implementing more 339 * complex decoding of the current function and our current state. 340 */ 341 int 342 kmt_step_out(mdb_tgt_t *t, uintptr_t *p) 343 { 344 kreg_t pc, i7, o7; 345 GElf_Sym func; 346 347 (void) kmdb_dpi_get_register("pc", &pc); 348 (void) kmdb_dpi_get_register("i7", &i7); 349 (void) kmdb_dpi_get_register("o7", &o7); 350 351 if (mdb_tgt_lookup_by_addr(t, pc, MDB_TGT_SYM_FUZZY, NULL, 0, 352 &func, NULL) == 0 && func.st_value == pc) 353 *p = o7 + 2 * sizeof (mdb_instr_t); 354 else { 355 mdb_instr_t instr; 356 357 if (mdb_tgt_vread(t, &instr, sizeof (instr), pc) != 358 sizeof (instr)) { 359 warn("failed to read instruction at %p for step out", 360 (void *)pc); 361 return (-1); 362 } 363 364 if (OP(instr) == OP_ARITH && OP3(instr) == OP3_SAVE) 365 *p = o7 + 2 * sizeof (mdb_instr_t); 366 else 367 *p = i7 + 2 * sizeof (mdb_instr_t); 368 } 369 370 return (0); 371 } 372 373 /*ARGSUSED*/ 374 int 375 kmt_step_branch(mdb_tgt_t *t) 376 { 377 return (set_errno(EMDB_TGTHWNOTSUP)); 378 } 379 380 static const char * 381 regno2name(int idx) 382 { 383 const mdb_tgt_regdesc_t *rd; 384 385 for (rd = mdb_sparcv9_kregs; rd->rd_name != NULL; rd++) { 386 if (idx == rd->rd_num) 387 return (rd->rd_name); 388 } 389 390 ASSERT(rd->rd_name != NULL); 391 392 return ("unknown"); 393 } 394 395 /* 396 * Step over call and jmpl by returning the address of the position where a 397 * temporary breakpoint can be set to catch return from the control transfer. 398 * This function does not currently provide advanced decoding of DCTI couples 399 * or any other complex special case; we just fall back to single-step. 400 */ 401 int 402 kmt_next(mdb_tgt_t *t, uintptr_t *p) 403 { 404 kreg_t pc, npc; 405 GElf_Sym func; 406 407 (void) kmdb_dpi_get_register("pc", &pc); 408 (void) kmdb_dpi_get_register("npc", &npc); 409 410 if (mdb_tgt_lookup_by_addr(t, pc, MDB_TGT_SYM_FUZZY, NULL, 0, 411 &func, NULL) != 0) 412 return (-1); 413 414 if (npc < func.st_value || func.st_value + func.st_size <= npc) { 415 mdb_instr_t instr; 416 kreg_t reg; 417 418 /* 419 * We're about to transfer control outside this function, so we 420 * want to stop when control returns from the other function. 421 * Normally the return address will be in %o7, tail-calls being 422 * the exception. We try to discover if this is a tail-call and 423 * compute the return address in that case. 424 */ 425 if (mdb_tgt_vread(t, &instr, sizeof (instr), pc) != 426 sizeof (instr)) { 427 warn("failed to read instruction at %p for next", 428 (void *)pc); 429 return (-1); 430 } 431 432 if (OP(instr) == OP_ARITH && OP3(instr) == OP3_RESTORE) { 433 (void) kmdb_dpi_get_register("i7", ®); 434 } else if (OP(instr) == OP_ARITH && OP3(instr) == OP3_OR && 435 RD(instr) == KREG_O7) { 436 if (RS1(instr) == KREG_G0) 437 return (set_errno(EAGAIN)); 438 439 (void) kmdb_dpi_get_register(regno2name(RS2(instr)), 440 ®); 441 } else 442 (void) kmdb_dpi_get_register("o7", ®); 443 444 *p = reg + 2 * sizeof (mdb_instr_t); 445 446 return (0); 447 } 448 449 return (set_errno(EAGAIN)); 450 } 451 452 const char * 453 kmt_trapname(int trapnum) 454 { 455 static char trapname[11]; 456 457 switch (trapnum) { 458 case T_INSTR_EXCEPTION: 459 return ("instruction access error trap"); 460 case T_ALIGNMENT: 461 return ("improper alignment trap"); 462 case T_UNIMP_INSTR: 463 return ("illegal instruction trap"); 464 case T_IDIV0: 465 return ("division by zero trap"); 466 case T_FAST_INSTR_MMU_MISS: 467 return ("instruction access MMU miss trap"); 468 case T_FAST_DATA_MMU_MISS: 469 return ("data access MMU miss trap"); 470 case ST_KMDB_TRAP|T_SOFTWARE_TRAP: 471 return ("debugger entry trap"); 472 case ST_KMDB_BREAKPOINT|T_SOFTWARE_TRAP: 473 return ("breakpoint trap"); 474 default: 475 (void) mdb_snprintf(trapname, sizeof (trapname), "trap %#x", 476 trapnum); 477 return (trapname); 478 } 479 } 480 481 void 482 kmt_init_isadep(mdb_tgt_t *t) 483 { 484 kmt_data_t *kmt = t->t_data; 485 486 kmt->kmt_rds = mdb_sparcv9_kregs; 487 488 kmt->kmt_trapmax = KMT_MAXTRAPNO; 489 kmt->kmt_trapmap = mdb_zalloc(BT_SIZEOFMAP(kmt->kmt_trapmax), UM_SLEEP); 490 491 /* Traps for which we want to provide an explicit message */ 492 (void) mdb_tgt_add_fault(t, T_INSTR_EXCEPTION, MDB_TGT_SPEC_INTERNAL, 493 no_se_f, NULL); 494 (void) mdb_tgt_add_fault(t, T_ALIGNMENT, MDB_TGT_SPEC_INTERNAL, 495 no_se_f, NULL); 496 (void) mdb_tgt_add_fault(t, T_UNIMP_INSTR, MDB_TGT_SPEC_INTERNAL, 497 no_se_f, NULL); 498 (void) mdb_tgt_add_fault(t, T_IDIV0, MDB_TGT_SPEC_INTERNAL, 499 no_se_f, NULL); 500 (void) mdb_tgt_add_fault(t, T_FAST_INSTR_MMU_MISS, 501 MDB_TGT_SPEC_INTERNAL, no_se_f, NULL); 502 (void) mdb_tgt_add_fault(t, T_FAST_DATA_MMU_MISS, MDB_TGT_SPEC_INTERNAL, 503 no_se_f, NULL); 504 505 /* 506 * Traps which will be handled elsewhere, and which therefore don't 507 * need the trap-based message. 508 */ 509 BT_SET(kmt->kmt_trapmap, ST_KMDB_TRAP|T_SOFTWARE_TRAP); 510 BT_SET(kmt->kmt_trapmap, ST_KMDB_BREAKPOINT|T_SOFTWARE_TRAP); 511 BT_SET(kmt->kmt_trapmap, T_PA_WATCHPOINT); 512 BT_SET(kmt->kmt_trapmap, T_VA_WATCHPOINT); 513 514 /* Catch-all for traps not explicitly listed here */ 515 (void) mdb_tgt_add_fault(t, KMT_TRAP_NOTENUM, MDB_TGT_SPEC_INTERNAL, 516 no_se_f, NULL); 517 } 518 519 /*ARGSUSED*/ 520 void 521 kmt_startup_isadep(mdb_tgt_t *t) 522 { 523 } 524