1*843e1988Sjohnlev /* 2*843e1988Sjohnlev * CDDL HEADER START 3*843e1988Sjohnlev * 4*843e1988Sjohnlev * The contents of this file are subject to the terms of the 5*843e1988Sjohnlev * Common Development and Distribution License (the "License"). 6*843e1988Sjohnlev * You may not use this file except in compliance with the License. 7*843e1988Sjohnlev * 8*843e1988Sjohnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*843e1988Sjohnlev * or http://www.opensolaris.org/os/licensing. 10*843e1988Sjohnlev * See the License for the specific language governing permissions 11*843e1988Sjohnlev * and limitations under the License. 12*843e1988Sjohnlev * 13*843e1988Sjohnlev * When distributing Covered Code, include this CDDL HEADER in each 14*843e1988Sjohnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*843e1988Sjohnlev * If applicable, add the following below this CDDL HEADER, with the 16*843e1988Sjohnlev * fields enclosed by brackets "[]" replaced with your own identifying 17*843e1988Sjohnlev * information: Portions Copyright [yyyy] [name of copyright owner] 18*843e1988Sjohnlev * 19*843e1988Sjohnlev * CDDL HEADER END 20*843e1988Sjohnlev */ 21*843e1988Sjohnlev /* 22*843e1988Sjohnlev * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23*843e1988Sjohnlev * Use is subject to license terms. 24*843e1988Sjohnlev */ 25*843e1988Sjohnlev 26*843e1988Sjohnlev #pragma ident "%Z%%M% %I% %E% SMI" 27*843e1988Sjohnlev 28*843e1988Sjohnlev /* 29*843e1988Sjohnlev * Libkvm Kernel Target Intel component 30*843e1988Sjohnlev * 31*843e1988Sjohnlev * This file provides the Intel-dependent portion of the libkvm kernel target. 32*843e1988Sjohnlev * For more details on the implementation refer to mdb_kvm.c. 33*843e1988Sjohnlev */ 34*843e1988Sjohnlev 35*843e1988Sjohnlev #include <mdb/mdb_target_impl.h> 36*843e1988Sjohnlev #include <mdb/mdb_kreg_impl.h> 37*843e1988Sjohnlev #include <mdb/mdb_errno.h> 38*843e1988Sjohnlev #include <mdb/mdb_err.h> 39*843e1988Sjohnlev #include <mdb/mdb_kvm.h> 40*843e1988Sjohnlev #include <mdb/mdb_ks.h> 41*843e1988Sjohnlev #include <mdb/mdb.h> 42*843e1988Sjohnlev #include <mdb/kvm_isadep.h> 43*843e1988Sjohnlev 44*843e1988Sjohnlev #include <sys/cpuvar.h> 45*843e1988Sjohnlev #include <sys/privmregs.h> 46*843e1988Sjohnlev 47*843e1988Sjohnlev int 48*843e1988Sjohnlev kt_getareg(mdb_tgt_t *t, mdb_tgt_tid_t tid, 49*843e1988Sjohnlev const char *rname, mdb_tgt_reg_t *rp) 50*843e1988Sjohnlev { 51*843e1988Sjohnlev const mdb_tgt_regdesc_t *rdp; 52*843e1988Sjohnlev kt_data_t *kt = t->t_data; 53*843e1988Sjohnlev 54*843e1988Sjohnlev if (tid != kt->k_tid) 55*843e1988Sjohnlev return (set_errno(EMDB_NOREGS)); 56*843e1988Sjohnlev 57*843e1988Sjohnlev for (rdp = kt->k_rds; rdp->rd_name != NULL; rdp++) { 58*843e1988Sjohnlev if (strcmp(rname, rdp->rd_name) == 0) { 59*843e1988Sjohnlev *rp = kt->k_regs->kregs[rdp->rd_num]; 60*843e1988Sjohnlev return (0); 61*843e1988Sjohnlev } 62*843e1988Sjohnlev } 63*843e1988Sjohnlev 64*843e1988Sjohnlev return (set_errno(EMDB_BADREG)); 65*843e1988Sjohnlev } 66*843e1988Sjohnlev 67*843e1988Sjohnlev int 68*843e1988Sjohnlev kt_putareg(mdb_tgt_t *t, mdb_tgt_tid_t tid, const char *rname, mdb_tgt_reg_t r) 69*843e1988Sjohnlev { 70*843e1988Sjohnlev const mdb_tgt_regdesc_t *rdp; 71*843e1988Sjohnlev kt_data_t *kt = t->t_data; 72*843e1988Sjohnlev 73*843e1988Sjohnlev if (tid != kt->k_tid) 74*843e1988Sjohnlev return (set_errno(EMDB_NOREGS)); 75*843e1988Sjohnlev 76*843e1988Sjohnlev for (rdp = kt->k_rds; rdp->rd_name != NULL; rdp++) { 77*843e1988Sjohnlev if (strcmp(rname, rdp->rd_name) == 0) { 78*843e1988Sjohnlev kt->k_regs->kregs[rdp->rd_num] = (kreg_t)r; 79*843e1988Sjohnlev return (0); 80*843e1988Sjohnlev } 81*843e1988Sjohnlev } 82*843e1988Sjohnlev 83*843e1988Sjohnlev return (set_errno(EMDB_BADREG)); 84*843e1988Sjohnlev } 85*843e1988Sjohnlev 86*843e1988Sjohnlev int 87*843e1988Sjohnlev kt_kvmregs(mdb_tgt_t *t, uint_t cpuid, mdb_tgt_gregset_t *kregs) 88*843e1988Sjohnlev { 89*843e1988Sjohnlev kt_data_t *kt = t->t_data; 90*843e1988Sjohnlev privmregs_t mregs; 91*843e1988Sjohnlev int ret; 92*843e1988Sjohnlev 93*843e1988Sjohnlev if ((ret = kt->k_kb_ops->kb_getmregs(kt->k_cookie, cpuid, &mregs)) != 0) 94*843e1988Sjohnlev return (ret); 95*843e1988Sjohnlev 96*843e1988Sjohnlev kt_regs_to_kregs(&mregs.pm_gregs, kregs); 97*843e1988Sjohnlev return (0); 98*843e1988Sjohnlev } 99*843e1988Sjohnlev 100*843e1988Sjohnlev static int 101*843e1988Sjohnlev kt_cpu2cpuid(uintptr_t cpup) 102*843e1988Sjohnlev { 103*843e1988Sjohnlev cpu_t cpu; 104*843e1988Sjohnlev 105*843e1988Sjohnlev if (mdb_vread(&cpu, sizeof (cpu_t), cpup) != sizeof (cpu_t)) 106*843e1988Sjohnlev return (-1); 107*843e1988Sjohnlev 108*843e1988Sjohnlev return (cpu.cpu_id); 109*843e1988Sjohnlev } 110*843e1988Sjohnlev 111*843e1988Sjohnlev int 112*843e1988Sjohnlev kt_cpustack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 113*843e1988Sjohnlev { 114*843e1988Sjohnlev mdb_tgt_t *t = mdb.m_target; 115*843e1988Sjohnlev mdb_tgt_gregset_t regs; 116*843e1988Sjohnlev intptr_t cpuid = 0; 117*843e1988Sjohnlev uint_t verbose = 0; 118*843e1988Sjohnlev int i; 119*843e1988Sjohnlev 120*843e1988Sjohnlev if (flags & DCMD_ADDRSPEC) { 121*843e1988Sjohnlev if ((cpuid = kt_cpu2cpuid(addr)) < 0) { 122*843e1988Sjohnlev (void) set_errno(EMDB_NOMAP); 123*843e1988Sjohnlev mdb_warn("failed to find cpuid for cpu at %p", addr); 124*843e1988Sjohnlev return (DCMD_ERR); 125*843e1988Sjohnlev } 126*843e1988Sjohnlev flags &= ~DCMD_ADDRSPEC; 127*843e1988Sjohnlev } 128*843e1988Sjohnlev 129*843e1988Sjohnlev 130*843e1988Sjohnlev i = mdb_getopts(argc, argv, 131*843e1988Sjohnlev 'c', MDB_OPT_UINTPTR, &cpuid, 132*843e1988Sjohnlev 'v', MDB_OPT_SETBITS, 1, &verbose, 133*843e1988Sjohnlev NULL); 134*843e1988Sjohnlev 135*843e1988Sjohnlev argc -= i; 136*843e1988Sjohnlev argv += i; 137*843e1988Sjohnlev 138*843e1988Sjohnlev if (kt_kvmregs(t, cpuid, ®s) != 0) { 139*843e1988Sjohnlev mdb_warn("failed to get regs for cpu %d\n", cpuid); 140*843e1988Sjohnlev return (DCMD_ERR); 141*843e1988Sjohnlev } 142*843e1988Sjohnlev 143*843e1988Sjohnlev /* 144*843e1988Sjohnlev * Tell the stack walker that we have regs. 145*843e1988Sjohnlev */ 146*843e1988Sjohnlev flags |= DCMD_ADDRSPEC; 147*843e1988Sjohnlev addr = regs.kregs[KREG_FP]; 148*843e1988Sjohnlev 149*843e1988Sjohnlev if (verbose) 150*843e1988Sjohnlev return (kt_stackv(addr, flags, argc, argv)); 151*843e1988Sjohnlev else 152*843e1988Sjohnlev return (kt_stack(addr, flags, argc, argv)); 153*843e1988Sjohnlev } 154*843e1988Sjohnlev 155*843e1988Sjohnlev /*ARGSUSED*/ 156*843e1988Sjohnlev int 157*843e1988Sjohnlev kt_cpuregs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 158*843e1988Sjohnlev { 159*843e1988Sjohnlev mdb_tgt_t *t = mdb.m_target; 160*843e1988Sjohnlev mdb_tgt_gregset_t regs; 161*843e1988Sjohnlev intptr_t cpuid = 0; 162*843e1988Sjohnlev int i; 163*843e1988Sjohnlev 164*843e1988Sjohnlev if (flags & DCMD_ADDRSPEC) { 165*843e1988Sjohnlev if (argc != 0) 166*843e1988Sjohnlev return (DCMD_USAGE); 167*843e1988Sjohnlev if ((cpuid = kt_cpu2cpuid(addr)) < 0) { 168*843e1988Sjohnlev (void) set_errno(EMDB_NOMAP); 169*843e1988Sjohnlev mdb_warn("failed to find cpuid for cpu at %p", addr); 170*843e1988Sjohnlev return (DCMD_ERR); 171*843e1988Sjohnlev } 172*843e1988Sjohnlev } 173*843e1988Sjohnlev 174*843e1988Sjohnlev 175*843e1988Sjohnlev i = mdb_getopts(argc, argv, 176*843e1988Sjohnlev 'c', MDB_OPT_UINTPTR, &cpuid, 177*843e1988Sjohnlev NULL); 178*843e1988Sjohnlev 179*843e1988Sjohnlev argc -= i; 180*843e1988Sjohnlev argv += i; 181*843e1988Sjohnlev 182*843e1988Sjohnlev if (argc != 0) 183*843e1988Sjohnlev return (DCMD_USAGE); 184*843e1988Sjohnlev 185*843e1988Sjohnlev if (kt_kvmregs(t, cpuid, ®s) != 0) { 186*843e1988Sjohnlev mdb_warn("failed to get regs for cpu %d\n", cpuid); 187*843e1988Sjohnlev return (DCMD_ERR); 188*843e1988Sjohnlev } 189*843e1988Sjohnlev 190*843e1988Sjohnlev return (kt_regs((uintptr_t)®s, flags, argc, argv)); 191*843e1988Sjohnlev } 192