10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51859Sha137994 * Common Development and Distribution License (the "License").
61859Sha137994 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*10610SJonathan.Adams@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #include <sys/types.h>
270Sstevel@tonic-gate
280Sstevel@tonic-gate #ifndef DEBUG
290Sstevel@tonic-gate #define DEBUG
300Sstevel@tonic-gate #define _SYS_DEBUG_H
310Sstevel@tonic-gate #include <sys/xc_impl.h>
320Sstevel@tonic-gate #undef DEBUG
330Sstevel@tonic-gate #else
340Sstevel@tonic-gate #define _SYS_DEBUG_H
350Sstevel@tonic-gate #include <sys/xc_impl.h>
360Sstevel@tonic-gate #endif
370Sstevel@tonic-gate
380Sstevel@tonic-gate #include <sys/traptrace.h>
390Sstevel@tonic-gate #include <sys/machparam.h>
402973Sgovinda #include <sys/intreg.h>
410Sstevel@tonic-gate #include <sys/ivintr.h>
420Sstevel@tonic-gate #include <sys/mutex_impl.h>
430Sstevel@tonic-gate
440Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
450Sstevel@tonic-gate #include <mdb/mdb_ctf.h>
46*10610SJonathan.Adams@Sun.COM #include <mdb/mdb_whatis.h>
470Sstevel@tonic-gate #include "sfmmu.h"
480Sstevel@tonic-gate
490Sstevel@tonic-gate #ifndef SYSTRAP_TT
500Sstevel@tonic-gate #define SYSTRAP_TT 0x1300
510Sstevel@tonic-gate #endif
520Sstevel@tonic-gate
530Sstevel@tonic-gate typedef struct trap_trace_fullrec {
540Sstevel@tonic-gate struct trap_trace_record ttf_rec;
550Sstevel@tonic-gate int ttf_cpu;
560Sstevel@tonic-gate } trap_trace_fullrec_t;
570Sstevel@tonic-gate
580Sstevel@tonic-gate #ifdef sun4v
590Sstevel@tonic-gate typedef struct htrap_trace_fullrec {
600Sstevel@tonic-gate struct htrap_trace_record ttf_rec;
610Sstevel@tonic-gate int ttf_cpu;
620Sstevel@tonic-gate } htrap_trace_fullrec_t;
630Sstevel@tonic-gate #endif
640Sstevel@tonic-gate
650Sstevel@tonic-gate /*
660Sstevel@tonic-gate * These strings and accompanying macros allow our string table to look
670Sstevel@tonic-gate * just like the real table in trap_table.s.
680Sstevel@tonic-gate */
690Sstevel@tonic-gate
700Sstevel@tonic-gate static const char NOT[] = "reserved"; /* common reserved string */
710Sstevel@tonic-gate static const char BAD[] = "unused"; /* common unused string */
720Sstevel@tonic-gate
730Sstevel@tonic-gate #define NOT4 NOT, NOT, NOT, NOT
740Sstevel@tonic-gate #define BAD4 BAD, BAD, BAD, BAD
750Sstevel@tonic-gate
760Sstevel@tonic-gate static const char *const ttdescr[] = {
770Sstevel@tonic-gate NOT, /* 000 reserved */
780Sstevel@tonic-gate "power-on", /* 001 power on reset */
790Sstevel@tonic-gate "watchdog", /* 002 watchdog reset */
800Sstevel@tonic-gate "xir", /* 003 externally initiated reset */
810Sstevel@tonic-gate "sir", /* 004 software initiated reset */
820Sstevel@tonic-gate "red", /* 005 red mode exception */
830Sstevel@tonic-gate NOT, NOT, /* 006 - 007 reserved */
840Sstevel@tonic-gate "immu-xcp", /* 008 instruction access exception */
850Sstevel@tonic-gate "immu-miss", /* 009 instruction access MMU miss */
860Sstevel@tonic-gate "immu-err", /* 00A instruction access error */
870Sstevel@tonic-gate NOT, NOT4, /* 00B - 00F reserved */
880Sstevel@tonic-gate "ill-inst", /* 010 illegal instruction */
890Sstevel@tonic-gate "priv-inst", /* 011 privileged opcode */
900Sstevel@tonic-gate "unimp-ldd", /* 012 unimplemented LDD */
910Sstevel@tonic-gate "unimp-std", /* 013 unimplemented STD */
920Sstevel@tonic-gate NOT4, NOT4, NOT4, /* 014 - 01F reserved */
930Sstevel@tonic-gate "fp-disable", /* 020 fp disabled */
940Sstevel@tonic-gate "fp-ieee754", /* 021 fp exception ieee 754 */
950Sstevel@tonic-gate "fp-xcp-other", /* 022 fp exception other */
960Sstevel@tonic-gate "tag-oflow", /* 023 tag overflow */
970Sstevel@tonic-gate "cleanwin", /* 024 clean window */
980Sstevel@tonic-gate "cleanwin", /* 025 clean window */
990Sstevel@tonic-gate "cleanwin", /* 026 clean window */
1000Sstevel@tonic-gate "cleanwin", /* 027 clean window */
1010Sstevel@tonic-gate "div-zero", /* 028 division by zero */
1020Sstevel@tonic-gate "internal-err", /* 029 internal processor error */
1030Sstevel@tonic-gate NOT, NOT, NOT4, /* 02A - 02F reserved */
1040Sstevel@tonic-gate "dmmu-xcp", /* 030 data access exception */
1050Sstevel@tonic-gate "dmmu-miss", /* 031 data access MMU miss */
1060Sstevel@tonic-gate "dmmu-err", /* 032 data access error */
1070Sstevel@tonic-gate "dmmu-prot", /* 033 data access protection */
1080Sstevel@tonic-gate "unalign", /* 034 mem address not aligned */
1090Sstevel@tonic-gate "lddf-unalign", /* 035 LDDF mem address not aligned */
1100Sstevel@tonic-gate "stdf-unalign", /* 036 STDF mem address not aligned */
1110Sstevel@tonic-gate "priv-act", /* 037 privileged action */
1120Sstevel@tonic-gate "ldqf-unalign", /* 038 LDQF mem address not aligned */
1130Sstevel@tonic-gate "stqf-unalign", /* 039 STQF mem address not aligned */
1140Sstevel@tonic-gate NOT, NOT, NOT4, /* 03A - 03F reserved */
1150Sstevel@tonic-gate "async-d-err", /* 040 async data error */
1160Sstevel@tonic-gate "level-1", /* 041 interrupt level 1 */
1170Sstevel@tonic-gate "level-2", /* 042 interrupt level 2 */
1180Sstevel@tonic-gate "level-3", /* 043 interrupt level 3 */
1190Sstevel@tonic-gate "level-4", /* 044 interrupt level 4 */
1200Sstevel@tonic-gate "level-5", /* 045 interrupt level 5 */
1210Sstevel@tonic-gate "level-6", /* 046 interrupt level 6 */
1220Sstevel@tonic-gate "level-7", /* 047 interrupt level 7 */
1230Sstevel@tonic-gate "level-8", /* 048 interrupt level 8 */
1240Sstevel@tonic-gate "level-9", /* 049 interrupt level 9 */
1250Sstevel@tonic-gate "level-10", /* 04A interrupt level 10 */
1260Sstevel@tonic-gate "level-11", /* 04B interrupt level 11 */
1270Sstevel@tonic-gate "level-12", /* 04C interrupt level 12 */
1280Sstevel@tonic-gate "level-13", /* 04D interrupt level 13 */
1290Sstevel@tonic-gate "level-14", /* 04E interrupt level 14 */
1300Sstevel@tonic-gate "level-15", /* 04F interrupt level 15 */
1310Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 050 - 05F reserved */
1320Sstevel@tonic-gate "int-vec", /* 060 interrupt vector */
1330Sstevel@tonic-gate "pa-watch", /* 061 PA watchpoint */
1340Sstevel@tonic-gate "va-watch", /* 062 VA watchpoint */
1350Sstevel@tonic-gate "ecc-err", /* 063 corrected ECC error */
1360Sstevel@tonic-gate "itlb-miss", /* 064 instruction access MMU miss */
1370Sstevel@tonic-gate "itlb-miss", /* 065 instruction access MMU miss */
1380Sstevel@tonic-gate "itlb-miss", /* 066 instruction access MMU miss */
1390Sstevel@tonic-gate "itlb-miss", /* 067 instruction access MMU miss */
1400Sstevel@tonic-gate "dtlb-miss", /* 068 data access MMU miss */
1410Sstevel@tonic-gate "dtlb-miss", /* 069 data access MMU miss */
1420Sstevel@tonic-gate "dtlb-miss", /* 06A data access MMU miss */
1430Sstevel@tonic-gate "dtlb-miss", /* 06B data access MMU miss */
1440Sstevel@tonic-gate "dtlb-prot", /* 06C data access protection */
1450Sstevel@tonic-gate "dtlb-prot", /* 06D data access protection */
1460Sstevel@tonic-gate "dtlb-prot", /* 06E data access protection */
1470Sstevel@tonic-gate "dtlb-prot", /* 06F data access protection */
1480Sstevel@tonic-gate "fast-ecc-err", /* 070 fast ecache ECC error */
1490Sstevel@tonic-gate "dp-err", /* 071 data cache parity error */
1500Sstevel@tonic-gate "ip-err", /* 072 instr cache parity error */
1510Sstevel@tonic-gate NOT, NOT4, NOT4, /* 073 - 07B reserved */
1520Sstevel@tonic-gate #ifdef sun4v
1530Sstevel@tonic-gate "cpu-mondo", /* 07C CPU mondo */
1540Sstevel@tonic-gate "dev-mondo", /* 07D device mondo */
1550Sstevel@tonic-gate "res.-err", /* 07E resumable error */
1560Sstevel@tonic-gate "non-res.-err", /* 07F non-resumable error */
1570Sstevel@tonic-gate #else
1580Sstevel@tonic-gate NOT4, /* 07C - 07F reserved */
1590Sstevel@tonic-gate #endif
1600Sstevel@tonic-gate "spill-0-norm", /* 080 spill 0 normal */
1610Sstevel@tonic-gate "spill-0-norm", /* 081 spill 0 normal */
1620Sstevel@tonic-gate "spill-0-norm", /* 082 spill 0 normal */
1630Sstevel@tonic-gate "spill-0-norm", /* 083 spill 0 normal */
1640Sstevel@tonic-gate "spill-1-norm", /* 084 spill 1 normal */
1650Sstevel@tonic-gate "spill-1-norm", /* 085 spill 1 normal */
1660Sstevel@tonic-gate "spill-1-norm", /* 086 spill 1 normal */
1670Sstevel@tonic-gate "spill-1-norm", /* 087 spill 1 normal */
1680Sstevel@tonic-gate "spill-2-norm", /* 088 spill 2 normal */
1690Sstevel@tonic-gate "spill-2-norm", /* 089 spill 2 normal */
1700Sstevel@tonic-gate "spill-2-norm", /* 08A spill 2 normal */
1710Sstevel@tonic-gate "spill-2-norm", /* 08B spill 2 normal */
1720Sstevel@tonic-gate "spill-3-norm", /* 08C spill 3 normal */
1730Sstevel@tonic-gate "spill-3-norm", /* 08D spill 3 normal */
1740Sstevel@tonic-gate "spill-3-norm", /* 08E spill 3 normal */
1750Sstevel@tonic-gate "spill-3-norm", /* 08F spill 3 normal */
1760Sstevel@tonic-gate "spill-4-norm", /* 090 spill 4 normal */
1770Sstevel@tonic-gate "spill-4-norm", /* 091 spill 4 normal */
1780Sstevel@tonic-gate "spill-4-norm", /* 092 spill 4 normal */
1790Sstevel@tonic-gate "spill-4-norm", /* 093 spill 4 normal */
1800Sstevel@tonic-gate "spill-5-norm", /* 094 spill 5 normal */
1810Sstevel@tonic-gate "spill-5-norm", /* 095 spill 5 normal */
1820Sstevel@tonic-gate "spill-5-norm", /* 096 spill 5 normal */
1830Sstevel@tonic-gate "spill-5-norm", /* 097 spill 5 normal */
1840Sstevel@tonic-gate "spill-6-norm", /* 098 spill 6 normal */
1850Sstevel@tonic-gate "spill-6-norm", /* 099 spill 6 normal */
1860Sstevel@tonic-gate "spill-6-norm", /* 09A spill 6 normal */
1870Sstevel@tonic-gate "spill-6-norm", /* 09B spill 6 normal */
1880Sstevel@tonic-gate "spill-7-norm", /* 09C spill 7 normal */
1890Sstevel@tonic-gate "spill-7-norm", /* 09D spill 7 normal */
1900Sstevel@tonic-gate "spill-7-norm", /* 09E spill 7 normal */
1910Sstevel@tonic-gate "spill-7-norm", /* 09F spill 7 normal */
1920Sstevel@tonic-gate "spill-0-oth", /* 0A0 spill 0 other */
1930Sstevel@tonic-gate "spill-0-oth", /* 0A1 spill 0 other */
1940Sstevel@tonic-gate "spill-0-oth", /* 0A2 spill 0 other */
1950Sstevel@tonic-gate "spill-0-oth", /* 0A3 spill 0 other */
1960Sstevel@tonic-gate "spill-1-oth", /* 0A4 spill 1 other */
1970Sstevel@tonic-gate "spill-1-oth", /* 0A5 spill 1 other */
1980Sstevel@tonic-gate "spill-1-oth", /* 0A6 spill 1 other */
1990Sstevel@tonic-gate "spill-1-oth", /* 0A7 spill 1 other */
2000Sstevel@tonic-gate "spill-2-oth", /* 0A8 spill 2 other */
2010Sstevel@tonic-gate "spill-2-oth", /* 0A9 spill 2 other */
2020Sstevel@tonic-gate "spill-2-oth", /* 0AA spill 2 other */
2030Sstevel@tonic-gate "spill-2-oth", /* 0AB spill 2 other */
2040Sstevel@tonic-gate "spill-3-oth", /* 0AC spill 3 other */
2050Sstevel@tonic-gate "spill-3-oth", /* 0AD spill 3 other */
2060Sstevel@tonic-gate "spill-3-oth", /* 0AE spill 3 other */
2070Sstevel@tonic-gate "spill-3-oth", /* 0AF spill 3 other */
2080Sstevel@tonic-gate "spill-4-oth", /* 0B0 spill 4 other */
2090Sstevel@tonic-gate "spill-4-oth", /* 0B1 spill 4 other */
2100Sstevel@tonic-gate "spill-4-oth", /* 0B2 spill 4 other */
2110Sstevel@tonic-gate "spill-4-oth", /* 0B3 spill 4 other */
2120Sstevel@tonic-gate "spill-5-oth", /* 0B4 spill 5 other */
2130Sstevel@tonic-gate "spill-5-oth", /* 0B5 spill 5 other */
2140Sstevel@tonic-gate "spill-5-oth", /* 0B6 spill 5 other */
2150Sstevel@tonic-gate "spill-5-oth", /* 0B7 spill 5 other */
2160Sstevel@tonic-gate "spill-6-oth", /* 0B8 spill 6 other */
2170Sstevel@tonic-gate "spill-6-oth", /* 0B9 spill 6 other */
2180Sstevel@tonic-gate "spill-6-oth", /* 0BA spill 6 other */
2190Sstevel@tonic-gate "spill-6-oth", /* 0BB spill 6 other */
2200Sstevel@tonic-gate "spill-7-oth", /* 0BC spill 7 other */
2210Sstevel@tonic-gate "spill-7-oth", /* 0BD spill 7 other */
2220Sstevel@tonic-gate "spill-7-oth", /* 0BE spill 7 other */
2230Sstevel@tonic-gate "spill-7-oth", /* 0BF spill 7 other */
2240Sstevel@tonic-gate "fill-0-norm", /* 0C0 fill 0 normal */
2250Sstevel@tonic-gate "fill-0-norm", /* 0C1 fill 0 normal */
2260Sstevel@tonic-gate "fill-0-norm", /* 0C2 fill 0 normal */
2270Sstevel@tonic-gate "fill-0-norm", /* 0C3 fill 0 normal */
2280Sstevel@tonic-gate "fill-1-norm", /* 0C4 fill 1 normal */
2290Sstevel@tonic-gate "fill-1-norm", /* 0C5 fill 1 normal */
2300Sstevel@tonic-gate "fill-1-norm", /* 0C6 fill 1 normal */
2310Sstevel@tonic-gate "fill-1-norm", /* 0C7 fill 1 normal */
2320Sstevel@tonic-gate "fill-2-norm", /* 0C8 fill 2 normal */
2330Sstevel@tonic-gate "fill-2-norm", /* 0C9 fill 2 normal */
2340Sstevel@tonic-gate "fill-2-norm", /* 0CA fill 2 normal */
2350Sstevel@tonic-gate "fill-2-norm", /* 0CB fill 2 normal */
2360Sstevel@tonic-gate "fill-3-norm", /* 0CC fill 3 normal */
2370Sstevel@tonic-gate "fill-3-norm", /* 0CD fill 3 normal */
2380Sstevel@tonic-gate "fill-3-norm", /* 0CE fill 3 normal */
2390Sstevel@tonic-gate "fill-3-norm", /* 0CF fill 3 normal */
2400Sstevel@tonic-gate "fill-4-norm", /* 0D0 fill 4 normal */
2410Sstevel@tonic-gate "fill-4-norm", /* 0D1 fill 4 normal */
2420Sstevel@tonic-gate "fill-4-norm", /* 0D2 fill 4 normal */
2430Sstevel@tonic-gate "fill-4-norm", /* 0D3 fill 4 normal */
2440Sstevel@tonic-gate "fill-5-norm", /* 0D4 fill 5 normal */
2450Sstevel@tonic-gate "fill-5-norm", /* 0D5 fill 5 normal */
2460Sstevel@tonic-gate "fill-5-norm", /* 0D6 fill 5 normal */
2470Sstevel@tonic-gate "fill-5-norm", /* 0D7 fill 5 normal */
2480Sstevel@tonic-gate "fill-6-norm", /* 0D8 fill 6 normal */
2490Sstevel@tonic-gate "fill-6-norm", /* 0D9 fill 6 normal */
2500Sstevel@tonic-gate "fill-6-norm", /* 0DA fill 6 normal */
2510Sstevel@tonic-gate "fill-6-norm", /* 0DB fill 6 normal */
2520Sstevel@tonic-gate "fill-7-norm", /* 0DC fill 7 normal */
2530Sstevel@tonic-gate "fill-7-norm", /* 0DD fill 7 normal */
2540Sstevel@tonic-gate "fill-7-norm", /* 0DE fill 7 normal */
2550Sstevel@tonic-gate "fill-7-norm", /* 0DF fill 7 normal */
2560Sstevel@tonic-gate "fill-0-oth", /* 0E0 fill 0 other */
2570Sstevel@tonic-gate "fill-0-oth", /* 0E1 fill 0 other */
2580Sstevel@tonic-gate "fill-0-oth", /* 0E2 fill 0 other */
2590Sstevel@tonic-gate "fill-0-oth", /* 0E3 fill 0 other */
2600Sstevel@tonic-gate "fill-1-oth", /* 0E4 fill 1 other */
2610Sstevel@tonic-gate "fill-1-oth", /* 0E5 fill 1 other */
2620Sstevel@tonic-gate "fill-1-oth", /* 0E6 fill 1 other */
2630Sstevel@tonic-gate "fill-1-oth", /* 0E7 fill 1 other */
2640Sstevel@tonic-gate "fill-2-oth", /* 0E8 fill 2 other */
2650Sstevel@tonic-gate "fill-2-oth", /* 0E9 fill 2 other */
2660Sstevel@tonic-gate "fill-2-oth", /* 0EA fill 2 other */
2670Sstevel@tonic-gate "fill-2-oth", /* 0EB fill 2 other */
2680Sstevel@tonic-gate "fill-3-oth", /* 0EC fill 3 other */
2690Sstevel@tonic-gate "fill-3-oth", /* 0ED fill 3 other */
2700Sstevel@tonic-gate "fill-3-oth", /* 0EE fill 3 other */
2710Sstevel@tonic-gate "fill-3-oth", /* 0EF fill 3 other */
2720Sstevel@tonic-gate "fill-4-oth", /* 0F0 fill 4 other */
2730Sstevel@tonic-gate "fill-4-oth", /* 0F1 fill 4 other */
2740Sstevel@tonic-gate "fill-4-oth", /* 0F2 fill 4 other */
2750Sstevel@tonic-gate "fill-4-oth", /* 0F3 fill 4 other */
2760Sstevel@tonic-gate "fill-5-oth", /* 0F4 fill 5 other */
2770Sstevel@tonic-gate "fill-5-oth", /* 0F5 fill 5 other */
2780Sstevel@tonic-gate "fill-5-oth", /* 0F6 fill 5 other */
2790Sstevel@tonic-gate "fill-5-oth", /* 0F7 fill 5 other */
2800Sstevel@tonic-gate "fill-6-oth", /* 0F8 fill 6 other */
2810Sstevel@tonic-gate "fill-6-oth", /* 0F9 fill 6 other */
2820Sstevel@tonic-gate "fill-6-oth", /* 0FA fill 6 other */
2830Sstevel@tonic-gate "fill-6-oth", /* 0FB fill 6 other */
2840Sstevel@tonic-gate "fill-7-oth", /* 0FC fill 7 other */
2850Sstevel@tonic-gate "fill-7-oth", /* 0FD fill 7 other */
2860Sstevel@tonic-gate "fill-7-oth", /* 0FE fill 7 other */
2870Sstevel@tonic-gate "fill-7-oth", /* 0FF fill 7 other */
2880Sstevel@tonic-gate "syscall-4x", /* 100 old system call */
2890Sstevel@tonic-gate "usr-brkpt", /* 101 user breakpoint */
2900Sstevel@tonic-gate "usr-div-zero", /* 102 user divide by zero */
2910Sstevel@tonic-gate "flush-wins", /* 103 flush windows */
2920Sstevel@tonic-gate "clean-wins", /* 104 clean windows */
2930Sstevel@tonic-gate "range-chk", /* 105 range check ?? */
2940Sstevel@tonic-gate "fix-align", /* 106 do unaligned references */
2950Sstevel@tonic-gate BAD, /* 107 unused */
2960Sstevel@tonic-gate "syscall-32", /* 108 ILP32 system call on LP64 */
2970Sstevel@tonic-gate "set-t0-addr", /* 109 set trap0 address */
2980Sstevel@tonic-gate BAD, BAD, BAD4, /* 10A - 10F unused */
2990Sstevel@tonic-gate BAD4, BAD4, BAD4, BAD4, /* 110 - 11F unused (V9 user traps?) */
3000Sstevel@tonic-gate "get-cc", /* 120 get condition codes */
3010Sstevel@tonic-gate "set-cc", /* 121 set condition codes */
3020Sstevel@tonic-gate "get-psr", /* 122 get psr */
3030Sstevel@tonic-gate "set-psr", /* 123 set psr (some fields) */
3040Sstevel@tonic-gate "getts", /* 124 get timestamp */
3050Sstevel@tonic-gate "gethrvtime", /* 125 get lwp virtual time */
3060Sstevel@tonic-gate "self-xcall", /* 126 self xcall */
3070Sstevel@tonic-gate "gethrtime", /* 127 get hrestime */
3080Sstevel@tonic-gate BAD, /* 128 unused (ST_SETV9STACK) */
3090Sstevel@tonic-gate "getlgrp", /* 129 get lgrpid */
3100Sstevel@tonic-gate BAD, BAD, BAD4, /* 12A - 12F unused */
3110Sstevel@tonic-gate BAD4, BAD4, /* 130 - 137 unused */
3120Sstevel@tonic-gate "dtrace-pid", /* 138 DTrace pid provider */
3132179Sahl BAD, /* 139 unused */
3140Sstevel@tonic-gate "dtrace-return", /* 13A DTrace pid provider */
3150Sstevel@tonic-gate BAD, BAD4, /* 13B - 13F unused */
3160Sstevel@tonic-gate "syscall-64", /* 140 LP64 system call */
3170Sstevel@tonic-gate BAD, /* 141 unused */
3180Sstevel@tonic-gate "tt-freeze", /* 142 freeze traptrace */
3190Sstevel@tonic-gate "tt-unfreeze", /* 143 unfreeze traptrace */
3200Sstevel@tonic-gate BAD4, BAD4, BAD4, /* 144 - 14F unused */
3210Sstevel@tonic-gate BAD4, BAD4, BAD4, BAD4, /* 150 - 15F unused */
3220Sstevel@tonic-gate BAD4, BAD4, BAD4, BAD4, /* 160 - 16F unused */
3230Sstevel@tonic-gate BAD4, BAD4, BAD4, /* 170 - 17B unused */
3240Sstevel@tonic-gate "ptl1-panic", /* 17C test ptl1_panic */
3250Sstevel@tonic-gate "kmdb-enter", /* 17D kmdb enter (L1-A) */
3260Sstevel@tonic-gate "kmdb-brkpt", /* 17E kmdb breakpoint */
3270Sstevel@tonic-gate "obp-brkpt", /* 17F obp breakpoint */
3280Sstevel@tonic-gate #ifdef sun4v
3290Sstevel@tonic-gate "fast_trap", /* 180 hypervisor fast trap */
3300Sstevel@tonic-gate "cpu_tick_npt", /* 181 cpu_tick_npt() hcall */
3310Sstevel@tonic-gate "cpu_stick_npt", /* 182 cpu_stick_npt() hcall */
3320Sstevel@tonic-gate "mmu_map_addr", /* 183 mmu_map_addr() hcall */
3330Sstevel@tonic-gate "mmu_unmap_addr", /* 184 mmu_unmap_addr() hcall */
3340Sstevel@tonic-gate "ttrace_addentry", /* 185 ttrace_addentry() hcall */
3350Sstevel@tonic-gate NOT, NOT, NOT4, NOT4, /* 186 - 18F reserved */
3360Sstevel@tonic-gate #else
3370Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 180 - 18F reserved */
3380Sstevel@tonic-gate #endif
3390Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 190 - 19F reserved */
3400Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 1A0 - 1AF reserved */
3410Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 1B0 - 1BF reserved */
3420Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 1C0 - 1CF reserved */
3430Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 1D0 - 1DF reserved */
3440Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4, /* 1E0 - 1EF reserved */
3450Sstevel@tonic-gate NOT4, NOT4, NOT4, NOT4 /* 1F0 - 1FF reserved */
3460Sstevel@tonic-gate };
3470Sstevel@tonic-gate static const size_t ttndescr = sizeof (ttdescr) / sizeof (ttdescr[0]);
3480Sstevel@tonic-gate
3490Sstevel@tonic-gate static GElf_Sym iv_sym;
3500Sstevel@tonic-gate
3510Sstevel@tonic-gate /*
3520Sstevel@tonic-gate * Persistent data (shouldn't change).
3530Sstevel@tonic-gate */
3540Sstevel@tonic-gate static int ncpu; /* _ncpu */
3550Sstevel@tonic-gate static ssize_t mbox_size; /* size of xc_mbox */
3560Sstevel@tonic-gate static ulong_t mbox_stoff; /* offset of xc_mbox.xc_state */
3570Sstevel@tonic-gate static mdb_ctf_id_t mbox_states; /* xc_state enumeration */
3580Sstevel@tonic-gate
3590Sstevel@tonic-gate static int
fetch_ncpu(void)3600Sstevel@tonic-gate fetch_ncpu(void)
3610Sstevel@tonic-gate {
3620Sstevel@tonic-gate if (ncpu == 0)
3630Sstevel@tonic-gate if (mdb_readsym(&ncpu, sizeof (ncpu), "_ncpu") == -1) {
3640Sstevel@tonic-gate mdb_warn("symbol '_ncpu' not found");
3650Sstevel@tonic-gate return (1);
3660Sstevel@tonic-gate }
3670Sstevel@tonic-gate return (0);
3680Sstevel@tonic-gate }
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate static int
fetch_mbox(void)3710Sstevel@tonic-gate fetch_mbox(void)
3720Sstevel@tonic-gate {
3730Sstevel@tonic-gate if (mbox_size <= 0) {
3740Sstevel@tonic-gate mdb_ctf_id_t id;
3750Sstevel@tonic-gate
3760Sstevel@tonic-gate if (mdb_ctf_lookup_by_name("struct xc_mbox", &id) == -1) {
3770Sstevel@tonic-gate mdb_warn("couldn't find type 'struct xc_mbox'");
3780Sstevel@tonic-gate return (1);
3790Sstevel@tonic-gate }
3800Sstevel@tonic-gate
3810Sstevel@tonic-gate /*
3820Sstevel@tonic-gate * These two could be combined into a single call to
3830Sstevel@tonic-gate * mdb_ctf_member_info if xc_state was actually of type
3840Sstevel@tonic-gate * enum xc_states.
3850Sstevel@tonic-gate */
3860Sstevel@tonic-gate if (mdb_ctf_lookup_by_name("enum xc_states",
3870Sstevel@tonic-gate &mbox_states) == -1) {
3880Sstevel@tonic-gate mdb_warn("couldn't find type 'enum xc_states'");
3890Sstevel@tonic-gate return (1);
3900Sstevel@tonic-gate }
3910Sstevel@tonic-gate if (mdb_ctf_offsetof(id, "xc_state", &mbox_stoff) == -1) {
3920Sstevel@tonic-gate mdb_warn("couldn't find 'xc_mbox.xc_state'");
3930Sstevel@tonic-gate return (1);
3940Sstevel@tonic-gate }
3950Sstevel@tonic-gate mbox_stoff /= NBBY;
3960Sstevel@tonic-gate
3970Sstevel@tonic-gate if ((mbox_size = mdb_ctf_type_size(id)) == -1) {
3980Sstevel@tonic-gate mdb_warn("couldn't size 'struct xc_mbox'");
3990Sstevel@tonic-gate return (1);
4000Sstevel@tonic-gate }
4010Sstevel@tonic-gate }
4020Sstevel@tonic-gate return (0);
4030Sstevel@tonic-gate }
4040Sstevel@tonic-gate
4050Sstevel@tonic-gate static int
print_range(int start,int end,int separator)4060Sstevel@tonic-gate print_range(int start, int end, int separator)
4070Sstevel@tonic-gate {
4080Sstevel@tonic-gate int count;
4090Sstevel@tonic-gate char tmp;
4100Sstevel@tonic-gate char *format;
4110Sstevel@tonic-gate
4120Sstevel@tonic-gate if (start == end) {
4130Sstevel@tonic-gate /* Unfortunately, mdb_printf returns void */
4140Sstevel@tonic-gate format = separator ? ", %d" : "%d";
4150Sstevel@tonic-gate mdb_printf(format, start);
4160Sstevel@tonic-gate count = mdb_snprintf(&tmp, 1, format, start);
4170Sstevel@tonic-gate } else {
4180Sstevel@tonic-gate format = separator ? ", %d-%d" : "%d-%d";
4190Sstevel@tonic-gate mdb_printf(format, start, end);
4200Sstevel@tonic-gate count = mdb_snprintf(&tmp, 1, format, start, end);
4210Sstevel@tonic-gate }
4220Sstevel@tonic-gate
4230Sstevel@tonic-gate return (count);
4240Sstevel@tonic-gate }
4250Sstevel@tonic-gate
4260Sstevel@tonic-gate static void
print_cpuset_range(ulong_t * cs,int words,int width)4270Sstevel@tonic-gate print_cpuset_range(ulong_t *cs, int words, int width)
4280Sstevel@tonic-gate {
4290Sstevel@tonic-gate int i, j;
4300Sstevel@tonic-gate ulong_t m;
4310Sstevel@tonic-gate int in = 0;
4320Sstevel@tonic-gate int start;
4330Sstevel@tonic-gate int end;
4340Sstevel@tonic-gate int count = 0;
4350Sstevel@tonic-gate int sep = 0;
4360Sstevel@tonic-gate
4370Sstevel@tonic-gate for (i = 0; i < words; i++)
4380Sstevel@tonic-gate for (j = 0, m = 1; j < BT_NBIPUL; j++, m <<= 1)
4390Sstevel@tonic-gate if (cs[i] & m) {
4400Sstevel@tonic-gate if (in == 0) {
4410Sstevel@tonic-gate start = i * BT_NBIPUL + j;
4420Sstevel@tonic-gate in = 1;
4430Sstevel@tonic-gate }
4440Sstevel@tonic-gate } else {
4450Sstevel@tonic-gate if (in == 1) {
4460Sstevel@tonic-gate end = i * BT_NBIPUL + j - 1;
4470Sstevel@tonic-gate count += print_range(start, end, sep);
4480Sstevel@tonic-gate sep = 1;
4490Sstevel@tonic-gate in = 0;
4500Sstevel@tonic-gate }
4510Sstevel@tonic-gate }
4520Sstevel@tonic-gate if (in == 1) {
4530Sstevel@tonic-gate end = i * BT_NBIPUL - 1;
4540Sstevel@tonic-gate count += print_range(start, end, sep);
4550Sstevel@tonic-gate }
4560Sstevel@tonic-gate
4570Sstevel@tonic-gate while (count++ < width)
4580Sstevel@tonic-gate mdb_printf(" ");
4590Sstevel@tonic-gate }
4600Sstevel@tonic-gate
4610Sstevel@tonic-gate /*ARGSUSED*/
4620Sstevel@tonic-gate static int
cmd_cpuset(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)4630Sstevel@tonic-gate cmd_cpuset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
4640Sstevel@tonic-gate {
4650Sstevel@tonic-gate uint_t rflag = 0, lflag = 0;
4660Sstevel@tonic-gate int words;
4671859Sha137994 ulong_t *setp, set = 0;
4680Sstevel@tonic-gate
4690Sstevel@tonic-gate if (mdb_getopts(argc, argv,
4700Sstevel@tonic-gate 'l', MDB_OPT_SETBITS, TRUE, &lflag,
4710Sstevel@tonic-gate 'r', MDB_OPT_SETBITS, TRUE, &rflag, NULL) != argc)
4720Sstevel@tonic-gate return (DCMD_USAGE);
4730Sstevel@tonic-gate
4740Sstevel@tonic-gate if (lflag && rflag)
4750Sstevel@tonic-gate return (DCMD_USAGE);
4760Sstevel@tonic-gate
4770Sstevel@tonic-gate if (fetch_ncpu())
4780Sstevel@tonic-gate return (DCMD_ERR);
4790Sstevel@tonic-gate
4800Sstevel@tonic-gate if ((words = BT_BITOUL(ncpu)) == 1) {
4811859Sha137994 setp = &set;
4821859Sha137994 mdb_vread(setp, sizeof (ulong_t), addr);
4830Sstevel@tonic-gate } else {
4841859Sha137994 setp = mdb_alloc(words * sizeof (ulong_t), UM_SLEEP | UM_GC);
4851859Sha137994 mdb_vread(setp, words * sizeof (ulong_t), addr);
4860Sstevel@tonic-gate }
4870Sstevel@tonic-gate
4880Sstevel@tonic-gate if (lflag) {
4890Sstevel@tonic-gate int i, j;
4900Sstevel@tonic-gate ulong_t m;
4910Sstevel@tonic-gate
4920Sstevel@tonic-gate for (i = 0; i < words; i++)
4930Sstevel@tonic-gate for (j = 0, m = 1; j < BT_NBIPUL; j++, m <<= 1)
4941859Sha137994 if (setp[i] & m)
4950Sstevel@tonic-gate mdb_printf("%r\n", i * BT_NBIPUL + j);
4960Sstevel@tonic-gate } else if (rflag) {
4970Sstevel@tonic-gate int i;
4980Sstevel@tonic-gate int sep = 0;
4990Sstevel@tonic-gate
5000Sstevel@tonic-gate for (i = 0; i < words; i++) {
5011859Sha137994 mdb_printf(sep ? " %?0lx" : "%?0lx", setp[i]);
5020Sstevel@tonic-gate sep = 1;
5030Sstevel@tonic-gate }
5040Sstevel@tonic-gate } else {
5051859Sha137994 print_cpuset_range(setp, words, 0);
5060Sstevel@tonic-gate }
5070Sstevel@tonic-gate
5080Sstevel@tonic-gate return (DCMD_OK);
5090Sstevel@tonic-gate }
5100Sstevel@tonic-gate
5110Sstevel@tonic-gate /*ARGSUSED*/
5120Sstevel@tonic-gate int
ttctl(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)5130Sstevel@tonic-gate ttctl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
5140Sstevel@tonic-gate {
5150Sstevel@tonic-gate TRAP_TRACE_CTL *ctls, *ctl;
5161078Ssvemuri int i, traptrace_buf_inuse = 0;
5170Sstevel@tonic-gate
5180Sstevel@tonic-gate if (argc != 0)
5190Sstevel@tonic-gate return (DCMD_USAGE);
5200Sstevel@tonic-gate
5210Sstevel@tonic-gate if (fetch_ncpu())
5220Sstevel@tonic-gate return (DCMD_ERR);
5230Sstevel@tonic-gate
5240Sstevel@tonic-gate ctls = mdb_alloc(sizeof (TRAP_TRACE_CTL) * ncpu, UM_SLEEP | UM_GC);
5250Sstevel@tonic-gate if (mdb_readsym(ctls, sizeof (TRAP_TRACE_CTL) * ncpu,
5260Sstevel@tonic-gate "trap_trace_ctl") == -1) {
5270Sstevel@tonic-gate mdb_warn("symbol 'trap_trace_ctl' not found");
5280Sstevel@tonic-gate return (DCMD_ERR);
5290Sstevel@tonic-gate }
5300Sstevel@tonic-gate
5310Sstevel@tonic-gate for (ctl = &ctls[0], i = 0; i < ncpu; i++, ctl++) {
5320Sstevel@tonic-gate if (ctl->d.vaddr_base == 0)
5330Sstevel@tonic-gate continue;
5340Sstevel@tonic-gate
5351078Ssvemuri traptrace_buf_inuse = 1;
5360Sstevel@tonic-gate mdb_printf("trap_trace_ctl[%d] = {\n", i);
5370Sstevel@tonic-gate mdb_printf(" vaddr_base = 0x%lx\n", (long)ctl->d.vaddr_base);
5380Sstevel@tonic-gate mdb_printf(" last_offset = 0x%x\n", ctl->d.last_offset);
5390Sstevel@tonic-gate mdb_printf(" offset = 0x%x\n", ctl->d.offset);
5400Sstevel@tonic-gate mdb_printf(" limit = 0x%x\n", ctl->d.limit);
5410Sstevel@tonic-gate mdb_printf(" paddr_base = 0x%llx\n", ctl->d.paddr_base);
5420Sstevel@tonic-gate mdb_printf(" asi = 0x%02x\n}\n", ctl->d.asi);
5430Sstevel@tonic-gate }
5441078Ssvemuri if (!traptrace_buf_inuse) {
5451078Ssvemuri mdb_warn("traptrace not configured");
5461078Ssvemuri return (DCMD_ERR);
5471078Ssvemuri }
5480Sstevel@tonic-gate
5490Sstevel@tonic-gate return (DCMD_OK);
5500Sstevel@tonic-gate }
5510Sstevel@tonic-gate
5520Sstevel@tonic-gate /*ARGSUSED*/
5530Sstevel@tonic-gate static int
ttprint_short(uintptr_t addr,const trap_trace_fullrec_t * full,int * cpu)5540Sstevel@tonic-gate ttprint_short(uintptr_t addr, const trap_trace_fullrec_t *full, int *cpu)
5550Sstevel@tonic-gate {
5560Sstevel@tonic-gate const char *ttstr;
5570Sstevel@tonic-gate const struct trap_trace_record *ttp = &full->ttf_rec;
5580Sstevel@tonic-gate
5590Sstevel@tonic-gate if (*cpu == -1)
5600Sstevel@tonic-gate mdb_printf("%3d ", full->ttf_cpu);
5610Sstevel@tonic-gate else
5620Sstevel@tonic-gate if (*cpu != full->ttf_cpu)
5630Sstevel@tonic-gate return (0);
5640Sstevel@tonic-gate
5650Sstevel@tonic-gate /*
5660Sstevel@tonic-gate * Decoding the traptype field is a bit messy. First we check for
5670Sstevel@tonic-gate * several well-defined 16-bit values defined in <sys/traptrace.h>.
5680Sstevel@tonic-gate */
5690Sstevel@tonic-gate switch (ttp->tt_tt) {
5700Sstevel@tonic-gate case TT_SC_ENTR:
5710Sstevel@tonic-gate ttstr = "sys-enter";
5720Sstevel@tonic-gate break;
5730Sstevel@tonic-gate case TT_SC_RET:
5740Sstevel@tonic-gate ttstr = "sys-exit";
5750Sstevel@tonic-gate break;
5760Sstevel@tonic-gate case TT_SYS_RTT_PROM:
5770Sstevel@tonic-gate ttstr = "prom_rtt";
5780Sstevel@tonic-gate break;
5790Sstevel@tonic-gate case TT_SYS_RTT_PRIV:
5800Sstevel@tonic-gate ttstr = "priv_rtt";
5810Sstevel@tonic-gate break;
5820Sstevel@tonic-gate case TT_SYS_RTT_USER:
5830Sstevel@tonic-gate ttstr = "user_rtt";
5840Sstevel@tonic-gate break;
5850Sstevel@tonic-gate case TT_INTR_EXIT:
5860Sstevel@tonic-gate ttstr = "int-thr-exit";
5870Sstevel@tonic-gate break;
5880Sstevel@tonic-gate default:
5890Sstevel@tonic-gate /*
5900Sstevel@tonic-gate * Next we consider several prefixes (which are
5910Sstevel@tonic-gate * typically OR'd with other information such as the
5920Sstevel@tonic-gate * %pil or %tt value at the time of the trace).
5930Sstevel@tonic-gate */
5940Sstevel@tonic-gate switch (ttp->tt_tt & 0xff00) {
5950Sstevel@tonic-gate case TT_SERVE_INTR:
5960Sstevel@tonic-gate ttstr = "serve-intr";
5970Sstevel@tonic-gate break;
5980Sstevel@tonic-gate case TT_XCALL:
5990Sstevel@tonic-gate ttstr = "xcall";
6000Sstevel@tonic-gate break;
6010Sstevel@tonic-gate case TT_XCALL_CONT:
6020Sstevel@tonic-gate ttstr = "xcall-cont";
6030Sstevel@tonic-gate break;
6040Sstevel@tonic-gate case SYSTRAP_TT:
6050Sstevel@tonic-gate ttstr = "sys_trap";
6060Sstevel@tonic-gate break;
6070Sstevel@tonic-gate default:
6080Sstevel@tonic-gate /*
6090Sstevel@tonic-gate * Otherwise we try to convert the
6100Sstevel@tonic-gate * tt value to a string using our
6110Sstevel@tonic-gate * giant lookup table.
6120Sstevel@tonic-gate */
6130Sstevel@tonic-gate ttstr = ttp->tt_tt < ttndescr ?
6140Sstevel@tonic-gate ttdescr[ttp->tt_tt] : "?";
6150Sstevel@tonic-gate }
6160Sstevel@tonic-gate }
6170Sstevel@tonic-gate
6180Sstevel@tonic-gate #ifdef sun4v
6190Sstevel@tonic-gate mdb_printf("%016llx %04hx %-12s %02x %02x %0?p %A\n", ttp->tt_tick,
6200Sstevel@tonic-gate ttp->tt_tt, ttstr, ttp->tt_tl, ttp->tt_gl,
6210Sstevel@tonic-gate ttp->tt_tpc, ttp->tt_tpc);
6220Sstevel@tonic-gate #else
6230Sstevel@tonic-gate mdb_printf("%016llx %04hx %-12s %04hx %0?p %A\n", ttp->tt_tick,
6240Sstevel@tonic-gate ttp->tt_tt, ttstr, ttp->tt_tl, ttp->tt_tpc, ttp->tt_tpc);
6250Sstevel@tonic-gate #endif
6260Sstevel@tonic-gate
6270Sstevel@tonic-gate return (WALK_NEXT);
6280Sstevel@tonic-gate }
6290Sstevel@tonic-gate
6300Sstevel@tonic-gate /*ARGSUSED*/
6310Sstevel@tonic-gate static int
ttprint_long(uintptr_t addr,const trap_trace_fullrec_t * full,int * cpu)6320Sstevel@tonic-gate ttprint_long(uintptr_t addr, const trap_trace_fullrec_t *full, int *cpu)
6330Sstevel@tonic-gate {
6340Sstevel@tonic-gate const struct trap_trace_record *ttp = &full->ttf_rec;
6350Sstevel@tonic-gate
6360Sstevel@tonic-gate if (*cpu == -1)
6370Sstevel@tonic-gate mdb_printf("%3d ", full->ttf_cpu);
6380Sstevel@tonic-gate else if (*cpu != full->ttf_cpu)
6390Sstevel@tonic-gate return (WALK_NEXT);
6400Sstevel@tonic-gate
6410Sstevel@tonic-gate #ifdef sun4v
6420Sstevel@tonic-gate mdb_printf("%016llx %016llx %04hx %02x %02x %0?p %0?p %0?p "
6430Sstevel@tonic-gate "[%p,%p,%p,%p]\n",
6440Sstevel@tonic-gate ttp->tt_tick, ttp->tt_tstate, ttp->tt_tt, ttp->tt_tl, ttp->tt_gl,
6450Sstevel@tonic-gate ttp->tt_tpc, ttp->tt_sp, ttp->tt_tr,
6460Sstevel@tonic-gate ttp->tt_f1, ttp->tt_f2, ttp->tt_f3, ttp->tt_f4);
6470Sstevel@tonic-gate #else
6480Sstevel@tonic-gate mdb_printf("%016llx %016llx %04hx %04hx %0?p %0?p %0?p [%p,%p,%p,%p]\n",
6490Sstevel@tonic-gate ttp->tt_tick, ttp->tt_tstate, ttp->tt_tt, ttp->tt_tl,
6500Sstevel@tonic-gate ttp->tt_tpc, ttp->tt_sp, ttp->tt_tr,
6510Sstevel@tonic-gate ttp->tt_f1, ttp->tt_f2, ttp->tt_f3, ttp->tt_f4);
6520Sstevel@tonic-gate #endif
6530Sstevel@tonic-gate
6540Sstevel@tonic-gate return (WALK_NEXT);
6550Sstevel@tonic-gate }
6560Sstevel@tonic-gate
6570Sstevel@tonic-gate typedef struct ttrace_cpu_data {
6580Sstevel@tonic-gate struct trap_trace_record *tc_buf;
6590Sstevel@tonic-gate struct trap_trace_record *tc_rec;
6600Sstevel@tonic-gate struct trap_trace_record *tc_stop;
6610Sstevel@tonic-gate size_t tc_bufsiz;
6620Sstevel@tonic-gate uintptr_t tc_base;
6630Sstevel@tonic-gate } ttrace_cpu_data_t;
6640Sstevel@tonic-gate
6650Sstevel@tonic-gate typedef struct ttrace_walk_data {
6660Sstevel@tonic-gate int tw_ncpu;
6670Sstevel@tonic-gate ttrace_cpu_data_t *tw_cpus;
6680Sstevel@tonic-gate } ttrace_walk_data_t;
6690Sstevel@tonic-gate
6700Sstevel@tonic-gate int
ttrace_walk_init(mdb_walk_state_t * wsp)6710Sstevel@tonic-gate ttrace_walk_init(mdb_walk_state_t *wsp)
6720Sstevel@tonic-gate {
6730Sstevel@tonic-gate TRAP_TRACE_CTL *ctls, *ctl;
6741078Ssvemuri int i, traptrace_buf_inuse = 0;
6750Sstevel@tonic-gate ttrace_walk_data_t *tw;
6760Sstevel@tonic-gate ttrace_cpu_data_t *tc;
6770Sstevel@tonic-gate struct trap_trace_record *buf;
6780Sstevel@tonic-gate
6790Sstevel@tonic-gate if (wsp->walk_addr != NULL) {
6800Sstevel@tonic-gate mdb_warn("ttrace only supports global walks\n");
6810Sstevel@tonic-gate return (WALK_ERR);
6820Sstevel@tonic-gate }
6830Sstevel@tonic-gate
6840Sstevel@tonic-gate if (fetch_ncpu())
6850Sstevel@tonic-gate return (WALK_ERR);
6860Sstevel@tonic-gate
6870Sstevel@tonic-gate ctls = mdb_alloc(sizeof (TRAP_TRACE_CTL) * ncpu, UM_SLEEP);
6880Sstevel@tonic-gate if (mdb_readsym(ctls, sizeof (TRAP_TRACE_CTL) * ncpu,
6890Sstevel@tonic-gate "trap_trace_ctl") == -1) {
6900Sstevel@tonic-gate mdb_warn("symbol 'trap_trace_ctl' not found");
6910Sstevel@tonic-gate mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu);
6920Sstevel@tonic-gate return (WALK_ERR);
6930Sstevel@tonic-gate }
6940Sstevel@tonic-gate
6950Sstevel@tonic-gate tw = mdb_zalloc(sizeof (ttrace_walk_data_t), UM_SLEEP);
6960Sstevel@tonic-gate tw->tw_ncpu = ncpu;
6970Sstevel@tonic-gate tw->tw_cpus = mdb_zalloc(sizeof (ttrace_cpu_data_t) * ncpu, UM_SLEEP);
6980Sstevel@tonic-gate
6990Sstevel@tonic-gate for (i = 0; i < ncpu; i++) {
7000Sstevel@tonic-gate ctl = &ctls[i];
7010Sstevel@tonic-gate
7020Sstevel@tonic-gate if (ctl->d.vaddr_base == 0)
7030Sstevel@tonic-gate continue;
7040Sstevel@tonic-gate
7051078Ssvemuri traptrace_buf_inuse = 1;
7060Sstevel@tonic-gate tc = &(tw->tw_cpus[i]);
7070Sstevel@tonic-gate tc->tc_bufsiz = ctl->d.limit -
7080Sstevel@tonic-gate sizeof (struct trap_trace_record);
7090Sstevel@tonic-gate tc->tc_buf = buf = mdb_alloc(tc->tc_bufsiz, UM_SLEEP);
7100Sstevel@tonic-gate tc->tc_base = (uintptr_t)ctl->d.vaddr_base;
7110Sstevel@tonic-gate
7120Sstevel@tonic-gate if (mdb_vread(buf, tc->tc_bufsiz, tc->tc_base) == -1) {
7130Sstevel@tonic-gate mdb_warn("failed to read trap trace buffer at %p",
7140Sstevel@tonic-gate ctl->d.vaddr_base);
7150Sstevel@tonic-gate mdb_free(buf, tc->tc_bufsiz);
7160Sstevel@tonic-gate tc->tc_buf = NULL;
7170Sstevel@tonic-gate } else {
7180Sstevel@tonic-gate tc->tc_rec = (struct trap_trace_record *)
7190Sstevel@tonic-gate ((uintptr_t)buf + (uintptr_t)ctl->d.last_offset);
7200Sstevel@tonic-gate tc->tc_stop = (struct trap_trace_record *)
7210Sstevel@tonic-gate ((uintptr_t)buf + (uintptr_t)ctl->d.offset);
7220Sstevel@tonic-gate }
7230Sstevel@tonic-gate }
7241078Ssvemuri if (!traptrace_buf_inuse) {
7251078Ssvemuri mdb_warn("traptrace not configured");
7261078Ssvemuri mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu);
7271078Ssvemuri return (DCMD_ERR);
7281078Ssvemuri }
7290Sstevel@tonic-gate
7300Sstevel@tonic-gate mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu);
7310Sstevel@tonic-gate wsp->walk_data = tw;
7320Sstevel@tonic-gate return (WALK_NEXT);
7330Sstevel@tonic-gate }
7340Sstevel@tonic-gate
7350Sstevel@tonic-gate int
ttrace_walk_step(mdb_walk_state_t * wsp)7360Sstevel@tonic-gate ttrace_walk_step(mdb_walk_state_t *wsp)
7370Sstevel@tonic-gate {
7380Sstevel@tonic-gate ttrace_walk_data_t *tw = wsp->walk_data;
7390Sstevel@tonic-gate ttrace_cpu_data_t *tc;
7400Sstevel@tonic-gate struct trap_trace_record *rec;
7410Sstevel@tonic-gate int oldest, i, status;
7420Sstevel@tonic-gate uint64_t oldest_tick = 0;
7430Sstevel@tonic-gate int done = 1;
7440Sstevel@tonic-gate trap_trace_fullrec_t fullrec;
7450Sstevel@tonic-gate
7460Sstevel@tonic-gate for (i = 0; i < tw->tw_ncpu; i++) {
7470Sstevel@tonic-gate tc = &(tw->tw_cpus[i]);
7480Sstevel@tonic-gate
7490Sstevel@tonic-gate if (tc->tc_rec == NULL)
7500Sstevel@tonic-gate continue;
7510Sstevel@tonic-gate done = 0;
7520Sstevel@tonic-gate
7530Sstevel@tonic-gate if (tc->tc_rec->tt_tick == 0)
7540Sstevel@tonic-gate mdb_warn("Warning: tt_tick == 0\n");
7550Sstevel@tonic-gate
7560Sstevel@tonic-gate if (tc->tc_rec->tt_tick > oldest_tick) {
7570Sstevel@tonic-gate oldest_tick = tc->tc_rec->tt_tick;
7580Sstevel@tonic-gate oldest = i;
7590Sstevel@tonic-gate }
7600Sstevel@tonic-gate }
7610Sstevel@tonic-gate
7620Sstevel@tonic-gate if (done)
7630Sstevel@tonic-gate return (-1);
7640Sstevel@tonic-gate
7650Sstevel@tonic-gate tc = &(tw->tw_cpus[oldest]);
7660Sstevel@tonic-gate rec = tc->tc_rec;
7670Sstevel@tonic-gate
7680Sstevel@tonic-gate fullrec.ttf_rec = *rec;
7690Sstevel@tonic-gate fullrec.ttf_cpu = oldest;
7700Sstevel@tonic-gate
7710Sstevel@tonic-gate if (oldest_tick != 0)
7720Sstevel@tonic-gate status = wsp->walk_callback((uintptr_t)rec -
7730Sstevel@tonic-gate (uintptr_t)tc->tc_buf + tc->tc_base, &fullrec,
7740Sstevel@tonic-gate wsp->walk_cbdata);
7750Sstevel@tonic-gate
7760Sstevel@tonic-gate tc->tc_rec--;
7770Sstevel@tonic-gate
7780Sstevel@tonic-gate if (tc->tc_rec < tc->tc_buf)
7790Sstevel@tonic-gate tc->tc_rec = (struct trap_trace_record *)((uintptr_t)
7800Sstevel@tonic-gate tc->tc_buf + (uintptr_t)tc->tc_bufsiz -
7810Sstevel@tonic-gate sizeof (struct trap_trace_record));
7820Sstevel@tonic-gate
7830Sstevel@tonic-gate if (tc->tc_rec == tc->tc_stop) {
7840Sstevel@tonic-gate tc->tc_rec = NULL;
7850Sstevel@tonic-gate mdb_free(tc->tc_buf, tc->tc_bufsiz);
7860Sstevel@tonic-gate }
7870Sstevel@tonic-gate
7880Sstevel@tonic-gate return (status);
7890Sstevel@tonic-gate }
7900Sstevel@tonic-gate
7910Sstevel@tonic-gate void
ttrace_walk_fini(mdb_walk_state_t * wsp)7920Sstevel@tonic-gate ttrace_walk_fini(mdb_walk_state_t *wsp)
7930Sstevel@tonic-gate {
7940Sstevel@tonic-gate ttrace_walk_data_t *tw = wsp->walk_data;
7950Sstevel@tonic-gate
7960Sstevel@tonic-gate mdb_free(tw->tw_cpus, sizeof (ttrace_cpu_data_t) * tw->tw_ncpu);
7970Sstevel@tonic-gate mdb_free(tw, sizeof (ttrace_walk_data_t));
7980Sstevel@tonic-gate }
7990Sstevel@tonic-gate
8000Sstevel@tonic-gate int
ttrace(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)8010Sstevel@tonic-gate ttrace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
8020Sstevel@tonic-gate {
8030Sstevel@tonic-gate uint_t opt_x = FALSE;
8040Sstevel@tonic-gate int cpu = -1;
8050Sstevel@tonic-gate mdb_walk_cb_t ttprint;
8060Sstevel@tonic-gate
8070Sstevel@tonic-gate if (mdb_getopts(argc, argv,
8080Sstevel@tonic-gate 'x', MDB_OPT_SETBITS, TRUE, &opt_x, NULL) != argc)
8090Sstevel@tonic-gate return (DCMD_USAGE);
8100Sstevel@tonic-gate
8110Sstevel@tonic-gate if (flags & DCMD_ADDRSPEC) {
8120Sstevel@tonic-gate if (fetch_ncpu())
8130Sstevel@tonic-gate return (DCMD_ERR);
8140Sstevel@tonic-gate if (addr >= ncpu) {
8150Sstevel@tonic-gate mdb_warn("expected cpu between 0 and %d\n", ncpu - 1);
8160Sstevel@tonic-gate return (DCMD_ERR);
8170Sstevel@tonic-gate }
8180Sstevel@tonic-gate cpu = (int)addr;
8190Sstevel@tonic-gate }
8200Sstevel@tonic-gate
8210Sstevel@tonic-gate if (cpu == -1)
8220Sstevel@tonic-gate mdb_printf("CPU ");
8230Sstevel@tonic-gate
8240Sstevel@tonic-gate if (opt_x) {
8250Sstevel@tonic-gate #ifdef sun4v
8260Sstevel@tonic-gate mdb_printf("%-16s %-16s %-4s %-3s %-3s %-?s %-?s %-?s "
8270Sstevel@tonic-gate "F1-4\n", "%tick", "%tstate", "%tt", "%tl", "%gl",
8280Sstevel@tonic-gate "%tpc", "%sp", "TR");
8290Sstevel@tonic-gate #else
8300Sstevel@tonic-gate mdb_printf("%-16s %-16s %-4s %-4s %-?s %-?s %-?s "
8310Sstevel@tonic-gate "F1-4\n", "%tick", "%tstate", "%tt", "%tl",
8320Sstevel@tonic-gate "%tpc", "%sp", "TR");
8330Sstevel@tonic-gate #endif
8340Sstevel@tonic-gate
8350Sstevel@tonic-gate ttprint = (mdb_walk_cb_t)ttprint_long;
8360Sstevel@tonic-gate } else {
8370Sstevel@tonic-gate #ifdef sun4v
8380Sstevel@tonic-gate mdb_printf("%-16s %-4s %-12s %-3s %-3s %s\n",
8390Sstevel@tonic-gate "%tick", "%tt", "", "%tl", "%gl", "%tpc");
8400Sstevel@tonic-gate #else
8410Sstevel@tonic-gate mdb_printf("%-16s %-4s %-12s %-4s %s\n",
8420Sstevel@tonic-gate "%tick", "%tt", "", "%tl", "%tpc");
8430Sstevel@tonic-gate #endif
8440Sstevel@tonic-gate
8450Sstevel@tonic-gate ttprint = (mdb_walk_cb_t)ttprint_short;
8460Sstevel@tonic-gate }
8470Sstevel@tonic-gate
8480Sstevel@tonic-gate if (mdb_walk("ttrace", ttprint, &cpu) == -1) {
8490Sstevel@tonic-gate mdb_warn("couldn't walk ttrace");
8500Sstevel@tonic-gate return (DCMD_ERR);
8510Sstevel@tonic-gate }
8520Sstevel@tonic-gate
8530Sstevel@tonic-gate return (DCMD_OK);
8540Sstevel@tonic-gate }
8550Sstevel@tonic-gate
8560Sstevel@tonic-gate #ifdef sun4v
8570Sstevel@tonic-gate /*ARGSUSED*/
8580Sstevel@tonic-gate int
httctl(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)8590Sstevel@tonic-gate httctl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
8600Sstevel@tonic-gate {
8610Sstevel@tonic-gate TRAP_TRACE_CTL *ctls, *ctl;
8621078Ssvemuri int i, htraptrace_buf_inuse = 0;
8630Sstevel@tonic-gate htrap_trace_hdr_t hdr;
8640Sstevel@tonic-gate
8650Sstevel@tonic-gate if (argc != 0)
8660Sstevel@tonic-gate return (DCMD_USAGE);
8670Sstevel@tonic-gate
8680Sstevel@tonic-gate if (fetch_ncpu())
8690Sstevel@tonic-gate return (DCMD_ERR);
8700Sstevel@tonic-gate
8710Sstevel@tonic-gate ctls = mdb_alloc(sizeof (TRAP_TRACE_CTL) * ncpu, UM_SLEEP | UM_GC);
8720Sstevel@tonic-gate if (mdb_readsym(ctls, sizeof (TRAP_TRACE_CTL) * ncpu,
8730Sstevel@tonic-gate "trap_trace_ctl") == -1) {
8740Sstevel@tonic-gate mdb_warn("symbol 'trap_trace_ctl' not found");
8750Sstevel@tonic-gate return (DCMD_ERR);
8760Sstevel@tonic-gate }
8770Sstevel@tonic-gate
8780Sstevel@tonic-gate for (ctl = &ctls[0], i = 0; i < ncpu; i++, ctl++) {
8790Sstevel@tonic-gate if (ctl->d.hvaddr_base == 0)
8800Sstevel@tonic-gate continue;
8810Sstevel@tonic-gate
8821078Ssvemuri htraptrace_buf_inuse = 1;
8830Sstevel@tonic-gate mdb_vread(&hdr, sizeof (htrap_trace_hdr_t),
884*10610SJonathan.Adams@Sun.COM (uintptr_t)ctl->d.hvaddr_base);
8850Sstevel@tonic-gate mdb_printf("htrap_trace_ctl[%d] = {\n", i);
8860Sstevel@tonic-gate mdb_printf(" vaddr_base = 0x%lx\n", (long)ctl->d.hvaddr_base);
8870Sstevel@tonic-gate mdb_printf(" last_offset = 0x%lx\n", hdr.last_offset);
8880Sstevel@tonic-gate mdb_printf(" offset = 0x%lx\n", hdr.offset);
8890Sstevel@tonic-gate mdb_printf(" limit = 0x%x\n", ctl->d.hlimit);
8900Sstevel@tonic-gate mdb_printf(" paddr_base = 0x%llx\n}\n", ctl->d.hpaddr_base);
8910Sstevel@tonic-gate }
8921078Ssvemuri if (!htraptrace_buf_inuse) {
8931078Ssvemuri mdb_warn("hv traptrace not configured");
8941078Ssvemuri return (DCMD_ERR);
8951078Ssvemuri }
8960Sstevel@tonic-gate
8970Sstevel@tonic-gate return (DCMD_OK);
8980Sstevel@tonic-gate }
8990Sstevel@tonic-gate
9000Sstevel@tonic-gate /*ARGSUSED*/
9010Sstevel@tonic-gate static int
httprint_short(uintptr_t addr,const htrap_trace_fullrec_t * full,int * cpu)9020Sstevel@tonic-gate httprint_short(uintptr_t addr, const htrap_trace_fullrec_t *full, int *cpu)
9030Sstevel@tonic-gate {
9040Sstevel@tonic-gate const char *ttstr;
9050Sstevel@tonic-gate const struct htrap_trace_record *ttp = &full->ttf_rec;
9060Sstevel@tonic-gate
9070Sstevel@tonic-gate if (*cpu == -1)
9080Sstevel@tonic-gate mdb_printf("%3d ", full->ttf_cpu);
9090Sstevel@tonic-gate else
9100Sstevel@tonic-gate if (*cpu != full->ttf_cpu)
9110Sstevel@tonic-gate return (0);
9120Sstevel@tonic-gate
9130Sstevel@tonic-gate /*
9140Sstevel@tonic-gate * Convert the tt value to a string using our gaint lookuo table
9150Sstevel@tonic-gate */
9160Sstevel@tonic-gate ttstr = ttp->tt_tt < ttndescr ? ttdescr[ttp->tt_tt] : "?";
9170Sstevel@tonic-gate
9180Sstevel@tonic-gate mdb_printf("%016llx %02x %04hx %04hx %-16s %02x %02x %0?p %A\n",
919*10610SJonathan.Adams@Sun.COM ttp->tt_tick, ttp->tt_ty, ttp->tt_tag, ttp->tt_tt, ttstr,
920*10610SJonathan.Adams@Sun.COM ttp->tt_tl, ttp->tt_gl, ttp->tt_tpc, ttp->tt_tpc);
9210Sstevel@tonic-gate
9220Sstevel@tonic-gate return (WALK_NEXT);
9230Sstevel@tonic-gate }
9240Sstevel@tonic-gate
9250Sstevel@tonic-gate /*ARGSUSED*/
9260Sstevel@tonic-gate static int
httprint_long(uintptr_t addr,const htrap_trace_fullrec_t * full,int * cpu)9270Sstevel@tonic-gate httprint_long(uintptr_t addr, const htrap_trace_fullrec_t *full, int *cpu)
9280Sstevel@tonic-gate {
9290Sstevel@tonic-gate const struct htrap_trace_record *ttp = &full->ttf_rec;
9300Sstevel@tonic-gate
9310Sstevel@tonic-gate if (*cpu == -1)
9320Sstevel@tonic-gate mdb_printf("%3d ", full->ttf_cpu);
9330Sstevel@tonic-gate else if (*cpu != full->ttf_cpu)
9340Sstevel@tonic-gate return (WALK_NEXT);
9350Sstevel@tonic-gate
9360Sstevel@tonic-gate mdb_printf("%016llx %016llx %02x %02x %04hx %04hx %02x %02x %0?p "
937*10610SJonathan.Adams@Sun.COM "[%p,%p,%p,%p]\n",
938*10610SJonathan.Adams@Sun.COM ttp->tt_tick, ttp->tt_tstate, ttp->tt_hpstate, ttp->tt_ty,
939*10610SJonathan.Adams@Sun.COM ttp->tt_tag, ttp->tt_tt, ttp->tt_tl, ttp->tt_gl, ttp->tt_tpc,
940*10610SJonathan.Adams@Sun.COM ttp->tt_f1, ttp->tt_f2, ttp->tt_f3, ttp->tt_f4);
9410Sstevel@tonic-gate
9420Sstevel@tonic-gate return (WALK_NEXT);
9430Sstevel@tonic-gate }
9440Sstevel@tonic-gate
9450Sstevel@tonic-gate typedef struct httrace_cpu_data {
9460Sstevel@tonic-gate struct htrap_trace_record *tc_buf;
9470Sstevel@tonic-gate struct htrap_trace_record *tc_rec;
9480Sstevel@tonic-gate struct htrap_trace_record *tc_stop;
9490Sstevel@tonic-gate size_t tc_bufsiz;
9500Sstevel@tonic-gate uintptr_t tc_base;
9510Sstevel@tonic-gate } httrace_cpu_data_t;
9520Sstevel@tonic-gate
9530Sstevel@tonic-gate typedef struct httrace_walk_data {
9540Sstevel@tonic-gate int tw_ncpu;
9550Sstevel@tonic-gate httrace_cpu_data_t *tw_cpus;
9560Sstevel@tonic-gate } httrace_walk_data_t;
9570Sstevel@tonic-gate
9580Sstevel@tonic-gate int
httrace_walk_init(mdb_walk_state_t * wsp)9590Sstevel@tonic-gate httrace_walk_init(mdb_walk_state_t *wsp)
9600Sstevel@tonic-gate {
9610Sstevel@tonic-gate TRAP_TRACE_CTL *ctls, *ctl;
9621078Ssvemuri int i, htraptrace_buf_inuse = 0;
9630Sstevel@tonic-gate httrace_walk_data_t *tw;
9640Sstevel@tonic-gate httrace_cpu_data_t *tc;
9650Sstevel@tonic-gate struct htrap_trace_record *buf;
9662471Sha137994 htrap_trace_hdr_t *hdr;
9670Sstevel@tonic-gate
9680Sstevel@tonic-gate if (wsp->walk_addr != NULL) {
9690Sstevel@tonic-gate mdb_warn("httrace only supports global walks\n");
9700Sstevel@tonic-gate return (WALK_ERR);
9710Sstevel@tonic-gate }
9720Sstevel@tonic-gate
9730Sstevel@tonic-gate if (fetch_ncpu())
9740Sstevel@tonic-gate return (WALK_ERR);
9750Sstevel@tonic-gate
9760Sstevel@tonic-gate ctls = mdb_alloc(sizeof (TRAP_TRACE_CTL) * ncpu, UM_SLEEP);
9770Sstevel@tonic-gate if (mdb_readsym(ctls, sizeof (TRAP_TRACE_CTL) * ncpu,
9780Sstevel@tonic-gate "trap_trace_ctl") == -1) {
9790Sstevel@tonic-gate mdb_warn("symbol 'trap_trace_ctl' not found");
9800Sstevel@tonic-gate mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu);
9810Sstevel@tonic-gate return (WALK_ERR);
9820Sstevel@tonic-gate }
9830Sstevel@tonic-gate
9840Sstevel@tonic-gate tw = mdb_zalloc(sizeof (httrace_walk_data_t), UM_SLEEP);
9850Sstevel@tonic-gate tw->tw_ncpu = ncpu;
9860Sstevel@tonic-gate tw->tw_cpus = mdb_zalloc(sizeof (httrace_cpu_data_t) * ncpu, UM_SLEEP);
9870Sstevel@tonic-gate
9880Sstevel@tonic-gate for (i = 0; i < ncpu; i++) {
9890Sstevel@tonic-gate ctl = &ctls[i];
9900Sstevel@tonic-gate
9910Sstevel@tonic-gate if (ctl->d.hvaddr_base == 0)
9920Sstevel@tonic-gate continue;
9930Sstevel@tonic-gate
9941078Ssvemuri htraptrace_buf_inuse = 1;
9950Sstevel@tonic-gate tc = &(tw->tw_cpus[i]);
9962471Sha137994 tc->tc_bufsiz = ctl->d.hlimit;
9970Sstevel@tonic-gate tc->tc_buf = buf = mdb_alloc(tc->tc_bufsiz, UM_SLEEP);
9980Sstevel@tonic-gate tc->tc_base = (uintptr_t)ctl->d.hvaddr_base;
9990Sstevel@tonic-gate
10000Sstevel@tonic-gate if (mdb_vread(buf, tc->tc_bufsiz, tc->tc_base) == -1) {
10010Sstevel@tonic-gate mdb_warn("failed to read hv trap trace buffer at %p",
10020Sstevel@tonic-gate ctl->d.hvaddr_base);
10030Sstevel@tonic-gate mdb_free(buf, tc->tc_bufsiz);
10040Sstevel@tonic-gate tc->tc_buf = NULL;
10050Sstevel@tonic-gate } else {
10062471Sha137994 hdr = (htrap_trace_hdr_t *)buf;
10070Sstevel@tonic-gate tc->tc_rec = (struct htrap_trace_record *)
1008*10610SJonathan.Adams@Sun.COM ((uintptr_t)buf + (uintptr_t)hdr->last_offset);
10090Sstevel@tonic-gate tc->tc_stop = (struct htrap_trace_record *)
1010*10610SJonathan.Adams@Sun.COM ((uintptr_t)buf + (uintptr_t)hdr->offset);
10110Sstevel@tonic-gate }
10120Sstevel@tonic-gate }
10131078Ssvemuri if (!htraptrace_buf_inuse) {
10141078Ssvemuri mdb_warn("hv traptrace not configured");
10151078Ssvemuri mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu);
10161078Ssvemuri return (DCMD_ERR);
10171078Ssvemuri }
10180Sstevel@tonic-gate
10190Sstevel@tonic-gate mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu);
10200Sstevel@tonic-gate wsp->walk_data = tw;
10210Sstevel@tonic-gate return (WALK_NEXT);
10220Sstevel@tonic-gate }
10230Sstevel@tonic-gate
10240Sstevel@tonic-gate int
httrace_walk_step(mdb_walk_state_t * wsp)10250Sstevel@tonic-gate httrace_walk_step(mdb_walk_state_t *wsp)
10260Sstevel@tonic-gate {
10270Sstevel@tonic-gate httrace_walk_data_t *tw = wsp->walk_data;
10280Sstevel@tonic-gate httrace_cpu_data_t *tc;
10290Sstevel@tonic-gate struct htrap_trace_record *rec;
10300Sstevel@tonic-gate int oldest, i, status;
10310Sstevel@tonic-gate uint64_t oldest_tick = 0;
10320Sstevel@tonic-gate int done = 1;
10330Sstevel@tonic-gate htrap_trace_fullrec_t fullrec;
10340Sstevel@tonic-gate
10350Sstevel@tonic-gate for (i = 0; i < tw->tw_ncpu; i++) {
10360Sstevel@tonic-gate tc = &(tw->tw_cpus[i]);
10370Sstevel@tonic-gate
10380Sstevel@tonic-gate if (tc->tc_rec == NULL)
10390Sstevel@tonic-gate continue;
10400Sstevel@tonic-gate done = 0;
10410Sstevel@tonic-gate
10420Sstevel@tonic-gate if (tc->tc_rec->tt_tick == 0)
10430Sstevel@tonic-gate mdb_warn("Warning: tt_tick == 0\n");
10440Sstevel@tonic-gate
10452471Sha137994 if (tc->tc_rec->tt_tick >= oldest_tick) {
10460Sstevel@tonic-gate oldest_tick = tc->tc_rec->tt_tick;
10470Sstevel@tonic-gate oldest = i;
10480Sstevel@tonic-gate }
10490Sstevel@tonic-gate }
10500Sstevel@tonic-gate
10510Sstevel@tonic-gate if (done)
10520Sstevel@tonic-gate return (-1);
10530Sstevel@tonic-gate
10540Sstevel@tonic-gate tc = &(tw->tw_cpus[oldest]);
10550Sstevel@tonic-gate rec = tc->tc_rec;
10560Sstevel@tonic-gate
10570Sstevel@tonic-gate fullrec.ttf_rec = *rec;
10580Sstevel@tonic-gate fullrec.ttf_cpu = oldest;
10590Sstevel@tonic-gate
10600Sstevel@tonic-gate if (oldest_tick != 0)
10610Sstevel@tonic-gate status = wsp->walk_callback((uintptr_t)rec -
10620Sstevel@tonic-gate (uintptr_t)tc->tc_buf + tc->tc_base, &fullrec,
10630Sstevel@tonic-gate wsp->walk_cbdata);
10640Sstevel@tonic-gate
10650Sstevel@tonic-gate tc->tc_rec--;
10660Sstevel@tonic-gate
10670Sstevel@tonic-gate /* first record of the trap trace buffer is trap trace header */
10680Sstevel@tonic-gate if (tc->tc_rec == tc->tc_buf)
10690Sstevel@tonic-gate tc->tc_rec = (struct htrap_trace_record *)((uintptr_t)
10700Sstevel@tonic-gate tc->tc_buf + (uintptr_t)tc->tc_bufsiz -
10710Sstevel@tonic-gate sizeof (struct htrap_trace_record));
10720Sstevel@tonic-gate
10730Sstevel@tonic-gate if (tc->tc_rec == tc->tc_stop) {
10740Sstevel@tonic-gate tc->tc_rec = NULL;
10750Sstevel@tonic-gate mdb_free(tc->tc_buf, tc->tc_bufsiz);
10760Sstevel@tonic-gate }
10770Sstevel@tonic-gate
10780Sstevel@tonic-gate return (status);
10790Sstevel@tonic-gate }
10800Sstevel@tonic-gate
10810Sstevel@tonic-gate void
httrace_walk_fini(mdb_walk_state_t * wsp)10820Sstevel@tonic-gate httrace_walk_fini(mdb_walk_state_t *wsp)
10830Sstevel@tonic-gate {
10840Sstevel@tonic-gate httrace_walk_data_t *tw = wsp->walk_data;
10850Sstevel@tonic-gate
10860Sstevel@tonic-gate mdb_free(tw->tw_cpus, sizeof (httrace_cpu_data_t) * tw->tw_ncpu);
10870Sstevel@tonic-gate mdb_free(tw, sizeof (httrace_walk_data_t));
10880Sstevel@tonic-gate }
10890Sstevel@tonic-gate
10900Sstevel@tonic-gate int
httrace(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)10910Sstevel@tonic-gate httrace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
10920Sstevel@tonic-gate {
10930Sstevel@tonic-gate uint_t opt_x = FALSE;
10940Sstevel@tonic-gate int cpu = -1;
10950Sstevel@tonic-gate mdb_walk_cb_t ttprint;
10960Sstevel@tonic-gate
10970Sstevel@tonic-gate if (mdb_getopts(argc, argv,
10980Sstevel@tonic-gate 'x', MDB_OPT_SETBITS, TRUE, &opt_x, NULL) != argc)
10990Sstevel@tonic-gate return (DCMD_USAGE);
11000Sstevel@tonic-gate
11010Sstevel@tonic-gate if (flags & DCMD_ADDRSPEC) {
11020Sstevel@tonic-gate if (fetch_ncpu())
11030Sstevel@tonic-gate return (DCMD_ERR);
11040Sstevel@tonic-gate if (addr >= ncpu) {
11050Sstevel@tonic-gate mdb_warn("expected cpu between 0 and %d\n", ncpu - 1);
11060Sstevel@tonic-gate return (DCMD_ERR);
11070Sstevel@tonic-gate }
11080Sstevel@tonic-gate cpu = (int)addr;
11090Sstevel@tonic-gate }
11100Sstevel@tonic-gate
11110Sstevel@tonic-gate if (cpu == -1)
11120Sstevel@tonic-gate mdb_printf("CPU ");
11130Sstevel@tonic-gate
11140Sstevel@tonic-gate if (opt_x) {
11150Sstevel@tonic-gate mdb_printf("%-16s %-16s %-3s %-3s %-4s %-4s %-3s %-3s %-?s "
1116*10610SJonathan.Adams@Sun.COM "F1-4\n", "%tick", "%tstate", "%hp", "%ty", "%tag",
1117*10610SJonathan.Adams@Sun.COM "%tt", "%tl", "%gl", "%tpc");
11180Sstevel@tonic-gate ttprint = (mdb_walk_cb_t)httprint_long;
11190Sstevel@tonic-gate } else {
11200Sstevel@tonic-gate mdb_printf("%-16s %-3s %-4s %-4s %-16s %-3s %-3s %s\n",
1121*10610SJonathan.Adams@Sun.COM "%tick", "%ty", "%tag", "%tt", "", "%tl", "%gl",
1122*10610SJonathan.Adams@Sun.COM "%tpc");
11230Sstevel@tonic-gate ttprint = (mdb_walk_cb_t)httprint_short;
11240Sstevel@tonic-gate }
11250Sstevel@tonic-gate
11260Sstevel@tonic-gate if (mdb_walk("httrace", ttprint, &cpu) == -1) {
11270Sstevel@tonic-gate mdb_warn("couldn't walk httrace");
11280Sstevel@tonic-gate return (DCMD_ERR);
11290Sstevel@tonic-gate }
11300Sstevel@tonic-gate
11310Sstevel@tonic-gate return (DCMD_OK);
11320Sstevel@tonic-gate }
11330Sstevel@tonic-gate #endif
11340Sstevel@tonic-gate
11350Sstevel@tonic-gate struct {
11360Sstevel@tonic-gate int xc_type;
11370Sstevel@tonic-gate const char *xc_str;
11380Sstevel@tonic-gate } xc_data[] = {
11390Sstevel@tonic-gate { XT_ONE_SELF, "xt-one-self" },
11400Sstevel@tonic-gate { XT_ONE_OTHER, "xt-one-other" },
11410Sstevel@tonic-gate { XT_SOME_SELF, "xt-some-self" },
11420Sstevel@tonic-gate { XT_SOME_OTHER, "xt-some-other" },
11430Sstevel@tonic-gate { XT_ALL_SELF, "xt-all-self" },
11440Sstevel@tonic-gate { XT_ALL_OTHER, "xt-all-other" },
11450Sstevel@tonic-gate { XC_ONE_SELF, "xc-one-self" },
11460Sstevel@tonic-gate { XC_ONE_OTHER, "xc-one-other" },
11470Sstevel@tonic-gate { XC_ONE_OTHER_H, "xc-one-other-h" },
11480Sstevel@tonic-gate { XC_SOME_SELF, "xc-some-self" },
11490Sstevel@tonic-gate { XC_SOME_OTHER, "xc-some-other" },
11500Sstevel@tonic-gate { XC_SOME_OTHER_H, "xc-some-other-h" },
11510Sstevel@tonic-gate { XC_ALL_SELF, "xc-all-self" },
11520Sstevel@tonic-gate { XC_ALL_OTHER, "xc-all-other" },
11530Sstevel@tonic-gate { XC_ALL_OTHER_H, "xc-all-other-h" },
11540Sstevel@tonic-gate { XC_ATTENTION, "xc-attention" },
11550Sstevel@tonic-gate { XC_DISMISSED, "xc-dismissed" },
11560Sstevel@tonic-gate { XC_LOOP_ENTER, "xc-loop-enter" },
11570Sstevel@tonic-gate { XC_LOOP_DOIT, "xc-loop-doit" },
11580Sstevel@tonic-gate { XC_LOOP_EXIT, "xc-loop-exit" },
11590Sstevel@tonic-gate { 0, NULL }
11600Sstevel@tonic-gate };
11610Sstevel@tonic-gate
11620Sstevel@tonic-gate /*ARGSUSED*/
11630Sstevel@tonic-gate int
xctrace_walk(uintptr_t addr,const trap_trace_fullrec_t * full,int * cpu)11640Sstevel@tonic-gate xctrace_walk(uintptr_t addr, const trap_trace_fullrec_t *full, int *cpu)
11650Sstevel@tonic-gate {
11660Sstevel@tonic-gate const struct trap_trace_record *ttp = &full->ttf_rec;
11670Sstevel@tonic-gate int i, type = ttp->tt_tt & 0xff;
11680Sstevel@tonic-gate const char *str = "???";
11690Sstevel@tonic-gate
11700Sstevel@tonic-gate if ((ttp->tt_tt & 0xff00) == TT_XCALL) {
11710Sstevel@tonic-gate for (i = 0; xc_data[i].xc_str != NULL; i++) {
11720Sstevel@tonic-gate if (xc_data[i].xc_type == type) {
11730Sstevel@tonic-gate str = xc_data[i].xc_str;
11740Sstevel@tonic-gate break;
11750Sstevel@tonic-gate }
11760Sstevel@tonic-gate }
11770Sstevel@tonic-gate } else if ((ttp->tt_tt & 0xff00) == TT_XCALL_CONT) {
11780Sstevel@tonic-gate str = "xcall-cont";
11790Sstevel@tonic-gate mdb_printf("%3d %016llx %-16s %08x %08x %08x %08x\n",
11800Sstevel@tonic-gate full->ttf_cpu, ttp->tt_tick, str, ttp->tt_f1, ttp->tt_f2,
11810Sstevel@tonic-gate ttp->tt_f3, ttp->tt_f4);
11820Sstevel@tonic-gate return (WALK_NEXT);
11830Sstevel@tonic-gate } else if (ttp->tt_tt == 0x60) {
11840Sstevel@tonic-gate str = "int-vec";
11850Sstevel@tonic-gate } else {
11860Sstevel@tonic-gate return (WALK_NEXT);
11870Sstevel@tonic-gate }
11880Sstevel@tonic-gate
11890Sstevel@tonic-gate mdb_printf("%3d %016llx %-16s %08x %a\n", full->ttf_cpu,
11900Sstevel@tonic-gate ttp->tt_tick, str, ttp->tt_sp, ttp->tt_tr);
11910Sstevel@tonic-gate
11920Sstevel@tonic-gate return (WALK_NEXT);
11930Sstevel@tonic-gate }
11940Sstevel@tonic-gate
11950Sstevel@tonic-gate /*ARGSUSED*/
11960Sstevel@tonic-gate int
xctrace(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)11970Sstevel@tonic-gate xctrace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
11980Sstevel@tonic-gate {
11990Sstevel@tonic-gate if ((flags & DCMD_ADDRSPEC) || argc != 0)
12000Sstevel@tonic-gate return (DCMD_USAGE);
12010Sstevel@tonic-gate
12020Sstevel@tonic-gate if (mdb_walk("ttrace", (mdb_walk_cb_t)xctrace_walk, NULL) == -1) {
12030Sstevel@tonic-gate mdb_warn("couldn't walk ttrace");
12040Sstevel@tonic-gate return (DCMD_ERR);
12050Sstevel@tonic-gate }
12060Sstevel@tonic-gate
12070Sstevel@tonic-gate return (DCMD_OK);
12080Sstevel@tonic-gate }
12090Sstevel@tonic-gate
12100Sstevel@tonic-gate /*
12110Sstevel@tonic-gate * Grrr... xc_mbox isn't in an _impl header file; we define it here.
12120Sstevel@tonic-gate */
12130Sstevel@tonic-gate typedef struct xc_mbox {
12140Sstevel@tonic-gate xcfunc_t *xc_func;
12150Sstevel@tonic-gate uint64_t xc_arg1;
12160Sstevel@tonic-gate uint64_t xc_arg2;
12170Sstevel@tonic-gate cpuset_t xc_cpuset;
12180Sstevel@tonic-gate volatile uint_t xc_state;
12190Sstevel@tonic-gate } xc_mbox_t;
12200Sstevel@tonic-gate
12210Sstevel@tonic-gate typedef struct xc_mbox_walk {
12220Sstevel@tonic-gate int xw_ndx;
12230Sstevel@tonic-gate uintptr_t xw_addr;
12240Sstevel@tonic-gate xc_mbox_t *xw_mbox;
12250Sstevel@tonic-gate } xc_mbox_walk_t;
12260Sstevel@tonic-gate
12270Sstevel@tonic-gate static int
xc_mbox_walk_init(mdb_walk_state_t * wsp)12280Sstevel@tonic-gate xc_mbox_walk_init(mdb_walk_state_t *wsp)
12290Sstevel@tonic-gate {
12300Sstevel@tonic-gate GElf_Sym sym;
12310Sstevel@tonic-gate xc_mbox_walk_t *xw;
12320Sstevel@tonic-gate
12330Sstevel@tonic-gate if (mdb_lookup_by_name("xc_mbox", &sym) == -1) {
12340Sstevel@tonic-gate mdb_warn("couldn't find 'xc_mbox'");
12350Sstevel@tonic-gate return (WALK_ERR);
12360Sstevel@tonic-gate }
12370Sstevel@tonic-gate
12380Sstevel@tonic-gate if (fetch_ncpu() || fetch_mbox())
12390Sstevel@tonic-gate return (WALK_ERR);
12400Sstevel@tonic-gate
12410Sstevel@tonic-gate xw = mdb_zalloc(sizeof (xc_mbox_walk_t), UM_SLEEP);
12420Sstevel@tonic-gate xw->xw_mbox = mdb_zalloc(mbox_size * ncpu, UM_SLEEP);
12430Sstevel@tonic-gate
12440Sstevel@tonic-gate if (mdb_readsym(xw->xw_mbox, mbox_size * ncpu, "xc_mbox") == -1) {
12450Sstevel@tonic-gate mdb_warn("couldn't read 'xc_mbox'");
12460Sstevel@tonic-gate mdb_free(xw->xw_mbox, mbox_size * ncpu);
12470Sstevel@tonic-gate mdb_free(xw, sizeof (xc_mbox_walk_t));
12480Sstevel@tonic-gate return (WALK_ERR);
12490Sstevel@tonic-gate }
12500Sstevel@tonic-gate
12510Sstevel@tonic-gate xw->xw_addr = sym.st_value;
12520Sstevel@tonic-gate wsp->walk_data = xw;
12530Sstevel@tonic-gate
12540Sstevel@tonic-gate return (WALK_NEXT);
12550Sstevel@tonic-gate }
12560Sstevel@tonic-gate
12570Sstevel@tonic-gate static int
xc_mbox_walk_step(mdb_walk_state_t * wsp)12580Sstevel@tonic-gate xc_mbox_walk_step(mdb_walk_state_t *wsp)
12590Sstevel@tonic-gate {
12600Sstevel@tonic-gate xc_mbox_walk_t *xw = wsp->walk_data;
12610Sstevel@tonic-gate int status;
12620Sstevel@tonic-gate
12630Sstevel@tonic-gate if (xw->xw_ndx == ncpu)
12640Sstevel@tonic-gate return (WALK_DONE);
12650Sstevel@tonic-gate
12660Sstevel@tonic-gate status = wsp->walk_callback(xw->xw_addr,
12670Sstevel@tonic-gate &xw->xw_mbox[xw->xw_ndx++], wsp->walk_cbdata);
12680Sstevel@tonic-gate
12690Sstevel@tonic-gate xw->xw_addr += mbox_size;
12700Sstevel@tonic-gate return (status);
12710Sstevel@tonic-gate }
12720Sstevel@tonic-gate
12730Sstevel@tonic-gate static void
xc_mbox_walk_fini(mdb_walk_state_t * wsp)12740Sstevel@tonic-gate xc_mbox_walk_fini(mdb_walk_state_t *wsp)
12750Sstevel@tonic-gate {
12760Sstevel@tonic-gate xc_mbox_walk_t *xw = wsp->walk_data;
12770Sstevel@tonic-gate
12780Sstevel@tonic-gate mdb_free(xw->xw_mbox, mbox_size * ncpu);
12790Sstevel@tonic-gate mdb_free(xw, sizeof (xc_mbox_walk_t));
12800Sstevel@tonic-gate }
12810Sstevel@tonic-gate
12820Sstevel@tonic-gate static int
xc_mbox(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)12830Sstevel@tonic-gate xc_mbox(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
12840Sstevel@tonic-gate {
12850Sstevel@tonic-gate xc_mbox_t *mbox;
12860Sstevel@tonic-gate GElf_Sym sym;
12870Sstevel@tonic-gate const char *state;
12880Sstevel@tonic-gate
12890Sstevel@tonic-gate if (argc != 0)
12900Sstevel@tonic-gate return (DCMD_USAGE);
12910Sstevel@tonic-gate
12920Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
12930Sstevel@tonic-gate if (mdb_walk_dcmd("xc_mbox", "xc_mbox", argc, argv) == -1) {
12940Sstevel@tonic-gate mdb_warn("can't walk 'xc_mbox'");
12950Sstevel@tonic-gate return (DCMD_ERR);
12960Sstevel@tonic-gate }
12970Sstevel@tonic-gate return (DCMD_OK);
12980Sstevel@tonic-gate }
12990Sstevel@tonic-gate
13000Sstevel@tonic-gate if (fetch_ncpu() || fetch_mbox())
13010Sstevel@tonic-gate return (DCMD_ERR);
13020Sstevel@tonic-gate
13030Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) {
13040Sstevel@tonic-gate mdb_printf("%3s %-8s %-8s %-9s %-16s %-16s %s\n",
13050Sstevel@tonic-gate "CPU", "ADDR", "STATE", "CPUSET", "ARG1", "ARG2", "HNDLR");
13060Sstevel@tonic-gate }
13070Sstevel@tonic-gate
13080Sstevel@tonic-gate mbox = mdb_alloc(mbox_size, UM_SLEEP | UM_GC);
13090Sstevel@tonic-gate if (mdb_vread(mbox, mbox_size, addr) == -1) {
13100Sstevel@tonic-gate mdb_warn("couldn't read xc_mbox at %p", addr);
13110Sstevel@tonic-gate return (DCMD_ERR);
13120Sstevel@tonic-gate }
13130Sstevel@tonic-gate
13140Sstevel@tonic-gate if (mbox->xc_func == NULL)
13150Sstevel@tonic-gate return (DCMD_OK);
13160Sstevel@tonic-gate
13170Sstevel@tonic-gate if (mdb_lookup_by_name("xc_mbox", &sym) == -1) {
13180Sstevel@tonic-gate mdb_warn("couldn't read 'xc_mbox'");
13190Sstevel@tonic-gate return (DCMD_ERR);
13200Sstevel@tonic-gate }
13210Sstevel@tonic-gate
13220Sstevel@tonic-gate state = mdb_ctf_enum_name(mbox_states,
13230Sstevel@tonic-gate /* LINTED - alignment */
13240Sstevel@tonic-gate *(int *)((char *)mbox + mbox_stoff));
13250Sstevel@tonic-gate
13260Sstevel@tonic-gate mdb_printf("%3d %08x %-8s [ ",
13270Sstevel@tonic-gate (int)((addr - sym.st_value) / mbox_size), addr,
13280Sstevel@tonic-gate state ? state : "XC_???");
13290Sstevel@tonic-gate
13301859Sha137994 print_cpuset_range((ulong_t *)&mbox->xc_cpuset, BT_BITOUL(ncpu), 5);
13310Sstevel@tonic-gate
13320Sstevel@tonic-gate mdb_printf(" ] %-16a %-16a %a\n",
13330Sstevel@tonic-gate mbox->xc_arg1, mbox->xc_arg2, mbox->xc_func);
13340Sstevel@tonic-gate
13350Sstevel@tonic-gate return (DCMD_OK);
13360Sstevel@tonic-gate }
13370Sstevel@tonic-gate
13382973Sgovinda typedef struct vecint_walk_data {
13392973Sgovinda intr_vec_t **vec_table;
13402973Sgovinda uintptr_t vec_base;
13412973Sgovinda size_t vec_idx;
13422973Sgovinda size_t vec_size;
13432973Sgovinda } vecint_walk_data_t;
13442973Sgovinda
13452973Sgovinda int
vecint_walk_init(mdb_walk_state_t * wsp)13462973Sgovinda vecint_walk_init(mdb_walk_state_t *wsp)
13472973Sgovinda {
13482973Sgovinda vecint_walk_data_t *vecint;
13492973Sgovinda
13502973Sgovinda if (wsp->walk_addr != NULL) {
13512973Sgovinda mdb_warn("vecint walk only supports global walks\n");
13522973Sgovinda return (WALK_ERR);
13532973Sgovinda }
13542973Sgovinda
13552973Sgovinda vecint = mdb_zalloc(sizeof (vecint_walk_data_t), UM_SLEEP);
13562973Sgovinda
13572973Sgovinda vecint->vec_size = MAXIVNUM * sizeof (intr_vec_t *);
13582973Sgovinda vecint->vec_base = (uintptr_t)iv_sym.st_value;
13592973Sgovinda vecint->vec_table = mdb_zalloc(vecint->vec_size, UM_SLEEP);
13602973Sgovinda
13612973Sgovinda if (mdb_vread(vecint->vec_table, vecint->vec_size,
13622973Sgovinda vecint->vec_base) == -1) {
13632973Sgovinda mdb_warn("couldn't read intr_vec_table");
13642973Sgovinda mdb_free(vecint->vec_table, vecint->vec_size);
13652973Sgovinda mdb_free(vecint, sizeof (vecint_walk_data_t));
13662973Sgovinda return (WALK_ERR);
13672973Sgovinda }
13682973Sgovinda
13692973Sgovinda wsp->walk_data = vecint;
13702973Sgovinda return (WALK_NEXT);
13712973Sgovinda }
13722973Sgovinda
13732973Sgovinda int
vecint_walk_step(mdb_walk_state_t * wsp)13742973Sgovinda vecint_walk_step(mdb_walk_state_t *wsp)
13752973Sgovinda {
13762973Sgovinda vecint_walk_data_t *vecint = (vecint_walk_data_t *)wsp->walk_data;
13772973Sgovinda size_t max = vecint->vec_size / sizeof (intr_vec_t *);
13782973Sgovinda intr_vec_t iv;
13792973Sgovinda int status;
13802973Sgovinda
13812973Sgovinda if (wsp->walk_addr == NULL) {
13822973Sgovinda while ((vecint->vec_idx < max) && ((wsp->walk_addr =
13832973Sgovinda (uintptr_t)vecint->vec_table[vecint->vec_idx++]) == NULL))
13842973Sgovinda continue;
13852973Sgovinda }
13862973Sgovinda
13872973Sgovinda if (wsp->walk_addr == NULL)
13882973Sgovinda return (WALK_DONE);
13892973Sgovinda
13902973Sgovinda status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
13912973Sgovinda wsp->walk_cbdata);
13922973Sgovinda
13932973Sgovinda if (mdb_vread(&iv, sizeof (intr_vec_t),
13942973Sgovinda (uintptr_t)wsp->walk_addr) == -1) {
13952973Sgovinda mdb_warn("failed to read iv_p %p\n", wsp->walk_addr);
13962973Sgovinda return (WALK_ERR);
13972973Sgovinda }
13982973Sgovinda
13992973Sgovinda wsp->walk_addr = (uintptr_t)iv.iv_vec_next;
14002973Sgovinda return (status);
14012973Sgovinda }
14022973Sgovinda
14032973Sgovinda void
vecint_walk_fini(mdb_walk_state_t * wsp)14042973Sgovinda vecint_walk_fini(mdb_walk_state_t *wsp)
14052973Sgovinda {
14062973Sgovinda vecint_walk_data_t *vecint = wsp->walk_data;
14072973Sgovinda
14082973Sgovinda mdb_free(vecint->vec_table, vecint->vec_size);
14092973Sgovinda mdb_free(vecint, sizeof (vecint_walk_data_t));
14102973Sgovinda }
14112973Sgovinda
14122973Sgovinda int
vecint_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)14132973Sgovinda vecint_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
14142973Sgovinda {
14152973Sgovinda intr_vec_t iv;
14162973Sgovinda
14172973Sgovinda if (!(flags & DCMD_ADDRSPEC)) {
14182973Sgovinda if (mdb_walk_dcmd("vecint", "vecint", argc, argv) == -1) {
14192973Sgovinda mdb_warn("can't walk vecint");
14202973Sgovinda return (DCMD_ERR);
14212973Sgovinda }
14222973Sgovinda return (DCMD_OK);
14232973Sgovinda }
14242973Sgovinda
14252973Sgovinda if (DCMD_HDRSPEC(flags)) {
14262973Sgovinda mdb_printf("%4s %?s %4s %?s %?s %s\n", "INUM", "ADDR",
14272973Sgovinda "PIL", "ARG1", "ARG2", "HANDLER");
14282973Sgovinda }
14292973Sgovinda
14302973Sgovinda if (mdb_vread(&iv, sizeof (iv), addr) == -1) {
14312973Sgovinda mdb_warn("couldn't read intr_vec_table at %p", addr);
14322973Sgovinda return (DCMD_ERR);
14332973Sgovinda }
14342973Sgovinda
14352973Sgovinda mdb_printf("%4x %?p %4d %?p %?p %a\n", iv.iv_inum, addr,
14362973Sgovinda iv.iv_pil, iv.iv_arg1, iv.iv_arg2, iv.iv_handler);
14372973Sgovinda
14382973Sgovinda return (DCMD_OK);
14392973Sgovinda }
14400Sstevel@tonic-gate
14410Sstevel@tonic-gate int
softint_walk_init(mdb_walk_state_t * wsp)14420Sstevel@tonic-gate softint_walk_init(mdb_walk_state_t *wsp)
14430Sstevel@tonic-gate {
14442973Sgovinda intr_vec_t *list;
14450Sstevel@tonic-gate
14460Sstevel@tonic-gate if (wsp->walk_addr != NULL) {
14470Sstevel@tonic-gate mdb_warn("softint walk only supports global walks\n");
14480Sstevel@tonic-gate return (WALK_ERR);
14490Sstevel@tonic-gate }
14500Sstevel@tonic-gate
14512973Sgovinda /* Read global softint linked list pointer */
14522973Sgovinda if (mdb_readvar(&list, "softint_list") == -1) {
14532973Sgovinda mdb_warn("failed to read the global softint_list pointer\n");
14540Sstevel@tonic-gate return (WALK_ERR);
14550Sstevel@tonic-gate }
14560Sstevel@tonic-gate
14572973Sgovinda wsp->walk_addr = (uintptr_t)list;
14580Sstevel@tonic-gate return (WALK_NEXT);
14590Sstevel@tonic-gate }
14600Sstevel@tonic-gate
14612973Sgovinda /*ARGSUSED*/
14622973Sgovinda void
softint_walk_fini(mdb_walk_state_t * wsp)14632973Sgovinda softint_walk_fini(mdb_walk_state_t *wsp)
14642973Sgovinda {
14652973Sgovinda /* Nothing to do here */
14662973Sgovinda }
14672973Sgovinda
14680Sstevel@tonic-gate int
softint_walk_step(mdb_walk_state_t * wsp)14690Sstevel@tonic-gate softint_walk_step(mdb_walk_state_t *wsp)
14700Sstevel@tonic-gate {
14712973Sgovinda intr_vec_t iv;
14722973Sgovinda int status;
14730Sstevel@tonic-gate
14742973Sgovinda if (wsp->walk_addr == NULL)
14752973Sgovinda return (WALK_DONE);
14760Sstevel@tonic-gate
14772973Sgovinda status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
14782973Sgovinda wsp->walk_cbdata);
14790Sstevel@tonic-gate
14802973Sgovinda if (mdb_vread(&iv, sizeof (intr_vec_t),
14812973Sgovinda (uintptr_t)wsp->walk_addr) == -1) {
14822973Sgovinda mdb_warn("failed to read iv_p %p\n", wsp->walk_addr);
14832973Sgovinda return (WALK_ERR);
14840Sstevel@tonic-gate }
14850Sstevel@tonic-gate
14862973Sgovinda wsp->walk_addr = (uintptr_t)iv.iv_vec_next;
14872973Sgovinda return (status);
14880Sstevel@tonic-gate }
14890Sstevel@tonic-gate
14900Sstevel@tonic-gate int
softint_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)14910Sstevel@tonic-gate softint_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
14920Sstevel@tonic-gate {
14932973Sgovinda intr_vec_t iv;
14940Sstevel@tonic-gate
14950Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
14960Sstevel@tonic-gate if (mdb_walk_dcmd("softint", "softint", argc, argv) == -1) {
14970Sstevel@tonic-gate mdb_warn("can't walk softint");
14980Sstevel@tonic-gate return (DCMD_ERR);
14990Sstevel@tonic-gate }
15000Sstevel@tonic-gate return (DCMD_OK);
15010Sstevel@tonic-gate }
15020Sstevel@tonic-gate
15030Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) {
15042973Sgovinda mdb_printf("%?s %4s %4s %4s %?s %?s %s\n", "ADDR", "TYPE",
15052973Sgovinda "PEND", "PIL", "ARG1", "ARG2", "HANDLER");
15060Sstevel@tonic-gate }
15070Sstevel@tonic-gate
15080Sstevel@tonic-gate if (mdb_vread(&iv, sizeof (iv), addr) == -1) {
15092973Sgovinda mdb_warn("couldn't read softint at %p", addr);
15100Sstevel@tonic-gate return (DCMD_ERR);
15110Sstevel@tonic-gate }
15120Sstevel@tonic-gate
15132973Sgovinda mdb_printf("%?p %4s %4d %4d %?p %?p %a\n", addr,
15142973Sgovinda (iv.iv_flags & IV_SOFTINT_MT) ? "M" : "S",
15152973Sgovinda iv.iv_flags & IV_SOFTINT_PEND, iv.iv_pil,
15162973Sgovinda iv.iv_arg1, iv.iv_arg2, iv.iv_handler);
15170Sstevel@tonic-gate
15180Sstevel@tonic-gate return (DCMD_OK);
15190Sstevel@tonic-gate }
15200Sstevel@tonic-gate
15210Sstevel@tonic-gate static int
whatis_walk_tt(uintptr_t taddr,const trap_trace_fullrec_t * ttf,mdb_whatis_t * w)1522*10610SJonathan.Adams@Sun.COM whatis_walk_tt(uintptr_t taddr, const trap_trace_fullrec_t *ttf,
1523*10610SJonathan.Adams@Sun.COM mdb_whatis_t *w)
15240Sstevel@tonic-gate {
1525*10610SJonathan.Adams@Sun.COM uintptr_t cur = 0;
15260Sstevel@tonic-gate
1527*10610SJonathan.Adams@Sun.COM while (mdb_whatis_match(w, taddr, sizeof (struct trap_trace_record),
1528*10610SJonathan.Adams@Sun.COM &cur))
1529*10610SJonathan.Adams@Sun.COM mdb_whatis_report_object(w, cur, taddr,
1530*10610SJonathan.Adams@Sun.COM "trap trace record for cpu %d\n", ttf->ttf_cpu);
15310Sstevel@tonic-gate
1532*10610SJonathan.Adams@Sun.COM return (WHATIS_WALKRET(w));
15330Sstevel@tonic-gate }
15340Sstevel@tonic-gate
15350Sstevel@tonic-gate /*ARGSUSED*/
1536*10610SJonathan.Adams@Sun.COM static int
whatis_run_traptrace(mdb_whatis_t * w,void * ignored)1537*10610SJonathan.Adams@Sun.COM whatis_run_traptrace(mdb_whatis_t *w, void *ignored)
15380Sstevel@tonic-gate {
15390Sstevel@tonic-gate GElf_Sym sym;
15400Sstevel@tonic-gate
1541*10610SJonathan.Adams@Sun.COM if (mdb_lookup_by_name("trap_trace_ctl", &sym) == -1)
1542*10610SJonathan.Adams@Sun.COM return (0);
15430Sstevel@tonic-gate
1544*10610SJonathan.Adams@Sun.COM if (mdb_walk("ttrace", (mdb_walk_cb_t)whatis_walk_tt, w) == -1)
15450Sstevel@tonic-gate mdb_warn("failed to walk 'ttrace'");
15460Sstevel@tonic-gate
1547*10610SJonathan.Adams@Sun.COM return (0);
15480Sstevel@tonic-gate }
15490Sstevel@tonic-gate
15500Sstevel@tonic-gate /*ARGSUSED*/
15510Sstevel@tonic-gate int
mutex_owner_init(mdb_walk_state_t * wsp)15520Sstevel@tonic-gate mutex_owner_init(mdb_walk_state_t *wsp)
15530Sstevel@tonic-gate {
15540Sstevel@tonic-gate return (WALK_NEXT);
15550Sstevel@tonic-gate }
15560Sstevel@tonic-gate
15570Sstevel@tonic-gate int
mutex_owner_step(mdb_walk_state_t * wsp)15580Sstevel@tonic-gate mutex_owner_step(mdb_walk_state_t *wsp)
15590Sstevel@tonic-gate {
15600Sstevel@tonic-gate uintptr_t addr = wsp->walk_addr;
15610Sstevel@tonic-gate mutex_impl_t mtx;
15620Sstevel@tonic-gate uintptr_t owner;
15630Sstevel@tonic-gate kthread_t thr;
15640Sstevel@tonic-gate
15650Sstevel@tonic-gate if (mdb_vread(&mtx, sizeof (mtx), addr) == -1)
15660Sstevel@tonic-gate return (WALK_ERR);
15670Sstevel@tonic-gate
15680Sstevel@tonic-gate if (!MUTEX_TYPE_ADAPTIVE(&mtx))
15690Sstevel@tonic-gate return (WALK_DONE);
15700Sstevel@tonic-gate
15710Sstevel@tonic-gate if ((owner = (uintptr_t)MUTEX_OWNER(&mtx)) == NULL)
15720Sstevel@tonic-gate return (WALK_DONE);
15730Sstevel@tonic-gate
15740Sstevel@tonic-gate if (mdb_vread(&thr, sizeof (thr), owner) != -1)
15750Sstevel@tonic-gate (void) wsp->walk_callback(owner, &thr, wsp->walk_cbdata);
15760Sstevel@tonic-gate
15770Sstevel@tonic-gate return (WALK_DONE);
15780Sstevel@tonic-gate }
15790Sstevel@tonic-gate
15800Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = {
15810Sstevel@tonic-gate { "cpuset", ":[-l|-r]", "dump a cpuset_t", cmd_cpuset },
15820Sstevel@tonic-gate { "ttctl", NULL, "dump trap trace ctl records", ttctl },
15830Sstevel@tonic-gate { "ttrace", "[-x]", "dump trap trace buffer for a cpu", ttrace },
15840Sstevel@tonic-gate #ifdef sun4v
15850Sstevel@tonic-gate { "httctl", NULL, "dump hv trap trace ctl records", httctl },
15860Sstevel@tonic-gate { "httrace", "[-x]", "dump hv trap trace buffer for a cpu", httrace },
15870Sstevel@tonic-gate #endif
15880Sstevel@tonic-gate { "xc_mbox", "?", "dump xcall mboxes", xc_mbox },
15890Sstevel@tonic-gate { "xctrace", NULL, "dump xcall trace buffer", xctrace },
15902973Sgovinda { "vecint", NULL, "display a registered hardware interrupt",
15912973Sgovinda vecint_dcmd },
15922973Sgovinda { "softint", NULL, "display a registered software interrupt",
15932973Sgovinda softint_dcmd },
15940Sstevel@tonic-gate { "sfmmu_vtop", ":[[-v] -a as]", "print virtual to physical mapping",
15950Sstevel@tonic-gate sfmmu_vtop },
15960Sstevel@tonic-gate { "memseg_list", ":", "show memseg list", memseg_list },
15970Sstevel@tonic-gate { "tsbinfo", ":[-l [-a]]", "show tsbinfo", tsbinfo_list,
15980Sstevel@tonic-gate tsbinfo_help },
15990Sstevel@tonic-gate { NULL }
16000Sstevel@tonic-gate };
16010Sstevel@tonic-gate
16020Sstevel@tonic-gate static const mdb_walker_t walkers[] = {
16030Sstevel@tonic-gate { "mutex_owner", "walks the owner of a mutex",
16040Sstevel@tonic-gate mutex_owner_init, mutex_owner_step },
16050Sstevel@tonic-gate { "ttrace", "walks the trap trace buffer for a CPU",
16060Sstevel@tonic-gate ttrace_walk_init, ttrace_walk_step, ttrace_walk_fini },
16070Sstevel@tonic-gate #ifdef sun4v
16080Sstevel@tonic-gate { "httrace", "walks the hv trap trace buffer for a CPU",
16090Sstevel@tonic-gate httrace_walk_init, httrace_walk_step, httrace_walk_fini },
16100Sstevel@tonic-gate #endif
16110Sstevel@tonic-gate { "xc_mbox", "walks the cross call mail boxes",
16120Sstevel@tonic-gate xc_mbox_walk_init, xc_mbox_walk_step, xc_mbox_walk_fini },
16132973Sgovinda { "vecint", "walk the list of registered hardware interrupts",
16142973Sgovinda vecint_walk_init, vecint_walk_step, vecint_walk_fini },
16152973Sgovinda { "softint", "walk the list of registered software interrupts",
16160Sstevel@tonic-gate softint_walk_init, softint_walk_step, softint_walk_fini },
16170Sstevel@tonic-gate { "memseg", "walk the memseg structures",
16180Sstevel@tonic-gate memseg_walk_init, memseg_walk_step, memseg_walk_fini },
16190Sstevel@tonic-gate { NULL }
16200Sstevel@tonic-gate };
16210Sstevel@tonic-gate
16220Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
16230Sstevel@tonic-gate
16240Sstevel@tonic-gate const mdb_modinfo_t *
_mdb_init(void)16250Sstevel@tonic-gate _mdb_init(void)
16260Sstevel@tonic-gate {
16272973Sgovinda if (mdb_lookup_by_name("intr_vec_table", &iv_sym) == -1) {
16282973Sgovinda mdb_warn("couldn't find intr_vec_table");
16290Sstevel@tonic-gate return (NULL);
16300Sstevel@tonic-gate }
16310Sstevel@tonic-gate
1632*10610SJonathan.Adams@Sun.COM mdb_whatis_register("traptrace", whatis_run_traptrace, NULL,
1633*10610SJonathan.Adams@Sun.COM WHATIS_PRIO_EARLY, WHATIS_REG_NO_ID);
1634*10610SJonathan.Adams@Sun.COM
16350Sstevel@tonic-gate return (&modinfo);
16360Sstevel@tonic-gate }
1637