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