xref: /onnv-gate/usr/src/cmd/mdb/sun4u/modules/unix/unix.c (revision 11459:976cd2e02041)
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