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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 14632973Sgovinda softint_walk_fini(mdb_walk_state_t *wsp) 14642973Sgovinda { 14652973Sgovinda /* Nothing to do here */ 14662973Sgovinda } 14672973Sgovinda 14680Sstevel@tonic-gate int 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 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 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 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 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 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 { "page_num2pp", ":", "page frame number to page structure", 15970Sstevel@tonic-gate page_num2pp }, 15980Sstevel@tonic-gate { "memseg_list", ":", "show memseg list", memseg_list }, 15990Sstevel@tonic-gate { "tsbinfo", ":[-l [-a]]", "show tsbinfo", tsbinfo_list, 16000Sstevel@tonic-gate tsbinfo_help }, 16010Sstevel@tonic-gate { NULL } 16020Sstevel@tonic-gate }; 16030Sstevel@tonic-gate 16040Sstevel@tonic-gate static const mdb_walker_t walkers[] = { 16050Sstevel@tonic-gate { "mutex_owner", "walks the owner of a mutex", 16060Sstevel@tonic-gate mutex_owner_init, mutex_owner_step }, 16070Sstevel@tonic-gate { "ttrace", "walks the trap trace buffer for a CPU", 16080Sstevel@tonic-gate ttrace_walk_init, ttrace_walk_step, ttrace_walk_fini }, 16090Sstevel@tonic-gate #ifdef sun4v 16100Sstevel@tonic-gate { "httrace", "walks the hv trap trace buffer for a CPU", 16110Sstevel@tonic-gate httrace_walk_init, httrace_walk_step, httrace_walk_fini }, 16120Sstevel@tonic-gate #endif 16130Sstevel@tonic-gate { "xc_mbox", "walks the cross call mail boxes", 16140Sstevel@tonic-gate xc_mbox_walk_init, xc_mbox_walk_step, xc_mbox_walk_fini }, 16152973Sgovinda { "vecint", "walk the list of registered hardware interrupts", 16162973Sgovinda vecint_walk_init, vecint_walk_step, vecint_walk_fini }, 16172973Sgovinda { "softint", "walk the list of registered software interrupts", 16180Sstevel@tonic-gate softint_walk_init, softint_walk_step, softint_walk_fini }, 16190Sstevel@tonic-gate { "memseg", "walk the memseg structures", 16200Sstevel@tonic-gate memseg_walk_init, memseg_walk_step, memseg_walk_fini }, 16210Sstevel@tonic-gate { NULL } 16220Sstevel@tonic-gate }; 16230Sstevel@tonic-gate 16240Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers }; 16250Sstevel@tonic-gate 16260Sstevel@tonic-gate const mdb_modinfo_t * 16270Sstevel@tonic-gate _mdb_init(void) 16280Sstevel@tonic-gate { 16292973Sgovinda if (mdb_lookup_by_name("intr_vec_table", &iv_sym) == -1) { 16302973Sgovinda mdb_warn("couldn't find intr_vec_table"); 16310Sstevel@tonic-gate return (NULL); 16320Sstevel@tonic-gate } 16330Sstevel@tonic-gate 1634*10610SJonathan.Adams@Sun.COM mdb_whatis_register("traptrace", whatis_run_traptrace, NULL, 1635*10610SJonathan.Adams@Sun.COM WHATIS_PRIO_EARLY, WHATIS_REG_NO_ID); 1636*10610SJonathan.Adams@Sun.COM 16370Sstevel@tonic-gate return (&modinfo); 16380Sstevel@tonic-gate } 1639