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