1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include <sys/types.h> 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate #ifndef DEBUG 32*0Sstevel@tonic-gate #define DEBUG 33*0Sstevel@tonic-gate #define _SYS_DEBUG_H 34*0Sstevel@tonic-gate #include <sys/xc_impl.h> 35*0Sstevel@tonic-gate #undef DEBUG 36*0Sstevel@tonic-gate #else 37*0Sstevel@tonic-gate #define _SYS_DEBUG_H 38*0Sstevel@tonic-gate #include <sys/xc_impl.h> 39*0Sstevel@tonic-gate #endif 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate #include <sys/traptrace.h> 42*0Sstevel@tonic-gate #include <sys/machparam.h> 43*0Sstevel@tonic-gate #include <sys/ivintr.h> 44*0Sstevel@tonic-gate #include <sys/mutex_impl.h> 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 47*0Sstevel@tonic-gate #include <mdb/mdb_ctf.h> 48*0Sstevel@tonic-gate #include "sfmmu.h" 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate #ifndef SYSTRAP_TT 51*0Sstevel@tonic-gate #define SYSTRAP_TT 0x1300 52*0Sstevel@tonic-gate #endif 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate typedef struct trap_trace_fullrec { 55*0Sstevel@tonic-gate struct trap_trace_record ttf_rec; 56*0Sstevel@tonic-gate int ttf_cpu; 57*0Sstevel@tonic-gate } trap_trace_fullrec_t; 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate #ifdef sun4v 60*0Sstevel@tonic-gate typedef struct htrap_trace_fullrec { 61*0Sstevel@tonic-gate struct htrap_trace_record ttf_rec; 62*0Sstevel@tonic-gate int ttf_cpu; 63*0Sstevel@tonic-gate } htrap_trace_fullrec_t; 64*0Sstevel@tonic-gate #endif 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate /* 67*0Sstevel@tonic-gate * These strings and accompanying macros allow our string table to look 68*0Sstevel@tonic-gate * just like the real table in trap_table.s. 69*0Sstevel@tonic-gate */ 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate static const char NOT[] = "reserved"; /* common reserved string */ 72*0Sstevel@tonic-gate static const char BAD[] = "unused"; /* common unused string */ 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate #define NOT4 NOT, NOT, NOT, NOT 75*0Sstevel@tonic-gate #define BAD4 BAD, BAD, BAD, BAD 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gate static const char *const ttdescr[] = { 78*0Sstevel@tonic-gate NOT, /* 000 reserved */ 79*0Sstevel@tonic-gate "power-on", /* 001 power on reset */ 80*0Sstevel@tonic-gate "watchdog", /* 002 watchdog reset */ 81*0Sstevel@tonic-gate "xir", /* 003 externally initiated reset */ 82*0Sstevel@tonic-gate "sir", /* 004 software initiated reset */ 83*0Sstevel@tonic-gate "red", /* 005 red mode exception */ 84*0Sstevel@tonic-gate NOT, NOT, /* 006 - 007 reserved */ 85*0Sstevel@tonic-gate "immu-xcp", /* 008 instruction access exception */ 86*0Sstevel@tonic-gate "immu-miss", /* 009 instruction access MMU miss */ 87*0Sstevel@tonic-gate "immu-err", /* 00A instruction access error */ 88*0Sstevel@tonic-gate NOT, NOT4, /* 00B - 00F reserved */ 89*0Sstevel@tonic-gate "ill-inst", /* 010 illegal instruction */ 90*0Sstevel@tonic-gate "priv-inst", /* 011 privileged opcode */ 91*0Sstevel@tonic-gate "unimp-ldd", /* 012 unimplemented LDD */ 92*0Sstevel@tonic-gate "unimp-std", /* 013 unimplemented STD */ 93*0Sstevel@tonic-gate NOT4, NOT4, NOT4, /* 014 - 01F reserved */ 94*0Sstevel@tonic-gate "fp-disable", /* 020 fp disabled */ 95*0Sstevel@tonic-gate "fp-ieee754", /* 021 fp exception ieee 754 */ 96*0Sstevel@tonic-gate "fp-xcp-other", /* 022 fp exception other */ 97*0Sstevel@tonic-gate "tag-oflow", /* 023 tag overflow */ 98*0Sstevel@tonic-gate "cleanwin", /* 024 clean window */ 99*0Sstevel@tonic-gate "cleanwin", /* 025 clean window */ 100*0Sstevel@tonic-gate "cleanwin", /* 026 clean window */ 101*0Sstevel@tonic-gate "cleanwin", /* 027 clean window */ 102*0Sstevel@tonic-gate "div-zero", /* 028 division by zero */ 103*0Sstevel@tonic-gate "internal-err", /* 029 internal processor error */ 104*0Sstevel@tonic-gate NOT, NOT, NOT4, /* 02A - 02F reserved */ 105*0Sstevel@tonic-gate "dmmu-xcp", /* 030 data access exception */ 106*0Sstevel@tonic-gate "dmmu-miss", /* 031 data access MMU miss */ 107*0Sstevel@tonic-gate "dmmu-err", /* 032 data access error */ 108*0Sstevel@tonic-gate "dmmu-prot", /* 033 data access protection */ 109*0Sstevel@tonic-gate "unalign", /* 034 mem address not aligned */ 110*0Sstevel@tonic-gate "lddf-unalign", /* 035 LDDF mem address not aligned */ 111*0Sstevel@tonic-gate "stdf-unalign", /* 036 STDF mem address not aligned */ 112*0Sstevel@tonic-gate "priv-act", /* 037 privileged action */ 113*0Sstevel@tonic-gate "ldqf-unalign", /* 038 LDQF mem address not aligned */ 114*0Sstevel@tonic-gate "stqf-unalign", /* 039 STQF mem address not aligned */ 115*0Sstevel@tonic-gate NOT, NOT, NOT4, /* 03A - 03F reserved */ 116*0Sstevel@tonic-gate "async-d-err", /* 040 async data error */ 117*0Sstevel@tonic-gate "level-1", /* 041 interrupt level 1 */ 118*0Sstevel@tonic-gate "level-2", /* 042 interrupt level 2 */ 119*0Sstevel@tonic-gate "level-3", /* 043 interrupt level 3 */ 120*0Sstevel@tonic-gate "level-4", /* 044 interrupt level 4 */ 121*0Sstevel@tonic-gate "level-5", /* 045 interrupt level 5 */ 122*0Sstevel@tonic-gate "level-6", /* 046 interrupt level 6 */ 123*0Sstevel@tonic-gate "level-7", /* 047 interrupt level 7 */ 124*0Sstevel@tonic-gate "level-8", /* 048 interrupt level 8 */ 125*0Sstevel@tonic-gate "level-9", /* 049 interrupt level 9 */ 126*0Sstevel@tonic-gate "level-10", /* 04A interrupt level 10 */ 127*0Sstevel@tonic-gate "level-11", /* 04B interrupt level 11 */ 128*0Sstevel@tonic-gate "level-12", /* 04C interrupt level 12 */ 129*0Sstevel@tonic-gate "level-13", /* 04D interrupt level 13 */ 130*0Sstevel@tonic-gate "level-14", /* 04E interrupt level 14 */ 131*0Sstevel@tonic-gate "level-15", /* 04F interrupt level 15 */ 132*0Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 050 - 05F reserved */ 133*0Sstevel@tonic-gate "int-vec", /* 060 interrupt vector */ 134*0Sstevel@tonic-gate "pa-watch", /* 061 PA watchpoint */ 135*0Sstevel@tonic-gate "va-watch", /* 062 VA watchpoint */ 136*0Sstevel@tonic-gate "ecc-err", /* 063 corrected ECC error */ 137*0Sstevel@tonic-gate "itlb-miss", /* 064 instruction access MMU miss */ 138*0Sstevel@tonic-gate "itlb-miss", /* 065 instruction access MMU miss */ 139*0Sstevel@tonic-gate "itlb-miss", /* 066 instruction access MMU miss */ 140*0Sstevel@tonic-gate "itlb-miss", /* 067 instruction access MMU miss */ 141*0Sstevel@tonic-gate "dtlb-miss", /* 068 data access MMU miss */ 142*0Sstevel@tonic-gate "dtlb-miss", /* 069 data access MMU miss */ 143*0Sstevel@tonic-gate "dtlb-miss", /* 06A data access MMU miss */ 144*0Sstevel@tonic-gate "dtlb-miss", /* 06B data access MMU miss */ 145*0Sstevel@tonic-gate "dtlb-prot", /* 06C data access protection */ 146*0Sstevel@tonic-gate "dtlb-prot", /* 06D data access protection */ 147*0Sstevel@tonic-gate "dtlb-prot", /* 06E data access protection */ 148*0Sstevel@tonic-gate "dtlb-prot", /* 06F data access protection */ 149*0Sstevel@tonic-gate "fast-ecc-err", /* 070 fast ecache ECC error */ 150*0Sstevel@tonic-gate "dp-err", /* 071 data cache parity error */ 151*0Sstevel@tonic-gate "ip-err", /* 072 instr cache parity error */ 152*0Sstevel@tonic-gate NOT, NOT4, NOT4, /* 073 - 07B reserved */ 153*0Sstevel@tonic-gate #ifdef sun4v 154*0Sstevel@tonic-gate "cpu-mondo", /* 07C CPU mondo */ 155*0Sstevel@tonic-gate "dev-mondo", /* 07D device mondo */ 156*0Sstevel@tonic-gate "res.-err", /* 07E resumable error */ 157*0Sstevel@tonic-gate "non-res.-err", /* 07F non-resumable error */ 158*0Sstevel@tonic-gate #else 159*0Sstevel@tonic-gate NOT4, /* 07C - 07F reserved */ 160*0Sstevel@tonic-gate #endif 161*0Sstevel@tonic-gate "spill-0-norm", /* 080 spill 0 normal */ 162*0Sstevel@tonic-gate "spill-0-norm", /* 081 spill 0 normal */ 163*0Sstevel@tonic-gate "spill-0-norm", /* 082 spill 0 normal */ 164*0Sstevel@tonic-gate "spill-0-norm", /* 083 spill 0 normal */ 165*0Sstevel@tonic-gate "spill-1-norm", /* 084 spill 1 normal */ 166*0Sstevel@tonic-gate "spill-1-norm", /* 085 spill 1 normal */ 167*0Sstevel@tonic-gate "spill-1-norm", /* 086 spill 1 normal */ 168*0Sstevel@tonic-gate "spill-1-norm", /* 087 spill 1 normal */ 169*0Sstevel@tonic-gate "spill-2-norm", /* 088 spill 2 normal */ 170*0Sstevel@tonic-gate "spill-2-norm", /* 089 spill 2 normal */ 171*0Sstevel@tonic-gate "spill-2-norm", /* 08A spill 2 normal */ 172*0Sstevel@tonic-gate "spill-2-norm", /* 08B spill 2 normal */ 173*0Sstevel@tonic-gate "spill-3-norm", /* 08C spill 3 normal */ 174*0Sstevel@tonic-gate "spill-3-norm", /* 08D spill 3 normal */ 175*0Sstevel@tonic-gate "spill-3-norm", /* 08E spill 3 normal */ 176*0Sstevel@tonic-gate "spill-3-norm", /* 08F spill 3 normal */ 177*0Sstevel@tonic-gate "spill-4-norm", /* 090 spill 4 normal */ 178*0Sstevel@tonic-gate "spill-4-norm", /* 091 spill 4 normal */ 179*0Sstevel@tonic-gate "spill-4-norm", /* 092 spill 4 normal */ 180*0Sstevel@tonic-gate "spill-4-norm", /* 093 spill 4 normal */ 181*0Sstevel@tonic-gate "spill-5-norm", /* 094 spill 5 normal */ 182*0Sstevel@tonic-gate "spill-5-norm", /* 095 spill 5 normal */ 183*0Sstevel@tonic-gate "spill-5-norm", /* 096 spill 5 normal */ 184*0Sstevel@tonic-gate "spill-5-norm", /* 097 spill 5 normal */ 185*0Sstevel@tonic-gate "spill-6-norm", /* 098 spill 6 normal */ 186*0Sstevel@tonic-gate "spill-6-norm", /* 099 spill 6 normal */ 187*0Sstevel@tonic-gate "spill-6-norm", /* 09A spill 6 normal */ 188*0Sstevel@tonic-gate "spill-6-norm", /* 09B spill 6 normal */ 189*0Sstevel@tonic-gate "spill-7-norm", /* 09C spill 7 normal */ 190*0Sstevel@tonic-gate "spill-7-norm", /* 09D spill 7 normal */ 191*0Sstevel@tonic-gate "spill-7-norm", /* 09E spill 7 normal */ 192*0Sstevel@tonic-gate "spill-7-norm", /* 09F spill 7 normal */ 193*0Sstevel@tonic-gate "spill-0-oth", /* 0A0 spill 0 other */ 194*0Sstevel@tonic-gate "spill-0-oth", /* 0A1 spill 0 other */ 195*0Sstevel@tonic-gate "spill-0-oth", /* 0A2 spill 0 other */ 196*0Sstevel@tonic-gate "spill-0-oth", /* 0A3 spill 0 other */ 197*0Sstevel@tonic-gate "spill-1-oth", /* 0A4 spill 1 other */ 198*0Sstevel@tonic-gate "spill-1-oth", /* 0A5 spill 1 other */ 199*0Sstevel@tonic-gate "spill-1-oth", /* 0A6 spill 1 other */ 200*0Sstevel@tonic-gate "spill-1-oth", /* 0A7 spill 1 other */ 201*0Sstevel@tonic-gate "spill-2-oth", /* 0A8 spill 2 other */ 202*0Sstevel@tonic-gate "spill-2-oth", /* 0A9 spill 2 other */ 203*0Sstevel@tonic-gate "spill-2-oth", /* 0AA spill 2 other */ 204*0Sstevel@tonic-gate "spill-2-oth", /* 0AB spill 2 other */ 205*0Sstevel@tonic-gate "spill-3-oth", /* 0AC spill 3 other */ 206*0Sstevel@tonic-gate "spill-3-oth", /* 0AD spill 3 other */ 207*0Sstevel@tonic-gate "spill-3-oth", /* 0AE spill 3 other */ 208*0Sstevel@tonic-gate "spill-3-oth", /* 0AF spill 3 other */ 209*0Sstevel@tonic-gate "spill-4-oth", /* 0B0 spill 4 other */ 210*0Sstevel@tonic-gate "spill-4-oth", /* 0B1 spill 4 other */ 211*0Sstevel@tonic-gate "spill-4-oth", /* 0B2 spill 4 other */ 212*0Sstevel@tonic-gate "spill-4-oth", /* 0B3 spill 4 other */ 213*0Sstevel@tonic-gate "spill-5-oth", /* 0B4 spill 5 other */ 214*0Sstevel@tonic-gate "spill-5-oth", /* 0B5 spill 5 other */ 215*0Sstevel@tonic-gate "spill-5-oth", /* 0B6 spill 5 other */ 216*0Sstevel@tonic-gate "spill-5-oth", /* 0B7 spill 5 other */ 217*0Sstevel@tonic-gate "spill-6-oth", /* 0B8 spill 6 other */ 218*0Sstevel@tonic-gate "spill-6-oth", /* 0B9 spill 6 other */ 219*0Sstevel@tonic-gate "spill-6-oth", /* 0BA spill 6 other */ 220*0Sstevel@tonic-gate "spill-6-oth", /* 0BB spill 6 other */ 221*0Sstevel@tonic-gate "spill-7-oth", /* 0BC spill 7 other */ 222*0Sstevel@tonic-gate "spill-7-oth", /* 0BD spill 7 other */ 223*0Sstevel@tonic-gate "spill-7-oth", /* 0BE spill 7 other */ 224*0Sstevel@tonic-gate "spill-7-oth", /* 0BF spill 7 other */ 225*0Sstevel@tonic-gate "fill-0-norm", /* 0C0 fill 0 normal */ 226*0Sstevel@tonic-gate "fill-0-norm", /* 0C1 fill 0 normal */ 227*0Sstevel@tonic-gate "fill-0-norm", /* 0C2 fill 0 normal */ 228*0Sstevel@tonic-gate "fill-0-norm", /* 0C3 fill 0 normal */ 229*0Sstevel@tonic-gate "fill-1-norm", /* 0C4 fill 1 normal */ 230*0Sstevel@tonic-gate "fill-1-norm", /* 0C5 fill 1 normal */ 231*0Sstevel@tonic-gate "fill-1-norm", /* 0C6 fill 1 normal */ 232*0Sstevel@tonic-gate "fill-1-norm", /* 0C7 fill 1 normal */ 233*0Sstevel@tonic-gate "fill-2-norm", /* 0C8 fill 2 normal */ 234*0Sstevel@tonic-gate "fill-2-norm", /* 0C9 fill 2 normal */ 235*0Sstevel@tonic-gate "fill-2-norm", /* 0CA fill 2 normal */ 236*0Sstevel@tonic-gate "fill-2-norm", /* 0CB fill 2 normal */ 237*0Sstevel@tonic-gate "fill-3-norm", /* 0CC fill 3 normal */ 238*0Sstevel@tonic-gate "fill-3-norm", /* 0CD fill 3 normal */ 239*0Sstevel@tonic-gate "fill-3-norm", /* 0CE fill 3 normal */ 240*0Sstevel@tonic-gate "fill-3-norm", /* 0CF fill 3 normal */ 241*0Sstevel@tonic-gate "fill-4-norm", /* 0D0 fill 4 normal */ 242*0Sstevel@tonic-gate "fill-4-norm", /* 0D1 fill 4 normal */ 243*0Sstevel@tonic-gate "fill-4-norm", /* 0D2 fill 4 normal */ 244*0Sstevel@tonic-gate "fill-4-norm", /* 0D3 fill 4 normal */ 245*0Sstevel@tonic-gate "fill-5-norm", /* 0D4 fill 5 normal */ 246*0Sstevel@tonic-gate "fill-5-norm", /* 0D5 fill 5 normal */ 247*0Sstevel@tonic-gate "fill-5-norm", /* 0D6 fill 5 normal */ 248*0Sstevel@tonic-gate "fill-5-norm", /* 0D7 fill 5 normal */ 249*0Sstevel@tonic-gate "fill-6-norm", /* 0D8 fill 6 normal */ 250*0Sstevel@tonic-gate "fill-6-norm", /* 0D9 fill 6 normal */ 251*0Sstevel@tonic-gate "fill-6-norm", /* 0DA fill 6 normal */ 252*0Sstevel@tonic-gate "fill-6-norm", /* 0DB fill 6 normal */ 253*0Sstevel@tonic-gate "fill-7-norm", /* 0DC fill 7 normal */ 254*0Sstevel@tonic-gate "fill-7-norm", /* 0DD fill 7 normal */ 255*0Sstevel@tonic-gate "fill-7-norm", /* 0DE fill 7 normal */ 256*0Sstevel@tonic-gate "fill-7-norm", /* 0DF fill 7 normal */ 257*0Sstevel@tonic-gate "fill-0-oth", /* 0E0 fill 0 other */ 258*0Sstevel@tonic-gate "fill-0-oth", /* 0E1 fill 0 other */ 259*0Sstevel@tonic-gate "fill-0-oth", /* 0E2 fill 0 other */ 260*0Sstevel@tonic-gate "fill-0-oth", /* 0E3 fill 0 other */ 261*0Sstevel@tonic-gate "fill-1-oth", /* 0E4 fill 1 other */ 262*0Sstevel@tonic-gate "fill-1-oth", /* 0E5 fill 1 other */ 263*0Sstevel@tonic-gate "fill-1-oth", /* 0E6 fill 1 other */ 264*0Sstevel@tonic-gate "fill-1-oth", /* 0E7 fill 1 other */ 265*0Sstevel@tonic-gate "fill-2-oth", /* 0E8 fill 2 other */ 266*0Sstevel@tonic-gate "fill-2-oth", /* 0E9 fill 2 other */ 267*0Sstevel@tonic-gate "fill-2-oth", /* 0EA fill 2 other */ 268*0Sstevel@tonic-gate "fill-2-oth", /* 0EB fill 2 other */ 269*0Sstevel@tonic-gate "fill-3-oth", /* 0EC fill 3 other */ 270*0Sstevel@tonic-gate "fill-3-oth", /* 0ED fill 3 other */ 271*0Sstevel@tonic-gate "fill-3-oth", /* 0EE fill 3 other */ 272*0Sstevel@tonic-gate "fill-3-oth", /* 0EF fill 3 other */ 273*0Sstevel@tonic-gate "fill-4-oth", /* 0F0 fill 4 other */ 274*0Sstevel@tonic-gate "fill-4-oth", /* 0F1 fill 4 other */ 275*0Sstevel@tonic-gate "fill-4-oth", /* 0F2 fill 4 other */ 276*0Sstevel@tonic-gate "fill-4-oth", /* 0F3 fill 4 other */ 277*0Sstevel@tonic-gate "fill-5-oth", /* 0F4 fill 5 other */ 278*0Sstevel@tonic-gate "fill-5-oth", /* 0F5 fill 5 other */ 279*0Sstevel@tonic-gate "fill-5-oth", /* 0F6 fill 5 other */ 280*0Sstevel@tonic-gate "fill-5-oth", /* 0F7 fill 5 other */ 281*0Sstevel@tonic-gate "fill-6-oth", /* 0F8 fill 6 other */ 282*0Sstevel@tonic-gate "fill-6-oth", /* 0F9 fill 6 other */ 283*0Sstevel@tonic-gate "fill-6-oth", /* 0FA fill 6 other */ 284*0Sstevel@tonic-gate "fill-6-oth", /* 0FB fill 6 other */ 285*0Sstevel@tonic-gate "fill-7-oth", /* 0FC fill 7 other */ 286*0Sstevel@tonic-gate "fill-7-oth", /* 0FD fill 7 other */ 287*0Sstevel@tonic-gate "fill-7-oth", /* 0FE fill 7 other */ 288*0Sstevel@tonic-gate "fill-7-oth", /* 0FF fill 7 other */ 289*0Sstevel@tonic-gate "syscall-4x", /* 100 old system call */ 290*0Sstevel@tonic-gate "usr-brkpt", /* 101 user breakpoint */ 291*0Sstevel@tonic-gate "usr-div-zero", /* 102 user divide by zero */ 292*0Sstevel@tonic-gate "flush-wins", /* 103 flush windows */ 293*0Sstevel@tonic-gate "clean-wins", /* 104 clean windows */ 294*0Sstevel@tonic-gate "range-chk", /* 105 range check ?? */ 295*0Sstevel@tonic-gate "fix-align", /* 106 do unaligned references */ 296*0Sstevel@tonic-gate BAD, /* 107 unused */ 297*0Sstevel@tonic-gate "syscall-32", /* 108 ILP32 system call on LP64 */ 298*0Sstevel@tonic-gate "set-t0-addr", /* 109 set trap0 address */ 299*0Sstevel@tonic-gate BAD, BAD, BAD4, /* 10A - 10F unused */ 300*0Sstevel@tonic-gate BAD4, BAD4, BAD4, BAD4, /* 110 - 11F unused (V9 user traps?) */ 301*0Sstevel@tonic-gate "get-cc", /* 120 get condition codes */ 302*0Sstevel@tonic-gate "set-cc", /* 121 set condition codes */ 303*0Sstevel@tonic-gate "get-psr", /* 122 get psr */ 304*0Sstevel@tonic-gate "set-psr", /* 123 set psr (some fields) */ 305*0Sstevel@tonic-gate "getts", /* 124 get timestamp */ 306*0Sstevel@tonic-gate "gethrvtime", /* 125 get lwp virtual time */ 307*0Sstevel@tonic-gate "self-xcall", /* 126 self xcall */ 308*0Sstevel@tonic-gate "gethrtime", /* 127 get hrestime */ 309*0Sstevel@tonic-gate BAD, /* 128 unused (ST_SETV9STACK) */ 310*0Sstevel@tonic-gate "getlgrp", /* 129 get lgrpid */ 311*0Sstevel@tonic-gate BAD, BAD, BAD4, /* 12A - 12F unused */ 312*0Sstevel@tonic-gate BAD4, BAD4, /* 130 - 137 unused */ 313*0Sstevel@tonic-gate "dtrace-pid", /* 138 DTrace pid provider */ 314*0Sstevel@tonic-gate "dtrace-fasttrap", /* 139 DTrace pid provider */ 315*0Sstevel@tonic-gate "dtrace-return", /* 13A DTrace pid provider */ 316*0Sstevel@tonic-gate BAD, BAD4, /* 13B - 13F unused */ 317*0Sstevel@tonic-gate "syscall-64", /* 140 LP64 system call */ 318*0Sstevel@tonic-gate BAD, /* 141 unused */ 319*0Sstevel@tonic-gate "tt-freeze", /* 142 freeze traptrace */ 320*0Sstevel@tonic-gate "tt-unfreeze", /* 143 unfreeze traptrace */ 321*0Sstevel@tonic-gate BAD4, BAD4, BAD4, /* 144 - 14F unused */ 322*0Sstevel@tonic-gate BAD4, BAD4, BAD4, BAD4, /* 150 - 15F unused */ 323*0Sstevel@tonic-gate BAD4, BAD4, BAD4, BAD4, /* 160 - 16F unused */ 324*0Sstevel@tonic-gate BAD4, BAD4, BAD4, /* 170 - 17B unused */ 325*0Sstevel@tonic-gate "ptl1-panic", /* 17C test ptl1_panic */ 326*0Sstevel@tonic-gate "kmdb-enter", /* 17D kmdb enter (L1-A) */ 327*0Sstevel@tonic-gate "kmdb-brkpt", /* 17E kmdb breakpoint */ 328*0Sstevel@tonic-gate "obp-brkpt", /* 17F obp breakpoint */ 329*0Sstevel@tonic-gate #ifdef sun4v 330*0Sstevel@tonic-gate "fast_trap", /* 180 hypervisor fast trap */ 331*0Sstevel@tonic-gate "cpu_tick_npt", /* 181 cpu_tick_npt() hcall */ 332*0Sstevel@tonic-gate "cpu_stick_npt", /* 182 cpu_stick_npt() hcall */ 333*0Sstevel@tonic-gate "mmu_map_addr", /* 183 mmu_map_addr() hcall */ 334*0Sstevel@tonic-gate "mmu_unmap_addr", /* 184 mmu_unmap_addr() hcall */ 335*0Sstevel@tonic-gate "ttrace_addentry", /* 185 ttrace_addentry() hcall */ 336*0Sstevel@tonic-gate NOT, NOT, NOT4, NOT4, /* 186 - 18F reserved */ 337*0Sstevel@tonic-gate #else 338*0Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 180 - 18F reserved */ 339*0Sstevel@tonic-gate #endif 340*0Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 190 - 19F reserved */ 341*0Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 1A0 - 1AF reserved */ 342*0Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 1B0 - 1BF reserved */ 343*0Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 1C0 - 1CF reserved */ 344*0Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 1D0 - 1DF reserved */ 345*0Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 1E0 - 1EF reserved */ 346*0Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4 /* 1F0 - 1FF reserved */ 347*0Sstevel@tonic-gate }; 348*0Sstevel@tonic-gate static const size_t ttndescr = sizeof (ttdescr) / sizeof (ttdescr[0]); 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate static GElf_Sym iv_sym; 351*0Sstevel@tonic-gate static GElf_Sym iv_nohandler_sym; 352*0Sstevel@tonic-gate 353*0Sstevel@tonic-gate /* 354*0Sstevel@tonic-gate * Persistent data (shouldn't change). 355*0Sstevel@tonic-gate */ 356*0Sstevel@tonic-gate static int ncpu; /* _ncpu */ 357*0Sstevel@tonic-gate static ssize_t mbox_size; /* size of xc_mbox */ 358*0Sstevel@tonic-gate static ulong_t mbox_stoff; /* offset of xc_mbox.xc_state */ 359*0Sstevel@tonic-gate static mdb_ctf_id_t mbox_states; /* xc_state enumeration */ 360*0Sstevel@tonic-gate 361*0Sstevel@tonic-gate static int 362*0Sstevel@tonic-gate fetch_ncpu(void) 363*0Sstevel@tonic-gate { 364*0Sstevel@tonic-gate if (ncpu == 0) 365*0Sstevel@tonic-gate if (mdb_readsym(&ncpu, sizeof (ncpu), "_ncpu") == -1) { 366*0Sstevel@tonic-gate mdb_warn("symbol '_ncpu' not found"); 367*0Sstevel@tonic-gate return (1); 368*0Sstevel@tonic-gate } 369*0Sstevel@tonic-gate return (0); 370*0Sstevel@tonic-gate } 371*0Sstevel@tonic-gate 372*0Sstevel@tonic-gate static int 373*0Sstevel@tonic-gate fetch_mbox(void) 374*0Sstevel@tonic-gate { 375*0Sstevel@tonic-gate if (mbox_size <= 0) { 376*0Sstevel@tonic-gate mdb_ctf_id_t id; 377*0Sstevel@tonic-gate 378*0Sstevel@tonic-gate if (mdb_ctf_lookup_by_name("struct xc_mbox", &id) == -1) { 379*0Sstevel@tonic-gate mdb_warn("couldn't find type 'struct xc_mbox'"); 380*0Sstevel@tonic-gate return (1); 381*0Sstevel@tonic-gate } 382*0Sstevel@tonic-gate 383*0Sstevel@tonic-gate /* 384*0Sstevel@tonic-gate * These two could be combined into a single call to 385*0Sstevel@tonic-gate * mdb_ctf_member_info if xc_state was actually of type 386*0Sstevel@tonic-gate * enum xc_states. 387*0Sstevel@tonic-gate */ 388*0Sstevel@tonic-gate if (mdb_ctf_lookup_by_name("enum xc_states", 389*0Sstevel@tonic-gate &mbox_states) == -1) { 390*0Sstevel@tonic-gate mdb_warn("couldn't find type 'enum xc_states'"); 391*0Sstevel@tonic-gate return (1); 392*0Sstevel@tonic-gate } 393*0Sstevel@tonic-gate if (mdb_ctf_offsetof(id, "xc_state", &mbox_stoff) == -1) { 394*0Sstevel@tonic-gate mdb_warn("couldn't find 'xc_mbox.xc_state'"); 395*0Sstevel@tonic-gate return (1); 396*0Sstevel@tonic-gate } 397*0Sstevel@tonic-gate mbox_stoff /= NBBY; 398*0Sstevel@tonic-gate 399*0Sstevel@tonic-gate if ((mbox_size = mdb_ctf_type_size(id)) == -1) { 400*0Sstevel@tonic-gate mdb_warn("couldn't size 'struct xc_mbox'"); 401*0Sstevel@tonic-gate return (1); 402*0Sstevel@tonic-gate } 403*0Sstevel@tonic-gate } 404*0Sstevel@tonic-gate return (0); 405*0Sstevel@tonic-gate } 406*0Sstevel@tonic-gate 407*0Sstevel@tonic-gate static int 408*0Sstevel@tonic-gate print_range(int start, int end, int separator) 409*0Sstevel@tonic-gate { 410*0Sstevel@tonic-gate int count; 411*0Sstevel@tonic-gate char tmp; 412*0Sstevel@tonic-gate char *format; 413*0Sstevel@tonic-gate 414*0Sstevel@tonic-gate if (start == end) { 415*0Sstevel@tonic-gate /* Unfortunately, mdb_printf returns void */ 416*0Sstevel@tonic-gate format = separator ? ", %d" : "%d"; 417*0Sstevel@tonic-gate mdb_printf(format, start); 418*0Sstevel@tonic-gate count = mdb_snprintf(&tmp, 1, format, start); 419*0Sstevel@tonic-gate } else { 420*0Sstevel@tonic-gate format = separator ? ", %d-%d" : "%d-%d"; 421*0Sstevel@tonic-gate mdb_printf(format, start, end); 422*0Sstevel@tonic-gate count = mdb_snprintf(&tmp, 1, format, start, end); 423*0Sstevel@tonic-gate } 424*0Sstevel@tonic-gate 425*0Sstevel@tonic-gate return (count); 426*0Sstevel@tonic-gate } 427*0Sstevel@tonic-gate 428*0Sstevel@tonic-gate static void 429*0Sstevel@tonic-gate print_cpuset_range(ulong_t *cs, int words, int width) 430*0Sstevel@tonic-gate { 431*0Sstevel@tonic-gate int i, j; 432*0Sstevel@tonic-gate ulong_t m; 433*0Sstevel@tonic-gate int in = 0; 434*0Sstevel@tonic-gate int start; 435*0Sstevel@tonic-gate int end; 436*0Sstevel@tonic-gate int count = 0; 437*0Sstevel@tonic-gate int sep = 0; 438*0Sstevel@tonic-gate 439*0Sstevel@tonic-gate for (i = 0; i < words; i++) 440*0Sstevel@tonic-gate for (j = 0, m = 1; j < BT_NBIPUL; j++, m <<= 1) 441*0Sstevel@tonic-gate if (cs[i] & m) { 442*0Sstevel@tonic-gate if (in == 0) { 443*0Sstevel@tonic-gate start = i * BT_NBIPUL + j; 444*0Sstevel@tonic-gate in = 1; 445*0Sstevel@tonic-gate } 446*0Sstevel@tonic-gate } else { 447*0Sstevel@tonic-gate if (in == 1) { 448*0Sstevel@tonic-gate end = i * BT_NBIPUL + j - 1; 449*0Sstevel@tonic-gate count += print_range(start, end, sep); 450*0Sstevel@tonic-gate sep = 1; 451*0Sstevel@tonic-gate in = 0; 452*0Sstevel@tonic-gate } 453*0Sstevel@tonic-gate } 454*0Sstevel@tonic-gate if (in == 1) { 455*0Sstevel@tonic-gate end = i * BT_NBIPUL - 1; 456*0Sstevel@tonic-gate count += print_range(start, end, sep); 457*0Sstevel@tonic-gate } 458*0Sstevel@tonic-gate 459*0Sstevel@tonic-gate while (count++ < width) 460*0Sstevel@tonic-gate mdb_printf(" "); 461*0Sstevel@tonic-gate } 462*0Sstevel@tonic-gate 463*0Sstevel@tonic-gate /*ARGSUSED*/ 464*0Sstevel@tonic-gate static int 465*0Sstevel@tonic-gate cmd_cpuset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 466*0Sstevel@tonic-gate { 467*0Sstevel@tonic-gate uint_t rflag = 0, lflag = 0; 468*0Sstevel@tonic-gate int words; 469*0Sstevel@tonic-gate ulong_t *set; 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate if (mdb_getopts(argc, argv, 472*0Sstevel@tonic-gate 'l', MDB_OPT_SETBITS, TRUE, &lflag, 473*0Sstevel@tonic-gate 'r', MDB_OPT_SETBITS, TRUE, &rflag, NULL) != argc) 474*0Sstevel@tonic-gate return (DCMD_USAGE); 475*0Sstevel@tonic-gate 476*0Sstevel@tonic-gate if (lflag && rflag) 477*0Sstevel@tonic-gate return (DCMD_USAGE); 478*0Sstevel@tonic-gate 479*0Sstevel@tonic-gate if (fetch_ncpu()) 480*0Sstevel@tonic-gate return (DCMD_ERR); 481*0Sstevel@tonic-gate 482*0Sstevel@tonic-gate if ((words = BT_BITOUL(ncpu)) == 1) { 483*0Sstevel@tonic-gate set = &addr; 484*0Sstevel@tonic-gate } else { 485*0Sstevel@tonic-gate set = mdb_alloc(words * sizeof (ulong_t), UM_SLEEP | UM_GC); 486*0Sstevel@tonic-gate mdb_vread(set, words * sizeof (ulong_t), addr); 487*0Sstevel@tonic-gate } 488*0Sstevel@tonic-gate 489*0Sstevel@tonic-gate if (lflag) { 490*0Sstevel@tonic-gate int i, j; 491*0Sstevel@tonic-gate ulong_t m; 492*0Sstevel@tonic-gate 493*0Sstevel@tonic-gate for (i = 0; i < words; i++) 494*0Sstevel@tonic-gate for (j = 0, m = 1; j < BT_NBIPUL; j++, m <<= 1) 495*0Sstevel@tonic-gate if (set[i] & m) 496*0Sstevel@tonic-gate mdb_printf("%r\n", i * BT_NBIPUL + j); 497*0Sstevel@tonic-gate } else if (rflag) { 498*0Sstevel@tonic-gate int i; 499*0Sstevel@tonic-gate int sep = 0; 500*0Sstevel@tonic-gate 501*0Sstevel@tonic-gate for (i = 0; i < words; i++) { 502*0Sstevel@tonic-gate mdb_printf(sep ? " %?0lx" : "%?0lx", set[i]); 503*0Sstevel@tonic-gate sep = 1; 504*0Sstevel@tonic-gate } 505*0Sstevel@tonic-gate } else { 506*0Sstevel@tonic-gate print_cpuset_range(set, words, 0); 507*0Sstevel@tonic-gate } 508*0Sstevel@tonic-gate 509*0Sstevel@tonic-gate return (DCMD_OK); 510*0Sstevel@tonic-gate } 511*0Sstevel@tonic-gate 512*0Sstevel@tonic-gate /*ARGSUSED*/ 513*0Sstevel@tonic-gate int 514*0Sstevel@tonic-gate ttctl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 515*0Sstevel@tonic-gate { 516*0Sstevel@tonic-gate TRAP_TRACE_CTL *ctls, *ctl; 517*0Sstevel@tonic-gate int i; 518*0Sstevel@tonic-gate 519*0Sstevel@tonic-gate if (argc != 0) 520*0Sstevel@tonic-gate return (DCMD_USAGE); 521*0Sstevel@tonic-gate 522*0Sstevel@tonic-gate if (fetch_ncpu()) 523*0Sstevel@tonic-gate return (DCMD_ERR); 524*0Sstevel@tonic-gate 525*0Sstevel@tonic-gate ctls = mdb_alloc(sizeof (TRAP_TRACE_CTL) * ncpu, UM_SLEEP | UM_GC); 526*0Sstevel@tonic-gate if (mdb_readsym(ctls, sizeof (TRAP_TRACE_CTL) * ncpu, 527*0Sstevel@tonic-gate "trap_trace_ctl") == -1) { 528*0Sstevel@tonic-gate mdb_warn("symbol 'trap_trace_ctl' not found"); 529*0Sstevel@tonic-gate return (DCMD_ERR); 530*0Sstevel@tonic-gate } 531*0Sstevel@tonic-gate 532*0Sstevel@tonic-gate for (ctl = &ctls[0], i = 0; i < ncpu; i++, ctl++) { 533*0Sstevel@tonic-gate if (ctl->d.vaddr_base == 0) 534*0Sstevel@tonic-gate continue; 535*0Sstevel@tonic-gate 536*0Sstevel@tonic-gate mdb_printf("trap_trace_ctl[%d] = {\n", i); 537*0Sstevel@tonic-gate mdb_printf(" vaddr_base = 0x%lx\n", (long)ctl->d.vaddr_base); 538*0Sstevel@tonic-gate mdb_printf(" last_offset = 0x%x\n", ctl->d.last_offset); 539*0Sstevel@tonic-gate mdb_printf(" offset = 0x%x\n", ctl->d.offset); 540*0Sstevel@tonic-gate mdb_printf(" limit = 0x%x\n", ctl->d.limit); 541*0Sstevel@tonic-gate mdb_printf(" paddr_base = 0x%llx\n", ctl->d.paddr_base); 542*0Sstevel@tonic-gate mdb_printf(" asi = 0x%02x\n}\n", ctl->d.asi); 543*0Sstevel@tonic-gate } 544*0Sstevel@tonic-gate 545*0Sstevel@tonic-gate return (DCMD_OK); 546*0Sstevel@tonic-gate } 547*0Sstevel@tonic-gate 548*0Sstevel@tonic-gate /*ARGSUSED*/ 549*0Sstevel@tonic-gate static int 550*0Sstevel@tonic-gate ttprint_short(uintptr_t addr, const trap_trace_fullrec_t *full, int *cpu) 551*0Sstevel@tonic-gate { 552*0Sstevel@tonic-gate const char *ttstr; 553*0Sstevel@tonic-gate const struct trap_trace_record *ttp = &full->ttf_rec; 554*0Sstevel@tonic-gate 555*0Sstevel@tonic-gate if (*cpu == -1) 556*0Sstevel@tonic-gate mdb_printf("%3d ", full->ttf_cpu); 557*0Sstevel@tonic-gate else 558*0Sstevel@tonic-gate if (*cpu != full->ttf_cpu) 559*0Sstevel@tonic-gate return (0); 560*0Sstevel@tonic-gate 561*0Sstevel@tonic-gate /* 562*0Sstevel@tonic-gate * Decoding the traptype field is a bit messy. First we check for 563*0Sstevel@tonic-gate * several well-defined 16-bit values defined in <sys/traptrace.h>. 564*0Sstevel@tonic-gate */ 565*0Sstevel@tonic-gate switch (ttp->tt_tt) { 566*0Sstevel@tonic-gate case TT_SC_ENTR: 567*0Sstevel@tonic-gate ttstr = "sys-enter"; 568*0Sstevel@tonic-gate break; 569*0Sstevel@tonic-gate case TT_SC_RET: 570*0Sstevel@tonic-gate ttstr = "sys-exit"; 571*0Sstevel@tonic-gate break; 572*0Sstevel@tonic-gate case TT_SYS_RTT_PROM: 573*0Sstevel@tonic-gate ttstr = "prom_rtt"; 574*0Sstevel@tonic-gate break; 575*0Sstevel@tonic-gate case TT_SYS_RTT_PRIV: 576*0Sstevel@tonic-gate ttstr = "priv_rtt"; 577*0Sstevel@tonic-gate break; 578*0Sstevel@tonic-gate case TT_SYS_RTT_USER: 579*0Sstevel@tonic-gate ttstr = "user_rtt"; 580*0Sstevel@tonic-gate break; 581*0Sstevel@tonic-gate case TT_INTR_EXIT: 582*0Sstevel@tonic-gate ttstr = "int-thr-exit"; 583*0Sstevel@tonic-gate break; 584*0Sstevel@tonic-gate default: 585*0Sstevel@tonic-gate /* 586*0Sstevel@tonic-gate * Next we consider several prefixes (which are 587*0Sstevel@tonic-gate * typically OR'd with other information such as the 588*0Sstevel@tonic-gate * %pil or %tt value at the time of the trace). 589*0Sstevel@tonic-gate */ 590*0Sstevel@tonic-gate switch (ttp->tt_tt & 0xff00) { 591*0Sstevel@tonic-gate case TT_SERVE_INTR: 592*0Sstevel@tonic-gate ttstr = "serve-intr"; 593*0Sstevel@tonic-gate break; 594*0Sstevel@tonic-gate case TT_XCALL: 595*0Sstevel@tonic-gate ttstr = "xcall"; 596*0Sstevel@tonic-gate break; 597*0Sstevel@tonic-gate case TT_XCALL_CONT: 598*0Sstevel@tonic-gate ttstr = "xcall-cont"; 599*0Sstevel@tonic-gate break; 600*0Sstevel@tonic-gate case SYSTRAP_TT: 601*0Sstevel@tonic-gate ttstr = "sys_trap"; 602*0Sstevel@tonic-gate break; 603*0Sstevel@tonic-gate default: 604*0Sstevel@tonic-gate /* 605*0Sstevel@tonic-gate * Otherwise we try to convert the 606*0Sstevel@tonic-gate * tt value to a string using our 607*0Sstevel@tonic-gate * giant lookup table. 608*0Sstevel@tonic-gate */ 609*0Sstevel@tonic-gate ttstr = ttp->tt_tt < ttndescr ? 610*0Sstevel@tonic-gate ttdescr[ttp->tt_tt] : "?"; 611*0Sstevel@tonic-gate } 612*0Sstevel@tonic-gate } 613*0Sstevel@tonic-gate 614*0Sstevel@tonic-gate #ifdef sun4v 615*0Sstevel@tonic-gate mdb_printf("%016llx %04hx %-12s %02x %02x %0?p %A\n", ttp->tt_tick, 616*0Sstevel@tonic-gate ttp->tt_tt, ttstr, ttp->tt_tl, ttp->tt_gl, 617*0Sstevel@tonic-gate ttp->tt_tpc, ttp->tt_tpc); 618*0Sstevel@tonic-gate #else 619*0Sstevel@tonic-gate mdb_printf("%016llx %04hx %-12s %04hx %0?p %A\n", ttp->tt_tick, 620*0Sstevel@tonic-gate ttp->tt_tt, ttstr, ttp->tt_tl, ttp->tt_tpc, ttp->tt_tpc); 621*0Sstevel@tonic-gate #endif 622*0Sstevel@tonic-gate 623*0Sstevel@tonic-gate return (WALK_NEXT); 624*0Sstevel@tonic-gate } 625*0Sstevel@tonic-gate 626*0Sstevel@tonic-gate /*ARGSUSED*/ 627*0Sstevel@tonic-gate static int 628*0Sstevel@tonic-gate ttprint_long(uintptr_t addr, const trap_trace_fullrec_t *full, int *cpu) 629*0Sstevel@tonic-gate { 630*0Sstevel@tonic-gate const struct trap_trace_record *ttp = &full->ttf_rec; 631*0Sstevel@tonic-gate 632*0Sstevel@tonic-gate if (*cpu == -1) 633*0Sstevel@tonic-gate mdb_printf("%3d ", full->ttf_cpu); 634*0Sstevel@tonic-gate else if (*cpu != full->ttf_cpu) 635*0Sstevel@tonic-gate return (WALK_NEXT); 636*0Sstevel@tonic-gate 637*0Sstevel@tonic-gate #ifdef sun4v 638*0Sstevel@tonic-gate mdb_printf("%016llx %016llx %04hx %02x %02x %0?p %0?p %0?p " 639*0Sstevel@tonic-gate "[%p,%p,%p,%p]\n", 640*0Sstevel@tonic-gate ttp->tt_tick, ttp->tt_tstate, ttp->tt_tt, ttp->tt_tl, ttp->tt_gl, 641*0Sstevel@tonic-gate ttp->tt_tpc, ttp->tt_sp, ttp->tt_tr, 642*0Sstevel@tonic-gate ttp->tt_f1, ttp->tt_f2, ttp->tt_f3, ttp->tt_f4); 643*0Sstevel@tonic-gate #else 644*0Sstevel@tonic-gate mdb_printf("%016llx %016llx %04hx %04hx %0?p %0?p %0?p [%p,%p,%p,%p]\n", 645*0Sstevel@tonic-gate ttp->tt_tick, ttp->tt_tstate, ttp->tt_tt, ttp->tt_tl, 646*0Sstevel@tonic-gate ttp->tt_tpc, ttp->tt_sp, ttp->tt_tr, 647*0Sstevel@tonic-gate ttp->tt_f1, ttp->tt_f2, ttp->tt_f3, ttp->tt_f4); 648*0Sstevel@tonic-gate #endif 649*0Sstevel@tonic-gate 650*0Sstevel@tonic-gate return (WALK_NEXT); 651*0Sstevel@tonic-gate } 652*0Sstevel@tonic-gate 653*0Sstevel@tonic-gate typedef struct ttrace_cpu_data { 654*0Sstevel@tonic-gate struct trap_trace_record *tc_buf; 655*0Sstevel@tonic-gate struct trap_trace_record *tc_rec; 656*0Sstevel@tonic-gate struct trap_trace_record *tc_stop; 657*0Sstevel@tonic-gate size_t tc_bufsiz; 658*0Sstevel@tonic-gate uintptr_t tc_base; 659*0Sstevel@tonic-gate } ttrace_cpu_data_t; 660*0Sstevel@tonic-gate 661*0Sstevel@tonic-gate typedef struct ttrace_walk_data { 662*0Sstevel@tonic-gate int tw_ncpu; 663*0Sstevel@tonic-gate ttrace_cpu_data_t *tw_cpus; 664*0Sstevel@tonic-gate } ttrace_walk_data_t; 665*0Sstevel@tonic-gate 666*0Sstevel@tonic-gate int 667*0Sstevel@tonic-gate ttrace_walk_init(mdb_walk_state_t *wsp) 668*0Sstevel@tonic-gate { 669*0Sstevel@tonic-gate TRAP_TRACE_CTL *ctls, *ctl; 670*0Sstevel@tonic-gate int i; 671*0Sstevel@tonic-gate ttrace_walk_data_t *tw; 672*0Sstevel@tonic-gate ttrace_cpu_data_t *tc; 673*0Sstevel@tonic-gate struct trap_trace_record *buf; 674*0Sstevel@tonic-gate 675*0Sstevel@tonic-gate if (wsp->walk_addr != NULL) { 676*0Sstevel@tonic-gate mdb_warn("ttrace only supports global walks\n"); 677*0Sstevel@tonic-gate return (WALK_ERR); 678*0Sstevel@tonic-gate } 679*0Sstevel@tonic-gate 680*0Sstevel@tonic-gate if (fetch_ncpu()) 681*0Sstevel@tonic-gate return (WALK_ERR); 682*0Sstevel@tonic-gate 683*0Sstevel@tonic-gate ctls = mdb_alloc(sizeof (TRAP_TRACE_CTL) * ncpu, UM_SLEEP); 684*0Sstevel@tonic-gate if (mdb_readsym(ctls, sizeof (TRAP_TRACE_CTL) * ncpu, 685*0Sstevel@tonic-gate "trap_trace_ctl") == -1) { 686*0Sstevel@tonic-gate mdb_warn("symbol 'trap_trace_ctl' not found"); 687*0Sstevel@tonic-gate mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu); 688*0Sstevel@tonic-gate return (WALK_ERR); 689*0Sstevel@tonic-gate } 690*0Sstevel@tonic-gate 691*0Sstevel@tonic-gate tw = mdb_zalloc(sizeof (ttrace_walk_data_t), UM_SLEEP); 692*0Sstevel@tonic-gate tw->tw_ncpu = ncpu; 693*0Sstevel@tonic-gate tw->tw_cpus = mdb_zalloc(sizeof (ttrace_cpu_data_t) * ncpu, UM_SLEEP); 694*0Sstevel@tonic-gate 695*0Sstevel@tonic-gate for (i = 0; i < ncpu; i++) { 696*0Sstevel@tonic-gate ctl = &ctls[i]; 697*0Sstevel@tonic-gate 698*0Sstevel@tonic-gate if (ctl->d.vaddr_base == 0) 699*0Sstevel@tonic-gate continue; 700*0Sstevel@tonic-gate 701*0Sstevel@tonic-gate tc = &(tw->tw_cpus[i]); 702*0Sstevel@tonic-gate tc->tc_bufsiz = ctl->d.limit - 703*0Sstevel@tonic-gate sizeof (struct trap_trace_record); 704*0Sstevel@tonic-gate tc->tc_buf = buf = mdb_alloc(tc->tc_bufsiz, UM_SLEEP); 705*0Sstevel@tonic-gate tc->tc_base = (uintptr_t)ctl->d.vaddr_base; 706*0Sstevel@tonic-gate 707*0Sstevel@tonic-gate if (mdb_vread(buf, tc->tc_bufsiz, tc->tc_base) == -1) { 708*0Sstevel@tonic-gate mdb_warn("failed to read trap trace buffer at %p", 709*0Sstevel@tonic-gate ctl->d.vaddr_base); 710*0Sstevel@tonic-gate mdb_free(buf, tc->tc_bufsiz); 711*0Sstevel@tonic-gate tc->tc_buf = NULL; 712*0Sstevel@tonic-gate } else { 713*0Sstevel@tonic-gate tc->tc_rec = (struct trap_trace_record *) 714*0Sstevel@tonic-gate ((uintptr_t)buf + (uintptr_t)ctl->d.last_offset); 715*0Sstevel@tonic-gate tc->tc_stop = (struct trap_trace_record *) 716*0Sstevel@tonic-gate ((uintptr_t)buf + (uintptr_t)ctl->d.offset); 717*0Sstevel@tonic-gate } 718*0Sstevel@tonic-gate } 719*0Sstevel@tonic-gate 720*0Sstevel@tonic-gate mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu); 721*0Sstevel@tonic-gate wsp->walk_data = tw; 722*0Sstevel@tonic-gate return (WALK_NEXT); 723*0Sstevel@tonic-gate } 724*0Sstevel@tonic-gate 725*0Sstevel@tonic-gate int 726*0Sstevel@tonic-gate ttrace_walk_step(mdb_walk_state_t *wsp) 727*0Sstevel@tonic-gate { 728*0Sstevel@tonic-gate ttrace_walk_data_t *tw = wsp->walk_data; 729*0Sstevel@tonic-gate ttrace_cpu_data_t *tc; 730*0Sstevel@tonic-gate struct trap_trace_record *rec; 731*0Sstevel@tonic-gate int oldest, i, status; 732*0Sstevel@tonic-gate uint64_t oldest_tick = 0; 733*0Sstevel@tonic-gate int done = 1; 734*0Sstevel@tonic-gate trap_trace_fullrec_t fullrec; 735*0Sstevel@tonic-gate 736*0Sstevel@tonic-gate for (i = 0; i < tw->tw_ncpu; i++) { 737*0Sstevel@tonic-gate tc = &(tw->tw_cpus[i]); 738*0Sstevel@tonic-gate 739*0Sstevel@tonic-gate if (tc->tc_rec == NULL) 740*0Sstevel@tonic-gate continue; 741*0Sstevel@tonic-gate done = 0; 742*0Sstevel@tonic-gate 743*0Sstevel@tonic-gate if (tc->tc_rec->tt_tick == 0) 744*0Sstevel@tonic-gate mdb_warn("Warning: tt_tick == 0\n"); 745*0Sstevel@tonic-gate 746*0Sstevel@tonic-gate if (tc->tc_rec->tt_tick > oldest_tick) { 747*0Sstevel@tonic-gate oldest_tick = tc->tc_rec->tt_tick; 748*0Sstevel@tonic-gate oldest = i; 749*0Sstevel@tonic-gate } 750*0Sstevel@tonic-gate } 751*0Sstevel@tonic-gate 752*0Sstevel@tonic-gate if (done) 753*0Sstevel@tonic-gate return (-1); 754*0Sstevel@tonic-gate 755*0Sstevel@tonic-gate tc = &(tw->tw_cpus[oldest]); 756*0Sstevel@tonic-gate rec = tc->tc_rec; 757*0Sstevel@tonic-gate 758*0Sstevel@tonic-gate fullrec.ttf_rec = *rec; 759*0Sstevel@tonic-gate fullrec.ttf_cpu = oldest; 760*0Sstevel@tonic-gate 761*0Sstevel@tonic-gate if (oldest_tick != 0) 762*0Sstevel@tonic-gate status = wsp->walk_callback((uintptr_t)rec - 763*0Sstevel@tonic-gate (uintptr_t)tc->tc_buf + tc->tc_base, &fullrec, 764*0Sstevel@tonic-gate wsp->walk_cbdata); 765*0Sstevel@tonic-gate 766*0Sstevel@tonic-gate tc->tc_rec--; 767*0Sstevel@tonic-gate 768*0Sstevel@tonic-gate if (tc->tc_rec < tc->tc_buf) 769*0Sstevel@tonic-gate tc->tc_rec = (struct trap_trace_record *)((uintptr_t) 770*0Sstevel@tonic-gate tc->tc_buf + (uintptr_t)tc->tc_bufsiz - 771*0Sstevel@tonic-gate sizeof (struct trap_trace_record)); 772*0Sstevel@tonic-gate 773*0Sstevel@tonic-gate if (tc->tc_rec == tc->tc_stop) { 774*0Sstevel@tonic-gate tc->tc_rec = NULL; 775*0Sstevel@tonic-gate mdb_free(tc->tc_buf, tc->tc_bufsiz); 776*0Sstevel@tonic-gate } 777*0Sstevel@tonic-gate 778*0Sstevel@tonic-gate return (status); 779*0Sstevel@tonic-gate } 780*0Sstevel@tonic-gate 781*0Sstevel@tonic-gate void 782*0Sstevel@tonic-gate ttrace_walk_fini(mdb_walk_state_t *wsp) 783*0Sstevel@tonic-gate { 784*0Sstevel@tonic-gate ttrace_walk_data_t *tw = wsp->walk_data; 785*0Sstevel@tonic-gate 786*0Sstevel@tonic-gate mdb_free(tw->tw_cpus, sizeof (ttrace_cpu_data_t) * tw->tw_ncpu); 787*0Sstevel@tonic-gate mdb_free(tw, sizeof (ttrace_walk_data_t)); 788*0Sstevel@tonic-gate } 789*0Sstevel@tonic-gate 790*0Sstevel@tonic-gate int 791*0Sstevel@tonic-gate ttrace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 792*0Sstevel@tonic-gate { 793*0Sstevel@tonic-gate uint_t opt_x = FALSE; 794*0Sstevel@tonic-gate int cpu = -1; 795*0Sstevel@tonic-gate mdb_walk_cb_t ttprint; 796*0Sstevel@tonic-gate 797*0Sstevel@tonic-gate if (mdb_getopts(argc, argv, 798*0Sstevel@tonic-gate 'x', MDB_OPT_SETBITS, TRUE, &opt_x, NULL) != argc) 799*0Sstevel@tonic-gate return (DCMD_USAGE); 800*0Sstevel@tonic-gate 801*0Sstevel@tonic-gate if (flags & DCMD_ADDRSPEC) { 802*0Sstevel@tonic-gate if (fetch_ncpu()) 803*0Sstevel@tonic-gate return (DCMD_ERR); 804*0Sstevel@tonic-gate if (addr >= ncpu) { 805*0Sstevel@tonic-gate mdb_warn("expected cpu between 0 and %d\n", ncpu - 1); 806*0Sstevel@tonic-gate return (DCMD_ERR); 807*0Sstevel@tonic-gate } 808*0Sstevel@tonic-gate cpu = (int)addr; 809*0Sstevel@tonic-gate } 810*0Sstevel@tonic-gate 811*0Sstevel@tonic-gate if (cpu == -1) 812*0Sstevel@tonic-gate mdb_printf("CPU "); 813*0Sstevel@tonic-gate 814*0Sstevel@tonic-gate if (opt_x) { 815*0Sstevel@tonic-gate #ifdef sun4v 816*0Sstevel@tonic-gate mdb_printf("%-16s %-16s %-4s %-3s %-3s %-?s %-?s %-?s " 817*0Sstevel@tonic-gate "F1-4\n", "%tick", "%tstate", "%tt", "%tl", "%gl", 818*0Sstevel@tonic-gate "%tpc", "%sp", "TR"); 819*0Sstevel@tonic-gate #else 820*0Sstevel@tonic-gate mdb_printf("%-16s %-16s %-4s %-4s %-?s %-?s %-?s " 821*0Sstevel@tonic-gate "F1-4\n", "%tick", "%tstate", "%tt", "%tl", 822*0Sstevel@tonic-gate "%tpc", "%sp", "TR"); 823*0Sstevel@tonic-gate #endif 824*0Sstevel@tonic-gate 825*0Sstevel@tonic-gate ttprint = (mdb_walk_cb_t)ttprint_long; 826*0Sstevel@tonic-gate } else { 827*0Sstevel@tonic-gate #ifdef sun4v 828*0Sstevel@tonic-gate mdb_printf("%-16s %-4s %-12s %-3s %-3s %s\n", 829*0Sstevel@tonic-gate "%tick", "%tt", "", "%tl", "%gl", "%tpc"); 830*0Sstevel@tonic-gate #else 831*0Sstevel@tonic-gate mdb_printf("%-16s %-4s %-12s %-4s %s\n", 832*0Sstevel@tonic-gate "%tick", "%tt", "", "%tl", "%tpc"); 833*0Sstevel@tonic-gate #endif 834*0Sstevel@tonic-gate 835*0Sstevel@tonic-gate ttprint = (mdb_walk_cb_t)ttprint_short; 836*0Sstevel@tonic-gate } 837*0Sstevel@tonic-gate 838*0Sstevel@tonic-gate if (mdb_walk("ttrace", ttprint, &cpu) == -1) { 839*0Sstevel@tonic-gate mdb_warn("couldn't walk ttrace"); 840*0Sstevel@tonic-gate return (DCMD_ERR); 841*0Sstevel@tonic-gate } 842*0Sstevel@tonic-gate 843*0Sstevel@tonic-gate return (DCMD_OK); 844*0Sstevel@tonic-gate } 845*0Sstevel@tonic-gate 846*0Sstevel@tonic-gate #ifdef sun4v 847*0Sstevel@tonic-gate /*ARGSUSED*/ 848*0Sstevel@tonic-gate int 849*0Sstevel@tonic-gate httctl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 850*0Sstevel@tonic-gate { 851*0Sstevel@tonic-gate TRAP_TRACE_CTL *ctls, *ctl; 852*0Sstevel@tonic-gate int i; 853*0Sstevel@tonic-gate htrap_trace_hdr_t hdr; 854*0Sstevel@tonic-gate 855*0Sstevel@tonic-gate if (argc != 0) 856*0Sstevel@tonic-gate return (DCMD_USAGE); 857*0Sstevel@tonic-gate 858*0Sstevel@tonic-gate if (fetch_ncpu()) 859*0Sstevel@tonic-gate return (DCMD_ERR); 860*0Sstevel@tonic-gate 861*0Sstevel@tonic-gate ctls = mdb_alloc(sizeof (TRAP_TRACE_CTL) * ncpu, UM_SLEEP | UM_GC); 862*0Sstevel@tonic-gate if (mdb_readsym(ctls, sizeof (TRAP_TRACE_CTL) * ncpu, 863*0Sstevel@tonic-gate "trap_trace_ctl") == -1) { 864*0Sstevel@tonic-gate mdb_warn("symbol 'trap_trace_ctl' not found"); 865*0Sstevel@tonic-gate return (DCMD_ERR); 866*0Sstevel@tonic-gate } 867*0Sstevel@tonic-gate 868*0Sstevel@tonic-gate for (ctl = &ctls[0], i = 0; i < ncpu; i++, ctl++) { 869*0Sstevel@tonic-gate if (ctl->d.hvaddr_base == 0) 870*0Sstevel@tonic-gate continue; 871*0Sstevel@tonic-gate 872*0Sstevel@tonic-gate mdb_vread(&hdr, sizeof (htrap_trace_hdr_t), 873*0Sstevel@tonic-gate (uintptr_t)ctl->d.hvaddr_base); 874*0Sstevel@tonic-gate mdb_printf("htrap_trace_ctl[%d] = {\n", i); 875*0Sstevel@tonic-gate mdb_printf(" vaddr_base = 0x%lx\n", (long)ctl->d.hvaddr_base); 876*0Sstevel@tonic-gate mdb_printf(" last_offset = 0x%lx\n", hdr.last_offset); 877*0Sstevel@tonic-gate mdb_printf(" offset = 0x%lx\n", hdr.offset); 878*0Sstevel@tonic-gate mdb_printf(" limit = 0x%x\n", ctl->d.hlimit); 879*0Sstevel@tonic-gate mdb_printf(" paddr_base = 0x%llx\n}\n", ctl->d.hpaddr_base); 880*0Sstevel@tonic-gate } 881*0Sstevel@tonic-gate 882*0Sstevel@tonic-gate return (DCMD_OK); 883*0Sstevel@tonic-gate } 884*0Sstevel@tonic-gate 885*0Sstevel@tonic-gate /*ARGSUSED*/ 886*0Sstevel@tonic-gate static int 887*0Sstevel@tonic-gate httprint_short(uintptr_t addr, const htrap_trace_fullrec_t *full, int *cpu) 888*0Sstevel@tonic-gate { 889*0Sstevel@tonic-gate const char *ttstr; 890*0Sstevel@tonic-gate const struct htrap_trace_record *ttp = &full->ttf_rec; 891*0Sstevel@tonic-gate 892*0Sstevel@tonic-gate if (*cpu == -1) 893*0Sstevel@tonic-gate mdb_printf("%3d ", full->ttf_cpu); 894*0Sstevel@tonic-gate else 895*0Sstevel@tonic-gate if (*cpu != full->ttf_cpu) 896*0Sstevel@tonic-gate return (0); 897*0Sstevel@tonic-gate 898*0Sstevel@tonic-gate /* 899*0Sstevel@tonic-gate * Convert the tt value to a string using our gaint lookuo table 900*0Sstevel@tonic-gate */ 901*0Sstevel@tonic-gate ttstr = ttp->tt_tt < ttndescr ? ttdescr[ttp->tt_tt] : "?"; 902*0Sstevel@tonic-gate 903*0Sstevel@tonic-gate mdb_printf("%016llx %02x %04hx %04hx %-16s %02x %02x %0?p %A\n", 904*0Sstevel@tonic-gate ttp->tt_tick, ttp->tt_ty, ttp->tt_tag, ttp->tt_tt, ttstr, 905*0Sstevel@tonic-gate ttp->tt_tl, ttp->tt_gl, ttp->tt_tpc, ttp->tt_tpc); 906*0Sstevel@tonic-gate 907*0Sstevel@tonic-gate return (WALK_NEXT); 908*0Sstevel@tonic-gate } 909*0Sstevel@tonic-gate 910*0Sstevel@tonic-gate /*ARGSUSED*/ 911*0Sstevel@tonic-gate static int 912*0Sstevel@tonic-gate httprint_long(uintptr_t addr, const htrap_trace_fullrec_t *full, int *cpu) 913*0Sstevel@tonic-gate { 914*0Sstevel@tonic-gate const struct htrap_trace_record *ttp = &full->ttf_rec; 915*0Sstevel@tonic-gate 916*0Sstevel@tonic-gate if (*cpu == -1) 917*0Sstevel@tonic-gate mdb_printf("%3d ", full->ttf_cpu); 918*0Sstevel@tonic-gate else if (*cpu != full->ttf_cpu) 919*0Sstevel@tonic-gate return (WALK_NEXT); 920*0Sstevel@tonic-gate 921*0Sstevel@tonic-gate mdb_printf("%016llx %016llx %02x %02x %04hx %04hx %02x %02x %0?p " 922*0Sstevel@tonic-gate "[%p,%p,%p,%p]\n", 923*0Sstevel@tonic-gate ttp->tt_tick, ttp->tt_tstate, ttp->tt_hpstate, ttp->tt_ty, 924*0Sstevel@tonic-gate ttp->tt_tag, ttp->tt_tt, ttp->tt_tl, ttp->tt_gl, ttp->tt_tpc, 925*0Sstevel@tonic-gate ttp->tt_f1, ttp->tt_f2, ttp->tt_f3, ttp->tt_f4); 926*0Sstevel@tonic-gate 927*0Sstevel@tonic-gate return (WALK_NEXT); 928*0Sstevel@tonic-gate } 929*0Sstevel@tonic-gate 930*0Sstevel@tonic-gate typedef struct httrace_cpu_data { 931*0Sstevel@tonic-gate struct htrap_trace_record *tc_buf; 932*0Sstevel@tonic-gate struct htrap_trace_record *tc_rec; 933*0Sstevel@tonic-gate struct htrap_trace_record *tc_stop; 934*0Sstevel@tonic-gate size_t tc_bufsiz; 935*0Sstevel@tonic-gate uintptr_t tc_base; 936*0Sstevel@tonic-gate } httrace_cpu_data_t; 937*0Sstevel@tonic-gate 938*0Sstevel@tonic-gate typedef struct httrace_walk_data { 939*0Sstevel@tonic-gate int tw_ncpu; 940*0Sstevel@tonic-gate httrace_cpu_data_t *tw_cpus; 941*0Sstevel@tonic-gate } httrace_walk_data_t; 942*0Sstevel@tonic-gate 943*0Sstevel@tonic-gate int 944*0Sstevel@tonic-gate httrace_walk_init(mdb_walk_state_t *wsp) 945*0Sstevel@tonic-gate { 946*0Sstevel@tonic-gate TRAP_TRACE_CTL *ctls, *ctl; 947*0Sstevel@tonic-gate int i; 948*0Sstevel@tonic-gate httrace_walk_data_t *tw; 949*0Sstevel@tonic-gate httrace_cpu_data_t *tc; 950*0Sstevel@tonic-gate struct htrap_trace_record *buf; 951*0Sstevel@tonic-gate htrap_trace_hdr_t hdr; 952*0Sstevel@tonic-gate 953*0Sstevel@tonic-gate if (wsp->walk_addr != NULL) { 954*0Sstevel@tonic-gate mdb_warn("httrace only supports global walks\n"); 955*0Sstevel@tonic-gate return (WALK_ERR); 956*0Sstevel@tonic-gate } 957*0Sstevel@tonic-gate 958*0Sstevel@tonic-gate if (fetch_ncpu()) 959*0Sstevel@tonic-gate return (WALK_ERR); 960*0Sstevel@tonic-gate 961*0Sstevel@tonic-gate ctls = mdb_alloc(sizeof (TRAP_TRACE_CTL) * ncpu, UM_SLEEP); 962*0Sstevel@tonic-gate if (mdb_readsym(ctls, sizeof (TRAP_TRACE_CTL) * ncpu, 963*0Sstevel@tonic-gate "trap_trace_ctl") == -1) { 964*0Sstevel@tonic-gate mdb_warn("symbol 'trap_trace_ctl' not found"); 965*0Sstevel@tonic-gate mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu); 966*0Sstevel@tonic-gate return (WALK_ERR); 967*0Sstevel@tonic-gate } 968*0Sstevel@tonic-gate 969*0Sstevel@tonic-gate tw = mdb_zalloc(sizeof (httrace_walk_data_t), UM_SLEEP); 970*0Sstevel@tonic-gate tw->tw_ncpu = ncpu; 971*0Sstevel@tonic-gate tw->tw_cpus = mdb_zalloc(sizeof (httrace_cpu_data_t) * ncpu, UM_SLEEP); 972*0Sstevel@tonic-gate 973*0Sstevel@tonic-gate for (i = 0; i < ncpu; i++) { 974*0Sstevel@tonic-gate ctl = &ctls[i]; 975*0Sstevel@tonic-gate 976*0Sstevel@tonic-gate if (ctl->d.hvaddr_base == 0) 977*0Sstevel@tonic-gate continue; 978*0Sstevel@tonic-gate 979*0Sstevel@tonic-gate tc = &(tw->tw_cpus[i]); 980*0Sstevel@tonic-gate tc->tc_bufsiz = ctl->d.hlimit - 981*0Sstevel@tonic-gate sizeof (struct htrap_trace_record); 982*0Sstevel@tonic-gate tc->tc_buf = buf = mdb_alloc(tc->tc_bufsiz, UM_SLEEP); 983*0Sstevel@tonic-gate tc->tc_base = (uintptr_t)ctl->d.hvaddr_base; 984*0Sstevel@tonic-gate 985*0Sstevel@tonic-gate if (mdb_vread(buf, tc->tc_bufsiz, tc->tc_base) == -1) { 986*0Sstevel@tonic-gate mdb_warn("failed to read hv trap trace buffer at %p", 987*0Sstevel@tonic-gate ctl->d.hvaddr_base); 988*0Sstevel@tonic-gate mdb_free(buf, tc->tc_bufsiz); 989*0Sstevel@tonic-gate tc->tc_buf = NULL; 990*0Sstevel@tonic-gate } else { 991*0Sstevel@tonic-gate mdb_vread(&hdr, sizeof (htrap_trace_hdr_t), 992*0Sstevel@tonic-gate (uintptr_t)ctl->d.hvaddr_base); 993*0Sstevel@tonic-gate tc->tc_rec = (struct htrap_trace_record *) 994*0Sstevel@tonic-gate ((uintptr_t)buf + (uintptr_t)hdr.last_offset); 995*0Sstevel@tonic-gate tc->tc_stop = (struct htrap_trace_record *) 996*0Sstevel@tonic-gate ((uintptr_t)buf + (uintptr_t)hdr.offset); 997*0Sstevel@tonic-gate } 998*0Sstevel@tonic-gate } 999*0Sstevel@tonic-gate 1000*0Sstevel@tonic-gate mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu); 1001*0Sstevel@tonic-gate wsp->walk_data = tw; 1002*0Sstevel@tonic-gate return (WALK_NEXT); 1003*0Sstevel@tonic-gate } 1004*0Sstevel@tonic-gate 1005*0Sstevel@tonic-gate int 1006*0Sstevel@tonic-gate httrace_walk_step(mdb_walk_state_t *wsp) 1007*0Sstevel@tonic-gate { 1008*0Sstevel@tonic-gate httrace_walk_data_t *tw = wsp->walk_data; 1009*0Sstevel@tonic-gate httrace_cpu_data_t *tc; 1010*0Sstevel@tonic-gate struct htrap_trace_record *rec; 1011*0Sstevel@tonic-gate int oldest, i, status; 1012*0Sstevel@tonic-gate uint64_t oldest_tick = 0; 1013*0Sstevel@tonic-gate int done = 1; 1014*0Sstevel@tonic-gate htrap_trace_fullrec_t fullrec; 1015*0Sstevel@tonic-gate 1016*0Sstevel@tonic-gate for (i = 0; i < tw->tw_ncpu; i++) { 1017*0Sstevel@tonic-gate tc = &(tw->tw_cpus[i]); 1018*0Sstevel@tonic-gate 1019*0Sstevel@tonic-gate if (tc->tc_rec == NULL) 1020*0Sstevel@tonic-gate continue; 1021*0Sstevel@tonic-gate done = 0; 1022*0Sstevel@tonic-gate 1023*0Sstevel@tonic-gate if (tc->tc_rec->tt_tick == 0) 1024*0Sstevel@tonic-gate mdb_warn("Warning: tt_tick == 0\n"); 1025*0Sstevel@tonic-gate 1026*0Sstevel@tonic-gate if (tc->tc_rec->tt_tick > oldest_tick) { 1027*0Sstevel@tonic-gate oldest_tick = tc->tc_rec->tt_tick; 1028*0Sstevel@tonic-gate oldest = i; 1029*0Sstevel@tonic-gate } 1030*0Sstevel@tonic-gate } 1031*0Sstevel@tonic-gate 1032*0Sstevel@tonic-gate if (done) 1033*0Sstevel@tonic-gate return (-1); 1034*0Sstevel@tonic-gate 1035*0Sstevel@tonic-gate tc = &(tw->tw_cpus[oldest]); 1036*0Sstevel@tonic-gate rec = tc->tc_rec; 1037*0Sstevel@tonic-gate 1038*0Sstevel@tonic-gate fullrec.ttf_rec = *rec; 1039*0Sstevel@tonic-gate fullrec.ttf_cpu = oldest; 1040*0Sstevel@tonic-gate 1041*0Sstevel@tonic-gate if (oldest_tick != 0) 1042*0Sstevel@tonic-gate status = wsp->walk_callback((uintptr_t)rec - 1043*0Sstevel@tonic-gate (uintptr_t)tc->tc_buf + tc->tc_base, &fullrec, 1044*0Sstevel@tonic-gate wsp->walk_cbdata); 1045*0Sstevel@tonic-gate 1046*0Sstevel@tonic-gate tc->tc_rec--; 1047*0Sstevel@tonic-gate 1048*0Sstevel@tonic-gate /* first record of the trap trace buffer is trap trace header */ 1049*0Sstevel@tonic-gate if (tc->tc_rec == tc->tc_buf) 1050*0Sstevel@tonic-gate tc->tc_rec = (struct htrap_trace_record *)((uintptr_t) 1051*0Sstevel@tonic-gate tc->tc_buf + (uintptr_t)tc->tc_bufsiz - 1052*0Sstevel@tonic-gate sizeof (struct htrap_trace_record)); 1053*0Sstevel@tonic-gate 1054*0Sstevel@tonic-gate if (tc->tc_rec == tc->tc_stop) { 1055*0Sstevel@tonic-gate tc->tc_rec = NULL; 1056*0Sstevel@tonic-gate mdb_free(tc->tc_buf, tc->tc_bufsiz); 1057*0Sstevel@tonic-gate } 1058*0Sstevel@tonic-gate 1059*0Sstevel@tonic-gate return (status); 1060*0Sstevel@tonic-gate } 1061*0Sstevel@tonic-gate 1062*0Sstevel@tonic-gate void 1063*0Sstevel@tonic-gate httrace_walk_fini(mdb_walk_state_t *wsp) 1064*0Sstevel@tonic-gate { 1065*0Sstevel@tonic-gate httrace_walk_data_t *tw = wsp->walk_data; 1066*0Sstevel@tonic-gate 1067*0Sstevel@tonic-gate mdb_free(tw->tw_cpus, sizeof (httrace_cpu_data_t) * tw->tw_ncpu); 1068*0Sstevel@tonic-gate mdb_free(tw, sizeof (httrace_walk_data_t)); 1069*0Sstevel@tonic-gate } 1070*0Sstevel@tonic-gate 1071*0Sstevel@tonic-gate int 1072*0Sstevel@tonic-gate httrace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1073*0Sstevel@tonic-gate { 1074*0Sstevel@tonic-gate uint_t opt_x = FALSE; 1075*0Sstevel@tonic-gate int cpu = -1; 1076*0Sstevel@tonic-gate mdb_walk_cb_t ttprint; 1077*0Sstevel@tonic-gate 1078*0Sstevel@tonic-gate if (mdb_getopts(argc, argv, 1079*0Sstevel@tonic-gate 'x', MDB_OPT_SETBITS, TRUE, &opt_x, NULL) != argc) 1080*0Sstevel@tonic-gate return (DCMD_USAGE); 1081*0Sstevel@tonic-gate 1082*0Sstevel@tonic-gate if (flags & DCMD_ADDRSPEC) { 1083*0Sstevel@tonic-gate if (fetch_ncpu()) 1084*0Sstevel@tonic-gate return (DCMD_ERR); 1085*0Sstevel@tonic-gate if (addr >= ncpu) { 1086*0Sstevel@tonic-gate mdb_warn("expected cpu between 0 and %d\n", ncpu - 1); 1087*0Sstevel@tonic-gate return (DCMD_ERR); 1088*0Sstevel@tonic-gate } 1089*0Sstevel@tonic-gate cpu = (int)addr; 1090*0Sstevel@tonic-gate } 1091*0Sstevel@tonic-gate 1092*0Sstevel@tonic-gate if (cpu == -1) 1093*0Sstevel@tonic-gate mdb_printf("CPU "); 1094*0Sstevel@tonic-gate 1095*0Sstevel@tonic-gate if (opt_x) { 1096*0Sstevel@tonic-gate mdb_printf("%-16s %-16s %-3s %-3s %-4s %-4s %-3s %-3s %-?s " 1097*0Sstevel@tonic-gate "F1-4\n", "%tick", "%tstate", "%hp", "%ty", "%tag", 1098*0Sstevel@tonic-gate "%tt", "%tl", "%gl", "%tpc"); 1099*0Sstevel@tonic-gate ttprint = (mdb_walk_cb_t)httprint_long; 1100*0Sstevel@tonic-gate } else { 1101*0Sstevel@tonic-gate mdb_printf("%-16s %-3s %-4s %-4s %-16s %-3s %-3s %s\n", 1102*0Sstevel@tonic-gate "%tick", "%ty", "%tag", "%tt", "", "%tl", "%gl", 1103*0Sstevel@tonic-gate "%tpc"); 1104*0Sstevel@tonic-gate ttprint = (mdb_walk_cb_t)httprint_short; 1105*0Sstevel@tonic-gate } 1106*0Sstevel@tonic-gate 1107*0Sstevel@tonic-gate if (mdb_walk("httrace", ttprint, &cpu) == -1) { 1108*0Sstevel@tonic-gate mdb_warn("couldn't walk httrace"); 1109*0Sstevel@tonic-gate return (DCMD_ERR); 1110*0Sstevel@tonic-gate } 1111*0Sstevel@tonic-gate 1112*0Sstevel@tonic-gate return (DCMD_OK); 1113*0Sstevel@tonic-gate } 1114*0Sstevel@tonic-gate #endif 1115*0Sstevel@tonic-gate 1116*0Sstevel@tonic-gate struct { 1117*0Sstevel@tonic-gate int xc_type; 1118*0Sstevel@tonic-gate const char *xc_str; 1119*0Sstevel@tonic-gate } xc_data[] = { 1120*0Sstevel@tonic-gate { XT_ONE_SELF, "xt-one-self" }, 1121*0Sstevel@tonic-gate { XT_ONE_OTHER, "xt-one-other" }, 1122*0Sstevel@tonic-gate { XT_SOME_SELF, "xt-some-self" }, 1123*0Sstevel@tonic-gate { XT_SOME_OTHER, "xt-some-other" }, 1124*0Sstevel@tonic-gate { XT_ALL_SELF, "xt-all-self" }, 1125*0Sstevel@tonic-gate { XT_ALL_OTHER, "xt-all-other" }, 1126*0Sstevel@tonic-gate { XC_ONE_SELF, "xc-one-self" }, 1127*0Sstevel@tonic-gate { XC_ONE_OTHER, "xc-one-other" }, 1128*0Sstevel@tonic-gate { XC_ONE_OTHER_H, "xc-one-other-h" }, 1129*0Sstevel@tonic-gate { XC_SOME_SELF, "xc-some-self" }, 1130*0Sstevel@tonic-gate { XC_SOME_OTHER, "xc-some-other" }, 1131*0Sstevel@tonic-gate { XC_SOME_OTHER_H, "xc-some-other-h" }, 1132*0Sstevel@tonic-gate { XC_ALL_SELF, "xc-all-self" }, 1133*0Sstevel@tonic-gate { XC_ALL_OTHER, "xc-all-other" }, 1134*0Sstevel@tonic-gate { XC_ALL_OTHER_H, "xc-all-other-h" }, 1135*0Sstevel@tonic-gate { XC_ATTENTION, "xc-attention" }, 1136*0Sstevel@tonic-gate { XC_DISMISSED, "xc-dismissed" }, 1137*0Sstevel@tonic-gate { XC_LOOP_ENTER, "xc-loop-enter" }, 1138*0Sstevel@tonic-gate { XC_LOOP_DOIT, "xc-loop-doit" }, 1139*0Sstevel@tonic-gate { XC_LOOP_EXIT, "xc-loop-exit" }, 1140*0Sstevel@tonic-gate { 0, NULL } 1141*0Sstevel@tonic-gate }; 1142*0Sstevel@tonic-gate 1143*0Sstevel@tonic-gate /*ARGSUSED*/ 1144*0Sstevel@tonic-gate int 1145*0Sstevel@tonic-gate xctrace_walk(uintptr_t addr, const trap_trace_fullrec_t *full, int *cpu) 1146*0Sstevel@tonic-gate { 1147*0Sstevel@tonic-gate const struct trap_trace_record *ttp = &full->ttf_rec; 1148*0Sstevel@tonic-gate int i, type = ttp->tt_tt & 0xff; 1149*0Sstevel@tonic-gate const char *str = "???"; 1150*0Sstevel@tonic-gate 1151*0Sstevel@tonic-gate if ((ttp->tt_tt & 0xff00) == TT_XCALL) { 1152*0Sstevel@tonic-gate for (i = 0; xc_data[i].xc_str != NULL; i++) { 1153*0Sstevel@tonic-gate if (xc_data[i].xc_type == type) { 1154*0Sstevel@tonic-gate str = xc_data[i].xc_str; 1155*0Sstevel@tonic-gate break; 1156*0Sstevel@tonic-gate } 1157*0Sstevel@tonic-gate } 1158*0Sstevel@tonic-gate } else if ((ttp->tt_tt & 0xff00) == TT_XCALL_CONT) { 1159*0Sstevel@tonic-gate str = "xcall-cont"; 1160*0Sstevel@tonic-gate mdb_printf("%3d %016llx %-16s %08x %08x %08x %08x\n", 1161*0Sstevel@tonic-gate full->ttf_cpu, ttp->tt_tick, str, ttp->tt_f1, ttp->tt_f2, 1162*0Sstevel@tonic-gate ttp->tt_f3, ttp->tt_f4); 1163*0Sstevel@tonic-gate return (WALK_NEXT); 1164*0Sstevel@tonic-gate } else if (ttp->tt_tt == 0x60) { 1165*0Sstevel@tonic-gate str = "int-vec"; 1166*0Sstevel@tonic-gate } else { 1167*0Sstevel@tonic-gate return (WALK_NEXT); 1168*0Sstevel@tonic-gate } 1169*0Sstevel@tonic-gate 1170*0Sstevel@tonic-gate mdb_printf("%3d %016llx %-16s %08x %a\n", full->ttf_cpu, 1171*0Sstevel@tonic-gate ttp->tt_tick, str, ttp->tt_sp, ttp->tt_tr); 1172*0Sstevel@tonic-gate 1173*0Sstevel@tonic-gate return (WALK_NEXT); 1174*0Sstevel@tonic-gate } 1175*0Sstevel@tonic-gate 1176*0Sstevel@tonic-gate /*ARGSUSED*/ 1177*0Sstevel@tonic-gate int 1178*0Sstevel@tonic-gate xctrace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1179*0Sstevel@tonic-gate { 1180*0Sstevel@tonic-gate if ((flags & DCMD_ADDRSPEC) || argc != 0) 1181*0Sstevel@tonic-gate return (DCMD_USAGE); 1182*0Sstevel@tonic-gate 1183*0Sstevel@tonic-gate if (mdb_walk("ttrace", (mdb_walk_cb_t)xctrace_walk, NULL) == -1) { 1184*0Sstevel@tonic-gate mdb_warn("couldn't walk ttrace"); 1185*0Sstevel@tonic-gate return (DCMD_ERR); 1186*0Sstevel@tonic-gate } 1187*0Sstevel@tonic-gate 1188*0Sstevel@tonic-gate return (DCMD_OK); 1189*0Sstevel@tonic-gate } 1190*0Sstevel@tonic-gate 1191*0Sstevel@tonic-gate /* 1192*0Sstevel@tonic-gate * Grrr... xc_mbox isn't in an _impl header file; we define it here. 1193*0Sstevel@tonic-gate */ 1194*0Sstevel@tonic-gate typedef struct xc_mbox { 1195*0Sstevel@tonic-gate xcfunc_t *xc_func; 1196*0Sstevel@tonic-gate uint64_t xc_arg1; 1197*0Sstevel@tonic-gate uint64_t xc_arg2; 1198*0Sstevel@tonic-gate cpuset_t xc_cpuset; 1199*0Sstevel@tonic-gate volatile uint_t xc_state; 1200*0Sstevel@tonic-gate } xc_mbox_t; 1201*0Sstevel@tonic-gate 1202*0Sstevel@tonic-gate typedef struct xc_mbox_walk { 1203*0Sstevel@tonic-gate int xw_ndx; 1204*0Sstevel@tonic-gate uintptr_t xw_addr; 1205*0Sstevel@tonic-gate xc_mbox_t *xw_mbox; 1206*0Sstevel@tonic-gate } xc_mbox_walk_t; 1207*0Sstevel@tonic-gate 1208*0Sstevel@tonic-gate static int 1209*0Sstevel@tonic-gate xc_mbox_walk_init(mdb_walk_state_t *wsp) 1210*0Sstevel@tonic-gate { 1211*0Sstevel@tonic-gate GElf_Sym sym; 1212*0Sstevel@tonic-gate xc_mbox_walk_t *xw; 1213*0Sstevel@tonic-gate 1214*0Sstevel@tonic-gate if (mdb_lookup_by_name("xc_mbox", &sym) == -1) { 1215*0Sstevel@tonic-gate mdb_warn("couldn't find 'xc_mbox'"); 1216*0Sstevel@tonic-gate return (WALK_ERR); 1217*0Sstevel@tonic-gate } 1218*0Sstevel@tonic-gate 1219*0Sstevel@tonic-gate if (fetch_ncpu() || fetch_mbox()) 1220*0Sstevel@tonic-gate return (WALK_ERR); 1221*0Sstevel@tonic-gate 1222*0Sstevel@tonic-gate xw = mdb_zalloc(sizeof (xc_mbox_walk_t), UM_SLEEP); 1223*0Sstevel@tonic-gate xw->xw_mbox = mdb_zalloc(mbox_size * ncpu, UM_SLEEP); 1224*0Sstevel@tonic-gate 1225*0Sstevel@tonic-gate if (mdb_readsym(xw->xw_mbox, mbox_size * ncpu, "xc_mbox") == -1) { 1226*0Sstevel@tonic-gate mdb_warn("couldn't read 'xc_mbox'"); 1227*0Sstevel@tonic-gate mdb_free(xw->xw_mbox, mbox_size * ncpu); 1228*0Sstevel@tonic-gate mdb_free(xw, sizeof (xc_mbox_walk_t)); 1229*0Sstevel@tonic-gate return (WALK_ERR); 1230*0Sstevel@tonic-gate } 1231*0Sstevel@tonic-gate 1232*0Sstevel@tonic-gate xw->xw_addr = sym.st_value; 1233*0Sstevel@tonic-gate wsp->walk_data = xw; 1234*0Sstevel@tonic-gate 1235*0Sstevel@tonic-gate return (WALK_NEXT); 1236*0Sstevel@tonic-gate } 1237*0Sstevel@tonic-gate 1238*0Sstevel@tonic-gate static int 1239*0Sstevel@tonic-gate xc_mbox_walk_step(mdb_walk_state_t *wsp) 1240*0Sstevel@tonic-gate { 1241*0Sstevel@tonic-gate xc_mbox_walk_t *xw = wsp->walk_data; 1242*0Sstevel@tonic-gate int status; 1243*0Sstevel@tonic-gate 1244*0Sstevel@tonic-gate if (xw->xw_ndx == ncpu) 1245*0Sstevel@tonic-gate return (WALK_DONE); 1246*0Sstevel@tonic-gate 1247*0Sstevel@tonic-gate status = wsp->walk_callback(xw->xw_addr, 1248*0Sstevel@tonic-gate &xw->xw_mbox[xw->xw_ndx++], wsp->walk_cbdata); 1249*0Sstevel@tonic-gate 1250*0Sstevel@tonic-gate xw->xw_addr += mbox_size; 1251*0Sstevel@tonic-gate return (status); 1252*0Sstevel@tonic-gate } 1253*0Sstevel@tonic-gate 1254*0Sstevel@tonic-gate static void 1255*0Sstevel@tonic-gate xc_mbox_walk_fini(mdb_walk_state_t *wsp) 1256*0Sstevel@tonic-gate { 1257*0Sstevel@tonic-gate xc_mbox_walk_t *xw = wsp->walk_data; 1258*0Sstevel@tonic-gate 1259*0Sstevel@tonic-gate mdb_free(xw->xw_mbox, mbox_size * ncpu); 1260*0Sstevel@tonic-gate mdb_free(xw, sizeof (xc_mbox_walk_t)); 1261*0Sstevel@tonic-gate } 1262*0Sstevel@tonic-gate 1263*0Sstevel@tonic-gate static int 1264*0Sstevel@tonic-gate xc_mbox(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1265*0Sstevel@tonic-gate { 1266*0Sstevel@tonic-gate xc_mbox_t *mbox; 1267*0Sstevel@tonic-gate GElf_Sym sym; 1268*0Sstevel@tonic-gate const char *state; 1269*0Sstevel@tonic-gate 1270*0Sstevel@tonic-gate if (argc != 0) 1271*0Sstevel@tonic-gate return (DCMD_USAGE); 1272*0Sstevel@tonic-gate 1273*0Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 1274*0Sstevel@tonic-gate if (mdb_walk_dcmd("xc_mbox", "xc_mbox", argc, argv) == -1) { 1275*0Sstevel@tonic-gate mdb_warn("can't walk 'xc_mbox'"); 1276*0Sstevel@tonic-gate return (DCMD_ERR); 1277*0Sstevel@tonic-gate } 1278*0Sstevel@tonic-gate return (DCMD_OK); 1279*0Sstevel@tonic-gate } 1280*0Sstevel@tonic-gate 1281*0Sstevel@tonic-gate if (fetch_ncpu() || fetch_mbox()) 1282*0Sstevel@tonic-gate return (DCMD_ERR); 1283*0Sstevel@tonic-gate 1284*0Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) { 1285*0Sstevel@tonic-gate mdb_printf("%3s %-8s %-8s %-9s %-16s %-16s %s\n", 1286*0Sstevel@tonic-gate "CPU", "ADDR", "STATE", "CPUSET", "ARG1", "ARG2", "HNDLR"); 1287*0Sstevel@tonic-gate } 1288*0Sstevel@tonic-gate 1289*0Sstevel@tonic-gate mbox = mdb_alloc(mbox_size, UM_SLEEP | UM_GC); 1290*0Sstevel@tonic-gate if (mdb_vread(mbox, mbox_size, addr) == -1) { 1291*0Sstevel@tonic-gate mdb_warn("couldn't read xc_mbox at %p", addr); 1292*0Sstevel@tonic-gate return (DCMD_ERR); 1293*0Sstevel@tonic-gate } 1294*0Sstevel@tonic-gate 1295*0Sstevel@tonic-gate if (mbox->xc_func == NULL) 1296*0Sstevel@tonic-gate return (DCMD_OK); 1297*0Sstevel@tonic-gate 1298*0Sstevel@tonic-gate if (mdb_lookup_by_name("xc_mbox", &sym) == -1) { 1299*0Sstevel@tonic-gate mdb_warn("couldn't read 'xc_mbox'"); 1300*0Sstevel@tonic-gate return (DCMD_ERR); 1301*0Sstevel@tonic-gate } 1302*0Sstevel@tonic-gate 1303*0Sstevel@tonic-gate state = mdb_ctf_enum_name(mbox_states, 1304*0Sstevel@tonic-gate /* LINTED - alignment */ 1305*0Sstevel@tonic-gate *(int *)((char *)mbox + mbox_stoff)); 1306*0Sstevel@tonic-gate 1307*0Sstevel@tonic-gate mdb_printf("%3d %08x %-8s [ ", 1308*0Sstevel@tonic-gate (int)((addr - sym.st_value) / mbox_size), addr, 1309*0Sstevel@tonic-gate state ? state : "XC_???"); 1310*0Sstevel@tonic-gate 1311*0Sstevel@tonic-gate print_cpuset_range(&mbox->xc_cpuset, BT_BITOUL(ncpu), 5); 1312*0Sstevel@tonic-gate 1313*0Sstevel@tonic-gate mdb_printf(" ] %-16a %-16a %a\n", 1314*0Sstevel@tonic-gate mbox->xc_arg1, mbox->xc_arg2, mbox->xc_func); 1315*0Sstevel@tonic-gate 1316*0Sstevel@tonic-gate return (DCMD_OK); 1317*0Sstevel@tonic-gate } 1318*0Sstevel@tonic-gate 1319*0Sstevel@tonic-gate typedef struct softint_walk_data { 1320*0Sstevel@tonic-gate struct intr_vector *sw_table; 1321*0Sstevel@tonic-gate uintptr_t sw_base; 1322*0Sstevel@tonic-gate size_t sw_ndx; 1323*0Sstevel@tonic-gate size_t sw_size; 1324*0Sstevel@tonic-gate } softint_walk_data_t; 1325*0Sstevel@tonic-gate 1326*0Sstevel@tonic-gate int 1327*0Sstevel@tonic-gate softint_walk_init(mdb_walk_state_t *wsp) 1328*0Sstevel@tonic-gate { 1329*0Sstevel@tonic-gate softint_walk_data_t *sw; 1330*0Sstevel@tonic-gate 1331*0Sstevel@tonic-gate if (wsp->walk_addr != NULL) { 1332*0Sstevel@tonic-gate mdb_warn("softint walk only supports global walks\n"); 1333*0Sstevel@tonic-gate return (WALK_ERR); 1334*0Sstevel@tonic-gate } 1335*0Sstevel@tonic-gate 1336*0Sstevel@tonic-gate /* 1337*0Sstevel@tonic-gate * If this fails, we'll just end up printing all the entries. 1338*0Sstevel@tonic-gate */ 1339*0Sstevel@tonic-gate if (mdb_lookup_by_name("nohandler", &iv_nohandler_sym) == -1) 1340*0Sstevel@tonic-gate mdb_warn("couldn't find iv nohandler"); 1341*0Sstevel@tonic-gate 1342*0Sstevel@tonic-gate sw = mdb_zalloc(sizeof (softint_walk_data_t), UM_SLEEP); 1343*0Sstevel@tonic-gate 1344*0Sstevel@tonic-gate sw->sw_size = iv_sym.st_size; 1345*0Sstevel@tonic-gate sw->sw_base = (uintptr_t)iv_sym.st_value; 1346*0Sstevel@tonic-gate sw->sw_table = mdb_zalloc(sw->sw_size, UM_SLEEP); 1347*0Sstevel@tonic-gate 1348*0Sstevel@tonic-gate if (mdb_vread(sw->sw_table, sw->sw_size, sw->sw_base) == -1) { 1349*0Sstevel@tonic-gate mdb_warn("couldn't read intr_vector table"); 1350*0Sstevel@tonic-gate mdb_free(sw->sw_table, sw->sw_size); 1351*0Sstevel@tonic-gate mdb_free(sw, sizeof (softint_walk_data_t)); 1352*0Sstevel@tonic-gate return (WALK_ERR); 1353*0Sstevel@tonic-gate } 1354*0Sstevel@tonic-gate 1355*0Sstevel@tonic-gate wsp->walk_data = sw; 1356*0Sstevel@tonic-gate return (WALK_NEXT); 1357*0Sstevel@tonic-gate } 1358*0Sstevel@tonic-gate 1359*0Sstevel@tonic-gate int 1360*0Sstevel@tonic-gate softint_walk_step(mdb_walk_state_t *wsp) 1361*0Sstevel@tonic-gate { 1362*0Sstevel@tonic-gate softint_walk_data_t *sw = (softint_walk_data_t *)wsp->walk_data; 1363*0Sstevel@tonic-gate size_t max = sw->sw_size / sizeof (struct intr_vector); 1364*0Sstevel@tonic-gate 1365*0Sstevel@tonic-gate while (sw->sw_ndx < max) { 1366*0Sstevel@tonic-gate struct intr_vector *iv = &(sw->sw_table[sw->sw_ndx++]); 1367*0Sstevel@tonic-gate 1368*0Sstevel@tonic-gate if (iv->iv_handler == (intrfunc)iv_nohandler_sym.st_value) 1369*0Sstevel@tonic-gate continue; 1370*0Sstevel@tonic-gate 1371*0Sstevel@tonic-gate return (wsp->walk_callback((uintptr_t)iv - 1372*0Sstevel@tonic-gate (uintptr_t)sw->sw_table + sw->sw_base, iv, 1373*0Sstevel@tonic-gate wsp->walk_cbdata)); 1374*0Sstevel@tonic-gate } 1375*0Sstevel@tonic-gate 1376*0Sstevel@tonic-gate return (WALK_DONE); 1377*0Sstevel@tonic-gate } 1378*0Sstevel@tonic-gate 1379*0Sstevel@tonic-gate void 1380*0Sstevel@tonic-gate softint_walk_fini(mdb_walk_state_t *wsp) 1381*0Sstevel@tonic-gate { 1382*0Sstevel@tonic-gate softint_walk_data_t *sw = wsp->walk_data; 1383*0Sstevel@tonic-gate 1384*0Sstevel@tonic-gate mdb_free(sw->sw_table, sw->sw_size); 1385*0Sstevel@tonic-gate mdb_free(sw, sizeof (softint_walk_data_t)); 1386*0Sstevel@tonic-gate } 1387*0Sstevel@tonic-gate 1388*0Sstevel@tonic-gate int 1389*0Sstevel@tonic-gate softint_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1390*0Sstevel@tonic-gate { 1391*0Sstevel@tonic-gate int inum; 1392*0Sstevel@tonic-gate struct intr_vector iv; 1393*0Sstevel@tonic-gate 1394*0Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 1395*0Sstevel@tonic-gate if (mdb_walk_dcmd("softint", "softint", argc, argv) == -1) { 1396*0Sstevel@tonic-gate mdb_warn("can't walk softint"); 1397*0Sstevel@tonic-gate return (DCMD_ERR); 1398*0Sstevel@tonic-gate } 1399*0Sstevel@tonic-gate return (DCMD_OK); 1400*0Sstevel@tonic-gate } 1401*0Sstevel@tonic-gate 1402*0Sstevel@tonic-gate inum = (int)((addr - (uintptr_t)iv_sym.st_value) / 1403*0Sstevel@tonic-gate sizeof (struct intr_vector)); 1404*0Sstevel@tonic-gate 1405*0Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) { 1406*0Sstevel@tonic-gate mdb_printf("%4s %?s %4s %4s %?s %s\n", "INUM", "ADDR", "PEND", 1407*0Sstevel@tonic-gate "PIL", "ARG", "HANDLER"); 1408*0Sstevel@tonic-gate } 1409*0Sstevel@tonic-gate 1410*0Sstevel@tonic-gate if (mdb_vread(&iv, sizeof (iv), addr) == -1) { 1411*0Sstevel@tonic-gate mdb_warn("couldn't read intr_vector at %p", addr); 1412*0Sstevel@tonic-gate return (DCMD_ERR); 1413*0Sstevel@tonic-gate } 1414*0Sstevel@tonic-gate 1415*0Sstevel@tonic-gate mdb_printf("%4d %0?p %4d %4d %?p %?p %a\n", inum, addr, iv.iv_pending, 1416*0Sstevel@tonic-gate iv.iv_pil, iv.iv_arg, iv.iv_softint_arg2, iv.iv_handler); 1417*0Sstevel@tonic-gate 1418*0Sstevel@tonic-gate return (DCMD_OK); 1419*0Sstevel@tonic-gate } 1420*0Sstevel@tonic-gate 1421*0Sstevel@tonic-gate static int 1422*0Sstevel@tonic-gate whatis_walk_tt(uintptr_t taddr, const trap_trace_fullrec_t *ttf, uintptr_t *ap) 1423*0Sstevel@tonic-gate { 1424*0Sstevel@tonic-gate uintptr_t addr = *ap; 1425*0Sstevel@tonic-gate 1426*0Sstevel@tonic-gate if (addr < taddr || addr > taddr + sizeof (struct trap_trace_record)) 1427*0Sstevel@tonic-gate return (WALK_NEXT); 1428*0Sstevel@tonic-gate 1429*0Sstevel@tonic-gate mdb_printf("%p is %p+%p, trap trace record for cpu %d\n", 1430*0Sstevel@tonic-gate addr, taddr, addr - taddr, ttf->ttf_cpu); 1431*0Sstevel@tonic-gate 1432*0Sstevel@tonic-gate mdb_set_dot(1); 1433*0Sstevel@tonic-gate return (WALK_DONE); 1434*0Sstevel@tonic-gate } 1435*0Sstevel@tonic-gate 1436*0Sstevel@tonic-gate /*ARGSUSED*/ 1437*0Sstevel@tonic-gate int 1438*0Sstevel@tonic-gate whatis(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1439*0Sstevel@tonic-gate { 1440*0Sstevel@tonic-gate GElf_Sym sym; 1441*0Sstevel@tonic-gate 1442*0Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 1443*0Sstevel@tonic-gate return (DCMD_USAGE); 1444*0Sstevel@tonic-gate 1445*0Sstevel@tonic-gate if (mdb_lookup_by_name("trap_trace_ctl", &sym) == -1) 1446*0Sstevel@tonic-gate return (DCMD_NEXT); 1447*0Sstevel@tonic-gate 1448*0Sstevel@tonic-gate mdb_set_dot(0); 1449*0Sstevel@tonic-gate 1450*0Sstevel@tonic-gate if (mdb_walk("ttrace", (mdb_walk_cb_t)whatis_walk_tt, &addr) == -1) 1451*0Sstevel@tonic-gate mdb_warn("failed to walk 'ttrace'"); 1452*0Sstevel@tonic-gate 1453*0Sstevel@tonic-gate return (DCMD_NEXT); 1454*0Sstevel@tonic-gate } 1455*0Sstevel@tonic-gate 1456*0Sstevel@tonic-gate /*ARGSUSED*/ 1457*0Sstevel@tonic-gate int 1458*0Sstevel@tonic-gate mutex_owner_init(mdb_walk_state_t *wsp) 1459*0Sstevel@tonic-gate { 1460*0Sstevel@tonic-gate return (WALK_NEXT); 1461*0Sstevel@tonic-gate } 1462*0Sstevel@tonic-gate 1463*0Sstevel@tonic-gate int 1464*0Sstevel@tonic-gate mutex_owner_step(mdb_walk_state_t *wsp) 1465*0Sstevel@tonic-gate { 1466*0Sstevel@tonic-gate uintptr_t addr = wsp->walk_addr; 1467*0Sstevel@tonic-gate mutex_impl_t mtx; 1468*0Sstevel@tonic-gate uintptr_t owner; 1469*0Sstevel@tonic-gate kthread_t thr; 1470*0Sstevel@tonic-gate 1471*0Sstevel@tonic-gate if (mdb_vread(&mtx, sizeof (mtx), addr) == -1) 1472*0Sstevel@tonic-gate return (WALK_ERR); 1473*0Sstevel@tonic-gate 1474*0Sstevel@tonic-gate if (!MUTEX_TYPE_ADAPTIVE(&mtx)) 1475*0Sstevel@tonic-gate return (WALK_DONE); 1476*0Sstevel@tonic-gate 1477*0Sstevel@tonic-gate if ((owner = (uintptr_t)MUTEX_OWNER(&mtx)) == NULL) 1478*0Sstevel@tonic-gate return (WALK_DONE); 1479*0Sstevel@tonic-gate 1480*0Sstevel@tonic-gate if (mdb_vread(&thr, sizeof (thr), owner) != -1) 1481*0Sstevel@tonic-gate (void) wsp->walk_callback(owner, &thr, wsp->walk_cbdata); 1482*0Sstevel@tonic-gate 1483*0Sstevel@tonic-gate return (WALK_DONE); 1484*0Sstevel@tonic-gate } 1485*0Sstevel@tonic-gate 1486*0Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = { 1487*0Sstevel@tonic-gate { "cpuset", ":[-l|-r]", "dump a cpuset_t", cmd_cpuset }, 1488*0Sstevel@tonic-gate { "ttctl", NULL, "dump trap trace ctl records", ttctl }, 1489*0Sstevel@tonic-gate { "ttrace", "[-x]", "dump trap trace buffer for a cpu", ttrace }, 1490*0Sstevel@tonic-gate #ifdef sun4v 1491*0Sstevel@tonic-gate { "httctl", NULL, "dump hv trap trace ctl records", httctl }, 1492*0Sstevel@tonic-gate { "httrace", "[-x]", "dump hv trap trace buffer for a cpu", httrace }, 1493*0Sstevel@tonic-gate #endif 1494*0Sstevel@tonic-gate { "xc_mbox", "?", "dump xcall mboxes", xc_mbox }, 1495*0Sstevel@tonic-gate { "xctrace", NULL, "dump xcall trace buffer", xctrace }, 1496*0Sstevel@tonic-gate { "softint", NULL, "dumps interrupt vector table", softint_dcmd }, 1497*0Sstevel@tonic-gate { "whatis", ":[-abv]", "given an address, return information", whatis }, 1498*0Sstevel@tonic-gate { "sfmmu_vtop", ":[[-v] -a as]", "print virtual to physical mapping", 1499*0Sstevel@tonic-gate sfmmu_vtop }, 1500*0Sstevel@tonic-gate { "page_num2pp", ":", "page frame number to page structure", 1501*0Sstevel@tonic-gate page_num2pp }, 1502*0Sstevel@tonic-gate { "memseg_list", ":", "show memseg list", memseg_list }, 1503*0Sstevel@tonic-gate { "tsbinfo", ":[-l [-a]]", "show tsbinfo", tsbinfo_list, 1504*0Sstevel@tonic-gate tsbinfo_help }, 1505*0Sstevel@tonic-gate { NULL } 1506*0Sstevel@tonic-gate }; 1507*0Sstevel@tonic-gate 1508*0Sstevel@tonic-gate static const mdb_walker_t walkers[] = { 1509*0Sstevel@tonic-gate { "mutex_owner", "walks the owner of a mutex", 1510*0Sstevel@tonic-gate mutex_owner_init, mutex_owner_step }, 1511*0Sstevel@tonic-gate { "ttrace", "walks the trap trace buffer for a CPU", 1512*0Sstevel@tonic-gate ttrace_walk_init, ttrace_walk_step, ttrace_walk_fini }, 1513*0Sstevel@tonic-gate #ifdef sun4v 1514*0Sstevel@tonic-gate { "httrace", "walks the hv trap trace buffer for a CPU", 1515*0Sstevel@tonic-gate httrace_walk_init, httrace_walk_step, httrace_walk_fini }, 1516*0Sstevel@tonic-gate #endif 1517*0Sstevel@tonic-gate { "xc_mbox", "walks the cross call mail boxes", 1518*0Sstevel@tonic-gate xc_mbox_walk_init, xc_mbox_walk_step, xc_mbox_walk_fini }, 1519*0Sstevel@tonic-gate { "softint", "walks the interrupt vector table", 1520*0Sstevel@tonic-gate softint_walk_init, softint_walk_step, softint_walk_fini }, 1521*0Sstevel@tonic-gate { "memseg", "walk the memseg structures", 1522*0Sstevel@tonic-gate memseg_walk_init, memseg_walk_step, memseg_walk_fini }, 1523*0Sstevel@tonic-gate { NULL } 1524*0Sstevel@tonic-gate }; 1525*0Sstevel@tonic-gate 1526*0Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers }; 1527*0Sstevel@tonic-gate 1528*0Sstevel@tonic-gate const mdb_modinfo_t * 1529*0Sstevel@tonic-gate _mdb_init(void) 1530*0Sstevel@tonic-gate { 1531*0Sstevel@tonic-gate if (mdb_lookup_by_name("intr_vector", &iv_sym) == -1) { 1532*0Sstevel@tonic-gate mdb_warn("couldn't find intr_vector"); 1533*0Sstevel@tonic-gate return (NULL); 1534*0Sstevel@tonic-gate } 1535*0Sstevel@tonic-gate 1536*0Sstevel@tonic-gate return (&modinfo); 1537*0Sstevel@tonic-gate } 1538