| 1 | /*- |
| 2 | * Copyright 1996 Massachusetts Institute of Technology |
| 3 | * |
| 4 | * Permission to use, copy, modify, and distribute this software and |
| 5 | * its documentation for any purpose and without fee is hereby |
| 6 | * granted, provided that both the above copyright notice and this |
| 7 | * permission notice appear in all copies, that both the above |
| 8 | * copyright notice and this permission notice appear in all |
| 9 | * supporting documentation, and that the name of M.I.T. not be used |
| 10 | * in advertising or publicity pertaining to distribution of the |
| 11 | * software without specific, written prior permission. M.I.T. makes |
| 12 | * no representations about the suitability of this software for any |
| 13 | * purpose. It is provided "as is" without express or implied |
| 14 | * warranty. |
| 15 | * |
| 16 | * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS |
| 17 | * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, |
| 18 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| 19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT |
| 20 | * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| 23 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| 26 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 27 | * SUCH DAMAGE. |
| 28 | */ |
| 29 | |
| 30 | /* |
| 31 | * Interface to performance-monitoring counters for Intel Pentium and |
| 32 | * Pentium Pro CPUs. |
| 33 | */ |
| 34 | |
| 35 | #ifndef	_MACHINE_PERFMON_H_ |
| 36 | #define	_MACHINE_PERFMON_H_ |
| 37 | |
| 38 | #ifndef _KERNEL |
| 39 | #include <sys/types.h> |
| 40 | #endif |
| 41 | #include <sys/ioccom.h> |
| 42 | |
| 43 | #define	NPMC	2 |
| 44 | |
| 45 | #define	PMIOSETUP	_IOW('5', 1, struct pmc) |
| 46 | #define	PMIOGET		_IOWR('5', 7, struct pmc) |
| 47 | #define	PMIOSTART	_IOW('5', 2, int) |
| 48 | #define	PMIOSTOP	_IOW('5', 3, int) |
| 49 | #define PMIOREAD	_IOWR('5', 4, struct pmc_data) |
| 50 | #define	PMIORESET	_IOW('5', 5, int) |
| 51 | #define	PMIOTSTAMP	_IOR('5', 6, struct pmc_tstamp) |
| 52 | |
| 53 | struct pmc { |
| 54 | 	int pmc_num; |
| 55 | 	union { |
| 56 | 		struct { |
| 57 | 			unsigned char pmcus_event; |
| 58 | 			unsigned char pmcus_unit; |
| 59 | 			unsigned char pmcus_flags; |
| 60 | 			unsigned char pmcus_mask; |
| 61 | 		} pmcu_s; |
| 62 | 		unsigned int pmcu_val; |
| 63 | 	} pmc_pmcu; |
| 64 | }; |
| 65 | |
| 66 | #define	PMC_ALL		(-1) |
| 67 | |
| 68 | #define	pmc_event	pmc_pmcu.pmcu_s.pmcus_event |
| 69 | #define	pmc_unit	pmc_pmcu.pmcu_s.pmcus_unit |
| 70 | #define	pmc_flags	pmc_pmcu.pmcu_s.pmcus_flags |
| 71 | #define	pmc_mask	pmc_pmcu.pmcu_s.pmcus_mask |
| 72 | #define	pmc_val		pmc_pmcu.pmcu_val |
| 73 | |
| 74 | #define	PMCF_USR	0x01	/* count events in user mode */ |
| 75 | #define	PMCF_OS		0x02	/* count events in kernel mode */ |
| 76 | #define	PMCF_E		0x04	/* use edge-detection mode */ |
| 77 | #define	PMCF_PC		0x08	/* PMx output pin control */ |
| 78 | #define	PMCF_INT	0x10	/* APIC interrupt enable (do not use) */ |
| 79 | #define	PMCF_EN		0x40	/* enable counters */ |
| 80 | #define	PMCF_INV	0x80	/* invert counter mask comparison */ |
| 81 | |
| 82 | #define	PMCF_SYS_FLAGS	(PMCF_INT | PMCF_EN) /* user cannot set */ |
| 83 | |
| 84 | struct pmc_data { |
| 85 | 	int pmcd_num; |
| 86 | 	quad_t pmcd_value; |
| 87 | }; |
| 88 | |
| 89 | struct pmc_tstamp { |
| 90 | 	int pmct_rate; |
| 91 | 	quad_t pmct_value; |
| 92 | }; |
| 93 | |
| 94 | #ifndef _KERNEL |
| 95 | |
| 96 | #define	_PATH_PERFMON	"/dev/perfmon" |
| 97 | |
| 98 | #else |
| 99 | |
| 100 | /* |
| 101 | * Intra-kernel interface to performance monitoring counters |
| 102 | */ |
| 103 | void	perfmon_init(void); |
| 104 | int	perfmon_avail(void); |
| 105 | int	perfmon_setup(int, unsigned int); |
| 106 | int	perfmon_get(int, unsigned int *); |
| 107 | int	perfmon_fini(int); |
| 108 | int	perfmon_start(int); |
| 109 | int	perfmon_stop(int); |
| 110 | int	perfmon_read(int, quad_t *); |
| 111 | int	perfmon_reset(int); |
| 112 | |
| 113 | #endif /* _KERNEL */ |
| 114 | |
| 115 | /* |
| 116 | * Pentium Pro performance counters, from Appendix B. |
| 117 | */ |
| 118 | /* Data Cache Unit */ |
| 119 | #define	PMC6_DATA_MEM_REFS	0x43 |
| 120 | #define	PMC6_DCU_LINES_IN	0x45 |
| 121 | #define	PMC6_DCU_M_LINES_IN	0x46 |
| 122 | #define	PMC6_DCU_M_LINES_OUT	0x47 |
| 123 | #define	PMC6_DCU_MISS_OUTSTANDING 0x48 |
| 124 | |
| 125 | /* Instruction Fetch Unit */ |
| 126 | #define	PMC6_IFU_IFETCH		0x80 |
| 127 | #define	PMC6_IFU_IFETCH_MISS	0x81 |
| 128 | #define	PMC6_ITLB_MISS		0x85 |
| 129 | #define	PMC6_IFU_MEM_STALL	0x86 |
| 130 | #define	PMC6_ILD_STALL		0x87 |
| 131 | |
| 132 | /* L2 Cache */ |
| 133 | #define	PMC6_L2_IFETCH		0x28 /* MESI */ |
| 134 | #define	PMC6_L2_LD		0x29 /* MESI */ |
| 135 | #define	PMC6_L2_ST		0x2a /* MESI */ |
| 136 | #define	PMC6_L2_LINES_IN	0x24 |
| 137 | #define	PMC6_L2_LINES_OUT	0x26 |
| 138 | #define	PMC6_L2_M_LINES_INM	0x25 |
| 139 | #define	PMC6_L2_M_LINES_OUTM	0x27 |
| 140 | #define	PMC6_L2_RQSTS		0x2e /* MESI */ |
| 141 | #define	PMC6_L2_ADS		0x21 |
| 142 | #define	PMC6_L2_DBUS_BUSY	0x22 |
| 143 | #define	PMC6_L2_DBUS_BUSY_RD	0x23 |
| 144 | |
| 145 | /* External Bus Logic */ |
| 146 | #define	PMC6_BUS_DRDY_CLOCKS	0x62 |
| 147 | #define	PMC6_BUS_LOCK_CLOCKS	0x63 |
| 148 | #define	PMC6_BUS_REQ_OUTSTANDING 0x60 |
| 149 | #define	PMC6_BUS_TRAN_BRD	0x65 |
| 150 | #define	PMC6_BUS_TRAN_RFO	0x66 |
| 151 | #define	PMC6_BUS_TRAN_WB	0x67 |
| 152 | #define	PMC6_BUS_TRAN_IFETCH	0x68 |
| 153 | #define	PMC6_BUS_TRAN_INVAL	0x69 |
| 154 | #define	PMC6_BUS_TRAN_PWR	0x6a |
| 155 | #define	PMC6_BUS_TRAN_P		0x6b |
| 156 | #define	PMC6_BUS_TRAN_IO	0x6c |
| 157 | #define	PMC6_BUS_TRAN_DEF	0x6d |
| 158 | #define	PMC6_BUS_TRAN_BURST	0x6e |
| 159 | #define	PMC6_BUS_TRAN_ANY	0x70 |
| 160 | #define	PMC6_BUS_TRAN_MEM	0x6f |
| 161 | #define	PMC6_BUS_DATA_RCV	0x64 |
| 162 | #define	PMC6_BUS_BNR_DRV	0x61 |
| 163 | #define	PMC6_BUS_HIT_DRV	0x7a |
| 164 | #define	PMC6_BUS_HITM_DRV	0x7b |
| 165 | #define	PMC6_BUS_SNOOP_STALL	0x7e |
| 166 | |
| 167 | /* Floating Point Unit */ |
| 168 | #define	PMC6_FLOPS		0xc1 /* counter 0 only */ |
| 169 | #define	PMC6_FP_COMP_OPS_EXE	0x10 /* counter 0 only */ |
| 170 | #define	PMC6_FP_ASSIST		0x11 /* counter 1 only */ |
| 171 | #define	PMC6_MUL		0x12 /* counter 1 only */ |
| 172 | #define	PMC6_DIV		0x13 /* counter 1 only */ |
| 173 | #define	PMC6_CYCLES_DIV_BUSY	0x14 /* counter 0 only */ |
| 174 | |
| 175 | /* Memory Ordering */ |
| 176 | #define	PMC6_LD_BLOCKS		0x03 |
| 177 | #define	PMC6_SB_DRAINS		0x04 |
| 178 | #define	PMC6_MISALIGN_MEM_REF	0x05 |
| 179 | |
| 180 | /* Instruction Decoding and Retirement */ |
| 181 | #define	PMC6_INST_RETIRED	0xc0 |
| 182 | #define	PMC6_UOPS_RETIRED	0xc2 |
| 183 | #define	PMC6_INST_DECODER	0xd0 /* (sic) */ |
| 184 | |
| 185 | /* Interrupts */ |
| 186 | #define	PMC6_HW_INT_RX		0xc8 |
| 187 | #define	PMC6_CYCLES_INT_MASKED	0xc6 |
| 188 | #define	PMC6_CYCLES_INT_PENDING_AND_MASKED 0xc7 |
| 189 | |
| 190 | /* Branches */ |
| 191 | #define	PMC6_BR_INST_RETIRED	0xc4 |
| 192 | #define	PMC6_BR_MISS_PRED_RETIRED 0xc5 |
| 193 | #define	PMC6_BR_TAKEN_RETIRED	0xc9 |
| 194 | #define	PMC6_BR_MISS_PRED_TAKEN_RET 0xca |
| 195 | #define	PMC6_BR_INST_DECODED	0xe0 |
| 196 | #define	PMC6_BTB_MISSES		0xe2 |
| 197 | #define	PMC6_BR_BOGUS		0xe4 |
| 198 | #define	PMC6_BACLEARS		0xe6 |
| 199 | |
| 200 | /* Stalls */ |
| 201 | #define	PMC6_RESOURCE_STALLS	0xa2 |
| 202 | #define	PMC6_PARTIAL_RAT_STALLS	0xd2 |
| 203 | |
| 204 | /* Segment Register Loads */ |
| 205 | #define	PMC6_SEGMENT_REG_LOADS	0x06 |
| 206 | |
| 207 | /* Clocks */ |
| 208 | #define	PMC6_CPU_CLK_UNHALTED	0x79 |
| 209 | |
| 210 | /* |
| 211 | * Pentium Performance Counters |
| 212 | * This list comes from the Harvard people, not Intel. |
| 213 | */ |
| 214 | #define	PMC5_DATA_READ		0 |
| 215 | #define	PMC5_DATA_WRITE		1 |
| 216 | #define	PMC5_DATA_TLB_MISS	2 |
| 217 | #define	PMC5_DATA_READ_MISS	3 |
| 218 | #define	PMC5_DATA_WRITE_MISS	4 |
| 219 | #define	PMC5_WRITE_M_E		5 |
| 220 | #define	PMC5_DATA_LINES_WBACK	6 |
| 221 | #define	PMC5_DATA_CACHE_SNOOP	7 |
| 222 | #define	PMC5_DATA_CACHE_SNOOP_HIT 8 |
| 223 | #define	PMC5_MEM_ACCESS_BOTH	9 |
| 224 | #define	PMC5_BANK_CONFLICTS	10 |
| 225 | #define	PMC5_MISALIGNED_DATA	11 |
| 226 | #define	PMC5_INST_READ		12 |
| 227 | #define	PMC5_INST_TLB_MISS	13 |
| 228 | #define	PMC5_INST_CACHE_MISS	14 |
| 229 | #define	PMC5_SEGMENT_REG_LOAD	15 |
| 230 | #define	PMC5_BRANCHES		18 |
| 231 | #define	PMC5_BTB_HITS		19 |
| 232 | #define	PMC5_BRANCH_TAKEN	20 |
| 233 | #define	PMC5_PIPELINE_FLUSH	21 |
| 234 | #define	PMC5_INST_EXECUTED	22 |
| 235 | #define PMC5_INST_EXECUTED_V	23 |
| 236 | #define	PMC5_BUS_UTILIZATION	24 |
| 237 | #define	PMC5_WRITE_BACKUP_STALL	25 |
| 238 | #define	PMC5_DATA_READ_STALL	26 |
| 239 | #define	PMC5_WRITE_E_M_STALL	27 |
| 240 | #define	PMC5_LOCKED_BUS		28 |
| 241 | #define	PMC5_IO_CYCLE		29 |
| 242 | #define	PMC5_NONCACHE_MEMORY	30 |
| 243 | #define	PMC5_ADDR_GEN_INTERLOCK	31 |
| 244 | #define	PMC5_FLOPS		34 |
| 245 | #define	PMC5_BP0_MATCH		35 |
| 246 | #define	PMC5_BP1_MATCH		36 |
| 247 | #define	PMC5_BP2_MATCH		37 |
| 248 | #define	PMC5_BP3_MATCH		38 |
| 249 | #define	PMC5_HW_INTR		39 |
| 250 | #define	PMC5_DATA_RW		40 |
| 251 | #define	PMC5_DATA_RW_MISS	41 |
| 252 | |
| 253 | #endif /* !_MACHINE_PERFMON_H_ */ |