xref: /titanic_51/usr/src/cmd/mdb/sun4u/modules/unix/unix.c (revision cbdcbd056f15c9c9fd82d5543b3a502677c4d391)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50400e0b7Sha137994  * Common Development and Distribution License (the "License").
60400e0b7Sha137994  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*4a1c2431SJonathan Adams  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <sys/types.h>
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #ifndef DEBUG
297c478bd9Sstevel@tonic-gate #define	DEBUG
307c478bd9Sstevel@tonic-gate #define	_SYS_DEBUG_H
317c478bd9Sstevel@tonic-gate #include <sys/xc_impl.h>
327c478bd9Sstevel@tonic-gate #undef	DEBUG
337c478bd9Sstevel@tonic-gate #else
347c478bd9Sstevel@tonic-gate #define	_SYS_DEBUG_H
357c478bd9Sstevel@tonic-gate #include <sys/xc_impl.h>
367c478bd9Sstevel@tonic-gate #endif
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #include <sys/traptrace.h>
397c478bd9Sstevel@tonic-gate #include <sys/machparam.h>
40b0fc0e77Sgovinda #include <sys/intreg.h>
417c478bd9Sstevel@tonic-gate #include <sys/ivintr.h>
427c478bd9Sstevel@tonic-gate #include <sys/mutex_impl.h>
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
457c478bd9Sstevel@tonic-gate #include <mdb/mdb_ctf.h>
46*4a1c2431SJonathan Adams #include <mdb/mdb_whatis.h>
477c478bd9Sstevel@tonic-gate #include "sfmmu.h"
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate #ifndef SYSTRAP_TT
507c478bd9Sstevel@tonic-gate #define	SYSTRAP_TT	0x1300
517c478bd9Sstevel@tonic-gate #endif
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate typedef struct trap_trace_fullrec {
547c478bd9Sstevel@tonic-gate 	struct trap_trace_record ttf_rec;
557c478bd9Sstevel@tonic-gate 	int ttf_cpu;
567c478bd9Sstevel@tonic-gate } trap_trace_fullrec_t;
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate #ifdef sun4v
597c478bd9Sstevel@tonic-gate typedef struct htrap_trace_fullrec {
607c478bd9Sstevel@tonic-gate 	struct htrap_trace_record ttf_rec;
617c478bd9Sstevel@tonic-gate 	int ttf_cpu;
627c478bd9Sstevel@tonic-gate } htrap_trace_fullrec_t;
637c478bd9Sstevel@tonic-gate #endif
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate /*
667c478bd9Sstevel@tonic-gate  * These strings and accompanying macros allow our string table to look
677c478bd9Sstevel@tonic-gate  * just like the real table in trap_table.s.
687c478bd9Sstevel@tonic-gate  */
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate static const char NOT[] = "reserved";	/* common reserved string */
717c478bd9Sstevel@tonic-gate static const char BAD[] = "unused";	/* common unused string */
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate #define	NOT4	NOT, NOT, NOT, NOT
747c478bd9Sstevel@tonic-gate #define	BAD4	BAD, BAD, BAD, BAD
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate static const char *const ttdescr[] = {
777c478bd9Sstevel@tonic-gate 	NOT,				/* 000	reserved */
787c478bd9Sstevel@tonic-gate 	"power-on",			/* 001	power on reset */
797c478bd9Sstevel@tonic-gate 	"watchdog",			/* 002	watchdog reset */
807c478bd9Sstevel@tonic-gate 	"xir",				/* 003	externally initiated reset */
817c478bd9Sstevel@tonic-gate 	"sir",				/* 004	software initiated reset */
827c478bd9Sstevel@tonic-gate 	"red",				/* 005	red mode exception */
837c478bd9Sstevel@tonic-gate 	NOT, NOT,			/* 006 - 007 reserved */
847c478bd9Sstevel@tonic-gate 	"immu-xcp",			/* 008	instruction access exception */
857c478bd9Sstevel@tonic-gate 	"immu-miss",			/* 009	instruction access MMU miss */
867c478bd9Sstevel@tonic-gate 	"immu-err",			/* 00A	instruction access error */
877c478bd9Sstevel@tonic-gate 	NOT, NOT4,			/* 00B - 00F reserved */
887c478bd9Sstevel@tonic-gate 	"ill-inst",			/* 010	illegal instruction */
897c478bd9Sstevel@tonic-gate 	"priv-inst",			/* 011	privileged opcode */
907c478bd9Sstevel@tonic-gate 	"unimp-ldd",			/* 012	unimplemented LDD */
917c478bd9Sstevel@tonic-gate 	"unimp-std",			/* 013	unimplemented STD */
927c478bd9Sstevel@tonic-gate 	NOT4, NOT4, NOT4,		/* 014 - 01F reserved */
937c478bd9Sstevel@tonic-gate 	"fp-disable",			/* 020	fp disabled */
947c478bd9Sstevel@tonic-gate 	"fp-ieee754",			/* 021	fp exception ieee 754 */
957c478bd9Sstevel@tonic-gate 	"fp-xcp-other",			/* 022	fp exception other */
967c478bd9Sstevel@tonic-gate 	"tag-oflow",			/* 023	tag overflow */
977c478bd9Sstevel@tonic-gate 	"cleanwin",			/* 024	clean window */
987c478bd9Sstevel@tonic-gate 	"cleanwin",			/* 025	clean window */
997c478bd9Sstevel@tonic-gate 	"cleanwin",			/* 026	clean window */
1007c478bd9Sstevel@tonic-gate 	"cleanwin",			/* 027	clean window */
1017c478bd9Sstevel@tonic-gate 	"div-zero",			/* 028	division by zero */
1027c478bd9Sstevel@tonic-gate 	"internal-err",			/* 029	internal processor error */
1037c478bd9Sstevel@tonic-gate 	NOT, NOT, NOT4,			/* 02A - 02F reserved */
1047c478bd9Sstevel@tonic-gate 	"dmmu-xcp",			/* 030	data access exception */
1057c478bd9Sstevel@tonic-gate 	"dmmu-miss",			/* 031	data access MMU miss */
1067c478bd9Sstevel@tonic-gate 	"dmmu-err",			/* 032	data access error */
1077c478bd9Sstevel@tonic-gate 	"dmmu-prot",			/* 033	data access protection */
1087c478bd9Sstevel@tonic-gate 	"unalign",			/* 034	mem address not aligned */
1097c478bd9Sstevel@tonic-gate 	"lddf-unalign",			/* 035	LDDF mem address not aligned */
1107c478bd9Sstevel@tonic-gate 	"stdf-unalign",			/* 036	STDF mem address not aligned */
1117c478bd9Sstevel@tonic-gate 	"priv-act",			/* 037	privileged action */
1127c478bd9Sstevel@tonic-gate 	"ldqf-unalign",			/* 038	LDQF mem address not aligned */
1137c478bd9Sstevel@tonic-gate 	"stqf-unalign",			/* 039	STQF mem address not aligned */
1147c478bd9Sstevel@tonic-gate 	NOT, NOT, NOT4,			/* 03A - 03F reserved */
1157c478bd9Sstevel@tonic-gate 	"async-d-err",			/* 040	async data error */
1167c478bd9Sstevel@tonic-gate 	"level-1",			/* 041	interrupt level 1 */
1177c478bd9Sstevel@tonic-gate 	"level-2",			/* 042	interrupt level 2 */
1187c478bd9Sstevel@tonic-gate 	"level-3",			/* 043	interrupt level 3 */
1197c478bd9Sstevel@tonic-gate 	"level-4",			/* 044	interrupt level 4 */
1207c478bd9Sstevel@tonic-gate 	"level-5",			/* 045	interrupt level 5 */
1217c478bd9Sstevel@tonic-gate 	"level-6",			/* 046	interrupt level 6 */
1227c478bd9Sstevel@tonic-gate 	"level-7",			/* 047	interrupt level 7 */
1237c478bd9Sstevel@tonic-gate 	"level-8",			/* 048	interrupt level 8 */
1247c478bd9Sstevel@tonic-gate 	"level-9",			/* 049	interrupt level 9 */
1257c478bd9Sstevel@tonic-gate 	"level-10",			/* 04A	interrupt level 10 */
1267c478bd9Sstevel@tonic-gate 	"level-11",			/* 04B	interrupt level 11 */
1277c478bd9Sstevel@tonic-gate 	"level-12",			/* 04C	interrupt level 12 */
1287c478bd9Sstevel@tonic-gate 	"level-13",			/* 04D	interrupt level 13 */
1297c478bd9Sstevel@tonic-gate 	"level-14",			/* 04E	interrupt level 14 */
1307c478bd9Sstevel@tonic-gate 	"level-15",			/* 04F	interrupt level 15 */
1317c478bd9Sstevel@tonic-gate 	NOT4, NOT4, NOT4, NOT4,		/* 050 - 05F reserved */
1327c478bd9Sstevel@tonic-gate 	"int-vec",			/* 060	interrupt vector */
1337c478bd9Sstevel@tonic-gate 	"pa-watch",			/* 061	PA watchpoint */
1347c478bd9Sstevel@tonic-gate 	"va-watch",			/* 062	VA watchpoint */
1357c478bd9Sstevel@tonic-gate 	"ecc-err",			/* 063	corrected ECC error */
1367c478bd9Sstevel@tonic-gate 	"itlb-miss",			/* 064	instruction access MMU miss */
1377c478bd9Sstevel@tonic-gate 	"itlb-miss",			/* 065	instruction access MMU miss */
1387c478bd9Sstevel@tonic-gate 	"itlb-miss",			/* 066	instruction access MMU miss */
1397c478bd9Sstevel@tonic-gate 	"itlb-miss",			/* 067	instruction access MMU miss */
1407c478bd9Sstevel@tonic-gate 	"dtlb-miss",			/* 068	data access MMU miss */
1417c478bd9Sstevel@tonic-gate 	"dtlb-miss",			/* 069	data access MMU miss */
1427c478bd9Sstevel@tonic-gate 	"dtlb-miss",			/* 06A	data access MMU miss */
1437c478bd9Sstevel@tonic-gate 	"dtlb-miss",			/* 06B	data access MMU miss */
1447c478bd9Sstevel@tonic-gate 	"dtlb-prot",			/* 06C	data access protection */
1457c478bd9Sstevel@tonic-gate 	"dtlb-prot",			/* 06D	data access protection */
1467c478bd9Sstevel@tonic-gate 	"dtlb-prot",			/* 06E	data access protection */
1477c478bd9Sstevel@tonic-gate 	"dtlb-prot",			/* 06F	data access protection */
1487c478bd9Sstevel@tonic-gate 	"fast-ecc-err",			/* 070	fast ecache ECC error */
1497c478bd9Sstevel@tonic-gate 	"dp-err",			/* 071	data cache parity error */
1507c478bd9Sstevel@tonic-gate 	"ip-err",			/* 072	instr cache parity error */
1517c478bd9Sstevel@tonic-gate 	NOT, NOT4, NOT4,		/* 073 - 07B reserved */
1527c478bd9Sstevel@tonic-gate #ifdef sun4v
1537c478bd9Sstevel@tonic-gate 	"cpu-mondo",			/* 07C  CPU mondo */
1547c478bd9Sstevel@tonic-gate 	"dev-mondo",			/* 07D  device mondo */
1557c478bd9Sstevel@tonic-gate 	"res.-err",			/* 07E  resumable error */
1567c478bd9Sstevel@tonic-gate 	"non-res.-err",			/* 07F  non-resumable error */
1577c478bd9Sstevel@tonic-gate #else
1587c478bd9Sstevel@tonic-gate 	NOT4,				/* 07C - 07F reserved */
1597c478bd9Sstevel@tonic-gate #endif
1607c478bd9Sstevel@tonic-gate 	"spill-0-norm",			/* 080	spill 0 normal */
1617c478bd9Sstevel@tonic-gate 	"spill-0-norm",			/* 081	spill 0 normal */
1627c478bd9Sstevel@tonic-gate 	"spill-0-norm",			/* 082	spill 0 normal */
1637c478bd9Sstevel@tonic-gate 	"spill-0-norm",			/* 083	spill 0 normal */
1647c478bd9Sstevel@tonic-gate 	"spill-1-norm",			/* 084	spill 1 normal */
1657c478bd9Sstevel@tonic-gate 	"spill-1-norm",			/* 085	spill 1 normal */
1667c478bd9Sstevel@tonic-gate 	"spill-1-norm",			/* 086	spill 1 normal */
1677c478bd9Sstevel@tonic-gate 	"spill-1-norm",			/* 087	spill 1 normal */
1687c478bd9Sstevel@tonic-gate 	"spill-2-norm",			/* 088	spill 2 normal */
1697c478bd9Sstevel@tonic-gate 	"spill-2-norm",			/* 089	spill 2 normal */
1707c478bd9Sstevel@tonic-gate 	"spill-2-norm",			/* 08A	spill 2 normal */
1717c478bd9Sstevel@tonic-gate 	"spill-2-norm",			/* 08B	spill 2 normal */
1727c478bd9Sstevel@tonic-gate 	"spill-3-norm",			/* 08C	spill 3 normal */
1737c478bd9Sstevel@tonic-gate 	"spill-3-norm",			/* 08D	spill 3 normal */
1747c478bd9Sstevel@tonic-gate 	"spill-3-norm",			/* 08E	spill 3 normal */
1757c478bd9Sstevel@tonic-gate 	"spill-3-norm",			/* 08F	spill 3 normal */
1767c478bd9Sstevel@tonic-gate 	"spill-4-norm",			/* 090	spill 4 normal */
1777c478bd9Sstevel@tonic-gate 	"spill-4-norm",			/* 091	spill 4 normal */
1787c478bd9Sstevel@tonic-gate 	"spill-4-norm",			/* 092	spill 4 normal */
1797c478bd9Sstevel@tonic-gate 	"spill-4-norm",			/* 093	spill 4 normal */
1807c478bd9Sstevel@tonic-gate 	"spill-5-norm",			/* 094	spill 5 normal */
1817c478bd9Sstevel@tonic-gate 	"spill-5-norm",			/* 095	spill 5 normal */
1827c478bd9Sstevel@tonic-gate 	"spill-5-norm",			/* 096	spill 5 normal */
1837c478bd9Sstevel@tonic-gate 	"spill-5-norm",			/* 097	spill 5 normal */
1847c478bd9Sstevel@tonic-gate 	"spill-6-norm",			/* 098	spill 6 normal */
1857c478bd9Sstevel@tonic-gate 	"spill-6-norm",			/* 099	spill 6 normal */
1867c478bd9Sstevel@tonic-gate 	"spill-6-norm",			/* 09A	spill 6 normal */
1877c478bd9Sstevel@tonic-gate 	"spill-6-norm",			/* 09B	spill 6 normal */
1887c478bd9Sstevel@tonic-gate 	"spill-7-norm",			/* 09C	spill 7 normal */
1897c478bd9Sstevel@tonic-gate 	"spill-7-norm",			/* 09D	spill 7 normal */
1907c478bd9Sstevel@tonic-gate 	"spill-7-norm",			/* 09E	spill 7 normal */
1917c478bd9Sstevel@tonic-gate 	"spill-7-norm",			/* 09F	spill 7 normal */
1927c478bd9Sstevel@tonic-gate 	"spill-0-oth",			/* 0A0	spill 0 other */
1937c478bd9Sstevel@tonic-gate 	"spill-0-oth",			/* 0A1	spill 0 other */
1947c478bd9Sstevel@tonic-gate 	"spill-0-oth",			/* 0A2	spill 0 other */
1957c478bd9Sstevel@tonic-gate 	"spill-0-oth",			/* 0A3	spill 0 other */
1967c478bd9Sstevel@tonic-gate 	"spill-1-oth",			/* 0A4	spill 1 other */
1977c478bd9Sstevel@tonic-gate 	"spill-1-oth",			/* 0A5	spill 1 other */
1987c478bd9Sstevel@tonic-gate 	"spill-1-oth",			/* 0A6	spill 1 other */
1997c478bd9Sstevel@tonic-gate 	"spill-1-oth",			/* 0A7	spill 1 other */
2007c478bd9Sstevel@tonic-gate 	"spill-2-oth",			/* 0A8	spill 2 other */
2017c478bd9Sstevel@tonic-gate 	"spill-2-oth",			/* 0A9	spill 2 other */
2027c478bd9Sstevel@tonic-gate 	"spill-2-oth",			/* 0AA	spill 2 other */
2037c478bd9Sstevel@tonic-gate 	"spill-2-oth",			/* 0AB	spill 2 other */
2047c478bd9Sstevel@tonic-gate 	"spill-3-oth",			/* 0AC	spill 3 other */
2057c478bd9Sstevel@tonic-gate 	"spill-3-oth",			/* 0AD	spill 3 other */
2067c478bd9Sstevel@tonic-gate 	"spill-3-oth",			/* 0AE	spill 3 other */
2077c478bd9Sstevel@tonic-gate 	"spill-3-oth",			/* 0AF	spill 3 other */
2087c478bd9Sstevel@tonic-gate 	"spill-4-oth",			/* 0B0	spill 4 other */
2097c478bd9Sstevel@tonic-gate 	"spill-4-oth",			/* 0B1	spill 4 other */
2107c478bd9Sstevel@tonic-gate 	"spill-4-oth",			/* 0B2	spill 4 other */
2117c478bd9Sstevel@tonic-gate 	"spill-4-oth",			/* 0B3	spill 4 other */
2127c478bd9Sstevel@tonic-gate 	"spill-5-oth",			/* 0B4	spill 5 other */
2137c478bd9Sstevel@tonic-gate 	"spill-5-oth",			/* 0B5	spill 5 other */
2147c478bd9Sstevel@tonic-gate 	"spill-5-oth",			/* 0B6	spill 5 other */
2157c478bd9Sstevel@tonic-gate 	"spill-5-oth",			/* 0B7	spill 5 other */
2167c478bd9Sstevel@tonic-gate 	"spill-6-oth",			/* 0B8	spill 6 other */
2177c478bd9Sstevel@tonic-gate 	"spill-6-oth",			/* 0B9	spill 6 other */
2187c478bd9Sstevel@tonic-gate 	"spill-6-oth",			/* 0BA	spill 6 other */
2197c478bd9Sstevel@tonic-gate 	"spill-6-oth",			/* 0BB	spill 6 other */
2207c478bd9Sstevel@tonic-gate 	"spill-7-oth",			/* 0BC	spill 7 other */
2217c478bd9Sstevel@tonic-gate 	"spill-7-oth",			/* 0BD	spill 7 other */
2227c478bd9Sstevel@tonic-gate 	"spill-7-oth",			/* 0BE	spill 7 other */
2237c478bd9Sstevel@tonic-gate 	"spill-7-oth",			/* 0BF	spill 7 other */
2247c478bd9Sstevel@tonic-gate 	"fill-0-norm",			/* 0C0	fill 0 normal */
2257c478bd9Sstevel@tonic-gate 	"fill-0-norm",			/* 0C1	fill 0 normal */
2267c478bd9Sstevel@tonic-gate 	"fill-0-norm",			/* 0C2	fill 0 normal */
2277c478bd9Sstevel@tonic-gate 	"fill-0-norm",			/* 0C3	fill 0 normal */
2287c478bd9Sstevel@tonic-gate 	"fill-1-norm",			/* 0C4	fill 1 normal */
2297c478bd9Sstevel@tonic-gate 	"fill-1-norm",			/* 0C5	fill 1 normal */
2307c478bd9Sstevel@tonic-gate 	"fill-1-norm",			/* 0C6	fill 1 normal */
2317c478bd9Sstevel@tonic-gate 	"fill-1-norm",			/* 0C7	fill 1 normal */
2327c478bd9Sstevel@tonic-gate 	"fill-2-norm",			/* 0C8	fill 2 normal */
2337c478bd9Sstevel@tonic-gate 	"fill-2-norm",			/* 0C9	fill 2 normal */
2347c478bd9Sstevel@tonic-gate 	"fill-2-norm",			/* 0CA	fill 2 normal */
2357c478bd9Sstevel@tonic-gate 	"fill-2-norm",			/* 0CB	fill 2 normal */
2367c478bd9Sstevel@tonic-gate 	"fill-3-norm",			/* 0CC	fill 3 normal */
2377c478bd9Sstevel@tonic-gate 	"fill-3-norm",			/* 0CD	fill 3 normal */
2387c478bd9Sstevel@tonic-gate 	"fill-3-norm",			/* 0CE	fill 3 normal */
2397c478bd9Sstevel@tonic-gate 	"fill-3-norm",			/* 0CF	fill 3 normal */
2407c478bd9Sstevel@tonic-gate 	"fill-4-norm",			/* 0D0	fill 4 normal */
2417c478bd9Sstevel@tonic-gate 	"fill-4-norm",			/* 0D1	fill 4 normal */
2427c478bd9Sstevel@tonic-gate 	"fill-4-norm",			/* 0D2	fill 4 normal */
2437c478bd9Sstevel@tonic-gate 	"fill-4-norm",			/* 0D3	fill 4 normal */
2447c478bd9Sstevel@tonic-gate 	"fill-5-norm",			/* 0D4	fill 5 normal */
2457c478bd9Sstevel@tonic-gate 	"fill-5-norm",			/* 0D5	fill 5 normal */
2467c478bd9Sstevel@tonic-gate 	"fill-5-norm",			/* 0D6	fill 5 normal */
2477c478bd9Sstevel@tonic-gate 	"fill-5-norm",			/* 0D7	fill 5 normal */
2487c478bd9Sstevel@tonic-gate 	"fill-6-norm",			/* 0D8	fill 6 normal */
2497c478bd9Sstevel@tonic-gate 	"fill-6-norm",			/* 0D9	fill 6 normal */
2507c478bd9Sstevel@tonic-gate 	"fill-6-norm",			/* 0DA	fill 6 normal */
2517c478bd9Sstevel@tonic-gate 	"fill-6-norm",			/* 0DB	fill 6 normal */
2527c478bd9Sstevel@tonic-gate 	"fill-7-norm",			/* 0DC	fill 7 normal */
2537c478bd9Sstevel@tonic-gate 	"fill-7-norm",			/* 0DD	fill 7 normal */
2547c478bd9Sstevel@tonic-gate 	"fill-7-norm",			/* 0DE	fill 7 normal */
2557c478bd9Sstevel@tonic-gate 	"fill-7-norm",			/* 0DF	fill 7 normal */
2567c478bd9Sstevel@tonic-gate 	"fill-0-oth",			/* 0E0	fill 0 other */
2577c478bd9Sstevel@tonic-gate 	"fill-0-oth",			/* 0E1	fill 0 other */
2587c478bd9Sstevel@tonic-gate 	"fill-0-oth",			/* 0E2	fill 0 other */
2597c478bd9Sstevel@tonic-gate 	"fill-0-oth",			/* 0E3	fill 0 other */
2607c478bd9Sstevel@tonic-gate 	"fill-1-oth",			/* 0E4	fill 1 other */
2617c478bd9Sstevel@tonic-gate 	"fill-1-oth",			/* 0E5	fill 1 other */
2627c478bd9Sstevel@tonic-gate 	"fill-1-oth",			/* 0E6	fill 1 other */
2637c478bd9Sstevel@tonic-gate 	"fill-1-oth",			/* 0E7	fill 1 other */
2647c478bd9Sstevel@tonic-gate 	"fill-2-oth",			/* 0E8	fill 2 other */
2657c478bd9Sstevel@tonic-gate 	"fill-2-oth",			/* 0E9	fill 2 other */
2667c478bd9Sstevel@tonic-gate 	"fill-2-oth",			/* 0EA	fill 2 other */
2677c478bd9Sstevel@tonic-gate 	"fill-2-oth",			/* 0EB	fill 2 other */
2687c478bd9Sstevel@tonic-gate 	"fill-3-oth",			/* 0EC	fill 3 other */
2697c478bd9Sstevel@tonic-gate 	"fill-3-oth",			/* 0ED	fill 3 other */
2707c478bd9Sstevel@tonic-gate 	"fill-3-oth",			/* 0EE	fill 3 other */
2717c478bd9Sstevel@tonic-gate 	"fill-3-oth",			/* 0EF	fill 3 other */
2727c478bd9Sstevel@tonic-gate 	"fill-4-oth",			/* 0F0	fill 4 other */
2737c478bd9Sstevel@tonic-gate 	"fill-4-oth",			/* 0F1	fill 4 other */
2747c478bd9Sstevel@tonic-gate 	"fill-4-oth",			/* 0F2	fill 4 other */
2757c478bd9Sstevel@tonic-gate 	"fill-4-oth",			/* 0F3	fill 4 other */
2767c478bd9Sstevel@tonic-gate 	"fill-5-oth",			/* 0F4	fill 5 other */
2777c478bd9Sstevel@tonic-gate 	"fill-5-oth",			/* 0F5	fill 5 other */
2787c478bd9Sstevel@tonic-gate 	"fill-5-oth",			/* 0F6	fill 5 other */
2797c478bd9Sstevel@tonic-gate 	"fill-5-oth",			/* 0F7	fill 5 other */
2807c478bd9Sstevel@tonic-gate 	"fill-6-oth",			/* 0F8	fill 6 other */
2817c478bd9Sstevel@tonic-gate 	"fill-6-oth",			/* 0F9	fill 6 other */
2827c478bd9Sstevel@tonic-gate 	"fill-6-oth",			/* 0FA	fill 6 other */
2837c478bd9Sstevel@tonic-gate 	"fill-6-oth",			/* 0FB	fill 6 other */
2847c478bd9Sstevel@tonic-gate 	"fill-7-oth",			/* 0FC	fill 7 other */
2857c478bd9Sstevel@tonic-gate 	"fill-7-oth",			/* 0FD	fill 7 other */
2867c478bd9Sstevel@tonic-gate 	"fill-7-oth",			/* 0FE	fill 7 other */
2877c478bd9Sstevel@tonic-gate 	"fill-7-oth",			/* 0FF	fill 7 other */
2887c478bd9Sstevel@tonic-gate 	"syscall-4x",			/* 100	old system call */
2897c478bd9Sstevel@tonic-gate 	"usr-brkpt",			/* 101	user breakpoint */
2907c478bd9Sstevel@tonic-gate 	"usr-div-zero",			/* 102	user divide by zero */
2917c478bd9Sstevel@tonic-gate 	"flush-wins",			/* 103	flush windows */
2927c478bd9Sstevel@tonic-gate 	"clean-wins",			/* 104	clean windows */
2937c478bd9Sstevel@tonic-gate 	"range-chk",			/* 105	range check ?? */
2947c478bd9Sstevel@tonic-gate 	"fix-align",			/* 106	do unaligned references */
2957c478bd9Sstevel@tonic-gate 	BAD,				/* 107	unused */
2967c478bd9Sstevel@tonic-gate 	"syscall-32",			/* 108	ILP32 system call on LP64 */
2977c478bd9Sstevel@tonic-gate 	"set-t0-addr",			/* 109	set trap0 address */
2987c478bd9Sstevel@tonic-gate 	BAD, BAD, BAD4,			/* 10A - 10F unused */
2997c478bd9Sstevel@tonic-gate 	BAD4, BAD4, BAD4, BAD4,		/* 110 - 11F unused (V9 user traps?) */
3007c478bd9Sstevel@tonic-gate 	"get-cc",			/* 120	get condition codes */
3017c478bd9Sstevel@tonic-gate 	"set-cc",			/* 121	set condition codes */
3027c478bd9Sstevel@tonic-gate 	"get-psr",			/* 122	get psr */
3037c478bd9Sstevel@tonic-gate 	"set-psr",			/* 123	set psr (some fields) */
3047c478bd9Sstevel@tonic-gate 	"getts",			/* 124	get timestamp */
3057c478bd9Sstevel@tonic-gate 	"gethrvtime",			/* 125	get lwp virtual time */
3067c478bd9Sstevel@tonic-gate 	"self-xcall",			/* 126	self xcall */
3077c478bd9Sstevel@tonic-gate 	"gethrtime",			/* 127	get hrestime */
3087c478bd9Sstevel@tonic-gate 	BAD,				/* 128  unused (ST_SETV9STACK) */
3097c478bd9Sstevel@tonic-gate 	"getlgrp",			/* 129	get lgrpid */
3107c478bd9Sstevel@tonic-gate 	BAD, BAD, BAD4,			/* 12A - 12F unused */
3117c478bd9Sstevel@tonic-gate 	BAD4, BAD4,			/* 130 - 137 unused */
3127c478bd9Sstevel@tonic-gate 	"dtrace-pid",			/* 138  DTrace pid provider */
313f498645aSahl 	BAD,				/* 139  unused */
3147c478bd9Sstevel@tonic-gate 	"dtrace-return",		/* 13A  DTrace pid provider */
3157c478bd9Sstevel@tonic-gate 	BAD, BAD4,			/* 13B - 13F unused */
3167c478bd9Sstevel@tonic-gate 	"syscall-64",			/* 140  LP64 system call */
3177c478bd9Sstevel@tonic-gate 	BAD,				/* 141  unused */
3187c478bd9Sstevel@tonic-gate 	"tt-freeze",			/* 142  freeze traptrace */
3197c478bd9Sstevel@tonic-gate 	"tt-unfreeze",			/* 143  unfreeze traptrace */
3207c478bd9Sstevel@tonic-gate 	BAD4, BAD4, BAD4,		/* 144 - 14F unused */
3217c478bd9Sstevel@tonic-gate 	BAD4, BAD4, BAD4, BAD4,		/* 150 - 15F unused */
3227c478bd9Sstevel@tonic-gate 	BAD4, BAD4, BAD4, BAD4,		/* 160 - 16F unused */
3237c478bd9Sstevel@tonic-gate 	BAD4, BAD4, BAD4,		/* 170 - 17B unused */
3247c478bd9Sstevel@tonic-gate 	"ptl1-panic",			/* 17C	test ptl1_panic */
3257c478bd9Sstevel@tonic-gate 	"kmdb-enter",			/* 17D	kmdb enter (L1-A) */
3267c478bd9Sstevel@tonic-gate 	"kmdb-brkpt",			/* 17E	kmdb breakpoint */
3277c478bd9Sstevel@tonic-gate 	"obp-brkpt",			/* 17F	obp breakpoint */
3287c478bd9Sstevel@tonic-gate #ifdef sun4v
3297c478bd9Sstevel@tonic-gate 	"fast_trap",			/* 180  hypervisor fast trap */
3307c478bd9Sstevel@tonic-gate 	"cpu_tick_npt",			/* 181  cpu_tick_npt() hcall */
3317c478bd9Sstevel@tonic-gate 	"cpu_stick_npt",		/* 182  cpu_stick_npt() hcall */
3327c478bd9Sstevel@tonic-gate 	"mmu_map_addr",			/* 183  mmu_map_addr() hcall */
3337c478bd9Sstevel@tonic-gate 	"mmu_unmap_addr",		/* 184  mmu_unmap_addr() hcall */
3347c478bd9Sstevel@tonic-gate 	"ttrace_addentry",		/* 185  ttrace_addentry() hcall */
3357c478bd9Sstevel@tonic-gate 	NOT, NOT, NOT4, NOT4,		/* 186 - 18F reserved */
3367c478bd9Sstevel@tonic-gate #else
3377c478bd9Sstevel@tonic-gate 	NOT4, NOT4, NOT4, NOT4,		/* 180 - 18F reserved */
3387c478bd9Sstevel@tonic-gate #endif
3397c478bd9Sstevel@tonic-gate 	NOT4, NOT4, NOT4, NOT4,		/* 190 - 19F reserved */
3407c478bd9Sstevel@tonic-gate 	NOT4, NOT4, NOT4, NOT4,		/* 1A0 - 1AF reserved */
3417c478bd9Sstevel@tonic-gate 	NOT4, NOT4, NOT4, NOT4,		/* 1B0 - 1BF reserved */
3427c478bd9Sstevel@tonic-gate 	NOT4, NOT4, NOT4, NOT4,		/* 1C0 - 1CF reserved */
3437c478bd9Sstevel@tonic-gate 	NOT4, NOT4, NOT4, NOT4,		/* 1D0 - 1DF reserved */
3447c478bd9Sstevel@tonic-gate 	NOT4, NOT4, NOT4, NOT4,		/* 1E0 - 1EF reserved */
3457c478bd9Sstevel@tonic-gate 	NOT4, NOT4, NOT4, NOT4		/* 1F0 - 1FF reserved */
3467c478bd9Sstevel@tonic-gate };
3477c478bd9Sstevel@tonic-gate static const size_t ttndescr = sizeof (ttdescr) / sizeof (ttdescr[0]);
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate static GElf_Sym iv_sym;
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate /*
3527c478bd9Sstevel@tonic-gate  * Persistent data (shouldn't change).
3537c478bd9Sstevel@tonic-gate  */
3547c478bd9Sstevel@tonic-gate static int ncpu;		/* _ncpu */
3557c478bd9Sstevel@tonic-gate static ssize_t mbox_size;	/* size of xc_mbox */
3567c478bd9Sstevel@tonic-gate static ulong_t mbox_stoff;	/* offset of xc_mbox.xc_state */
3577c478bd9Sstevel@tonic-gate static mdb_ctf_id_t mbox_states; /* xc_state enumeration */
3587c478bd9Sstevel@tonic-gate 
3597c478bd9Sstevel@tonic-gate static int
3607c478bd9Sstevel@tonic-gate fetch_ncpu(void)
3617c478bd9Sstevel@tonic-gate {
3627c478bd9Sstevel@tonic-gate 	if (ncpu == 0)
3637c478bd9Sstevel@tonic-gate 		if (mdb_readsym(&ncpu, sizeof (ncpu), "_ncpu") == -1) {
3647c478bd9Sstevel@tonic-gate 			mdb_warn("symbol '_ncpu' not found");
3657c478bd9Sstevel@tonic-gate 			return (1);
3667c478bd9Sstevel@tonic-gate 		}
3677c478bd9Sstevel@tonic-gate 	return (0);
3687c478bd9Sstevel@tonic-gate }
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate static int
3717c478bd9Sstevel@tonic-gate fetch_mbox(void)
3727c478bd9Sstevel@tonic-gate {
3737c478bd9Sstevel@tonic-gate 	if (mbox_size <= 0) {
3747c478bd9Sstevel@tonic-gate 		mdb_ctf_id_t id;
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 		if (mdb_ctf_lookup_by_name("struct xc_mbox", &id) == -1) {
3777c478bd9Sstevel@tonic-gate 			mdb_warn("couldn't find type 'struct xc_mbox'");
3787c478bd9Sstevel@tonic-gate 			return (1);
3797c478bd9Sstevel@tonic-gate 		}
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate 		/*
3827c478bd9Sstevel@tonic-gate 		 * These two could be combined into a single call to
3837c478bd9Sstevel@tonic-gate 		 * mdb_ctf_member_info if xc_state was actually of type
3847c478bd9Sstevel@tonic-gate 		 * enum xc_states.
3857c478bd9Sstevel@tonic-gate 		 */
3867c478bd9Sstevel@tonic-gate 		if (mdb_ctf_lookup_by_name("enum xc_states",
3877c478bd9Sstevel@tonic-gate 		    &mbox_states) == -1) {
3887c478bd9Sstevel@tonic-gate 			mdb_warn("couldn't find type 'enum xc_states'");
3897c478bd9Sstevel@tonic-gate 			return (1);
3907c478bd9Sstevel@tonic-gate 		}
3917c478bd9Sstevel@tonic-gate 		if (mdb_ctf_offsetof(id, "xc_state", &mbox_stoff) == -1) {
3927c478bd9Sstevel@tonic-gate 			mdb_warn("couldn't find 'xc_mbox.xc_state'");
3937c478bd9Sstevel@tonic-gate 			return (1);
3947c478bd9Sstevel@tonic-gate 		}
3957c478bd9Sstevel@tonic-gate 		mbox_stoff /= NBBY;
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate 		if ((mbox_size = mdb_ctf_type_size(id)) == -1) {
3987c478bd9Sstevel@tonic-gate 			mdb_warn("couldn't size 'struct xc_mbox'");
3997c478bd9Sstevel@tonic-gate 			return (1);
4007c478bd9Sstevel@tonic-gate 		}
4017c478bd9Sstevel@tonic-gate 	}
4027c478bd9Sstevel@tonic-gate 	return (0);
4037c478bd9Sstevel@tonic-gate }
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate static int
4067c478bd9Sstevel@tonic-gate print_range(int start, int end, int separator)
4077c478bd9Sstevel@tonic-gate {
4087c478bd9Sstevel@tonic-gate 	int	count;
4097c478bd9Sstevel@tonic-gate 	char	tmp;
4107c478bd9Sstevel@tonic-gate 	char	*format;
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	if (start == end) {
4137c478bd9Sstevel@tonic-gate 		/* Unfortunately, mdb_printf returns void */
4147c478bd9Sstevel@tonic-gate 		format = separator ? ", %d" : "%d";
4157c478bd9Sstevel@tonic-gate 		mdb_printf(format, start);
4167c478bd9Sstevel@tonic-gate 		count = mdb_snprintf(&tmp, 1, format, start);
4177c478bd9Sstevel@tonic-gate 	} else {
4187c478bd9Sstevel@tonic-gate 		format = separator ? ", %d-%d" : "%d-%d";
4197c478bd9Sstevel@tonic-gate 		mdb_printf(format, start, end);
4207c478bd9Sstevel@tonic-gate 		count = mdb_snprintf(&tmp, 1, format, start, end);
4217c478bd9Sstevel@tonic-gate 	}
4227c478bd9Sstevel@tonic-gate 
4237c478bd9Sstevel@tonic-gate 	return (count);
4247c478bd9Sstevel@tonic-gate }
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate static void
4277c478bd9Sstevel@tonic-gate print_cpuset_range(ulong_t *cs, int words, int width)
4287c478bd9Sstevel@tonic-gate {
4297c478bd9Sstevel@tonic-gate 	int i, j;
4307c478bd9Sstevel@tonic-gate 	ulong_t m;
4317c478bd9Sstevel@tonic-gate 	int in = 0;
4327c478bd9Sstevel@tonic-gate 	int start;
4337c478bd9Sstevel@tonic-gate 	int end;
4347c478bd9Sstevel@tonic-gate 	int count = 0;
4357c478bd9Sstevel@tonic-gate 	int sep = 0;
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate 	for (i = 0; i < words; i++)
4387c478bd9Sstevel@tonic-gate 		for (j = 0, m = 1; j < BT_NBIPUL; j++, m <<= 1)
4397c478bd9Sstevel@tonic-gate 			if (cs[i] & m) {
4407c478bd9Sstevel@tonic-gate 				if (in == 0) {
4417c478bd9Sstevel@tonic-gate 					start = i * BT_NBIPUL + j;
4427c478bd9Sstevel@tonic-gate 					in = 1;
4437c478bd9Sstevel@tonic-gate 				}
4447c478bd9Sstevel@tonic-gate 			} else {
4457c478bd9Sstevel@tonic-gate 				if (in == 1) {
4467c478bd9Sstevel@tonic-gate 					end = i * BT_NBIPUL + j - 1;
4477c478bd9Sstevel@tonic-gate 					count += print_range(start, end, sep);
4487c478bd9Sstevel@tonic-gate 					sep = 1;
4497c478bd9Sstevel@tonic-gate 					in = 0;
4507c478bd9Sstevel@tonic-gate 				}
4517c478bd9Sstevel@tonic-gate 			}
4527c478bd9Sstevel@tonic-gate 	if (in == 1) {
4537c478bd9Sstevel@tonic-gate 		end = i * BT_NBIPUL - 1;
4547c478bd9Sstevel@tonic-gate 		count += print_range(start, end, sep);
4557c478bd9Sstevel@tonic-gate 	}
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate 	while (count++ < width)
4587c478bd9Sstevel@tonic-gate 		mdb_printf(" ");
4597c478bd9Sstevel@tonic-gate }
4607c478bd9Sstevel@tonic-gate 
4617c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4627c478bd9Sstevel@tonic-gate static int
4637c478bd9Sstevel@tonic-gate cmd_cpuset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
4647c478bd9Sstevel@tonic-gate {
4657c478bd9Sstevel@tonic-gate 	uint_t rflag = 0, lflag = 0;
4667c478bd9Sstevel@tonic-gate 	int words;
4670400e0b7Sha137994 	ulong_t *setp, set = 0;
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv,
4707c478bd9Sstevel@tonic-gate 	    'l', MDB_OPT_SETBITS, TRUE, &lflag,
4717c478bd9Sstevel@tonic-gate 	    'r', MDB_OPT_SETBITS, TRUE, &rflag,  NULL) != argc)
4727c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	if (lflag && rflag)
4757c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate 	if (fetch_ncpu())
4787c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 	if ((words = BT_BITOUL(ncpu)) == 1) {
4810400e0b7Sha137994 		setp = &set;
4820400e0b7Sha137994 		mdb_vread(setp, sizeof (ulong_t), addr);
4837c478bd9Sstevel@tonic-gate 	} else {
4840400e0b7Sha137994 		setp = mdb_alloc(words * sizeof (ulong_t), UM_SLEEP | UM_GC);
4850400e0b7Sha137994 		mdb_vread(setp, words * sizeof (ulong_t), addr);
4867c478bd9Sstevel@tonic-gate 	}
4877c478bd9Sstevel@tonic-gate 
4887c478bd9Sstevel@tonic-gate 	if (lflag) {
4897c478bd9Sstevel@tonic-gate 		int i, j;
4907c478bd9Sstevel@tonic-gate 		ulong_t m;
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate 		for (i = 0; i < words; i++)
4937c478bd9Sstevel@tonic-gate 			for (j = 0, m = 1; j < BT_NBIPUL; j++, m <<= 1)
4940400e0b7Sha137994 				if (setp[i] & m)
4957c478bd9Sstevel@tonic-gate 					mdb_printf("%r\n", i * BT_NBIPUL + j);
4967c478bd9Sstevel@tonic-gate 	} else if (rflag) {
4977c478bd9Sstevel@tonic-gate 		int i;
4987c478bd9Sstevel@tonic-gate 		int sep = 0;
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 		for (i = 0; i < words; i++) {
5010400e0b7Sha137994 			mdb_printf(sep ? " %?0lx" : "%?0lx", setp[i]);
5027c478bd9Sstevel@tonic-gate 			sep = 1;
5037c478bd9Sstevel@tonic-gate 		}
5047c478bd9Sstevel@tonic-gate 	} else {
5050400e0b7Sha137994 		print_cpuset_range(setp, words, 0);
5067c478bd9Sstevel@tonic-gate 	}
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
5097c478bd9Sstevel@tonic-gate }
5107c478bd9Sstevel@tonic-gate 
5117c478bd9Sstevel@tonic-gate /*ARGSUSED*/
5127c478bd9Sstevel@tonic-gate int
5137c478bd9Sstevel@tonic-gate ttctl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
5147c478bd9Sstevel@tonic-gate {
5157c478bd9Sstevel@tonic-gate 	TRAP_TRACE_CTL *ctls, *ctl;
516a92801d6Ssvemuri 	int i, traptrace_buf_inuse = 0;
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate 	if (argc != 0)
5197c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate 	if (fetch_ncpu())
5227c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate 	ctls = mdb_alloc(sizeof (TRAP_TRACE_CTL) * ncpu, UM_SLEEP | UM_GC);
5257c478bd9Sstevel@tonic-gate 	if (mdb_readsym(ctls, sizeof (TRAP_TRACE_CTL) * ncpu,
5267c478bd9Sstevel@tonic-gate 	    "trap_trace_ctl") == -1) {
5277c478bd9Sstevel@tonic-gate 		mdb_warn("symbol 'trap_trace_ctl' not found");
5287c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
5297c478bd9Sstevel@tonic-gate 	}
5307c478bd9Sstevel@tonic-gate 
5317c478bd9Sstevel@tonic-gate 	for (ctl = &ctls[0], i = 0; i < ncpu; i++, ctl++) {
5327c478bd9Sstevel@tonic-gate 		if (ctl->d.vaddr_base == 0)
5337c478bd9Sstevel@tonic-gate 			continue;
5347c478bd9Sstevel@tonic-gate 
535a92801d6Ssvemuri 		traptrace_buf_inuse = 1;
5367c478bd9Sstevel@tonic-gate 		mdb_printf("trap_trace_ctl[%d] = {\n", i);
5377c478bd9Sstevel@tonic-gate 		mdb_printf("  vaddr_base = 0x%lx\n", (long)ctl->d.vaddr_base);
5387c478bd9Sstevel@tonic-gate 		mdb_printf("  last_offset = 0x%x\n", ctl->d.last_offset);
5397c478bd9Sstevel@tonic-gate 		mdb_printf("  offset = 0x%x\n", ctl->d.offset);
5407c478bd9Sstevel@tonic-gate 		mdb_printf("  limit = 0x%x\n", ctl->d.limit);
5417c478bd9Sstevel@tonic-gate 		mdb_printf("  paddr_base = 0x%llx\n", ctl->d.paddr_base);
5427c478bd9Sstevel@tonic-gate 		mdb_printf("  asi = 0x%02x\n}\n", ctl->d.asi);
5437c478bd9Sstevel@tonic-gate 	}
544a92801d6Ssvemuri 	if (!traptrace_buf_inuse) {
545a92801d6Ssvemuri 		mdb_warn("traptrace not configured");
546a92801d6Ssvemuri 		return (DCMD_ERR);
547a92801d6Ssvemuri 	}
5487c478bd9Sstevel@tonic-gate 
5497c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
5507c478bd9Sstevel@tonic-gate }
5517c478bd9Sstevel@tonic-gate 
5527c478bd9Sstevel@tonic-gate /*ARGSUSED*/
5537c478bd9Sstevel@tonic-gate static int
5547c478bd9Sstevel@tonic-gate ttprint_short(uintptr_t addr, const trap_trace_fullrec_t *full, int *cpu)
5557c478bd9Sstevel@tonic-gate {
5567c478bd9Sstevel@tonic-gate 	const char *ttstr;
5577c478bd9Sstevel@tonic-gate 	const struct trap_trace_record *ttp = &full->ttf_rec;
5587c478bd9Sstevel@tonic-gate 
5597c478bd9Sstevel@tonic-gate 	if (*cpu == -1)
5607c478bd9Sstevel@tonic-gate 		mdb_printf("%3d ", full->ttf_cpu);
5617c478bd9Sstevel@tonic-gate 	else
5627c478bd9Sstevel@tonic-gate 		if (*cpu != full->ttf_cpu)
5637c478bd9Sstevel@tonic-gate 			return (0);
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate 	/*
5667c478bd9Sstevel@tonic-gate 	 * Decoding the traptype field is a bit messy.  First we check for
5677c478bd9Sstevel@tonic-gate 	 * several well-defined 16-bit values defined in <sys/traptrace.h>.
5687c478bd9Sstevel@tonic-gate 	 */
5697c478bd9Sstevel@tonic-gate 	switch (ttp->tt_tt) {
5707c478bd9Sstevel@tonic-gate 		case TT_SC_ENTR:
5717c478bd9Sstevel@tonic-gate 			ttstr = "sys-enter";
5727c478bd9Sstevel@tonic-gate 			break;
5737c478bd9Sstevel@tonic-gate 		case TT_SC_RET:
5747c478bd9Sstevel@tonic-gate 			ttstr = "sys-exit";
5757c478bd9Sstevel@tonic-gate 			break;
5767c478bd9Sstevel@tonic-gate 		case TT_SYS_RTT_PROM:
5777c478bd9Sstevel@tonic-gate 			ttstr = "prom_rtt";
5787c478bd9Sstevel@tonic-gate 			break;
5797c478bd9Sstevel@tonic-gate 		case TT_SYS_RTT_PRIV:
5807c478bd9Sstevel@tonic-gate 			ttstr = "priv_rtt";
5817c478bd9Sstevel@tonic-gate 			break;
5827c478bd9Sstevel@tonic-gate 		case TT_SYS_RTT_USER:
5837c478bd9Sstevel@tonic-gate 			ttstr = "user_rtt";
5847c478bd9Sstevel@tonic-gate 			break;
5857c478bd9Sstevel@tonic-gate 		case TT_INTR_EXIT:
5867c478bd9Sstevel@tonic-gate 			ttstr = "int-thr-exit";
5877c478bd9Sstevel@tonic-gate 			break;
5887c478bd9Sstevel@tonic-gate 		default:
5897c478bd9Sstevel@tonic-gate 			/*
5907c478bd9Sstevel@tonic-gate 			 * Next we consider several prefixes (which are
5917c478bd9Sstevel@tonic-gate 			 * typically OR'd with other information such as the
5927c478bd9Sstevel@tonic-gate 			 * %pil or %tt value at the time of the trace).
5937c478bd9Sstevel@tonic-gate 			 */
5947c478bd9Sstevel@tonic-gate 			switch (ttp->tt_tt & 0xff00) {
5957c478bd9Sstevel@tonic-gate 				case TT_SERVE_INTR:
5967c478bd9Sstevel@tonic-gate 					ttstr = "serve-intr";
5977c478bd9Sstevel@tonic-gate 					break;
5987c478bd9Sstevel@tonic-gate 				case TT_XCALL:
5997c478bd9Sstevel@tonic-gate 					ttstr = "xcall";
6007c478bd9Sstevel@tonic-gate 					break;
6017c478bd9Sstevel@tonic-gate 				case TT_XCALL_CONT:
6027c478bd9Sstevel@tonic-gate 					ttstr = "xcall-cont";
6037c478bd9Sstevel@tonic-gate 					break;
6047c478bd9Sstevel@tonic-gate 				case SYSTRAP_TT:
6057c478bd9Sstevel@tonic-gate 					ttstr = "sys_trap";
6067c478bd9Sstevel@tonic-gate 					break;
6077c478bd9Sstevel@tonic-gate 				default:
6087c478bd9Sstevel@tonic-gate 					/*
6097c478bd9Sstevel@tonic-gate 					 * Otherwise we try to convert the
6107c478bd9Sstevel@tonic-gate 					 * tt value to a string using our
6117c478bd9Sstevel@tonic-gate 					 * giant lookup table.
6127c478bd9Sstevel@tonic-gate 					 */
6137c478bd9Sstevel@tonic-gate 					ttstr = ttp->tt_tt < ttndescr ?
6147c478bd9Sstevel@tonic-gate 					    ttdescr[ttp->tt_tt] : "?";
6157c478bd9Sstevel@tonic-gate 			}
6167c478bd9Sstevel@tonic-gate 	}
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate #ifdef sun4v
6197c478bd9Sstevel@tonic-gate 	mdb_printf("%016llx %04hx %-12s  %02x  %02x %0?p %A\n", ttp->tt_tick,
6207c478bd9Sstevel@tonic-gate 	    ttp->tt_tt, ttstr, ttp->tt_tl, ttp->tt_gl,
6217c478bd9Sstevel@tonic-gate 	    ttp->tt_tpc, ttp->tt_tpc);
6227c478bd9Sstevel@tonic-gate #else
6237c478bd9Sstevel@tonic-gate 	mdb_printf("%016llx %04hx %-12s %04hx %0?p %A\n", ttp->tt_tick,
6247c478bd9Sstevel@tonic-gate 	    ttp->tt_tt, ttstr, ttp->tt_tl, ttp->tt_tpc, ttp->tt_tpc);
6257c478bd9Sstevel@tonic-gate #endif
6267c478bd9Sstevel@tonic-gate 
6277c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
6287c478bd9Sstevel@tonic-gate }
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate /*ARGSUSED*/
6317c478bd9Sstevel@tonic-gate static int
6327c478bd9Sstevel@tonic-gate ttprint_long(uintptr_t addr, const trap_trace_fullrec_t *full, int *cpu)
6337c478bd9Sstevel@tonic-gate {
6347c478bd9Sstevel@tonic-gate 	const struct trap_trace_record *ttp = &full->ttf_rec;
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate 	if (*cpu == -1)
6377c478bd9Sstevel@tonic-gate 		mdb_printf("%3d ", full->ttf_cpu);
6387c478bd9Sstevel@tonic-gate 	else if (*cpu != full->ttf_cpu)
6397c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate #ifdef sun4v
6427c478bd9Sstevel@tonic-gate 	mdb_printf("%016llx %016llx %04hx  %02x  %02x %0?p %0?p %0?p "
6437c478bd9Sstevel@tonic-gate 	    "[%p,%p,%p,%p]\n",
6447c478bd9Sstevel@tonic-gate 	    ttp->tt_tick, ttp->tt_tstate, ttp->tt_tt, ttp->tt_tl, ttp->tt_gl,
6457c478bd9Sstevel@tonic-gate 	    ttp->tt_tpc, ttp->tt_sp, ttp->tt_tr,
6467c478bd9Sstevel@tonic-gate 	    ttp->tt_f1, ttp->tt_f2, ttp->tt_f3, ttp->tt_f4);
6477c478bd9Sstevel@tonic-gate #else
6487c478bd9Sstevel@tonic-gate 	mdb_printf("%016llx %016llx %04hx %04hx %0?p %0?p %0?p [%p,%p,%p,%p]\n",
6497c478bd9Sstevel@tonic-gate 	    ttp->tt_tick, ttp->tt_tstate, ttp->tt_tt, ttp->tt_tl,
6507c478bd9Sstevel@tonic-gate 	    ttp->tt_tpc, ttp->tt_sp, ttp->tt_tr,
6517c478bd9Sstevel@tonic-gate 	    ttp->tt_f1, ttp->tt_f2, ttp->tt_f3, ttp->tt_f4);
6527c478bd9Sstevel@tonic-gate #endif
6537c478bd9Sstevel@tonic-gate 
6547c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
6557c478bd9Sstevel@tonic-gate }
6567c478bd9Sstevel@tonic-gate 
6577c478bd9Sstevel@tonic-gate typedef struct ttrace_cpu_data {
6587c478bd9Sstevel@tonic-gate 	struct trap_trace_record *tc_buf;
6597c478bd9Sstevel@tonic-gate 	struct trap_trace_record *tc_rec;
6607c478bd9Sstevel@tonic-gate 	struct trap_trace_record *tc_stop;
6617c478bd9Sstevel@tonic-gate 	size_t tc_bufsiz;
6627c478bd9Sstevel@tonic-gate 	uintptr_t tc_base;
6637c478bd9Sstevel@tonic-gate } ttrace_cpu_data_t;
6647c478bd9Sstevel@tonic-gate 
6657c478bd9Sstevel@tonic-gate typedef struct ttrace_walk_data {
6667c478bd9Sstevel@tonic-gate 	int tw_ncpu;
6677c478bd9Sstevel@tonic-gate 	ttrace_cpu_data_t *tw_cpus;
6687c478bd9Sstevel@tonic-gate } ttrace_walk_data_t;
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate int
6717c478bd9Sstevel@tonic-gate ttrace_walk_init(mdb_walk_state_t *wsp)
6727c478bd9Sstevel@tonic-gate {
6737c478bd9Sstevel@tonic-gate 	TRAP_TRACE_CTL *ctls, *ctl;
674a92801d6Ssvemuri 	int i, traptrace_buf_inuse = 0;
6757c478bd9Sstevel@tonic-gate 	ttrace_walk_data_t *tw;
6767c478bd9Sstevel@tonic-gate 	ttrace_cpu_data_t *tc;
6777c478bd9Sstevel@tonic-gate 	struct trap_trace_record *buf;
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr != NULL) {
6807c478bd9Sstevel@tonic-gate 		mdb_warn("ttrace only supports global walks\n");
6817c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
6827c478bd9Sstevel@tonic-gate 	}
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate 	if (fetch_ncpu())
6857c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
6867c478bd9Sstevel@tonic-gate 
6877c478bd9Sstevel@tonic-gate 	ctls = mdb_alloc(sizeof (TRAP_TRACE_CTL) * ncpu, UM_SLEEP);
6887c478bd9Sstevel@tonic-gate 	if (mdb_readsym(ctls, sizeof (TRAP_TRACE_CTL) * ncpu,
6897c478bd9Sstevel@tonic-gate 	    "trap_trace_ctl") == -1) {
6907c478bd9Sstevel@tonic-gate 		mdb_warn("symbol 'trap_trace_ctl' not found");
6917c478bd9Sstevel@tonic-gate 		mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu);
6927c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
6937c478bd9Sstevel@tonic-gate 	}
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate 	tw = mdb_zalloc(sizeof (ttrace_walk_data_t), UM_SLEEP);
6967c478bd9Sstevel@tonic-gate 	tw->tw_ncpu = ncpu;
6977c478bd9Sstevel@tonic-gate 	tw->tw_cpus = mdb_zalloc(sizeof (ttrace_cpu_data_t) * ncpu, UM_SLEEP);
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate 	for (i = 0; i < ncpu; i++) {
7007c478bd9Sstevel@tonic-gate 		ctl = &ctls[i];
7017c478bd9Sstevel@tonic-gate 
7027c478bd9Sstevel@tonic-gate 		if (ctl->d.vaddr_base == 0)
7037c478bd9Sstevel@tonic-gate 			continue;
7047c478bd9Sstevel@tonic-gate 
705a92801d6Ssvemuri 		traptrace_buf_inuse = 1;
7067c478bd9Sstevel@tonic-gate 		tc = &(tw->tw_cpus[i]);
7077c478bd9Sstevel@tonic-gate 		tc->tc_bufsiz = ctl->d.limit -
7087c478bd9Sstevel@tonic-gate 		    sizeof (struct trap_trace_record);
7097c478bd9Sstevel@tonic-gate 		tc->tc_buf = buf = mdb_alloc(tc->tc_bufsiz, UM_SLEEP);
7107c478bd9Sstevel@tonic-gate 		tc->tc_base = (uintptr_t)ctl->d.vaddr_base;
7117c478bd9Sstevel@tonic-gate 
7127c478bd9Sstevel@tonic-gate 		if (mdb_vread(buf, tc->tc_bufsiz, tc->tc_base) == -1) {
7137c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read trap trace buffer at %p",
7147c478bd9Sstevel@tonic-gate 			    ctl->d.vaddr_base);
7157c478bd9Sstevel@tonic-gate 			mdb_free(buf, tc->tc_bufsiz);
7167c478bd9Sstevel@tonic-gate 			tc->tc_buf = NULL;
7177c478bd9Sstevel@tonic-gate 		} else {
7187c478bd9Sstevel@tonic-gate 			tc->tc_rec = (struct trap_trace_record *)
7197c478bd9Sstevel@tonic-gate 			    ((uintptr_t)buf + (uintptr_t)ctl->d.last_offset);
7207c478bd9Sstevel@tonic-gate 			tc->tc_stop = (struct trap_trace_record *)
7217c478bd9Sstevel@tonic-gate 			    ((uintptr_t)buf + (uintptr_t)ctl->d.offset);
7227c478bd9Sstevel@tonic-gate 		}
7237c478bd9Sstevel@tonic-gate 	}
724a92801d6Ssvemuri 	if (!traptrace_buf_inuse) {
725a92801d6Ssvemuri 		mdb_warn("traptrace not configured");
726a92801d6Ssvemuri 		mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu);
727a92801d6Ssvemuri 		return (DCMD_ERR);
728a92801d6Ssvemuri 	}
7297c478bd9Sstevel@tonic-gate 
7307c478bd9Sstevel@tonic-gate 	mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu);
7317c478bd9Sstevel@tonic-gate 	wsp->walk_data = tw;
7327c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
7337c478bd9Sstevel@tonic-gate }
7347c478bd9Sstevel@tonic-gate 
7357c478bd9Sstevel@tonic-gate int
7367c478bd9Sstevel@tonic-gate ttrace_walk_step(mdb_walk_state_t *wsp)
7377c478bd9Sstevel@tonic-gate {
7387c478bd9Sstevel@tonic-gate 	ttrace_walk_data_t *tw = wsp->walk_data;
7397c478bd9Sstevel@tonic-gate 	ttrace_cpu_data_t *tc;
7407c478bd9Sstevel@tonic-gate 	struct trap_trace_record *rec;
7417c478bd9Sstevel@tonic-gate 	int oldest, i, status;
7427c478bd9Sstevel@tonic-gate 	uint64_t oldest_tick = 0;
7437c478bd9Sstevel@tonic-gate 	int done = 1;
7447c478bd9Sstevel@tonic-gate 	trap_trace_fullrec_t fullrec;
7457c478bd9Sstevel@tonic-gate 
7467c478bd9Sstevel@tonic-gate 	for (i = 0; i < tw->tw_ncpu; i++) {
7477c478bd9Sstevel@tonic-gate 		tc = &(tw->tw_cpus[i]);
7487c478bd9Sstevel@tonic-gate 
7497c478bd9Sstevel@tonic-gate 		if (tc->tc_rec == NULL)
7507c478bd9Sstevel@tonic-gate 			continue;
7517c478bd9Sstevel@tonic-gate 		done = 0;
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate 		if (tc->tc_rec->tt_tick == 0)
7547c478bd9Sstevel@tonic-gate 			mdb_warn("Warning: tt_tick == 0\n");
7557c478bd9Sstevel@tonic-gate 
7567c478bd9Sstevel@tonic-gate 		if (tc->tc_rec->tt_tick > oldest_tick) {
7577c478bd9Sstevel@tonic-gate 			oldest_tick = tc->tc_rec->tt_tick;
7587c478bd9Sstevel@tonic-gate 			oldest = i;
7597c478bd9Sstevel@tonic-gate 		}
7607c478bd9Sstevel@tonic-gate 	}
7617c478bd9Sstevel@tonic-gate 
7627c478bd9Sstevel@tonic-gate 	if (done)
7637c478bd9Sstevel@tonic-gate 		return (-1);
7647c478bd9Sstevel@tonic-gate 
7657c478bd9Sstevel@tonic-gate 	tc = &(tw->tw_cpus[oldest]);
7667c478bd9Sstevel@tonic-gate 	rec = tc->tc_rec;
7677c478bd9Sstevel@tonic-gate 
7687c478bd9Sstevel@tonic-gate 	fullrec.ttf_rec = *rec;
7697c478bd9Sstevel@tonic-gate 	fullrec.ttf_cpu = oldest;
7707c478bd9Sstevel@tonic-gate 
7717c478bd9Sstevel@tonic-gate 	if (oldest_tick != 0)
7727c478bd9Sstevel@tonic-gate 		status = wsp->walk_callback((uintptr_t)rec -
7737c478bd9Sstevel@tonic-gate 		    (uintptr_t)tc->tc_buf + tc->tc_base, &fullrec,
7747c478bd9Sstevel@tonic-gate 		    wsp->walk_cbdata);
7757c478bd9Sstevel@tonic-gate 
7767c478bd9Sstevel@tonic-gate 	tc->tc_rec--;
7777c478bd9Sstevel@tonic-gate 
7787c478bd9Sstevel@tonic-gate 	if (tc->tc_rec < tc->tc_buf)
7797c478bd9Sstevel@tonic-gate 		tc->tc_rec = (struct trap_trace_record *)((uintptr_t)
7807c478bd9Sstevel@tonic-gate 		    tc->tc_buf + (uintptr_t)tc->tc_bufsiz -
7817c478bd9Sstevel@tonic-gate 		    sizeof (struct trap_trace_record));
7827c478bd9Sstevel@tonic-gate 
7837c478bd9Sstevel@tonic-gate 	if (tc->tc_rec == tc->tc_stop) {
7847c478bd9Sstevel@tonic-gate 		tc->tc_rec = NULL;
7857c478bd9Sstevel@tonic-gate 		mdb_free(tc->tc_buf, tc->tc_bufsiz);
7867c478bd9Sstevel@tonic-gate 	}
7877c478bd9Sstevel@tonic-gate 
7887c478bd9Sstevel@tonic-gate 	return (status);
7897c478bd9Sstevel@tonic-gate }
7907c478bd9Sstevel@tonic-gate 
7917c478bd9Sstevel@tonic-gate void
7927c478bd9Sstevel@tonic-gate ttrace_walk_fini(mdb_walk_state_t *wsp)
7937c478bd9Sstevel@tonic-gate {
7947c478bd9Sstevel@tonic-gate 	ttrace_walk_data_t *tw = wsp->walk_data;
7957c478bd9Sstevel@tonic-gate 
7967c478bd9Sstevel@tonic-gate 	mdb_free(tw->tw_cpus, sizeof (ttrace_cpu_data_t) * tw->tw_ncpu);
7977c478bd9Sstevel@tonic-gate 	mdb_free(tw, sizeof (ttrace_walk_data_t));
7987c478bd9Sstevel@tonic-gate }
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate int
8017c478bd9Sstevel@tonic-gate ttrace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
8027c478bd9Sstevel@tonic-gate {
8037c478bd9Sstevel@tonic-gate 	uint_t opt_x = FALSE;
8047c478bd9Sstevel@tonic-gate 	int cpu = -1;
8057c478bd9Sstevel@tonic-gate 	mdb_walk_cb_t ttprint;
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv,
8087c478bd9Sstevel@tonic-gate 	    'x', MDB_OPT_SETBITS, TRUE, &opt_x, NULL) != argc)
8097c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
8107c478bd9Sstevel@tonic-gate 
8117c478bd9Sstevel@tonic-gate 	if (flags & DCMD_ADDRSPEC) {
8127c478bd9Sstevel@tonic-gate 		if (fetch_ncpu())
8137c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
8147c478bd9Sstevel@tonic-gate 		if (addr >= ncpu) {
8157c478bd9Sstevel@tonic-gate 			mdb_warn("expected cpu between 0 and %d\n", ncpu - 1);
8167c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
8177c478bd9Sstevel@tonic-gate 		}
8187c478bd9Sstevel@tonic-gate 		cpu = (int)addr;
8197c478bd9Sstevel@tonic-gate 	}
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate 	if (cpu == -1)
8227c478bd9Sstevel@tonic-gate 		mdb_printf("CPU ");
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate 	if (opt_x) {
8257c478bd9Sstevel@tonic-gate #ifdef sun4v
8267c478bd9Sstevel@tonic-gate 		mdb_printf("%-16s %-16s %-4s %-3s %-3s %-?s %-?s %-?s "
8277c478bd9Sstevel@tonic-gate 		    "F1-4\n", "%tick", "%tstate", "%tt", "%tl", "%gl",
8287c478bd9Sstevel@tonic-gate 		    "%tpc", "%sp", "TR");
8297c478bd9Sstevel@tonic-gate #else
8307c478bd9Sstevel@tonic-gate 		mdb_printf("%-16s %-16s %-4s %-4s %-?s %-?s %-?s "
8317c478bd9Sstevel@tonic-gate 		    "F1-4\n", "%tick", "%tstate", "%tt", "%tl",
8327c478bd9Sstevel@tonic-gate 		    "%tpc", "%sp", "TR");
8337c478bd9Sstevel@tonic-gate #endif
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate 		ttprint = (mdb_walk_cb_t)ttprint_long;
8367c478bd9Sstevel@tonic-gate 	} else {
8377c478bd9Sstevel@tonic-gate #ifdef sun4v
8387c478bd9Sstevel@tonic-gate 		mdb_printf("%-16s %-4s %-12s %-3s %-3s %s\n",
8397c478bd9Sstevel@tonic-gate 		    "%tick", "%tt", "", "%tl", "%gl", "%tpc");
8407c478bd9Sstevel@tonic-gate #else
8417c478bd9Sstevel@tonic-gate 		mdb_printf("%-16s %-4s %-12s %-4s %s\n",
8427c478bd9Sstevel@tonic-gate 		    "%tick", "%tt", "", "%tl", "%tpc");
8437c478bd9Sstevel@tonic-gate #endif
8447c478bd9Sstevel@tonic-gate 
8457c478bd9Sstevel@tonic-gate 		ttprint = (mdb_walk_cb_t)ttprint_short;
8467c478bd9Sstevel@tonic-gate 	}
8477c478bd9Sstevel@tonic-gate 
8487c478bd9Sstevel@tonic-gate 	if (mdb_walk("ttrace", ttprint, &cpu) == -1) {
8497c478bd9Sstevel@tonic-gate 		mdb_warn("couldn't walk ttrace");
8507c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
8517c478bd9Sstevel@tonic-gate 	}
8527c478bd9Sstevel@tonic-gate 
8537c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
8547c478bd9Sstevel@tonic-gate }
8557c478bd9Sstevel@tonic-gate 
8567c478bd9Sstevel@tonic-gate #ifdef sun4v
8577c478bd9Sstevel@tonic-gate /*ARGSUSED*/
8587c478bd9Sstevel@tonic-gate int
8597c478bd9Sstevel@tonic-gate httctl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
8607c478bd9Sstevel@tonic-gate {
8617c478bd9Sstevel@tonic-gate 	TRAP_TRACE_CTL *ctls, *ctl;
862a92801d6Ssvemuri 	int i, htraptrace_buf_inuse = 0;
8637c478bd9Sstevel@tonic-gate 	htrap_trace_hdr_t hdr;
8647c478bd9Sstevel@tonic-gate 
8657c478bd9Sstevel@tonic-gate 	if (argc != 0)
8667c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
8677c478bd9Sstevel@tonic-gate 
8687c478bd9Sstevel@tonic-gate 	if (fetch_ncpu())
8697c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate 	ctls = mdb_alloc(sizeof (TRAP_TRACE_CTL) * ncpu, UM_SLEEP | UM_GC);
8727c478bd9Sstevel@tonic-gate 	if (mdb_readsym(ctls, sizeof (TRAP_TRACE_CTL) * ncpu,
8737c478bd9Sstevel@tonic-gate 	    "trap_trace_ctl") == -1) {
8747c478bd9Sstevel@tonic-gate 		mdb_warn("symbol 'trap_trace_ctl' not found");
8757c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
8767c478bd9Sstevel@tonic-gate 	}
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate 	for (ctl = &ctls[0], i = 0; i < ncpu; i++, ctl++) {
8797c478bd9Sstevel@tonic-gate 		if (ctl->d.hvaddr_base == 0)
8807c478bd9Sstevel@tonic-gate 			continue;
8817c478bd9Sstevel@tonic-gate 
882a92801d6Ssvemuri 		htraptrace_buf_inuse = 1;
8837c478bd9Sstevel@tonic-gate 		mdb_vread(&hdr, sizeof (htrap_trace_hdr_t),
8847c478bd9Sstevel@tonic-gate 		    (uintptr_t)ctl->d.hvaddr_base);
8857c478bd9Sstevel@tonic-gate 		mdb_printf("htrap_trace_ctl[%d] = {\n", i);
8867c478bd9Sstevel@tonic-gate 		mdb_printf("  vaddr_base = 0x%lx\n", (long)ctl->d.hvaddr_base);
8877c478bd9Sstevel@tonic-gate 		mdb_printf("  last_offset = 0x%lx\n", hdr.last_offset);
8887c478bd9Sstevel@tonic-gate 		mdb_printf("  offset = 0x%lx\n", hdr.offset);
8897c478bd9Sstevel@tonic-gate 		mdb_printf("  limit = 0x%x\n", ctl->d.hlimit);
8907c478bd9Sstevel@tonic-gate 		mdb_printf("  paddr_base = 0x%llx\n}\n", ctl->d.hpaddr_base);
8917c478bd9Sstevel@tonic-gate 	}
892a92801d6Ssvemuri 	if (!htraptrace_buf_inuse) {
893a92801d6Ssvemuri 		mdb_warn("hv traptrace not configured");
894a92801d6Ssvemuri 		return (DCMD_ERR);
895a92801d6Ssvemuri 	}
8967c478bd9Sstevel@tonic-gate 
8977c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
8987c478bd9Sstevel@tonic-gate }
8997c478bd9Sstevel@tonic-gate 
9007c478bd9Sstevel@tonic-gate /*ARGSUSED*/
9017c478bd9Sstevel@tonic-gate static int
9027c478bd9Sstevel@tonic-gate httprint_short(uintptr_t addr, const htrap_trace_fullrec_t *full, int *cpu)
9037c478bd9Sstevel@tonic-gate {
9047c478bd9Sstevel@tonic-gate 	const char *ttstr;
9057c478bd9Sstevel@tonic-gate 	const struct htrap_trace_record *ttp = &full->ttf_rec;
9067c478bd9Sstevel@tonic-gate 
9077c478bd9Sstevel@tonic-gate 	if (*cpu == -1)
9087c478bd9Sstevel@tonic-gate 		mdb_printf("%3d ", full->ttf_cpu);
9097c478bd9Sstevel@tonic-gate 	else
9107c478bd9Sstevel@tonic-gate 		if (*cpu != full->ttf_cpu)
9117c478bd9Sstevel@tonic-gate 			return (0);
9127c478bd9Sstevel@tonic-gate 
9137c478bd9Sstevel@tonic-gate 	/*
9147c478bd9Sstevel@tonic-gate 	 * Convert the tt value to a string using our gaint lookuo table
9157c478bd9Sstevel@tonic-gate 	 */
9167c478bd9Sstevel@tonic-gate 	ttstr = ttp->tt_tt < ttndescr ? ttdescr[ttp->tt_tt] : "?";
9177c478bd9Sstevel@tonic-gate 
9187c478bd9Sstevel@tonic-gate 	mdb_printf("%016llx %02x  %04hx %04hx %-16s %02x  %02x  %0?p %A\n",
9197c478bd9Sstevel@tonic-gate 	    ttp->tt_tick, ttp->tt_ty, ttp->tt_tag, ttp->tt_tt, ttstr,
9207c478bd9Sstevel@tonic-gate 	    ttp->tt_tl, ttp->tt_gl, ttp->tt_tpc, ttp->tt_tpc);
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
9237c478bd9Sstevel@tonic-gate }
9247c478bd9Sstevel@tonic-gate 
9257c478bd9Sstevel@tonic-gate /*ARGSUSED*/
9267c478bd9Sstevel@tonic-gate static int
9277c478bd9Sstevel@tonic-gate httprint_long(uintptr_t addr, const htrap_trace_fullrec_t *full, int *cpu)
9287c478bd9Sstevel@tonic-gate {
9297c478bd9Sstevel@tonic-gate 	const struct htrap_trace_record *ttp = &full->ttf_rec;
9307c478bd9Sstevel@tonic-gate 
9317c478bd9Sstevel@tonic-gate 	if (*cpu == -1)
9327c478bd9Sstevel@tonic-gate 		mdb_printf("%3d ", full->ttf_cpu);
9337c478bd9Sstevel@tonic-gate 	else if (*cpu != full->ttf_cpu)
9347c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
9357c478bd9Sstevel@tonic-gate 
9367c478bd9Sstevel@tonic-gate 	mdb_printf("%016llx %016llx %02x  %02x  %04hx %04hx %02x  %02x  %0?p "
9377c478bd9Sstevel@tonic-gate 	    "[%p,%p,%p,%p]\n",
9387c478bd9Sstevel@tonic-gate 	    ttp->tt_tick, ttp->tt_tstate, ttp->tt_hpstate, ttp->tt_ty,
9397c478bd9Sstevel@tonic-gate 	    ttp->tt_tag, ttp->tt_tt, ttp->tt_tl, ttp->tt_gl, ttp->tt_tpc,
9407c478bd9Sstevel@tonic-gate 	    ttp->tt_f1, ttp->tt_f2, ttp->tt_f3, ttp->tt_f4);
9417c478bd9Sstevel@tonic-gate 
9427c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
9437c478bd9Sstevel@tonic-gate }
9447c478bd9Sstevel@tonic-gate 
9457c478bd9Sstevel@tonic-gate typedef struct httrace_cpu_data {
9467c478bd9Sstevel@tonic-gate 	struct htrap_trace_record *tc_buf;
9477c478bd9Sstevel@tonic-gate 	struct htrap_trace_record *tc_rec;
9487c478bd9Sstevel@tonic-gate 	struct htrap_trace_record *tc_stop;
9497c478bd9Sstevel@tonic-gate 	size_t tc_bufsiz;
9507c478bd9Sstevel@tonic-gate 	uintptr_t tc_base;
9517c478bd9Sstevel@tonic-gate } httrace_cpu_data_t;
9527c478bd9Sstevel@tonic-gate 
9537c478bd9Sstevel@tonic-gate typedef struct httrace_walk_data {
9547c478bd9Sstevel@tonic-gate 	int tw_ncpu;
9557c478bd9Sstevel@tonic-gate 	httrace_cpu_data_t *tw_cpus;
9567c478bd9Sstevel@tonic-gate } httrace_walk_data_t;
9577c478bd9Sstevel@tonic-gate 
9587c478bd9Sstevel@tonic-gate int
9597c478bd9Sstevel@tonic-gate httrace_walk_init(mdb_walk_state_t *wsp)
9607c478bd9Sstevel@tonic-gate {
9617c478bd9Sstevel@tonic-gate 	TRAP_TRACE_CTL *ctls, *ctl;
962a92801d6Ssvemuri 	int i, htraptrace_buf_inuse = 0;
9637c478bd9Sstevel@tonic-gate 	httrace_walk_data_t *tw;
9647c478bd9Sstevel@tonic-gate 	httrace_cpu_data_t *tc;
9657c478bd9Sstevel@tonic-gate 	struct htrap_trace_record *buf;
966a45d830bSha137994 	htrap_trace_hdr_t *hdr;
9677c478bd9Sstevel@tonic-gate 
9687c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr != NULL) {
9697c478bd9Sstevel@tonic-gate 		mdb_warn("httrace only supports global walks\n");
9707c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
9717c478bd9Sstevel@tonic-gate 	}
9727c478bd9Sstevel@tonic-gate 
9737c478bd9Sstevel@tonic-gate 	if (fetch_ncpu())
9747c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
9757c478bd9Sstevel@tonic-gate 
9767c478bd9Sstevel@tonic-gate 	ctls = mdb_alloc(sizeof (TRAP_TRACE_CTL) * ncpu, UM_SLEEP);
9777c478bd9Sstevel@tonic-gate 	if (mdb_readsym(ctls, sizeof (TRAP_TRACE_CTL) * ncpu,
9787c478bd9Sstevel@tonic-gate 	    "trap_trace_ctl") == -1) {
9797c478bd9Sstevel@tonic-gate 		mdb_warn("symbol 'trap_trace_ctl' not found");
9807c478bd9Sstevel@tonic-gate 		mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu);
9817c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
9827c478bd9Sstevel@tonic-gate 	}
9837c478bd9Sstevel@tonic-gate 
9847c478bd9Sstevel@tonic-gate 	tw = mdb_zalloc(sizeof (httrace_walk_data_t), UM_SLEEP);
9857c478bd9Sstevel@tonic-gate 	tw->tw_ncpu = ncpu;
9867c478bd9Sstevel@tonic-gate 	tw->tw_cpus = mdb_zalloc(sizeof (httrace_cpu_data_t) * ncpu, UM_SLEEP);
9877c478bd9Sstevel@tonic-gate 
9887c478bd9Sstevel@tonic-gate 	for (i = 0; i < ncpu; i++) {
9897c478bd9Sstevel@tonic-gate 		ctl = &ctls[i];
9907c478bd9Sstevel@tonic-gate 
9917c478bd9Sstevel@tonic-gate 		if (ctl->d.hvaddr_base == 0)
9927c478bd9Sstevel@tonic-gate 			continue;
9937c478bd9Sstevel@tonic-gate 
994a92801d6Ssvemuri 		htraptrace_buf_inuse = 1;
9957c478bd9Sstevel@tonic-gate 		tc = &(tw->tw_cpus[i]);
996a45d830bSha137994 		tc->tc_bufsiz = ctl->d.hlimit;
9977c478bd9Sstevel@tonic-gate 		tc->tc_buf = buf = mdb_alloc(tc->tc_bufsiz, UM_SLEEP);
9987c478bd9Sstevel@tonic-gate 		tc->tc_base = (uintptr_t)ctl->d.hvaddr_base;
9997c478bd9Sstevel@tonic-gate 
10007c478bd9Sstevel@tonic-gate 		if (mdb_vread(buf, tc->tc_bufsiz, tc->tc_base) == -1) {
10017c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read hv trap trace buffer at %p",
10027c478bd9Sstevel@tonic-gate 			    ctl->d.hvaddr_base);
10037c478bd9Sstevel@tonic-gate 			mdb_free(buf, tc->tc_bufsiz);
10047c478bd9Sstevel@tonic-gate 			tc->tc_buf = NULL;
10057c478bd9Sstevel@tonic-gate 		} else {
1006a45d830bSha137994 			hdr = (htrap_trace_hdr_t *)buf;
10077c478bd9Sstevel@tonic-gate 			tc->tc_rec = (struct htrap_trace_record *)
1008a45d830bSha137994 			    ((uintptr_t)buf + (uintptr_t)hdr->last_offset);
10097c478bd9Sstevel@tonic-gate 			tc->tc_stop = (struct htrap_trace_record *)
1010a45d830bSha137994 			    ((uintptr_t)buf + (uintptr_t)hdr->offset);
10117c478bd9Sstevel@tonic-gate 		}
10127c478bd9Sstevel@tonic-gate 	}
1013a92801d6Ssvemuri 	if (!htraptrace_buf_inuse) {
1014a92801d6Ssvemuri 		mdb_warn("hv traptrace not configured");
1015a92801d6Ssvemuri 		mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu);
1016a92801d6Ssvemuri 		return (DCMD_ERR);
1017a92801d6Ssvemuri 	}
10187c478bd9Sstevel@tonic-gate 
10197c478bd9Sstevel@tonic-gate 	mdb_free(ctls, sizeof (TRAP_TRACE_CTL) * ncpu);
10207c478bd9Sstevel@tonic-gate 	wsp->walk_data = tw;
10217c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
10227c478bd9Sstevel@tonic-gate }
10237c478bd9Sstevel@tonic-gate 
10247c478bd9Sstevel@tonic-gate int
10257c478bd9Sstevel@tonic-gate httrace_walk_step(mdb_walk_state_t *wsp)
10267c478bd9Sstevel@tonic-gate {
10277c478bd9Sstevel@tonic-gate 	httrace_walk_data_t *tw = wsp->walk_data;
10287c478bd9Sstevel@tonic-gate 	httrace_cpu_data_t *tc;
10297c478bd9Sstevel@tonic-gate 	struct htrap_trace_record *rec;
10307c478bd9Sstevel@tonic-gate 	int oldest, i, status;
10317c478bd9Sstevel@tonic-gate 	uint64_t oldest_tick = 0;
10327c478bd9Sstevel@tonic-gate 	int done = 1;
10337c478bd9Sstevel@tonic-gate 	htrap_trace_fullrec_t fullrec;
10347c478bd9Sstevel@tonic-gate 
10357c478bd9Sstevel@tonic-gate 	for (i = 0; i < tw->tw_ncpu; i++) {
10367c478bd9Sstevel@tonic-gate 		tc = &(tw->tw_cpus[i]);
10377c478bd9Sstevel@tonic-gate 
10387c478bd9Sstevel@tonic-gate 		if (tc->tc_rec == NULL)
10397c478bd9Sstevel@tonic-gate 			continue;
10407c478bd9Sstevel@tonic-gate 		done = 0;
10417c478bd9Sstevel@tonic-gate 
10427c478bd9Sstevel@tonic-gate 		if (tc->tc_rec->tt_tick == 0)
10437c478bd9Sstevel@tonic-gate 			mdb_warn("Warning: tt_tick == 0\n");
10447c478bd9Sstevel@tonic-gate 
1045a45d830bSha137994 		if (tc->tc_rec->tt_tick >= oldest_tick) {
10467c478bd9Sstevel@tonic-gate 			oldest_tick = tc->tc_rec->tt_tick;
10477c478bd9Sstevel@tonic-gate 			oldest = i;
10487c478bd9Sstevel@tonic-gate 		}
10497c478bd9Sstevel@tonic-gate 	}
10507c478bd9Sstevel@tonic-gate 
10517c478bd9Sstevel@tonic-gate 	if (done)
10527c478bd9Sstevel@tonic-gate 		return (-1);
10537c478bd9Sstevel@tonic-gate 
10547c478bd9Sstevel@tonic-gate 	tc = &(tw->tw_cpus[oldest]);
10557c478bd9Sstevel@tonic-gate 	rec = tc->tc_rec;
10567c478bd9Sstevel@tonic-gate 
10577c478bd9Sstevel@tonic-gate 	fullrec.ttf_rec = *rec;
10587c478bd9Sstevel@tonic-gate 	fullrec.ttf_cpu = oldest;
10597c478bd9Sstevel@tonic-gate 
10607c478bd9Sstevel@tonic-gate 	if (oldest_tick != 0)
10617c478bd9Sstevel@tonic-gate 		status = wsp->walk_callback((uintptr_t)rec -
10627c478bd9Sstevel@tonic-gate 		    (uintptr_t)tc->tc_buf + tc->tc_base, &fullrec,
10637c478bd9Sstevel@tonic-gate 		    wsp->walk_cbdata);
10647c478bd9Sstevel@tonic-gate 
10657c478bd9Sstevel@tonic-gate 	tc->tc_rec--;
10667c478bd9Sstevel@tonic-gate 
10677c478bd9Sstevel@tonic-gate 	/* first record of the trap trace buffer is trap trace header */
10687c478bd9Sstevel@tonic-gate 	if (tc->tc_rec == tc->tc_buf)
10697c478bd9Sstevel@tonic-gate 		tc->tc_rec = (struct htrap_trace_record *)((uintptr_t)
10707c478bd9Sstevel@tonic-gate 		    tc->tc_buf + (uintptr_t)tc->tc_bufsiz -
10717c478bd9Sstevel@tonic-gate 		    sizeof (struct htrap_trace_record));
10727c478bd9Sstevel@tonic-gate 
10737c478bd9Sstevel@tonic-gate 	if (tc->tc_rec == tc->tc_stop) {
10747c478bd9Sstevel@tonic-gate 		tc->tc_rec = NULL;
10757c478bd9Sstevel@tonic-gate 		mdb_free(tc->tc_buf, tc->tc_bufsiz);
10767c478bd9Sstevel@tonic-gate 	}
10777c478bd9Sstevel@tonic-gate 
10787c478bd9Sstevel@tonic-gate 	return (status);
10797c478bd9Sstevel@tonic-gate }
10807c478bd9Sstevel@tonic-gate 
10817c478bd9Sstevel@tonic-gate void
10827c478bd9Sstevel@tonic-gate httrace_walk_fini(mdb_walk_state_t *wsp)
10837c478bd9Sstevel@tonic-gate {
10847c478bd9Sstevel@tonic-gate 	httrace_walk_data_t *tw = wsp->walk_data;
10857c478bd9Sstevel@tonic-gate 
10867c478bd9Sstevel@tonic-gate 	mdb_free(tw->tw_cpus, sizeof (httrace_cpu_data_t) * tw->tw_ncpu);
10877c478bd9Sstevel@tonic-gate 	mdb_free(tw, sizeof (httrace_walk_data_t));
10887c478bd9Sstevel@tonic-gate }
10897c478bd9Sstevel@tonic-gate 
10907c478bd9Sstevel@tonic-gate int
10917c478bd9Sstevel@tonic-gate httrace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
10927c478bd9Sstevel@tonic-gate {
10937c478bd9Sstevel@tonic-gate 	uint_t opt_x = FALSE;
10947c478bd9Sstevel@tonic-gate 	int cpu = -1;
10957c478bd9Sstevel@tonic-gate 	mdb_walk_cb_t ttprint;
10967c478bd9Sstevel@tonic-gate 
10977c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv,
10987c478bd9Sstevel@tonic-gate 	    'x', MDB_OPT_SETBITS, TRUE, &opt_x, NULL) != argc)
10997c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
11007c478bd9Sstevel@tonic-gate 
11017c478bd9Sstevel@tonic-gate 	if (flags & DCMD_ADDRSPEC) {
11027c478bd9Sstevel@tonic-gate 		if (fetch_ncpu())
11037c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
11047c478bd9Sstevel@tonic-gate 		if (addr >= ncpu) {
11057c478bd9Sstevel@tonic-gate 			mdb_warn("expected cpu between 0 and %d\n", ncpu - 1);
11067c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
11077c478bd9Sstevel@tonic-gate 		}
11087c478bd9Sstevel@tonic-gate 		cpu = (int)addr;
11097c478bd9Sstevel@tonic-gate 	}
11107c478bd9Sstevel@tonic-gate 
11117c478bd9Sstevel@tonic-gate 	if (cpu == -1)
11127c478bd9Sstevel@tonic-gate 		mdb_printf("CPU ");
11137c478bd9Sstevel@tonic-gate 
11147c478bd9Sstevel@tonic-gate 	if (opt_x) {
11157c478bd9Sstevel@tonic-gate 		mdb_printf("%-16s %-16s %-3s %-3s %-4s %-4s %-3s %-3s %-?s "
11167c478bd9Sstevel@tonic-gate 		    "F1-4\n", "%tick", "%tstate", "%hp", "%ty", "%tag",
11177c478bd9Sstevel@tonic-gate 		    "%tt", "%tl", "%gl", "%tpc");
11187c478bd9Sstevel@tonic-gate 		ttprint = (mdb_walk_cb_t)httprint_long;
11197c478bd9Sstevel@tonic-gate 	} else {
11207c478bd9Sstevel@tonic-gate 		mdb_printf("%-16s %-3s %-4s %-4s %-16s %-3s %-3s %s\n",
11217c478bd9Sstevel@tonic-gate 		    "%tick", "%ty", "%tag", "%tt", "", "%tl", "%gl",
11227c478bd9Sstevel@tonic-gate 		    "%tpc");
11237c478bd9Sstevel@tonic-gate 		ttprint = (mdb_walk_cb_t)httprint_short;
11247c478bd9Sstevel@tonic-gate 	}
11257c478bd9Sstevel@tonic-gate 
11267c478bd9Sstevel@tonic-gate 	if (mdb_walk("httrace", ttprint, &cpu) == -1) {
11277c478bd9Sstevel@tonic-gate 		mdb_warn("couldn't walk httrace");
11287c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
11297c478bd9Sstevel@tonic-gate 	}
11307c478bd9Sstevel@tonic-gate 
11317c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
11327c478bd9Sstevel@tonic-gate }
11337c478bd9Sstevel@tonic-gate #endif
11347c478bd9Sstevel@tonic-gate 
11357c478bd9Sstevel@tonic-gate struct {
11367c478bd9Sstevel@tonic-gate 	int xc_type;
11377c478bd9Sstevel@tonic-gate 	const char *xc_str;
11387c478bd9Sstevel@tonic-gate } xc_data[] = {
11397c478bd9Sstevel@tonic-gate 	{ XT_ONE_SELF,		"xt-one-self" },
11407c478bd9Sstevel@tonic-gate 	{ XT_ONE_OTHER,		"xt-one-other" },
11417c478bd9Sstevel@tonic-gate 	{ XT_SOME_SELF,		"xt-some-self" },
11427c478bd9Sstevel@tonic-gate 	{ XT_SOME_OTHER,	"xt-some-other" },
11437c478bd9Sstevel@tonic-gate 	{ XT_ALL_SELF,		"xt-all-self" },
11447c478bd9Sstevel@tonic-gate 	{ XT_ALL_OTHER,		"xt-all-other" },
11457c478bd9Sstevel@tonic-gate 	{ XC_ONE_SELF,		"xc-one-self" },
11467c478bd9Sstevel@tonic-gate 	{ XC_ONE_OTHER,		"xc-one-other" },
11477c478bd9Sstevel@tonic-gate 	{ XC_ONE_OTHER_H,	"xc-one-other-h" },
11487c478bd9Sstevel@tonic-gate 	{ XC_SOME_SELF,		"xc-some-self" },
11497c478bd9Sstevel@tonic-gate 	{ XC_SOME_OTHER,	"xc-some-other" },
11507c478bd9Sstevel@tonic-gate 	{ XC_SOME_OTHER_H,	"xc-some-other-h" },
11517c478bd9Sstevel@tonic-gate 	{ XC_ALL_SELF,		"xc-all-self" },
11527c478bd9Sstevel@tonic-gate 	{ XC_ALL_OTHER,		"xc-all-other" },
11537c478bd9Sstevel@tonic-gate 	{ XC_ALL_OTHER_H,	"xc-all-other-h" },
11547c478bd9Sstevel@tonic-gate 	{ XC_ATTENTION,		"xc-attention" },
11557c478bd9Sstevel@tonic-gate 	{ XC_DISMISSED,		"xc-dismissed" },
11567c478bd9Sstevel@tonic-gate 	{ XC_LOOP_ENTER,	"xc-loop-enter" },
11577c478bd9Sstevel@tonic-gate 	{ XC_LOOP_DOIT,		"xc-loop-doit" },
11587c478bd9Sstevel@tonic-gate 	{ XC_LOOP_EXIT,		"xc-loop-exit" },
11597c478bd9Sstevel@tonic-gate 	{ 0,			NULL }
11607c478bd9Sstevel@tonic-gate };
11617c478bd9Sstevel@tonic-gate 
11627c478bd9Sstevel@tonic-gate /*ARGSUSED*/
11637c478bd9Sstevel@tonic-gate int
11647c478bd9Sstevel@tonic-gate xctrace_walk(uintptr_t addr, const trap_trace_fullrec_t *full, int *cpu)
11657c478bd9Sstevel@tonic-gate {
11667c478bd9Sstevel@tonic-gate 	const struct trap_trace_record *ttp = &full->ttf_rec;
11677c478bd9Sstevel@tonic-gate 	int i, type = ttp->tt_tt & 0xff;
11687c478bd9Sstevel@tonic-gate 	const char *str = "???";
11697c478bd9Sstevel@tonic-gate 
11707c478bd9Sstevel@tonic-gate 	if ((ttp->tt_tt & 0xff00) == TT_XCALL) {
11717c478bd9Sstevel@tonic-gate 		for (i = 0; xc_data[i].xc_str != NULL; i++) {
11727c478bd9Sstevel@tonic-gate 			if (xc_data[i].xc_type == type) {
11737c478bd9Sstevel@tonic-gate 				str = xc_data[i].xc_str;
11747c478bd9Sstevel@tonic-gate 				break;
11757c478bd9Sstevel@tonic-gate 			}
11767c478bd9Sstevel@tonic-gate 		}
11777c478bd9Sstevel@tonic-gate 	} else if ((ttp->tt_tt & 0xff00) == TT_XCALL_CONT) {
11787c478bd9Sstevel@tonic-gate 		str = "xcall-cont";
11797c478bd9Sstevel@tonic-gate 		mdb_printf("%3d %016llx %-16s %08x %08x %08x %08x\n",
11807c478bd9Sstevel@tonic-gate 		    full->ttf_cpu, ttp->tt_tick, str, ttp->tt_f1, ttp->tt_f2,
11817c478bd9Sstevel@tonic-gate 		    ttp->tt_f3, ttp->tt_f4);
11827c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
11837c478bd9Sstevel@tonic-gate 	} else if (ttp->tt_tt == 0x60) {
11847c478bd9Sstevel@tonic-gate 		str = "int-vec";
11857c478bd9Sstevel@tonic-gate 	} else {
11867c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
11877c478bd9Sstevel@tonic-gate 	}
11887c478bd9Sstevel@tonic-gate 
11897c478bd9Sstevel@tonic-gate 	mdb_printf("%3d %016llx %-16s %08x %a\n", full->ttf_cpu,
11907c478bd9Sstevel@tonic-gate 	    ttp->tt_tick, str, ttp->tt_sp, ttp->tt_tr);
11917c478bd9Sstevel@tonic-gate 
11927c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
11937c478bd9Sstevel@tonic-gate }
11947c478bd9Sstevel@tonic-gate 
11957c478bd9Sstevel@tonic-gate /*ARGSUSED*/
11967c478bd9Sstevel@tonic-gate int
11977c478bd9Sstevel@tonic-gate xctrace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
11987c478bd9Sstevel@tonic-gate {
11997c478bd9Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) || argc != 0)
12007c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
12017c478bd9Sstevel@tonic-gate 
12027c478bd9Sstevel@tonic-gate 	if (mdb_walk("ttrace", (mdb_walk_cb_t)xctrace_walk, NULL) == -1) {
12037c478bd9Sstevel@tonic-gate 		mdb_warn("couldn't walk ttrace");
12047c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
12057c478bd9Sstevel@tonic-gate 	}
12067c478bd9Sstevel@tonic-gate 
12077c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
12087c478bd9Sstevel@tonic-gate }
12097c478bd9Sstevel@tonic-gate 
12107c478bd9Sstevel@tonic-gate /*
12117c478bd9Sstevel@tonic-gate  * Grrr... xc_mbox isn't in an _impl header file; we define it here.
12127c478bd9Sstevel@tonic-gate  */
12137c478bd9Sstevel@tonic-gate typedef struct xc_mbox {
12147c478bd9Sstevel@tonic-gate 	xcfunc_t *xc_func;
12157c478bd9Sstevel@tonic-gate 	uint64_t xc_arg1;
12167c478bd9Sstevel@tonic-gate 	uint64_t xc_arg2;
12177c478bd9Sstevel@tonic-gate 	cpuset_t xc_cpuset;
12187c478bd9Sstevel@tonic-gate 	volatile uint_t xc_state;
12197c478bd9Sstevel@tonic-gate } xc_mbox_t;
12207c478bd9Sstevel@tonic-gate 
12217c478bd9Sstevel@tonic-gate typedef struct xc_mbox_walk {
12227c478bd9Sstevel@tonic-gate 	int xw_ndx;
12237c478bd9Sstevel@tonic-gate 	uintptr_t xw_addr;
12247c478bd9Sstevel@tonic-gate 	xc_mbox_t *xw_mbox;
12257c478bd9Sstevel@tonic-gate } xc_mbox_walk_t;
12267c478bd9Sstevel@tonic-gate 
12277c478bd9Sstevel@tonic-gate static int
12287c478bd9Sstevel@tonic-gate xc_mbox_walk_init(mdb_walk_state_t *wsp)
12297c478bd9Sstevel@tonic-gate {
12307c478bd9Sstevel@tonic-gate 	GElf_Sym sym;
12317c478bd9Sstevel@tonic-gate 	xc_mbox_walk_t *xw;
12327c478bd9Sstevel@tonic-gate 
12337c478bd9Sstevel@tonic-gate 	if (mdb_lookup_by_name("xc_mbox", &sym) == -1) {
12347c478bd9Sstevel@tonic-gate 		mdb_warn("couldn't find 'xc_mbox'");
12357c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
12367c478bd9Sstevel@tonic-gate 	}
12377c478bd9Sstevel@tonic-gate 
12387c478bd9Sstevel@tonic-gate 	if (fetch_ncpu() || fetch_mbox())
12397c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
12407c478bd9Sstevel@tonic-gate 
12417c478bd9Sstevel@tonic-gate 	xw = mdb_zalloc(sizeof (xc_mbox_walk_t), UM_SLEEP);
12427c478bd9Sstevel@tonic-gate 	xw->xw_mbox = mdb_zalloc(mbox_size * ncpu, UM_SLEEP);
12437c478bd9Sstevel@tonic-gate 
12447c478bd9Sstevel@tonic-gate 	if (mdb_readsym(xw->xw_mbox, mbox_size * ncpu, "xc_mbox") == -1) {
12457c478bd9Sstevel@tonic-gate 		mdb_warn("couldn't read 'xc_mbox'");
12467c478bd9Sstevel@tonic-gate 		mdb_free(xw->xw_mbox, mbox_size * ncpu);
12477c478bd9Sstevel@tonic-gate 		mdb_free(xw, sizeof (xc_mbox_walk_t));
12487c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
12497c478bd9Sstevel@tonic-gate 	}
12507c478bd9Sstevel@tonic-gate 
12517c478bd9Sstevel@tonic-gate 	xw->xw_addr = sym.st_value;
12527c478bd9Sstevel@tonic-gate 	wsp->walk_data = xw;
12537c478bd9Sstevel@tonic-gate 
12547c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
12557c478bd9Sstevel@tonic-gate }
12567c478bd9Sstevel@tonic-gate 
12577c478bd9Sstevel@tonic-gate static int
12587c478bd9Sstevel@tonic-gate xc_mbox_walk_step(mdb_walk_state_t *wsp)
12597c478bd9Sstevel@tonic-gate {
12607c478bd9Sstevel@tonic-gate 	xc_mbox_walk_t *xw = wsp->walk_data;
12617c478bd9Sstevel@tonic-gate 	int status;
12627c478bd9Sstevel@tonic-gate 
12637c478bd9Sstevel@tonic-gate 	if (xw->xw_ndx == ncpu)
12647c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
12657c478bd9Sstevel@tonic-gate 
12667c478bd9Sstevel@tonic-gate 	status = wsp->walk_callback(xw->xw_addr,
12677c478bd9Sstevel@tonic-gate 	    &xw->xw_mbox[xw->xw_ndx++], wsp->walk_cbdata);
12687c478bd9Sstevel@tonic-gate 
12697c478bd9Sstevel@tonic-gate 	xw->xw_addr += mbox_size;
12707c478bd9Sstevel@tonic-gate 	return (status);
12717c478bd9Sstevel@tonic-gate }
12727c478bd9Sstevel@tonic-gate 
12737c478bd9Sstevel@tonic-gate static void
12747c478bd9Sstevel@tonic-gate xc_mbox_walk_fini(mdb_walk_state_t *wsp)
12757c478bd9Sstevel@tonic-gate {
12767c478bd9Sstevel@tonic-gate 	xc_mbox_walk_t *xw = wsp->walk_data;
12777c478bd9Sstevel@tonic-gate 
12787c478bd9Sstevel@tonic-gate 	mdb_free(xw->xw_mbox, mbox_size * ncpu);
12797c478bd9Sstevel@tonic-gate 	mdb_free(xw, sizeof (xc_mbox_walk_t));
12807c478bd9Sstevel@tonic-gate }
12817c478bd9Sstevel@tonic-gate 
12827c478bd9Sstevel@tonic-gate static int
12837c478bd9Sstevel@tonic-gate xc_mbox(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
12847c478bd9Sstevel@tonic-gate {
12857c478bd9Sstevel@tonic-gate 	xc_mbox_t *mbox;
12867c478bd9Sstevel@tonic-gate 	GElf_Sym sym;
12877c478bd9Sstevel@tonic-gate 	const char *state;
12887c478bd9Sstevel@tonic-gate 
12897c478bd9Sstevel@tonic-gate 	if (argc != 0)
12907c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
12917c478bd9Sstevel@tonic-gate 
12927c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
12937c478bd9Sstevel@tonic-gate 		if (mdb_walk_dcmd("xc_mbox", "xc_mbox", argc, argv) == -1) {
12947c478bd9Sstevel@tonic-gate 			mdb_warn("can't walk 'xc_mbox'");
12957c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
12967c478bd9Sstevel@tonic-gate 		}
12977c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
12987c478bd9Sstevel@tonic-gate 	}
12997c478bd9Sstevel@tonic-gate 
13007c478bd9Sstevel@tonic-gate 	if (fetch_ncpu() || fetch_mbox())
13017c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
13027c478bd9Sstevel@tonic-gate 
13037c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
13047c478bd9Sstevel@tonic-gate 		mdb_printf("%3s %-8s %-8s %-9s %-16s %-16s %s\n",
13057c478bd9Sstevel@tonic-gate 		    "CPU", "ADDR", "STATE", "CPUSET", "ARG1", "ARG2", "HNDLR");
13067c478bd9Sstevel@tonic-gate 	}
13077c478bd9Sstevel@tonic-gate 
13087c478bd9Sstevel@tonic-gate 	mbox = mdb_alloc(mbox_size, UM_SLEEP | UM_GC);
13097c478bd9Sstevel@tonic-gate 	if (mdb_vread(mbox, mbox_size, addr) == -1) {
13107c478bd9Sstevel@tonic-gate 		mdb_warn("couldn't read xc_mbox at %p", addr);
13117c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
13127c478bd9Sstevel@tonic-gate 	}
13137c478bd9Sstevel@tonic-gate 
13147c478bd9Sstevel@tonic-gate 	if (mbox->xc_func == NULL)
13157c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
13167c478bd9Sstevel@tonic-gate 
13177c478bd9Sstevel@tonic-gate 	if (mdb_lookup_by_name("xc_mbox", &sym) == -1) {
13187c478bd9Sstevel@tonic-gate 		mdb_warn("couldn't read 'xc_mbox'");
13197c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
13207c478bd9Sstevel@tonic-gate 	}
13217c478bd9Sstevel@tonic-gate 
13227c478bd9Sstevel@tonic-gate 	state = mdb_ctf_enum_name(mbox_states,
13237c478bd9Sstevel@tonic-gate 	    /* LINTED - alignment */
13247c478bd9Sstevel@tonic-gate 	    *(int *)((char *)mbox + mbox_stoff));
13257c478bd9Sstevel@tonic-gate 
13267c478bd9Sstevel@tonic-gate 	mdb_printf("%3d %08x %-8s [ ",
13277c478bd9Sstevel@tonic-gate 	    (int)((addr - sym.st_value) / mbox_size), addr,
13287c478bd9Sstevel@tonic-gate 	    state ? state : "XC_???");
13297c478bd9Sstevel@tonic-gate 
13300400e0b7Sha137994 	print_cpuset_range((ulong_t *)&mbox->xc_cpuset, BT_BITOUL(ncpu), 5);
13317c478bd9Sstevel@tonic-gate 
13327c478bd9Sstevel@tonic-gate 	mdb_printf(" ] %-16a %-16a %a\n",
13337c478bd9Sstevel@tonic-gate 	    mbox->xc_arg1, mbox->xc_arg2, mbox->xc_func);
13347c478bd9Sstevel@tonic-gate 
13357c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
13367c478bd9Sstevel@tonic-gate }
13377c478bd9Sstevel@tonic-gate 
1338b0fc0e77Sgovinda typedef struct vecint_walk_data {
1339b0fc0e77Sgovinda 	intr_vec_t **vec_table;
1340b0fc0e77Sgovinda 	uintptr_t vec_base;
1341b0fc0e77Sgovinda 	size_t vec_idx;
1342b0fc0e77Sgovinda 	size_t vec_size;
1343b0fc0e77Sgovinda } vecint_walk_data_t;
1344b0fc0e77Sgovinda 
1345b0fc0e77Sgovinda int
1346b0fc0e77Sgovinda vecint_walk_init(mdb_walk_state_t *wsp)
1347b0fc0e77Sgovinda {
1348b0fc0e77Sgovinda 	vecint_walk_data_t	*vecint;
1349b0fc0e77Sgovinda 
1350b0fc0e77Sgovinda 	if (wsp->walk_addr != NULL) {
1351b0fc0e77Sgovinda 		mdb_warn("vecint walk only supports global walks\n");
1352b0fc0e77Sgovinda 		return (WALK_ERR);
1353b0fc0e77Sgovinda 	}
1354b0fc0e77Sgovinda 
1355b0fc0e77Sgovinda 	vecint = mdb_zalloc(sizeof (vecint_walk_data_t), UM_SLEEP);
1356b0fc0e77Sgovinda 
1357b0fc0e77Sgovinda 	vecint->vec_size = MAXIVNUM * sizeof (intr_vec_t *);
1358b0fc0e77Sgovinda 	vecint->vec_base = (uintptr_t)iv_sym.st_value;
1359b0fc0e77Sgovinda 	vecint->vec_table = mdb_zalloc(vecint->vec_size, UM_SLEEP);
1360b0fc0e77Sgovinda 
1361b0fc0e77Sgovinda 	if (mdb_vread(vecint->vec_table, vecint->vec_size,
1362b0fc0e77Sgovinda 	    vecint->vec_base) == -1) {
1363b0fc0e77Sgovinda 		mdb_warn("couldn't read intr_vec_table");
1364b0fc0e77Sgovinda 		mdb_free(vecint->vec_table, vecint->vec_size);
1365b0fc0e77Sgovinda 		mdb_free(vecint, sizeof (vecint_walk_data_t));
1366b0fc0e77Sgovinda 		return (WALK_ERR);
1367b0fc0e77Sgovinda 	}
1368b0fc0e77Sgovinda 
1369b0fc0e77Sgovinda 	wsp->walk_data = vecint;
1370b0fc0e77Sgovinda 	return (WALK_NEXT);
1371b0fc0e77Sgovinda }
1372b0fc0e77Sgovinda 
1373b0fc0e77Sgovinda int
1374b0fc0e77Sgovinda vecint_walk_step(mdb_walk_state_t *wsp)
1375b0fc0e77Sgovinda {
1376b0fc0e77Sgovinda 	vecint_walk_data_t	*vecint = (vecint_walk_data_t *)wsp->walk_data;
1377b0fc0e77Sgovinda 	size_t			max = vecint->vec_size / sizeof (intr_vec_t *);
1378b0fc0e77Sgovinda 	intr_vec_t		iv;
1379b0fc0e77Sgovinda 	int			status;
1380b0fc0e77Sgovinda 
1381b0fc0e77Sgovinda 	if (wsp->walk_addr == NULL) {
1382b0fc0e77Sgovinda 		while ((vecint->vec_idx < max) && ((wsp->walk_addr =
1383b0fc0e77Sgovinda 		    (uintptr_t)vecint->vec_table[vecint->vec_idx++]) == NULL))
1384b0fc0e77Sgovinda 			continue;
1385b0fc0e77Sgovinda 	}
1386b0fc0e77Sgovinda 
1387b0fc0e77Sgovinda 	if (wsp->walk_addr == NULL)
1388b0fc0e77Sgovinda 		return (WALK_DONE);
1389b0fc0e77Sgovinda 
1390b0fc0e77Sgovinda 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
1391b0fc0e77Sgovinda 	    wsp->walk_cbdata);
1392b0fc0e77Sgovinda 
1393b0fc0e77Sgovinda 	if (mdb_vread(&iv, sizeof (intr_vec_t),
1394b0fc0e77Sgovinda 	    (uintptr_t)wsp->walk_addr) == -1) {
1395b0fc0e77Sgovinda 		mdb_warn("failed to read iv_p %p\n", wsp->walk_addr);
1396b0fc0e77Sgovinda 		return (WALK_ERR);
1397b0fc0e77Sgovinda 	}
1398b0fc0e77Sgovinda 
1399b0fc0e77Sgovinda 	wsp->walk_addr = (uintptr_t)iv.iv_vec_next;
1400b0fc0e77Sgovinda 	return (status);
1401b0fc0e77Sgovinda }
1402b0fc0e77Sgovinda 
1403b0fc0e77Sgovinda void
1404b0fc0e77Sgovinda vecint_walk_fini(mdb_walk_state_t *wsp)
1405b0fc0e77Sgovinda {
1406b0fc0e77Sgovinda 	vecint_walk_data_t	*vecint = wsp->walk_data;
1407b0fc0e77Sgovinda 
1408b0fc0e77Sgovinda 	mdb_free(vecint->vec_table, vecint->vec_size);
1409b0fc0e77Sgovinda 	mdb_free(vecint, sizeof (vecint_walk_data_t));
1410b0fc0e77Sgovinda }
1411b0fc0e77Sgovinda 
1412b0fc0e77Sgovinda int
1413b0fc0e77Sgovinda vecint_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1414b0fc0e77Sgovinda {
1415b0fc0e77Sgovinda 	intr_vec_t	iv;
1416b0fc0e77Sgovinda 
1417b0fc0e77Sgovinda 	if (!(flags & DCMD_ADDRSPEC)) {
1418b0fc0e77Sgovinda 		if (mdb_walk_dcmd("vecint", "vecint", argc, argv) == -1) {
1419b0fc0e77Sgovinda 			mdb_warn("can't walk vecint");
1420b0fc0e77Sgovinda 			return (DCMD_ERR);
1421b0fc0e77Sgovinda 		}
1422b0fc0e77Sgovinda 		return (DCMD_OK);
1423b0fc0e77Sgovinda 	}
1424b0fc0e77Sgovinda 
1425b0fc0e77Sgovinda 	if (DCMD_HDRSPEC(flags)) {
1426b0fc0e77Sgovinda 		mdb_printf("%4s %?s %4s %?s %?s %s\n", "INUM", "ADDR",
1427b0fc0e77Sgovinda 		    "PIL", "ARG1", "ARG2", "HANDLER");
1428b0fc0e77Sgovinda 	}
1429b0fc0e77Sgovinda 
1430b0fc0e77Sgovinda 	if (mdb_vread(&iv, sizeof (iv), addr) == -1) {
1431b0fc0e77Sgovinda 		mdb_warn("couldn't read intr_vec_table at %p", addr);
1432b0fc0e77Sgovinda 		return (DCMD_ERR);
1433b0fc0e77Sgovinda 	}
1434b0fc0e77Sgovinda 
1435b0fc0e77Sgovinda 	mdb_printf("%4x %?p %4d %?p %?p %a\n", iv.iv_inum, addr,
1436b0fc0e77Sgovinda 	    iv.iv_pil, iv.iv_arg1, iv.iv_arg2, iv.iv_handler);
1437b0fc0e77Sgovinda 
1438b0fc0e77Sgovinda 	return (DCMD_OK);
1439b0fc0e77Sgovinda }
14407c478bd9Sstevel@tonic-gate 
14417c478bd9Sstevel@tonic-gate int
14427c478bd9Sstevel@tonic-gate softint_walk_init(mdb_walk_state_t *wsp)
14437c478bd9Sstevel@tonic-gate {
1444b0fc0e77Sgovinda 	intr_vec_t	*list;
14457c478bd9Sstevel@tonic-gate 
14467c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr != NULL) {
14477c478bd9Sstevel@tonic-gate 		mdb_warn("softint walk only supports global walks\n");
14487c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
14497c478bd9Sstevel@tonic-gate 	}
14507c478bd9Sstevel@tonic-gate 
1451b0fc0e77Sgovinda 	/* Read global softint linked list pointer */
1452b0fc0e77Sgovinda 	if (mdb_readvar(&list, "softint_list") == -1) {
1453b0fc0e77Sgovinda 		mdb_warn("failed to read the global softint_list pointer\n");
14547c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
14557c478bd9Sstevel@tonic-gate 	}
14567c478bd9Sstevel@tonic-gate 
1457b0fc0e77Sgovinda 	wsp->walk_addr = (uintptr_t)list;
14587c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
14597c478bd9Sstevel@tonic-gate }
14607c478bd9Sstevel@tonic-gate 
1461b0fc0e77Sgovinda /*ARGSUSED*/
1462b0fc0e77Sgovinda void
1463b0fc0e77Sgovinda softint_walk_fini(mdb_walk_state_t *wsp)
1464b0fc0e77Sgovinda {
1465b0fc0e77Sgovinda 	/* Nothing to do here */
1466b0fc0e77Sgovinda }
1467b0fc0e77Sgovinda 
14687c478bd9Sstevel@tonic-gate int
14697c478bd9Sstevel@tonic-gate softint_walk_step(mdb_walk_state_t *wsp)
14707c478bd9Sstevel@tonic-gate {
1471b0fc0e77Sgovinda 	intr_vec_t		iv;
1472b0fc0e77Sgovinda 	int			status;
14737c478bd9Sstevel@tonic-gate 
1474b0fc0e77Sgovinda 	if (wsp->walk_addr == NULL)
14757c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
1476b0fc0e77Sgovinda 
1477b0fc0e77Sgovinda 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
1478b0fc0e77Sgovinda 	    wsp->walk_cbdata);
1479b0fc0e77Sgovinda 
1480b0fc0e77Sgovinda 	if (mdb_vread(&iv, sizeof (intr_vec_t),
1481b0fc0e77Sgovinda 	    (uintptr_t)wsp->walk_addr) == -1) {
1482b0fc0e77Sgovinda 		mdb_warn("failed to read iv_p %p\n", wsp->walk_addr);
1483b0fc0e77Sgovinda 		return (WALK_ERR);
14847c478bd9Sstevel@tonic-gate 	}
14857c478bd9Sstevel@tonic-gate 
1486b0fc0e77Sgovinda 	wsp->walk_addr = (uintptr_t)iv.iv_vec_next;
1487b0fc0e77Sgovinda 	return (status);
14887c478bd9Sstevel@tonic-gate }
14897c478bd9Sstevel@tonic-gate 
14907c478bd9Sstevel@tonic-gate int
14917c478bd9Sstevel@tonic-gate softint_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
14927c478bd9Sstevel@tonic-gate {
1493b0fc0e77Sgovinda 	intr_vec_t	iv;
14947c478bd9Sstevel@tonic-gate 
14957c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
14967c478bd9Sstevel@tonic-gate 		if (mdb_walk_dcmd("softint", "softint", argc, argv) == -1) {
14977c478bd9Sstevel@tonic-gate 			mdb_warn("can't walk softint");
14987c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
14997c478bd9Sstevel@tonic-gate 		}
15007c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
15017c478bd9Sstevel@tonic-gate 	}
15027c478bd9Sstevel@tonic-gate 
15037c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
1504b0fc0e77Sgovinda 		mdb_printf("%?s %4s %4s %4s %?s %?s %s\n", "ADDR", "TYPE",
1505b0fc0e77Sgovinda 		    "PEND", "PIL", "ARG1", "ARG2", "HANDLER");
15067c478bd9Sstevel@tonic-gate 	}
15077c478bd9Sstevel@tonic-gate 
15087c478bd9Sstevel@tonic-gate 	if (mdb_vread(&iv, sizeof (iv), addr) == -1) {
1509b0fc0e77Sgovinda 		mdb_warn("couldn't read softint at %p", addr);
15107c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
15117c478bd9Sstevel@tonic-gate 	}
15127c478bd9Sstevel@tonic-gate 
1513b0fc0e77Sgovinda 	mdb_printf("%?p %4s %4d %4d %?p %?p %a\n", addr,
1514b0fc0e77Sgovinda 	    (iv.iv_flags & IV_SOFTINT_MT) ? "M" : "S",
1515b0fc0e77Sgovinda 	    iv.iv_flags & IV_SOFTINT_PEND, iv.iv_pil,
1516b0fc0e77Sgovinda 	    iv.iv_arg1, iv.iv_arg2, iv.iv_handler);
15177c478bd9Sstevel@tonic-gate 
15187c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
15197c478bd9Sstevel@tonic-gate }
15207c478bd9Sstevel@tonic-gate 
15217c478bd9Sstevel@tonic-gate static int
1522*4a1c2431SJonathan Adams whatis_walk_tt(uintptr_t taddr, const trap_trace_fullrec_t *ttf,
1523*4a1c2431SJonathan Adams     mdb_whatis_t *w)
15247c478bd9Sstevel@tonic-gate {
1525*4a1c2431SJonathan Adams 	uintptr_t cur = 0;
15267c478bd9Sstevel@tonic-gate 
1527*4a1c2431SJonathan Adams 	while (mdb_whatis_match(w, taddr, sizeof (struct trap_trace_record),
1528*4a1c2431SJonathan Adams 	    &cur))
1529*4a1c2431SJonathan Adams 		mdb_whatis_report_object(w, cur, taddr,
1530*4a1c2431SJonathan Adams 		    "trap trace record for cpu %d\n", ttf->ttf_cpu);
15317c478bd9Sstevel@tonic-gate 
1532*4a1c2431SJonathan Adams 	return (WHATIS_WALKRET(w));
15337c478bd9Sstevel@tonic-gate }
15347c478bd9Sstevel@tonic-gate 
15357c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1536*4a1c2431SJonathan Adams static int
1537*4a1c2431SJonathan Adams whatis_run_traptrace(mdb_whatis_t *w, void *ignored)
15387c478bd9Sstevel@tonic-gate {
15397c478bd9Sstevel@tonic-gate 	GElf_Sym sym;
15407c478bd9Sstevel@tonic-gate 
15417c478bd9Sstevel@tonic-gate 	if (mdb_lookup_by_name("trap_trace_ctl", &sym) == -1)
1542*4a1c2431SJonathan Adams 		return (0);
15437c478bd9Sstevel@tonic-gate 
1544*4a1c2431SJonathan Adams 	if (mdb_walk("ttrace", (mdb_walk_cb_t)whatis_walk_tt, w) == -1)
15457c478bd9Sstevel@tonic-gate 		mdb_warn("failed to walk 'ttrace'");
15467c478bd9Sstevel@tonic-gate 
1547*4a1c2431SJonathan Adams 	return (0);
15487c478bd9Sstevel@tonic-gate }
15497c478bd9Sstevel@tonic-gate 
15507c478bd9Sstevel@tonic-gate /*ARGSUSED*/
15517c478bd9Sstevel@tonic-gate int
15527c478bd9Sstevel@tonic-gate mutex_owner_init(mdb_walk_state_t *wsp)
15537c478bd9Sstevel@tonic-gate {
15547c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
15557c478bd9Sstevel@tonic-gate }
15567c478bd9Sstevel@tonic-gate 
15577c478bd9Sstevel@tonic-gate int
15587c478bd9Sstevel@tonic-gate mutex_owner_step(mdb_walk_state_t *wsp)
15597c478bd9Sstevel@tonic-gate {
15607c478bd9Sstevel@tonic-gate 	uintptr_t addr = wsp->walk_addr;
15617c478bd9Sstevel@tonic-gate 	mutex_impl_t mtx;
15627c478bd9Sstevel@tonic-gate 	uintptr_t owner;
15637c478bd9Sstevel@tonic-gate 	kthread_t thr;
15647c478bd9Sstevel@tonic-gate 
15657c478bd9Sstevel@tonic-gate 	if (mdb_vread(&mtx, sizeof (mtx), addr) == -1)
15667c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
15677c478bd9Sstevel@tonic-gate 
15687c478bd9Sstevel@tonic-gate 	if (!MUTEX_TYPE_ADAPTIVE(&mtx))
15697c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
15707c478bd9Sstevel@tonic-gate 
15717c478bd9Sstevel@tonic-gate 	if ((owner = (uintptr_t)MUTEX_OWNER(&mtx)) == NULL)
15727c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
15737c478bd9Sstevel@tonic-gate 
15747c478bd9Sstevel@tonic-gate 	if (mdb_vread(&thr, sizeof (thr), owner) != -1)
15757c478bd9Sstevel@tonic-gate 		(void) wsp->walk_callback(owner, &thr, wsp->walk_cbdata);
15767c478bd9Sstevel@tonic-gate 
15777c478bd9Sstevel@tonic-gate 	return (WALK_DONE);
15787c478bd9Sstevel@tonic-gate }
15797c478bd9Sstevel@tonic-gate 
15807c478bd9Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = {
15817c478bd9Sstevel@tonic-gate 	{ "cpuset", ":[-l|-r]", "dump a cpuset_t", cmd_cpuset },
15827c478bd9Sstevel@tonic-gate 	{ "ttctl", NULL, "dump trap trace ctl records", ttctl },
15837c478bd9Sstevel@tonic-gate 	{ "ttrace", "[-x]", "dump trap trace buffer for a cpu", ttrace },
15847c478bd9Sstevel@tonic-gate #ifdef sun4v
15857c478bd9Sstevel@tonic-gate 	{ "httctl", NULL, "dump hv trap trace ctl records", httctl },
15867c478bd9Sstevel@tonic-gate 	{ "httrace", "[-x]", "dump hv trap trace buffer for a cpu", httrace },
15877c478bd9Sstevel@tonic-gate #endif
15887c478bd9Sstevel@tonic-gate 	{ "xc_mbox", "?", "dump xcall mboxes", xc_mbox },
15897c478bd9Sstevel@tonic-gate 	{ "xctrace", NULL, "dump xcall trace buffer", xctrace },
1590b0fc0e77Sgovinda 	{ "vecint", NULL, "display a registered hardware interrupt",
1591b0fc0e77Sgovinda 	    vecint_dcmd },
1592b0fc0e77Sgovinda 	{ "softint", NULL, "display a registered software interrupt",
1593b0fc0e77Sgovinda 	    softint_dcmd },
15947c478bd9Sstevel@tonic-gate 	{ "sfmmu_vtop", ":[[-v] -a as]", "print virtual to physical mapping",
15957c478bd9Sstevel@tonic-gate 	    sfmmu_vtop },
15967c478bd9Sstevel@tonic-gate 	{ "memseg_list", ":", "show memseg list", memseg_list },
15977c478bd9Sstevel@tonic-gate 	{ "tsbinfo", ":[-l [-a]]", "show tsbinfo", tsbinfo_list,
15987c478bd9Sstevel@tonic-gate 	    tsbinfo_help },
15997c478bd9Sstevel@tonic-gate 	{ NULL }
16007c478bd9Sstevel@tonic-gate };
16017c478bd9Sstevel@tonic-gate 
16027c478bd9Sstevel@tonic-gate static const mdb_walker_t walkers[] = {
16037c478bd9Sstevel@tonic-gate 	{ "mutex_owner", "walks the owner of a mutex",
16047c478bd9Sstevel@tonic-gate 		mutex_owner_init, mutex_owner_step },
16057c478bd9Sstevel@tonic-gate 	{ "ttrace", "walks the trap trace buffer for a CPU",
16067c478bd9Sstevel@tonic-gate 		ttrace_walk_init, ttrace_walk_step, ttrace_walk_fini },
16077c478bd9Sstevel@tonic-gate #ifdef sun4v
16087c478bd9Sstevel@tonic-gate 	{ "httrace", "walks the hv trap trace buffer for a CPU",
16097c478bd9Sstevel@tonic-gate 		httrace_walk_init, httrace_walk_step, httrace_walk_fini },
16107c478bd9Sstevel@tonic-gate #endif
16117c478bd9Sstevel@tonic-gate 	{ "xc_mbox", "walks the cross call mail boxes",
16127c478bd9Sstevel@tonic-gate 		xc_mbox_walk_init, xc_mbox_walk_step, xc_mbox_walk_fini },
1613b0fc0e77Sgovinda 	{ "vecint", "walk the list of registered hardware interrupts",
1614b0fc0e77Sgovinda 		vecint_walk_init, vecint_walk_step, vecint_walk_fini },
1615b0fc0e77Sgovinda 	{ "softint", "walk the list of registered software interrupts",
16167c478bd9Sstevel@tonic-gate 		softint_walk_init, softint_walk_step, softint_walk_fini },
16177c478bd9Sstevel@tonic-gate 	{ "memseg", "walk the memseg structures",
16187c478bd9Sstevel@tonic-gate 		memseg_walk_init, memseg_walk_step, memseg_walk_fini },
16197c478bd9Sstevel@tonic-gate 	{ NULL }
16207c478bd9Sstevel@tonic-gate };
16217c478bd9Sstevel@tonic-gate 
16227c478bd9Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
16237c478bd9Sstevel@tonic-gate 
16247c478bd9Sstevel@tonic-gate const mdb_modinfo_t *
16257c478bd9Sstevel@tonic-gate _mdb_init(void)
16267c478bd9Sstevel@tonic-gate {
1627b0fc0e77Sgovinda 	if (mdb_lookup_by_name("intr_vec_table", &iv_sym) == -1) {
1628b0fc0e77Sgovinda 		mdb_warn("couldn't find intr_vec_table");
16297c478bd9Sstevel@tonic-gate 		return (NULL);
16307c478bd9Sstevel@tonic-gate 	}
16317c478bd9Sstevel@tonic-gate 
1632*4a1c2431SJonathan Adams 	mdb_whatis_register("traptrace", whatis_run_traptrace, NULL,
1633*4a1c2431SJonathan Adams 	    WHATIS_PRIO_EARLY, WHATIS_REG_NO_ID);
1634*4a1c2431SJonathan Adams 
16357c478bd9Sstevel@tonic-gate 	return (&modinfo);
16367c478bd9Sstevel@tonic-gate }
1637