| 1 | /*- |
| 2 | * SPDX-License-Identifier: BSD-2-Clause |
| 3 | * |
| 4 | * Copyright (c) 2008 Joseph Koshy |
| 5 | * All rights reserved. |
| 6 | * |
| 7 | * Redistribution and use in source and binary forms, with or without |
| 8 | * modification, are permitted provided that the following conditions |
| 9 | * are met: |
| 10 | * 1. Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. |
| 15 | * |
| 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 26 | * SUCH DAMAGE. |
| 27 | */ |
| 28 | |
| 29 | #ifndef _DEV_HWPMC_CORE_H_ |
| 30 | #define	_DEV_HWPMC_CORE_H_ 1 |
| 31 | |
| 32 | #define	IA32_PERF_CAPABILITIES		0x345 |
| 33 | #define	PERFCAP_LBR_FORMAT		0x003f |
| 34 | #define	PERFCAP_PEBS_TRAP		0x0040 |
| 35 | #define	PERFCAP_PEBS_SAVEARCH		0x0080 |
| 36 | #define	PERFCAP_PEBS_RECFORMAT		0x0f00 |
| 37 | #define	PERFCAP_SMM_FREEZE		0x1000 |
| 38 | #define	PERFCAP_FW_WRITE		0x2000	/* full width write aliases */ |
| 39 | |
| 40 | #define	IAF_OS		0x1 |
| 41 | #define	IAF_USR		0x2 |
| 42 | #define	IAF_ANY		0x4 |
| 43 | #define	IAF_PMI		0x8 |
| 44 | |
| 45 | /* |
| 46 | * Programmable PMCs. |
| 47 | */ |
| 48 | struct pmc_md_iap_op_pmcallocate { |
| 49 | 	uint64_t	pm_iap_config; |
| 50 | 	uint64_t	pm_iap_rsp; |
| 51 | }; |
| 52 | |
| 53 | #define	IAP_EVSEL(C)	((C) & 0xFF) |
| 54 | #define	IAP_UMASK(C)	(((C) & 0xFF) << 8) |
| 55 | #define	IAP_USR		(1 << 16) |
| 56 | #define	IAP_OS		(1 << 17) |
| 57 | #define	IAP_EDGE	(1 << 18) |
| 58 | #define	IAP_INT		(1 << 20) |
| 59 | #define	IAP_ANY		(1 << 21) |
| 60 | #define	IAP_EN		(1 << 22) |
| 61 | #define	IAP_INV		(1 << 23) |
| 62 | #define	IAP_CMASK(C)	(((C) & 0xFF) << 24) |
| 63 | |
| 64 | #define	IAP_EVSEL_GET(C)	((C) & 0xFF) |
| 65 | #define	IAP_UMASK_GET(C)	(((C) & 0xFF00) >> 8) |
| 66 | |
| 67 | #define	IA_OFFCORE_RSP_MASK_I7WM	0x000000F7FF |
| 68 | #define	IA_OFFCORE_RSP_MASK_SBIB	0x3F807F8FFF |
| 69 | |
| 70 | #ifdef	_KERNEL |
| 71 | |
| 72 | /* |
| 73 | * Fixed-function counters. |
| 74 | */ |
| 75 | |
| 76 | #define	IAF_MASK				0x000000010000000f |
| 77 | |
| 78 | #define	IAF_CTR0				0x309 |
| 79 | #define	IAF_CTR1				0x30A |
| 80 | #define	IAF_CTR2				0x30B |
| 81 | |
| 82 | /* |
| 83 | * The IAF_CTRL MSR is laid out in the following way. |
| 84 | * |
| 85 | * Bit Position Use |
| 86 | * 63 - 45 Reserved (do not touch) |
| 87 | * 44 Ctr 3 Adaptive Record (v5) |
| 88 | * 43 - 41 Reserved (do not touch) |
| 89 | * 40 Ctr 2 Adaptive Record (v5) |
| 90 | * 39 - 37 Reserved (do not touch) |
| 91 | * 36 Ctr 1 Adaptive Record (v5) |
| 92 | * 35 - 33 Reserved (do not touch) |
| 93 | * 32 Ctr 0 Adaptive Record (v5) |
| 94 | * 15 Ctr 3 PMI |
| 95 | * 14 Ctr 3 Any Thread (v3) |
| 96 | * 13-12 Ctr 3 Enable |
| 97 | * 11 Ctr 2 PMI |
| 98 | * 10 Ctr 2 Any Thread (v3) |
| 99 | * 9-8 Ctr 2 Enable |
| 100 | * 7 Ctr 1 PMI |
| 101 | * 6 Ctr 1 Any Thread (v3) |
| 102 | * 5-4 Ctr 1 Enable |
| 103 | * 3 Ctr 0 PMI |
| 104 | * 2 Ctr 0 Any Thread (v3) |
| 105 | * 1-0 Ctr 0 Enable (3: All Levels, 2: User, 1: OS, 0: Disable) |
| 106 | */ |
| 107 | |
| 108 | #define	IAF_OFFSET				32 |
| 109 | #define	IAF_CTRL				0x38D |
| 110 | |
| 111 | /* |
| 112 | * Programmable counters. |
| 113 | */ |
| 114 | |
| 115 | #define	IAP_PMC0				0x0C1 |
| 116 | #define	IAP_A_PMC0				0x4C1 |
| 117 | |
| 118 | /* |
| 119 | * IAP_EVSEL(n) is laid out in the following way. |
| 120 | * |
| 121 | * Bit Position Use |
| 122 | * 63-35 Reserved (do not touch) |
| 123 | * 34 Adaptive Record (v5) |
| 124 | * 33 IN_TX (v3) |
| 125 | * 32 IN_TXCP (v3) |
| 126 | * 31-24 Counter Mask |
| 127 | * 23 Invert |
| 128 | * 22 Enable |
| 129 | * 21 Any Thread (v3) |
| 130 | * 20 APIC Interrupt Enable |
| 131 | * 19 Pin Control |
| 132 | * 18 Edge Detect |
| 133 | * 17 OS |
| 134 | * 16 User |
| 135 | * 15-8 Unit Mask |
| 136 | * 7-0 Event Select |
| 137 | */ |
| 138 | |
| 139 | #define	IAP_EVSEL0				0x186 |
| 140 | |
| 141 | /* |
| 142 | * Simplified programming interface in Intel Performance Architecture |
| 143 | * v2 and later. |
| 144 | */ |
| 145 | |
| 146 | #define	IA_GLOBAL_STATUS			0x38E |
| 147 | #define	IA_GLOBAL_CTRL				0x38F |
| 148 | |
| 149 | /* |
| 150 | * IA_GLOBAL_CTRL is laid out in the following way. |
| 151 | * |
| 152 | * Bit Position Use |
| 153 | * 63-49 Reserved (do not touch) |
| 154 | * 48 Perf Metrics Enable (v5) |
| 155 | * 47-36 Reserved (do not touch) |
| 156 | * 35 IAF Counter 3 Enable |
| 157 | * 34 IAF Counter 2 Enable |
| 158 | * 33 IAF Counter 1 Enable |
| 159 | * 32 IAF Counter 0 Enable |
| 160 | * 31-0 Depends on programmable counters |
| 161 | */ |
| 162 | |
| 163 | #define	IA_GLOBAL_OVF_CTRL			0x390 |
| 164 | #define	IA_GLOBAL_STATUS_RESET			0x390 |
| 165 | #define	IA_GLOBAL_STATUS_SET			0x391		/* v4 */ |
| 166 | |
| 167 | #define	IA_GLOBAL_STATUS_FLAG_CONDCHG		(1ULL << 63) |
| 168 | #define	IA_GLOBAL_STATUS_FLAG_OVFBUF		(1ULL << 62) |
| 169 | #define	IA_GLOBAL_STATUS_FLAG_OVFUNCORE		(1ULL << 61)	/* v3 */ |
| 170 | #define	IA_GLOBAL_STATUS_FLAG_ASCI		(1ULL << 60)	/* v4 */ |
| 171 | #define	IA_GLOBAL_STATUS_FLAG_CTR_FRZ		(1ULL << 59)	/* v4 */ |
| 172 | #define	IA_GLOBAL_STATUS_FLAG_LBP_FRZ		(1ULL << 58)	/* v4 */ |
| 173 | #define	IA_GLOBAL_STATUS_FLAG_TRACETOPAPMI	(1ULL << 55)	/* v4 */ |
| 174 | |
| 175 | #define	IA_GLOBAL_INUSE				0x392		/* v4 */ |
| 176 | |
| 177 | /* |
| 178 | * Offcore response configuration. |
| 179 | */ |
| 180 | #define	IA_OFFCORE_RSP0				0x1A6 |
| 181 | #define	IA_OFFCORE_RSP1				0x1A7 |
| 182 | |
| 183 | struct pmc_md_iaf_pmc { |
| 184 | 	uint64_t	pm_iaf_ctrl; |
| 185 | }; |
| 186 | |
| 187 | struct pmc_md_iap_pmc { |
| 188 | 	uint64_t	pm_iap_evsel; |
| 189 | 	uint64_t	pm_iap_rsp; |
| 190 | }; |
| 191 | |
| 192 | /* |
| 193 | * Prototypes. |
| 194 | */ |
| 195 | |
| 196 | int	pmc_core_initialize(struct pmc_mdep *_md, int _maxcpu, |
| 197 | 	 int _version_override); |
| 198 | void	pmc_core_finalize(struct pmc_mdep *_md); |
| 199 | |
| 200 | int	pmc_iaf_initialize(struct pmc_mdep *_md, int _maxcpu, int _npmc, int _width); |
| 201 | |
| 202 | int	pmc_iap_initialize(struct pmc_mdep *_md, int _maxcpu, int _npmc, int _width, |
| 203 | 	 int _flags); |
| 204 | |
| 205 | #endif	/* _KERNEL */ |
| 206 | #endif	/* _DEV_HWPMC_CORE_H */ |