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 559ac0c16Sdavemq * Common Development and Distribution License (the "License"). 659ac0c16Sdavemq * 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*4df55fdeSJanie Lu * 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 #ifndef _SYS_TRAPSTAT_H 277c478bd9Sstevel@tonic-gate #define _SYS_TRAPSTAT_H 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #ifndef _ASM 307c478bd9Sstevel@tonic-gate #include <sys/processor.h> 317c478bd9Sstevel@tonic-gate #endif 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #ifdef __cplusplus 347c478bd9Sstevel@tonic-gate extern "C" { 357c478bd9Sstevel@tonic-gate #endif 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #define TSTATIOC (('t' << 16) | ('s' << 8)) 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate #define TSTATIOC_READ (TSTATIOC | 1) 407c478bd9Sstevel@tonic-gate #define TSTATIOC_GO (TSTATIOC | 2) 417c478bd9Sstevel@tonic-gate #define TSTATIOC_NOGO (TSTATIOC | 3) 427c478bd9Sstevel@tonic-gate #define TSTATIOC_STOP (TSTATIOC | 4) 437c478bd9Sstevel@tonic-gate #define TSTATIOC_CPU (TSTATIOC | 5) 447c478bd9Sstevel@tonic-gate #define TSTATIOC_NOCPU (TSTATIOC | 6) 457c478bd9Sstevel@tonic-gate #define TSTATIOC_ENTRY (TSTATIOC | 7) 467c478bd9Sstevel@tonic-gate #define TSTATIOC_NOENTRY (TSTATIOC | 8) 477c478bd9Sstevel@tonic-gate #define TSTATIOC_TLBDATA (TSTATIOC | 9) 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate #define TSTAT_NENT 512 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate #ifndef _ASM 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate /* 547c478bd9Sstevel@tonic-gate * tstat_missdata_t must be of size 2^n, for some value of n. This allows 557c478bd9Sstevel@tonic-gate * tstat_tlbdata_t to be of size 2^(n+2), and tstat_pgszdata_t to be of 567c478bd9Sstevel@tonic-gate * size 2^(n+3) -- a constraint which greatly simplifies the TLB return 577c478bd9Sstevel@tonic-gate * entry. 587c478bd9Sstevel@tonic-gate */ 597c478bd9Sstevel@tonic-gate typedef struct tstat_missdata { 607c478bd9Sstevel@tonic-gate uint64_t tmiss_count; 617c478bd9Sstevel@tonic-gate hrtime_t tmiss_time; 627c478bd9Sstevel@tonic-gate } tstat_missdata_t; 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate typedef struct tstat_tlbdata { 657c478bd9Sstevel@tonic-gate tstat_missdata_t ttlb_tlb; 667c478bd9Sstevel@tonic-gate tstat_missdata_t ttlb_tsb; 677c478bd9Sstevel@tonic-gate } tstat_tlbdata_t; 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate typedef struct tstat_modedata { 707c478bd9Sstevel@tonic-gate tstat_tlbdata_t tmode_itlb; 717c478bd9Sstevel@tonic-gate tstat_tlbdata_t tmode_dtlb; 727c478bd9Sstevel@tonic-gate } tstat_modedata_t; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate typedef struct tstat_pgszdata { 757c478bd9Sstevel@tonic-gate tstat_modedata_t tpgsz_user; 767c478bd9Sstevel@tonic-gate tstat_modedata_t tpgsz_kernel; 777c478bd9Sstevel@tonic-gate } tstat_pgszdata_t; 787c478bd9Sstevel@tonic-gate 79*4df55fdeSJanie Lu #ifdef sun4v 80*4df55fdeSJanie Lu /* 81*4df55fdeSJanie Lu * For sun4v, we optimized by using a smaller 4K data area 82*4df55fdeSJanie Lu * per-cpu. We use separate structures for data collection, 83*4df55fdeSJanie Lu * one for normal trapstat collection and one for collecting 84*4df55fdeSJanie Lu * TLB stats. Note that we either collect normal trapstats 85*4df55fdeSJanie Lu * or TLB stats, never both. For TLB stats, we are only 86*4df55fdeSJanie Lu * interested in the MMU/TLB miss traps (which are trap #s 87*4df55fdeSJanie Lu * 0x9, 0x32, 0x64 & 0x68) 88*4df55fdeSJanie Lu */ 89*4df55fdeSJanie Lu #define TSTAT_TLB_NENT 200 /* max trap entries for tlb stats */ 90*4df55fdeSJanie Lu 91*4df55fdeSJanie Lu typedef struct tstat_ndata { 92*4df55fdeSJanie Lu uint64_t tdata_traps[TSTAT_NENT]; 93*4df55fdeSJanie Lu } tstat_ndata_t; 94*4df55fdeSJanie Lu 95*4df55fdeSJanie Lu typedef struct tstat_tdata { 96*4df55fdeSJanie Lu uint64_t tdata_traps[TSTAT_TLB_NENT]; 97*4df55fdeSJanie Lu hrtime_t tdata_tmptick; 98*4df55fdeSJanie Lu tstat_pgszdata_t tdata_pgsz[1]; 99*4df55fdeSJanie Lu } tstat_tdata_t; 100*4df55fdeSJanie Lu #endif /* sun4v */ 101*4df55fdeSJanie Lu 1027c478bd9Sstevel@tonic-gate typedef struct tstat_data { 1037c478bd9Sstevel@tonic-gate processorid_t tdata_cpuid; 1047c478bd9Sstevel@tonic-gate hrtime_t tdata_snapts; 1057c478bd9Sstevel@tonic-gate hrtime_t tdata_snaptick; 1067c478bd9Sstevel@tonic-gate hrtime_t tdata_tmptick; 1077c478bd9Sstevel@tonic-gate hrtime_t tdata_peffect; 1087c478bd9Sstevel@tonic-gate uint64_t tdata_traps[TSTAT_NENT]; 1097c478bd9Sstevel@tonic-gate tstat_pgszdata_t tdata_pgsz[1]; 1107c478bd9Sstevel@tonic-gate } tstat_data_t; 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate #endif 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate #ifdef _KERNEL 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate #define TSTAT_TLGT0_NENT 256 1177c478bd9Sstevel@tonic-gate #define TSTAT_TOTAL_NENT (TSTAT_NENT + TSTAT_TLGT0_NENT) 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate #define TSTAT_ENT_NINSTR 8 /* 8 instructions/entry */ 1207c478bd9Sstevel@tonic-gate #define TSTAT_ENT_SHIFT 5 /* 32 bytes/entry */ 1217c478bd9Sstevel@tonic-gate #define TSTAT_ENT_ITLBMISS 0x64 1227c478bd9Sstevel@tonic-gate #define TSTAT_ENT_DTLBMISS 0x68 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate #define TSTAT_TLBRET_NINSTR 32 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate #define TSTAT_PROBE_NPAGES 2048 1277c478bd9Sstevel@tonic-gate #define TSTAT_PROBE_SIZE (TSTAT_PROBE_NPAGES * MMU_PAGESIZE) 1287c478bd9Sstevel@tonic-gate #define TSTAT_PROBE_NLAPS 10 1297c478bd9Sstevel@tonic-gate 130ce0352ebSgirish #ifdef sun4v 13159ac0c16Sdavemq #define TSTAT_TRAPCNT_NINSTR 8 13259ac0c16Sdavemq #define TSTAT_TLBENT_NINSTR 64 133ce0352ebSgirish #define TSTAT_ENT_IMMUMISS 0x09 134ce0352ebSgirish #define TSTAT_ENT_DMMUMISS 0x31 135ce0352ebSgirish #endif 136ce0352ebSgirish 1377c478bd9Sstevel@tonic-gate #ifndef _ASM 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate typedef struct tstat_tlbretent { 1407c478bd9Sstevel@tonic-gate uint32_t ttlbrent_instr[TSTAT_TLBRET_NINSTR]; 1417c478bd9Sstevel@tonic-gate } tstat_tlbretent_t; 1427c478bd9Sstevel@tonic-gate 143ce0352ebSgirish #ifdef sun4v 144ce0352ebSgirish typedef struct tstat_tlbent { 145ce0352ebSgirish uint32_t ttlbent_instr[TSTAT_TLBENT_NINSTR]; 146ce0352ebSgirish } tstat_tlbent_t; 147ce0352ebSgirish #endif /* sun4v */ 148ce0352ebSgirish 149ce0352ebSgirish 1507c478bd9Sstevel@tonic-gate typedef struct tstat_tlbret { 1517c478bd9Sstevel@tonic-gate tstat_tlbretent_t ttlbr_ktlb; 1527c478bd9Sstevel@tonic-gate tstat_tlbretent_t ttlbr_ktsb; 1537c478bd9Sstevel@tonic-gate tstat_tlbretent_t ttlbr_utlb; 1547c478bd9Sstevel@tonic-gate tstat_tlbretent_t ttlbr_utsb; 1557c478bd9Sstevel@tonic-gate } tstat_tlbret_t; 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate typedef struct tstat_instr { 1587c478bd9Sstevel@tonic-gate uint32_t tinst_traptab[TSTAT_TOTAL_NENT * TSTAT_ENT_NINSTR]; 1597c478bd9Sstevel@tonic-gate tstat_tlbret_t tinst_itlbret; 1607c478bd9Sstevel@tonic-gate tstat_tlbret_t tinst_dtlbret; 161ce0352ebSgirish #ifdef sun4v 162ce0352ebSgirish tstat_tlbent_t tinst_immumiss; 163ce0352ebSgirish tstat_tlbent_t tinst_dmmumiss; 16459ac0c16Sdavemq uint32_t tinst_trapcnt[TSTAT_TRAPCNT_NINSTR]; 165ce0352ebSgirish #endif 1667c478bd9Sstevel@tonic-gate } tstat_instr_t; 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate typedef struct tstat_tsbmiss_patch_entry { 1697c478bd9Sstevel@tonic-gate uint32_t *tpe_addr; 1707c478bd9Sstevel@tonic-gate uint32_t tpe_instr; 1717c478bd9Sstevel@tonic-gate } tstat_tsbmiss_patch_entry_t; 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate #endif 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate #ifdef sun4v 17659ac0c16Sdavemq 1777c478bd9Sstevel@tonic-gate #define TSTAT_TLB_STATS 0x1 /* cpu_tstat_flags */ 17859ac0c16Sdavemq #define TSTAT_INSTR_SIZE \ 17959ac0c16Sdavemq ((sizeof (tstat_instr_t) + MMU_PAGESIZE - 1) & ~(MMU_PAGESIZE - 1)) 180*4df55fdeSJanie Lu #define TSTAT_DATA_SHIFT 12 181*4df55fdeSJanie Lu #define TSTAT_DATA_SIZE (1 << TSTAT_DATA_SHIFT) /* 4K per CPU */ 18259ac0c16Sdavemq #define TSTAT_TBA_MASK ~((1 << 15) - 1) /* 32K boundary */ 18359ac0c16Sdavemq 18459ac0c16Sdavemq #define TSTAT_CPU0_DATA_OFFS(tcpu, mem) \ 18559ac0c16Sdavemq ((uintptr_t)(tcpu)->tcpu_ibase + TSTAT_INSTR_SIZE + \ 186*4df55fdeSJanie Lu offsetof(tstat_ndata_t, mem)) 187*4df55fdeSJanie Lu 188*4df55fdeSJanie Lu #define TSTAT_CPU0_TLBDATA_OFFS(tcpu, mem) \ 189*4df55fdeSJanie Lu ((uintptr_t)(tcpu)->tcpu_ibase + TSTAT_INSTR_SIZE + \ 190*4df55fdeSJanie Lu offsetof(tstat_tdata_t, mem)) 191*4df55fdeSJanie Lu 192*4df55fdeSJanie Lu /* 193*4df55fdeSJanie Lu * Sun4v trapstat can use up to 3 4MB pages to support 194*4df55fdeSJanie Lu * 3064 cpus. Each cpu needs 4K of data page for stats collection. 195*4df55fdeSJanie Lu * The first 32K (TSTAT_TRAPTBLE_SIZE) in the first 4 MB page is 196*4df55fdeSJanie Lu * use for the traptable leaving 4MB - 32K = 4064K for cpu data 197*4df55fdeSJanie Lu * which work out to be 4064/4K = 1016 cpus. Each additional 198*4df55fdeSJanie Lu * 4MB page (2nd and 3rd ones) can support 4096/4 = 1024 cpus. 199*4df55fdeSJanie Lu * This works out to be a total of 1016 + 1024 + 1024 = 3064 cpus. 200*4df55fdeSJanie Lu */ 201*4df55fdeSJanie Lu #define ROUNDUP(a, n) (((a) + ((n) - 1)) & ~((n) - 1)) 202*4df55fdeSJanie Lu #define TSTAT_MAXNUM4M_MAPPING 3 203*4df55fdeSJanie Lu #define TSTAT_TRAPTBL_SIZE (32 * 1024) 204*4df55fdeSJanie Lu #define TSTAT_NUM4M_LIMIT \ 205*4df55fdeSJanie Lu (ROUNDUP((NCPU * TSTAT_DATA_SIZE) + TSTAT_TRAPTBL_SIZE, \ 206*4df55fdeSJanie Lu MMU_PAGESIZE4M) >> MMU_PAGESHIFT4M) 207*4df55fdeSJanie Lu 208*4df55fdeSJanie Lu #if (TSTAT_NUM4M_LIMIT > TSTAT_MAXNUM4M_MAPPING) 209*4df55fdeSJanie Lu #error "NCPU is too large for trapstat" 210*4df55fdeSJanie Lu #endif 211*4df55fdeSJanie Lu 212*4df55fdeSJanie Lu /* 213*4df55fdeSJanie Lu * Note that the macro below is almost identical to the 214*4df55fdeSJanie Lu * one for TSTAT_NUM4M_LIMIT with one difference. Instead of 215*4df55fdeSJanie Lu * using TSTAT_TRAPTBL_SIZE constant, it uses TSTAT_INSTR_SIZE which 216*4df55fdeSJanie Lu * has a runtime sizeof() expression. The result should be 217*4df55fdeSJanie Lu * the same. This macro is used at runtime as an extra 218*4df55fdeSJanie Lu * validation for correctness. 219*4df55fdeSJanie Lu */ 220*4df55fdeSJanie Lu #define TSTAT_NUM4M_MACRO(ncpu) \ 221*4df55fdeSJanie Lu (ROUNDUP(((ncpu) * TSTAT_DATA_SIZE) + TSTAT_INSTR_SIZE, \ 222*4df55fdeSJanie Lu MMU_PAGESIZE4M) >> MMU_PAGESHIFT4M) 22359ac0c16Sdavemq 2247c478bd9Sstevel@tonic-gate #else /* sun4v */ 22559ac0c16Sdavemq 2267c478bd9Sstevel@tonic-gate #define TSTAT_INSTR_PAGES ((sizeof (tstat_instr_t) >> MMU_PAGESHIFT) + 1) 2277c478bd9Sstevel@tonic-gate #define TSTAT_INSTR_SIZE (TSTAT_INSTR_PAGES * MMU_PAGESIZE) 2287c478bd9Sstevel@tonic-gate #define TSTAT_TBA_MASK ~((1 << 16) - 1) /* 64K per cpu */ 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate #define TSTAT_DATA_OFFS(tcpu, mem) \ 2317c478bd9Sstevel@tonic-gate ((uintptr_t)(tcpu)->tcpu_dbase + offsetof(tstat_data_t, mem)) 23259ac0c16Sdavemq 23359ac0c16Sdavemq #endif /* sun4v */ 23459ac0c16Sdavemq 2357c478bd9Sstevel@tonic-gate #define TSTAT_INSTR_OFFS(tcpu, mem) \ 2367c478bd9Sstevel@tonic-gate ((uintptr_t)(tcpu)->tcpu_ibase + offsetof(tstat_instr_t, mem)) 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate #define TSTAT_CPU_SELECTED 0x0001 2397c478bd9Sstevel@tonic-gate #define TSTAT_CPU_ALLOCATED 0x0002 2407c478bd9Sstevel@tonic-gate #define TSTAT_CPU_ENABLED 0x0004 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate #define TSTAT_OPT_CPU 0x0001 2437c478bd9Sstevel@tonic-gate #define TSTAT_OPT_NOGO 0x0002 2447c478bd9Sstevel@tonic-gate #define TSTAT_OPT_TLBDATA 0x0004 2457c478bd9Sstevel@tonic-gate #define TSTAT_OPT_ENTRY 0x0008 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate #define TSTAT_TSBMISS_INSTR 0x8e01e000 /* add %g7, 0, %g7 */ 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate #ifndef _ASM 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate typedef struct tstat_percpu { 2527c478bd9Sstevel@tonic-gate uint32_t tcpu_flags; 2537c478bd9Sstevel@tonic-gate caddr_t tcpu_tba; 2547c478bd9Sstevel@tonic-gate caddr_t tcpu_vabase; 2557c478bd9Sstevel@tonic-gate caddr_t tcpu_ibase; 2567c478bd9Sstevel@tonic-gate caddr_t tcpu_dbase; 2577c478bd9Sstevel@tonic-gate pfn_t *tcpu_pfn; 2587c478bd9Sstevel@tonic-gate tstat_instr_t *tcpu_instr; 2597c478bd9Sstevel@tonic-gate tstat_data_t *tcpu_data; 260*4df55fdeSJanie Lu #ifdef sun4v 261*4df55fdeSJanie Lu hrtime_t tcpu_tdata_peffect; 262*4df55fdeSJanie Lu #endif /* sun4v */ 2637c478bd9Sstevel@tonic-gate } tstat_percpu_t; 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate #endif 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate #endif 2687c478bd9Sstevel@tonic-gate #ifdef __cplusplus 2697c478bd9Sstevel@tonic-gate } 2707c478bd9Sstevel@tonic-gate #endif 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate #endif /* _SYS_TRAPSTAT_H */ 273