10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 54732Sdavemq * Common Development and Distribution License (the "License"). 64732Sdavemq * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*11304SJanie.Lu@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #ifndef _SYS_TRAPSTAT_H 270Sstevel@tonic-gate #define _SYS_TRAPSTAT_H 280Sstevel@tonic-gate 290Sstevel@tonic-gate #ifndef _ASM 300Sstevel@tonic-gate #include <sys/processor.h> 310Sstevel@tonic-gate #endif 320Sstevel@tonic-gate 330Sstevel@tonic-gate #ifdef __cplusplus 340Sstevel@tonic-gate extern "C" { 350Sstevel@tonic-gate #endif 360Sstevel@tonic-gate 370Sstevel@tonic-gate #define TSTATIOC (('t' << 16) | ('s' << 8)) 380Sstevel@tonic-gate 390Sstevel@tonic-gate #define TSTATIOC_READ (TSTATIOC | 1) 400Sstevel@tonic-gate #define TSTATIOC_GO (TSTATIOC | 2) 410Sstevel@tonic-gate #define TSTATIOC_NOGO (TSTATIOC | 3) 420Sstevel@tonic-gate #define TSTATIOC_STOP (TSTATIOC | 4) 430Sstevel@tonic-gate #define TSTATIOC_CPU (TSTATIOC | 5) 440Sstevel@tonic-gate #define TSTATIOC_NOCPU (TSTATIOC | 6) 450Sstevel@tonic-gate #define TSTATIOC_ENTRY (TSTATIOC | 7) 460Sstevel@tonic-gate #define TSTATIOC_NOENTRY (TSTATIOC | 8) 470Sstevel@tonic-gate #define TSTATIOC_TLBDATA (TSTATIOC | 9) 480Sstevel@tonic-gate 490Sstevel@tonic-gate #define TSTAT_NENT 512 500Sstevel@tonic-gate 510Sstevel@tonic-gate #ifndef _ASM 520Sstevel@tonic-gate 530Sstevel@tonic-gate /* 540Sstevel@tonic-gate * tstat_missdata_t must be of size 2^n, for some value of n. This allows 550Sstevel@tonic-gate * tstat_tlbdata_t to be of size 2^(n+2), and tstat_pgszdata_t to be of 560Sstevel@tonic-gate * size 2^(n+3) -- a constraint which greatly simplifies the TLB return 570Sstevel@tonic-gate * entry. 580Sstevel@tonic-gate */ 590Sstevel@tonic-gate typedef struct tstat_missdata { 600Sstevel@tonic-gate uint64_t tmiss_count; 610Sstevel@tonic-gate hrtime_t tmiss_time; 620Sstevel@tonic-gate } tstat_missdata_t; 630Sstevel@tonic-gate 640Sstevel@tonic-gate typedef struct tstat_tlbdata { 650Sstevel@tonic-gate tstat_missdata_t ttlb_tlb; 660Sstevel@tonic-gate tstat_missdata_t ttlb_tsb; 670Sstevel@tonic-gate } tstat_tlbdata_t; 680Sstevel@tonic-gate 690Sstevel@tonic-gate typedef struct tstat_modedata { 700Sstevel@tonic-gate tstat_tlbdata_t tmode_itlb; 710Sstevel@tonic-gate tstat_tlbdata_t tmode_dtlb; 720Sstevel@tonic-gate } tstat_modedata_t; 730Sstevel@tonic-gate 740Sstevel@tonic-gate typedef struct tstat_pgszdata { 750Sstevel@tonic-gate tstat_modedata_t tpgsz_user; 760Sstevel@tonic-gate tstat_modedata_t tpgsz_kernel; 770Sstevel@tonic-gate } tstat_pgszdata_t; 780Sstevel@tonic-gate 79*11304SJanie.Lu@Sun.COM #ifdef sun4v 80*11304SJanie.Lu@Sun.COM /* 81*11304SJanie.Lu@Sun.COM * For sun4v, we optimized by using a smaller 4K data area 82*11304SJanie.Lu@Sun.COM * per-cpu. We use separate structures for data collection, 83*11304SJanie.Lu@Sun.COM * one for normal trapstat collection and one for collecting 84*11304SJanie.Lu@Sun.COM * TLB stats. Note that we either collect normal trapstats 85*11304SJanie.Lu@Sun.COM * or TLB stats, never both. For TLB stats, we are only 86*11304SJanie.Lu@Sun.COM * interested in the MMU/TLB miss traps (which are trap #s 87*11304SJanie.Lu@Sun.COM * 0x9, 0x32, 0x64 & 0x68) 88*11304SJanie.Lu@Sun.COM */ 89*11304SJanie.Lu@Sun.COM #define TSTAT_TLB_NENT 200 /* max trap entries for tlb stats */ 90*11304SJanie.Lu@Sun.COM 91*11304SJanie.Lu@Sun.COM typedef struct tstat_ndata { 92*11304SJanie.Lu@Sun.COM uint64_t tdata_traps[TSTAT_NENT]; 93*11304SJanie.Lu@Sun.COM } tstat_ndata_t; 94*11304SJanie.Lu@Sun.COM 95*11304SJanie.Lu@Sun.COM typedef struct tstat_tdata { 96*11304SJanie.Lu@Sun.COM uint64_t tdata_traps[TSTAT_TLB_NENT]; 97*11304SJanie.Lu@Sun.COM hrtime_t tdata_tmptick; 98*11304SJanie.Lu@Sun.COM tstat_pgszdata_t tdata_pgsz[1]; 99*11304SJanie.Lu@Sun.COM } tstat_tdata_t; 100*11304SJanie.Lu@Sun.COM #endif /* sun4v */ 101*11304SJanie.Lu@Sun.COM 1020Sstevel@tonic-gate typedef struct tstat_data { 1030Sstevel@tonic-gate processorid_t tdata_cpuid; 1040Sstevel@tonic-gate hrtime_t tdata_snapts; 1050Sstevel@tonic-gate hrtime_t tdata_snaptick; 1060Sstevel@tonic-gate hrtime_t tdata_tmptick; 1070Sstevel@tonic-gate hrtime_t tdata_peffect; 1080Sstevel@tonic-gate uint64_t tdata_traps[TSTAT_NENT]; 1090Sstevel@tonic-gate tstat_pgszdata_t tdata_pgsz[1]; 1100Sstevel@tonic-gate } tstat_data_t; 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate #endif 1130Sstevel@tonic-gate 1140Sstevel@tonic-gate #ifdef _KERNEL 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate #define TSTAT_TLGT0_NENT 256 1170Sstevel@tonic-gate #define TSTAT_TOTAL_NENT (TSTAT_NENT + TSTAT_TLGT0_NENT) 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate #define TSTAT_ENT_NINSTR 8 /* 8 instructions/entry */ 1200Sstevel@tonic-gate #define TSTAT_ENT_SHIFT 5 /* 32 bytes/entry */ 1210Sstevel@tonic-gate #define TSTAT_ENT_ITLBMISS 0x64 1220Sstevel@tonic-gate #define TSTAT_ENT_DTLBMISS 0x68 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate #define TSTAT_TLBRET_NINSTR 32 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate #define TSTAT_PROBE_NPAGES 2048 1270Sstevel@tonic-gate #define TSTAT_PROBE_SIZE (TSTAT_PROBE_NPAGES * MMU_PAGESIZE) 1280Sstevel@tonic-gate #define TSTAT_PROBE_NLAPS 10 1290Sstevel@tonic-gate 1301050Sgirish #ifdef sun4v 1314732Sdavemq #define TSTAT_TRAPCNT_NINSTR 8 1324732Sdavemq #define TSTAT_TLBENT_NINSTR 64 1331050Sgirish #define TSTAT_ENT_IMMUMISS 0x09 1341050Sgirish #define TSTAT_ENT_DMMUMISS 0x31 1351050Sgirish #endif 1361050Sgirish 1370Sstevel@tonic-gate #ifndef _ASM 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate typedef struct tstat_tlbretent { 1400Sstevel@tonic-gate uint32_t ttlbrent_instr[TSTAT_TLBRET_NINSTR]; 1410Sstevel@tonic-gate } tstat_tlbretent_t; 1420Sstevel@tonic-gate 1431050Sgirish #ifdef sun4v 1441050Sgirish typedef struct tstat_tlbent { 1451050Sgirish uint32_t ttlbent_instr[TSTAT_TLBENT_NINSTR]; 1461050Sgirish } tstat_tlbent_t; 1471050Sgirish #endif /* sun4v */ 1481050Sgirish 1491050Sgirish 1500Sstevel@tonic-gate typedef struct tstat_tlbret { 1510Sstevel@tonic-gate tstat_tlbretent_t ttlbr_ktlb; 1520Sstevel@tonic-gate tstat_tlbretent_t ttlbr_ktsb; 1530Sstevel@tonic-gate tstat_tlbretent_t ttlbr_utlb; 1540Sstevel@tonic-gate tstat_tlbretent_t ttlbr_utsb; 1550Sstevel@tonic-gate } tstat_tlbret_t; 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate typedef struct tstat_instr { 1580Sstevel@tonic-gate uint32_t tinst_traptab[TSTAT_TOTAL_NENT * TSTAT_ENT_NINSTR]; 1590Sstevel@tonic-gate tstat_tlbret_t tinst_itlbret; 1600Sstevel@tonic-gate tstat_tlbret_t tinst_dtlbret; 1611050Sgirish #ifdef sun4v 1621050Sgirish tstat_tlbent_t tinst_immumiss; 1631050Sgirish tstat_tlbent_t tinst_dmmumiss; 1644732Sdavemq uint32_t tinst_trapcnt[TSTAT_TRAPCNT_NINSTR]; 1651050Sgirish #endif 1660Sstevel@tonic-gate } tstat_instr_t; 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate typedef struct tstat_tsbmiss_patch_entry { 1690Sstevel@tonic-gate uint32_t *tpe_addr; 1700Sstevel@tonic-gate uint32_t tpe_instr; 1710Sstevel@tonic-gate } tstat_tsbmiss_patch_entry_t; 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate #endif 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate #ifdef sun4v 1764732Sdavemq 1770Sstevel@tonic-gate #define TSTAT_TLB_STATS 0x1 /* cpu_tstat_flags */ 1784732Sdavemq #define TSTAT_INSTR_SIZE \ 1794732Sdavemq ((sizeof (tstat_instr_t) + MMU_PAGESIZE - 1) & ~(MMU_PAGESIZE - 1)) 180*11304SJanie.Lu@Sun.COM #define TSTAT_DATA_SHIFT 12 181*11304SJanie.Lu@Sun.COM #define TSTAT_DATA_SIZE (1 << TSTAT_DATA_SHIFT) /* 4K per CPU */ 1824732Sdavemq #define TSTAT_TBA_MASK ~((1 << 15) - 1) /* 32K boundary */ 1834732Sdavemq 1844732Sdavemq #define TSTAT_CPU0_DATA_OFFS(tcpu, mem) \ 1854732Sdavemq ((uintptr_t)(tcpu)->tcpu_ibase + TSTAT_INSTR_SIZE + \ 186*11304SJanie.Lu@Sun.COM offsetof(tstat_ndata_t, mem)) 187*11304SJanie.Lu@Sun.COM 188*11304SJanie.Lu@Sun.COM #define TSTAT_CPU0_TLBDATA_OFFS(tcpu, mem) \ 189*11304SJanie.Lu@Sun.COM ((uintptr_t)(tcpu)->tcpu_ibase + TSTAT_INSTR_SIZE + \ 190*11304SJanie.Lu@Sun.COM offsetof(tstat_tdata_t, mem)) 191*11304SJanie.Lu@Sun.COM 192*11304SJanie.Lu@Sun.COM /* 193*11304SJanie.Lu@Sun.COM * Sun4v trapstat can use up to 3 4MB pages to support 194*11304SJanie.Lu@Sun.COM * 3064 cpus. Each cpu needs 4K of data page for stats collection. 195*11304SJanie.Lu@Sun.COM * The first 32K (TSTAT_TRAPTBLE_SIZE) in the first 4 MB page is 196*11304SJanie.Lu@Sun.COM * use for the traptable leaving 4MB - 32K = 4064K for cpu data 197*11304SJanie.Lu@Sun.COM * which work out to be 4064/4K = 1016 cpus. Each additional 198*11304SJanie.Lu@Sun.COM * 4MB page (2nd and 3rd ones) can support 4096/4 = 1024 cpus. 199*11304SJanie.Lu@Sun.COM * This works out to be a total of 1016 + 1024 + 1024 = 3064 cpus. 200*11304SJanie.Lu@Sun.COM */ 201*11304SJanie.Lu@Sun.COM #define ROUNDUP(a, n) (((a) + ((n) - 1)) & ~((n) - 1)) 202*11304SJanie.Lu@Sun.COM #define TSTAT_MAXNUM4M_MAPPING 3 203*11304SJanie.Lu@Sun.COM #define TSTAT_TRAPTBL_SIZE (32 * 1024) 204*11304SJanie.Lu@Sun.COM #define TSTAT_NUM4M_LIMIT \ 205*11304SJanie.Lu@Sun.COM (ROUNDUP((NCPU * TSTAT_DATA_SIZE) + TSTAT_TRAPTBL_SIZE, \ 206*11304SJanie.Lu@Sun.COM MMU_PAGESIZE4M) >> MMU_PAGESHIFT4M) 207*11304SJanie.Lu@Sun.COM 208*11304SJanie.Lu@Sun.COM #if (TSTAT_NUM4M_LIMIT > TSTAT_MAXNUM4M_MAPPING) 209*11304SJanie.Lu@Sun.COM #error "NCPU is too large for trapstat" 210*11304SJanie.Lu@Sun.COM #endif 211*11304SJanie.Lu@Sun.COM 212*11304SJanie.Lu@Sun.COM /* 213*11304SJanie.Lu@Sun.COM * Note that the macro below is almost identical to the 214*11304SJanie.Lu@Sun.COM * one for TSTAT_NUM4M_LIMIT with one difference. Instead of 215*11304SJanie.Lu@Sun.COM * using TSTAT_TRAPTBL_SIZE constant, it uses TSTAT_INSTR_SIZE which 216*11304SJanie.Lu@Sun.COM * has a runtime sizeof() expression. The result should be 217*11304SJanie.Lu@Sun.COM * the same. This macro is used at runtime as an extra 218*11304SJanie.Lu@Sun.COM * validation for correctness. 219*11304SJanie.Lu@Sun.COM */ 220*11304SJanie.Lu@Sun.COM #define TSTAT_NUM4M_MACRO(ncpu) \ 221*11304SJanie.Lu@Sun.COM (ROUNDUP(((ncpu) * TSTAT_DATA_SIZE) + TSTAT_INSTR_SIZE, \ 222*11304SJanie.Lu@Sun.COM MMU_PAGESIZE4M) >> MMU_PAGESHIFT4M) 2234732Sdavemq 2240Sstevel@tonic-gate #else /* sun4v */ 2254732Sdavemq 2260Sstevel@tonic-gate #define TSTAT_INSTR_PAGES ((sizeof (tstat_instr_t) >> MMU_PAGESHIFT) + 1) 2270Sstevel@tonic-gate #define TSTAT_INSTR_SIZE (TSTAT_INSTR_PAGES * MMU_PAGESIZE) 2280Sstevel@tonic-gate #define TSTAT_TBA_MASK ~((1 << 16) - 1) /* 64K per cpu */ 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate #define TSTAT_DATA_OFFS(tcpu, mem) \ 2310Sstevel@tonic-gate ((uintptr_t)(tcpu)->tcpu_dbase + offsetof(tstat_data_t, mem)) 2324732Sdavemq 2334732Sdavemq #endif /* sun4v */ 2344732Sdavemq 2350Sstevel@tonic-gate #define TSTAT_INSTR_OFFS(tcpu, mem) \ 2360Sstevel@tonic-gate ((uintptr_t)(tcpu)->tcpu_ibase + offsetof(tstat_instr_t, mem)) 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate #define TSTAT_CPU_SELECTED 0x0001 2390Sstevel@tonic-gate #define TSTAT_CPU_ALLOCATED 0x0002 2400Sstevel@tonic-gate #define TSTAT_CPU_ENABLED 0x0004 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate #define TSTAT_OPT_CPU 0x0001 2430Sstevel@tonic-gate #define TSTAT_OPT_NOGO 0x0002 2440Sstevel@tonic-gate #define TSTAT_OPT_TLBDATA 0x0004 2450Sstevel@tonic-gate #define TSTAT_OPT_ENTRY 0x0008 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate #define TSTAT_TSBMISS_INSTR 0x8e01e000 /* add %g7, 0, %g7 */ 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate #ifndef _ASM 2500Sstevel@tonic-gate 2510Sstevel@tonic-gate typedef struct tstat_percpu { 2520Sstevel@tonic-gate uint32_t tcpu_flags; 2530Sstevel@tonic-gate caddr_t tcpu_tba; 2540Sstevel@tonic-gate caddr_t tcpu_vabase; 2550Sstevel@tonic-gate caddr_t tcpu_ibase; 2560Sstevel@tonic-gate caddr_t tcpu_dbase; 2570Sstevel@tonic-gate pfn_t *tcpu_pfn; 2580Sstevel@tonic-gate tstat_instr_t *tcpu_instr; 2590Sstevel@tonic-gate tstat_data_t *tcpu_data; 260*11304SJanie.Lu@Sun.COM #ifdef sun4v 261*11304SJanie.Lu@Sun.COM hrtime_t tcpu_tdata_peffect; 262*11304SJanie.Lu@Sun.COM #endif /* sun4v */ 2630Sstevel@tonic-gate } tstat_percpu_t; 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate #endif 2660Sstevel@tonic-gate 2670Sstevel@tonic-gate #endif 2680Sstevel@tonic-gate #ifdef __cplusplus 2690Sstevel@tonic-gate } 2700Sstevel@tonic-gate #endif 2710Sstevel@tonic-gate 2720Sstevel@tonic-gate #endif /* _SYS_TRAPSTAT_H */ 273