Home | History | Annotate | Download | only in sys
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #ifndef _SYS_TRAPSTAT_H
     27 #define	_SYS_TRAPSTAT_H
     28 
     29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     30 
     31 #ifndef _ASM
     32 #include <sys/processor.h>
     33 #endif
     34 
     35 #ifdef	__cplusplus
     36 extern "C" {
     37 #endif
     38 
     39 #define	TSTATIOC	(('t' << 16) | ('s' << 8))
     40 
     41 #define	TSTATIOC_READ		(TSTATIOC | 1)
     42 #define	TSTATIOC_GO		(TSTATIOC | 2)
     43 #define	TSTATIOC_NOGO		(TSTATIOC | 3)
     44 #define	TSTATIOC_STOP		(TSTATIOC | 4)
     45 #define	TSTATIOC_CPU		(TSTATIOC | 5)
     46 #define	TSTATIOC_NOCPU		(TSTATIOC | 6)
     47 #define	TSTATIOC_ENTRY		(TSTATIOC | 7)
     48 #define	TSTATIOC_NOENTRY	(TSTATIOC | 8)
     49 #define	TSTATIOC_TLBDATA	(TSTATIOC | 9)
     50 
     51 #define	TSTAT_NENT		512
     52 
     53 #ifndef _ASM
     54 
     55 /*
     56  * tstat_missdata_t must be of size 2^n, for some value of n.  This allows
     57  * tstat_tlbdata_t to be of size 2^(n+2), and tstat_pgszdata_t to be of
     58  * size 2^(n+3) -- a constraint which greatly simplifies the TLB return
     59  * entry.
     60  */
     61 typedef struct tstat_missdata {
     62 	uint64_t	tmiss_count;
     63 	hrtime_t	tmiss_time;
     64 } tstat_missdata_t;
     65 
     66 typedef struct tstat_tlbdata {
     67 	tstat_missdata_t	ttlb_tlb;
     68 	tstat_missdata_t	ttlb_tsb;
     69 } tstat_tlbdata_t;
     70 
     71 typedef struct tstat_modedata {
     72 	tstat_tlbdata_t		tmode_itlb;
     73 	tstat_tlbdata_t		tmode_dtlb;
     74 } tstat_modedata_t;
     75 
     76 typedef struct tstat_pgszdata {
     77 	tstat_modedata_t	tpgsz_user;
     78 	tstat_modedata_t	tpgsz_kernel;
     79 } tstat_pgszdata_t;
     80 
     81 typedef struct tstat_data {
     82 	processorid_t	tdata_cpuid;
     83 	hrtime_t	tdata_snapts;
     84 	hrtime_t	tdata_snaptick;
     85 	hrtime_t	tdata_tmptick;
     86 	hrtime_t	tdata_peffect;
     87 	uint64_t	tdata_traps[TSTAT_NENT];
     88 	tstat_pgszdata_t tdata_pgsz[1];
     89 } tstat_data_t;
     90 
     91 #endif
     92 
     93 #ifdef _KERNEL
     94 
     95 #define	TSTAT_TLGT0_NENT	256
     96 #define	TSTAT_TOTAL_NENT	(TSTAT_NENT + TSTAT_TLGT0_NENT)
     97 
     98 #define	TSTAT_ENT_NINSTR	8		/* 8 instructions/entry */
     99 #define	TSTAT_ENT_SHIFT		5		/* 32 bytes/entry */
    100 #define	TSTAT_ENT_ITLBMISS	0x64
    101 #define	TSTAT_ENT_DTLBMISS	0x68
    102 
    103 #define	TSTAT_TLBRET_NINSTR	32
    104 
    105 #define	TSTAT_PROBE_NPAGES	2048
    106 #define	TSTAT_PROBE_SIZE	(TSTAT_PROBE_NPAGES * MMU_PAGESIZE)
    107 #define	TSTAT_PROBE_NLAPS	10
    108 
    109 #ifdef sun4v
    110 #define	TSTAT_TRAPCNT_NINSTR	8
    111 #define	TSTAT_TLBENT_NINSTR	64
    112 #define	TSTAT_ENT_IMMUMISS	0x09
    113 #define	TSTAT_ENT_DMMUMISS	0x31
    114 #endif
    115 
    116 #ifndef _ASM
    117 
    118 typedef struct tstat_tlbretent {
    119 	uint32_t	ttlbrent_instr[TSTAT_TLBRET_NINSTR];
    120 } tstat_tlbretent_t;
    121 
    122 #ifdef sun4v
    123 typedef struct tstat_tlbent {
    124 	uint32_t	ttlbent_instr[TSTAT_TLBENT_NINSTR];
    125 } tstat_tlbent_t;
    126 #endif /* sun4v */
    127 
    128 
    129 typedef struct tstat_tlbret {
    130 	tstat_tlbretent_t	ttlbr_ktlb;
    131 	tstat_tlbretent_t	ttlbr_ktsb;
    132 	tstat_tlbretent_t	ttlbr_utlb;
    133 	tstat_tlbretent_t	ttlbr_utsb;
    134 } tstat_tlbret_t;
    135 
    136 typedef struct tstat_instr {
    137 	uint32_t	tinst_traptab[TSTAT_TOTAL_NENT * TSTAT_ENT_NINSTR];
    138 	tstat_tlbret_t	tinst_itlbret;
    139 	tstat_tlbret_t	tinst_dtlbret;
    140 #ifdef sun4v
    141 	tstat_tlbent_t	tinst_immumiss;
    142 	tstat_tlbent_t	tinst_dmmumiss;
    143 	uint32_t	tinst_trapcnt[TSTAT_TRAPCNT_NINSTR];
    144 #endif
    145 } tstat_instr_t;
    146 
    147 typedef struct tstat_tsbmiss_patch_entry {
    148 	uint32_t *tpe_addr;
    149 	uint32_t tpe_instr;
    150 } tstat_tsbmiss_patch_entry_t;
    151 
    152 #endif
    153 
    154 #ifdef sun4v
    155 
    156 #if (NCPU > 508)
    157 #error "sun4v trapstat supports up to 508 cpus"
    158 #endif
    159 
    160 #define	TSTAT_TLB_STATS		0x1		/* cpu_tstat_flags */
    161 #define	TSTAT_INSTR_SIZE	\
    162 	((sizeof (tstat_instr_t) + MMU_PAGESIZE - 1) & ~(MMU_PAGESIZE - 1))
    163 #define	TSTAT_DATA_SHIFT	13
    164 #define	TSTAT_DATA_SIZE		(1 << TSTAT_DATA_SHIFT)	/* 8K per CPU */
    165 #define	TSTAT_TBA_MASK		~((1 << 15) - 1)	/* 32K boundary */
    166 
    167 #define	TSTAT_CPU0_DATA_OFFS(tcpu, mem)	\
    168 	((uintptr_t)(tcpu)->tcpu_ibase + TSTAT_INSTR_SIZE + \
    169 	    offsetof(tstat_data_t, mem))
    170 
    171 #else /* sun4v */
    172 
    173 #define	TSTAT_INSTR_PAGES	((sizeof (tstat_instr_t) >> MMU_PAGESHIFT) + 1)
    174 #define	TSTAT_INSTR_SIZE	(TSTAT_INSTR_PAGES * MMU_PAGESIZE)
    175 #define	TSTAT_TBA_MASK		~((1 << 16) - 1)	/* 64K per cpu */
    176 
    177 #define	TSTAT_DATA_OFFS(tcpu, mem)	\
    178 	((uintptr_t)(tcpu)->tcpu_dbase + offsetof(tstat_data_t, mem))
    179 
    180 #endif /* sun4v */
    181 
    182 #define	TSTAT_INSTR_OFFS(tcpu, mem)	\
    183 	((uintptr_t)(tcpu)->tcpu_ibase + offsetof(tstat_instr_t, mem))
    184 
    185 #define	TSTAT_CPU_SELECTED	0x0001
    186 #define	TSTAT_CPU_ALLOCATED	0x0002
    187 #define	TSTAT_CPU_ENABLED	0x0004
    188 
    189 #define	TSTAT_OPT_CPU		0x0001
    190 #define	TSTAT_OPT_NOGO		0x0002
    191 #define	TSTAT_OPT_TLBDATA	0x0004
    192 #define	TSTAT_OPT_ENTRY		0x0008
    193 
    194 #define	TSTAT_TSBMISS_INSTR	0x8e01e000	/* add %g7, 0, %g7 */
    195 
    196 #ifndef _ASM
    197 
    198 typedef struct tstat_percpu {
    199 	uint32_t	tcpu_flags;
    200 	caddr_t		tcpu_tba;
    201 	caddr_t		tcpu_vabase;
    202 	caddr_t		tcpu_ibase;
    203 	caddr_t		tcpu_dbase;
    204 	pfn_t		*tcpu_pfn;
    205 	tstat_instr_t	*tcpu_instr;
    206 	tstat_data_t	*tcpu_data;
    207 } tstat_percpu_t;
    208 
    209 #endif
    210 
    211 #endif
    212 #ifdef	__cplusplus
    213 }
    214 #endif
    215 
    216 #endif	/* _SYS_TRAPSTAT_H */
    217