1 /* $NetBSD: tprof_x86.c,v 1.19 2023/07/07 04:43:15 msaitoh Exp $ */ 2 3 /* 4 * Copyright (c) 2018-2019 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Maxime Villard. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <stdbool.h> 36 #include <string.h> 37 #include <unistd.h> 38 #include <err.h> 39 #include <machine/specialreg.h> 40 #include <dev/tprof/tprof_ioctl.h> 41 #include "../tprof.h" 42 43 int tprof_event_init(uint32_t); 44 void tprof_event_list(void); 45 void tprof_event_lookup(const char *, struct tprof_param *); 46 47 struct name_to_event { 48 const char *name; 49 uint64_t event; 50 uint64_t unit; 51 bool enabled; 52 }; 53 54 struct event_table { 55 const char *tablename; 56 struct name_to_event *names; 57 size_t nevents; 58 struct event_table *next; 59 }; 60 61 static struct event_table *cpuevents = NULL; 62 63 static void 64 x86_cpuid(unsigned int *eax, unsigned int *ebx, 65 unsigned int *ecx, unsigned int *edx) 66 { 67 asm volatile("cpuid" 68 : "=a" (*eax), 69 "=b" (*ebx), 70 "=c" (*ecx), 71 "=d" (*edx) 72 : "0" (*eax), "2" (*ecx)); 73 } 74 75 /* ------------------------------------------------------------------------- */ 76 77 /* 78 * Intel Architectural Version 1. 79 */ 80 static struct name_to_event intel_arch1_names[] = { 81 /* Event Name - Event Select - UMask */ 82 { "unhalted-core-cycles", 0x3c, 0x00, true }, 83 { "instruction-retired", 0xc0, 0x00, true }, 84 { "unhalted-reference-cycles", 0x3c, 0x01, true }, 85 { "llc-reference", 0x2e, 0x4f, true }, 86 { "llc-misses", 0x2e, 0x41, true }, 87 { "branch-instruction-retired", 0xc4, 0x00, true }, 88 { "branch-misses-retired", 0xc5, 0x00, true }, 89 { "topdown-slots", 0xa4, 0x01, true }, 90 }; 91 92 static struct event_table intel_arch1 = { 93 .tablename = "Intel Architectural Version 1", 94 .names = intel_arch1_names, 95 .nevents = sizeof(intel_arch1_names) / 96 sizeof(struct name_to_event), 97 .next = NULL 98 }; 99 100 static struct event_table * 101 init_intel_arch1(void) 102 { 103 unsigned int eax, ebx, ecx, edx, vectorlen; 104 struct event_table *table; 105 size_t i; 106 107 eax = 0x0a; 108 ebx = 0; 109 ecx = 0; 110 edx = 0; 111 x86_cpuid(&eax, &ebx, &ecx, &edx); 112 113 vectorlen = __SHIFTOUT(eax, CPUID_PERF_BVECLEN); 114 115 table = &intel_arch1; 116 for (i = 0; i < table->nevents; i++) { 117 /* 118 * Disable the unsupported events from: 119 * a) the bit vector length in EAX. 120 * b) the disable bit in EBX. 121 */ 122 if (i >= vectorlen) 123 table->names[i].enabled = false; 124 if ((ebx & (i << 1)) != 0) 125 table->names[i].enabled = false; 126 } 127 128 return table; 129 } 130 131 /* 132 * Intel Silvermont/Airmont. 133 */ 134 static struct name_to_event intel_silvermont_airmont_names[] = { 135 { "REHABQ.LD_BLOCK_ST_FORWARD", 0x03, 0x01, true }, 136 { "REHABQ.LD_BLOCK_STD_NOTREADY", 0x03, 0x02, true }, 137 { "REHABQ.ST_SPLITS", 0x03, 0x04, true }, 138 { "REHABQ.LD_SPLITS", 0x03, 0x08, true }, 139 { "REHABQ.LOCK", 0x03, 0x10, true }, 140 { "REHABQ.STA_FULL", 0x03, 0x20, true }, 141 { "REHABQ.ANY_LD", 0x03, 0x40, true }, 142 { "REHABQ.ANY_ST", 0x03, 0x80, true }, 143 { "MEM_UOPS_RETIRED.L1_MISS_LOADS", 0x04, 0x01, true }, 144 { "MEM_UOPS_RETIRED.L2_HIT_LOADS", 0x04, 0x02, true }, 145 { "MEM_UOPS_RETIRED.L2_MISS_LOADS", 0x04, 0x04, true }, 146 { "MEM_UOPS_RETIRED.DTLB_MISS_LOADS", 0x04, 0x08, true }, 147 { "MEM_UOPS_RETIRED.UTLB_MISS", 0x04, 0x10, true }, 148 { "MEM_UOPS_RETIRED.HITM", 0x04, 0x20, true }, 149 { "MEM_UOPS_RETIRED.ALL_LOADS", 0x04, 0x40, true }, 150 { "MEM_UOP_RETIRED.ALL_STORES", 0x04, 0x80, true }, 151 { "PAGE_WALKS.D_SIDE_CYCLES", 0x05, 0x01, true }, 152 { "PAGE_WALKS.I_SIDE_CYCLES", 0x05, 0x02, true }, 153 { "PAGE_WALKS.WALKS", 0x05, 0x03, true }, 154 { "LONGEST_LAT_CACHE.MISS", 0x2e, 0x41, true }, 155 { "LONGEST_LAT_CACHE.REFERENCE", 0x2e, 0x4f, true }, 156 { "L2_REJECT_XQ.ALL", 0x30, 0x00, true }, 157 { "CORE_REJECT_L2Q.ALL", 0x31, 0x00, true }, 158 { "CPU_CLK_UNHALTED.CORE_P", 0x3c, 0x00, true }, 159 { "CPU_CLK_UNHALTED.REF_P", 0x3c, 0x01, true }, 160 { "ICACHE.HIT", 0x80, 0x01, true }, 161 { "ICACHE.MISSES", 0x80, 0x02, true }, 162 { "ICACHE.ACCESSES", 0x80, 0x03, true }, 163 { "OFFCORE_RESPONSE_0", 0xb7, 0x01, true }, 164 { "OFFCORE_RESPONSE_1", 0xb7, 0x02, true }, 165 { "INST_RETIRED.ANY_P", 0xc0, 0x00, true }, 166 { "UOPS_RETIRED.MS", 0xc2, 0x01, true }, 167 { "UOPS_RETIRED.ALL", 0xc2, 0x10, true }, 168 { "MACHINE_CLEARS.SMC", 0xc3, 0x01, true }, 169 { "MACHINE_CLEARS.MEMORY_ORDERING", 0xc3, 0x02, true }, 170 { "MACHINE_CLEARS.FP_ASSIST", 0xc3, 0x04, true }, 171 { "MACHINE_CLEARS.ALL", 0xc3, 0x08, true }, 172 { "BR_INST_RETIRED.ALL_BRANCHES", 0xc4, 0x00, true }, 173 { "BR_INST_RETIRED.JCC", 0xc4, 0x7e, true }, 174 { "BR_INST_RETIRED.FAR_BRANCH", 0xc4, 0xbf, true }, 175 { "BR_INST_RETIRED.NON_RETURN_IND", 0xc4, 0xeb, true }, 176 { "BR_INST_RETIRED.RETURN", 0xc4, 0xf7, true }, 177 { "BR_INST_RETIRED.CALL", 0xc4, 0xf9, true }, 178 { "BR_INST_RETIRED.IND_CALL", 0xc4, 0xfb, true }, 179 { "BR_INST_RETIRED.REL_CALL", 0xc4, 0xfd, true }, 180 { "BR_INST_RETIRED.TAKEN_JCC", 0xc4, 0xfe, true }, 181 { "BR_MISP_RETIRED.ALL_BRANCHES", 0xc5, 0x00, true }, 182 { "BR_MISP_RETIRED.JCC", 0xc5, 0x7e, true }, 183 { "BR_MISP_RETIRED.FAR", 0xc5, 0xbf, true }, 184 { "BR_MISP_RETIRED.NON_RETURN_IND", 0xc5, 0xeb, true }, 185 { "BR_MISP_RETIRED.RETURN", 0xc5, 0xf7, true }, 186 { "BR_MISP_RETIRED.CALL", 0xc5, 0xf9, true }, 187 { "BR_MISP_RETIRED.IND_CALL", 0xc5, 0xfb, true }, 188 { "BR_MISP_RETIRED.REL_CALL", 0xc5, 0xfd, true }, 189 { "BR_MISP_RETIRED.TAKEN_JCC", 0xc5, 0xfe, true }, 190 { "NO_ALLOC_CYCLES.ROB_FULL", 0xca, 0x01, true }, 191 { "NO_ALLOC_CYCLES.RAT_STALL", 0xca, 0x20, true }, 192 { "NO_ALLOC_CYCLES.ALL", 0xca, 0x3f, true }, 193 { "NO_ALLOC_CYCLES.NOT_DELIVERED", 0xca, 0x50, true }, 194 { "RS_FULL_STALL.MEC", 0xcb, 0x01, true }, 195 { "RS_FULL_STALL.ALL", 0xcb, 0x1f, true }, 196 { "CYCLES_DIV_BUSY.ANY", 0xcd, 0x01, true }, 197 { "BACLEARS.ALL", 0xe6, 0x01, true }, 198 { "BACLEARS.RETURN", 0xe6, 0x08, true }, 199 { "BACLEARS.COND", 0xe6, 0x10, true }, 200 { "MS_DECODED.MS_ENTRY", 0xe7, 0x01, true }, 201 }; 202 203 static struct event_table intel_silvermont_airmont = { 204 .tablename = "Intel Silvermont/Airmont", 205 .names = intel_silvermont_airmont_names, 206 .nevents = sizeof(intel_silvermont_airmont_names) / 207 sizeof(struct name_to_event), 208 .next = NULL 209 }; 210 211 static struct event_table * 212 init_intel_silvermont_airmont(void) 213 { 214 215 return &intel_silvermont_airmont; 216 } 217 218 /* 219 * Intel Goldmont 220 */ 221 static struct name_to_event intel_goldmont_names[] = { 222 { "LD_BLOCKS.ALL_BLOCK", 0x03, 0x10, true }, 223 { "LD_BLOCKS.UTLB_MISS", 0x03, 0x08, true }, 224 { "LD_BLOCKS.STORE_FORWARD", 0x03, 0x02, true }, 225 { "LD_BLOCKS.DATA_UNKNOWN", 0x03, 0x01, true }, 226 { "LD_BLOCKS.4K_ALIAS", 0x03, 0x04, true }, 227 { "PAGE_WALKS.D_SIDE_CYCLES", 0x05, 0x01, true }, 228 { "PAGE_WALKS.I_SIDE_CYCLES", 0x05, 0x02, true }, 229 { "PAGE_WALKS.CYCLES", 0x05, 0x03, true }, 230 { "UOPS_ISSUED.ANY", 0x0e, 0x00, true }, 231 { "MISALIGN_MEM_REF.LOAD_PAGE_SPLIT", 0x13, 0x02, true }, 232 { "MISALIGN_MEM_REF.STORE_PAGE_SPLIT", 0x13, 0x04, true }, 233 { "LONGEST_LAT_CACHE.REFERENCE", 0x2e, 0x4f, true }, 234 { "LONGEST_LAT_CACHE.MISS", 0x2e, 0x41, true }, 235 { "L2_REJECT_XQ.ALL", 0x30, 0x00, true }, 236 { "CORE_REJECT_L2Q.ALL", 0x31, 0x00, true }, 237 { "CPU_CLK_UNHALTED.CORE_P", 0x3c, 0x00, true }, 238 { "CPU_CLK_UNHALTED.REF", 0x3c, 0x01, true }, 239 { "DL1.DIRTY_EVICTION", 0x51, 0x01, true }, 240 { "ICACHE.HIT", 0x80, 0x01, true }, 241 { "ICACHE.MISSES", 0x80, 0x02, true }, 242 { "ICACHE.ACCESSES", 0x80, 0x03, true }, 243 { "ITLB.MISS", 0x81, 0x04, true }, 244 { "FETCH_STALL.ALL", 0x86, 0x00, true }, 245 { "FETCH_STALL.ITLB_FILL_PENDING_CYCLES", 0x86, 0x01, true }, 246 { "FETCH_STALL.ICACHE_FILL_PENDING_CYCLES", 0x86, 0x02, true }, 247 { "UOPS_NOT_DELIVERED.ANY", 0x9c, 0x00, true }, 248 { "OFFCORE_RESPONSE.0", 0xb7, 0x01, true }, 249 { "OFFCORE_RESPONSE.1", 0xb7, 0x02, true }, 250 { "INST_RETIRED.ANY_P", 0xc0, 0x00, true }, 251 { "UOPS_RETIRED.ANY", 0xc2, 0x00, true }, 252 { "UOPS_RETIRED.MS", 0xc2, 0x01, true }, 253 { "UOPS_RETIRED.FPDIV", 0xc2, 0x08, true }, 254 { "UOPS_RETIRED.IDIV", 0xc2, 0x10, true }, 255 { "MACHINE_CLEARS.SMC", 0xc3, 0x01, true }, 256 { "MACHINE_CLEARS.MEMORY_ORDERING", 0xc3, 0x02, true }, 257 { "MACHINE_CLEARS.FP_ASSIST", 0xc3, 0x04, true }, 258 { "MACHINE_CLEARS.DISAMBIGUATION", 0xc3, 0x08, true }, 259 { "MACHINE_CLEARS.ALL", 0xc3, 0x00, true }, 260 { "BR_INST_RETIRED.ALL_BRANCHES", 0xc4, 0x00, true }, 261 { "BR_INST_RETIRED.JCC", 0xc4, 0x7e, true }, 262 { "BR_INST_RETIRED.ALL_TAKEN_BRANCHES", 0xc4, 0x80, true }, 263 { "BR_INST_RETIRED.TAKEN_JCC", 0xc4, 0xfe, true }, 264 { "BR_INST_RETIRED.CALL", 0xc4, 0xf9, true }, 265 { "BR_INST_RETIRED.REL_CALL", 0xc4, 0xfd, true }, 266 { "BR_INST_RETIRED.IND_CALL", 0xc4, 0xfb, true }, 267 { "BR_INST_RETIRED.RETURN", 0xc4, 0xf7, true }, 268 { "BR_INST_RETIRED.NON_RETURN_IND", 0xc4, 0xeb, true }, 269 { "BR_INST_RETIRED.FAR_BRANCH", 0xc4, 0xbf, true }, 270 { "BR_MISP_RETIRED.ALL_BRANCHES", 0xc5, 0x00, true }, 271 { "BR_MISP_RETIRED.JCC", 0xc5, 0x7e, true }, 272 { "BR_MISP_RETIRED.TAKEN_JCC", 0xc5, 0xfe, true }, 273 { "BR_MISP_RETIRED.IND_CALL", 0xc5, 0xfb, true }, 274 { "BR_MISP_RETIRED.RETURN", 0xc5, 0xf7, true }, 275 { "BR_MISP_RETIRED.NON_RETURN_IND", 0xc5, 0xeb, true }, 276 { "ISSUE_SLOTS_NOT_CONSUMED.RESOURCE_FULL", 0xca, 0x01, true }, 277 { "ISSUE_SLOTS_NOT_CONSUMED.RECOVERY", 0xca, 0x02, true }, 278 { "ISSUE_SLOTS_NOT_CONSUMED.ANY", 0xca, 0x00, true }, 279 { "HW_INTERRUPTS.RECEIVED", 0xcb, 0x01, true }, 280 { "HW_INTERRUPTS.MASKED", 0xcb, 0x02, true }, 281 { "HW_INTERRUPTS.PENDING_AND_MASKED", 0xcb, 0x04, true }, 282 { "CYCLES_DIV_BUSY.ALL", 0xcd, 0x00, true }, 283 { "CYCLES_DIV_BUSY.IDIV", 0xcd, 0x01, true }, 284 { "CYCLES_DIV_BUSY.FPDIV", 0xcd, 0x02, true }, 285 { "MEM_UOPS_RETIRED.ALL_LOADS", 0xd0, 0x81, true }, 286 { "MEM_UOPS_RETIRED.ALL_STORES", 0xd0, 0x82, true }, 287 { "MEM_UOPS_RETIRED.ALL", 0xd0, 0x83, true }, 288 { "MEM_UOPS_RETIRED.DTLB_MISS_LOADS", 0xd0, 0x11, true }, 289 { "MEM_UOPS_RETIRED.DTLB_MISS_STORES", 0xd0, 0x12, true }, 290 { "MEM_UOPS_RETIRED.DTLB_MISS", 0xd0, 0x13, true }, 291 { "MEM_UOPS_RETIRED.LOCK_LOADS", 0xd0, 0x21, true }, 292 { "MEM_UOPS_RETIRED.SPLIT_LOADS", 0xd0, 0x41, true }, 293 { "MEM_UOPS_RETIRED.SPLIT_STORES", 0xd0, 0x42, true }, 294 { "MEM_UOPS_RETIRED.SPLIT", 0xd0, 0x43, true }, 295 { "MEM_LOAD_UOPS_RETIRED.L1_HIT", 0xd1, 0x01, true }, 296 { "MEM_LOAD_UOPS_RETIRED.L1_MISS", 0xd1, 0x08, true }, 297 { "MEM_LOAD_UOPS_RETIRED.L2_HIT", 0xd1, 0x02, true }, 298 { "MEM_LOAD_UOPS_RETIRED.L2_MISS", 0xd1, 0x10, true }, 299 { "MEM_LOAD_UOPS_RETIRED.HITM", 0xd1, 0x20, true }, 300 { "MEM_LOAD_UOPS_RETIRED.WCB_HIT", 0xd1, 0x40, true }, 301 { "MEM_LOAD_UOPS_RETIRED.DRAM_HIT", 0xd1, 0x80, true }, 302 { "BACLEARS.ALL", 0xe6, 0x01, true }, 303 { "BACLEARS.RETURN", 0xe6, 0x08, true }, 304 { "BACLEAR.CONDS", 0xe6, 0x10, true }, 305 { "MS_DECODED.MS_ENTRY", 0xe7, 0x01, true }, 306 { "DECODED_RESTRICTION.PREDECODE_WRONG", 0xe9, 0x01, true }, 307 }; 308 309 static struct event_table intel_goldmont = { 310 .tablename = "Intel Goldmont", 311 .names = intel_goldmont_names, 312 .nevents = sizeof(intel_goldmont_names) / 313 sizeof(struct name_to_event), 314 .next = NULL 315 }; 316 317 static struct event_table * 318 init_intel_goldmont(void) 319 { 320 321 return &intel_goldmont; 322 } 323 324 /* 325 * Intel Goldmont Plus (Additions from Goldmont) 326 */ 327 static struct name_to_event intel_goldmontplus_names[] = { 328 { "INST_RETIRED.ANY", 0x00, 0x01, true }, 329 { "DTLB_LOAD_MISSES.WALK_COMPLETED_4K", 0x08, 0x02, true }, 330 { "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M", 0x08, 0x04, true }, 331 { "DTLB_LOAD_MISSES.WALK_COMPLETED_1GB", 0x08, 0x08, true }, 332 { "DTLB_LOAD_MISSES.WALK_PENDING", 0x08, 0x10, true }, 333 { "DTLB_STORE_MISSES.WALK_COMPLETED_4K", 0x49, 0x02, true }, 334 { "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", 0x49, 0x04, true }, 335 { "DTLB_STORE_MISSES.WALK_COMPLETED_1GB", 0x49, 0x08, true }, 336 { "DTLB_STORE_MISSES.WALK_PENDING", 0x49, 0x10, true }, 337 { "EPT.WALK_PENDING", 0x4f, 0x10, true }, 338 { "ITLB_MISSES.WALK_COMPLETED_4K", 0x85, 0x08, true }, 339 { "ITLB_MISSES.WALK_COMPLETED_2M_4M", 0x85, 0x04, true }, 340 { "ITLB_MISSES.WALK_COMPLETED_1GB", 0x85, 0x08, true }, 341 { "ITLB_MISSES.WALK_PENDING", 0x85, 0x10, true }, 342 { "TLB_FLUSHES.STLB_ANY", 0xbd, 0x20, true }, 343 { "MACHINE_CLEARS.PAGE_FAULT", 0xc3, 0x20, true }, 344 }; 345 346 static struct event_table intel_goldmontplus = { 347 .tablename = "Intel Goldmont Plus", 348 .names = intel_goldmontplus_names, 349 .nevents = sizeof(intel_goldmontplus_names) / 350 sizeof(struct name_to_event), 351 .next = NULL 352 }; 353 354 static struct event_table * 355 init_intel_goldmontplus(void) 356 { 357 358 intel_goldmont.next = &intel_goldmontplus; 359 360 return &intel_goldmont; 361 } 362 363 /* 364 * Intel Skylake/Kabylake. 365 * 366 * The events that are not listed, because they are of little interest or 367 * require extra configuration: 368 * TX_* 369 * FRONTEND_RETIRED.* 370 * FP_ARITH_INST_RETIRED.* 371 * HLE_RETIRED.* 372 * RTM_RETIRED.* 373 * MEM_TRANS_RETIRED.* 374 * UOPS_DISPATCHED_PORT.* 375 */ 376 static struct name_to_event intel_skylake_kabylake_names[] = { 377 /* Event Name - Event Select - UMask */ 378 { "LD_BLOCKS.STORE_FORWARD", 0x03, 0x02, true }, 379 { "LD_BLOCKS.NO_SR", 0x03, 0x08, true }, 380 { "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", 0x07, 0x01, true }, 381 { "DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK", 0x08, 0x01, true }, 382 { "DTLB_LOAD_MISSES.WALK_COMPLETED_4K", 0x08, 0x02, true }, 383 { "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M", 0x08, 0x04, true }, 384 { "DTLB_LOAD_MISSES.WALK_COMPLETED_1G", 0x08, 0x08, true }, 385 { "DTLB_LOAD_MISSES.WALK_COMPLETED", 0x08, 0x0e, true }, 386 { "DTLB_LOAD_MISSES.WALK_PENDING", 0x08, 0x10, true }, 387 { "DTLB_LOAD_MISSES.STLB_HIT", 0x08, 0x20, true }, 388 { "INT_MISC.RECOVERY_CYCLES", 0x0d, 0x01, true }, 389 { "INT_MISC.CLEAR_RESTEER_CYCLES", 0x0d, 0x80, true }, 390 { "UOPS_ISSUED.ANY", 0x0e, 0x01, true }, 391 { "UOPS_ISSUED.VECTOR_WIDTH_MISMATCH", 0x0e, 0x02, true }, 392 { "UOPS_ISSUED.SLOW_LEA", 0x0e, 0x20, true }, 393 { "L2_RQSTS.DEMAND_DATA_RD_MISS", 0x24, 0x21, true }, 394 { "L2_RQSTS.RFO_MISS", 0x24, 0x22, true }, 395 { "L2_RQSTS.CODE_RD_MISS", 0x24, 0x24, true }, 396 { "L2_RQSTS.ALL_DEMAND_MISS", 0x24, 0x27, true }, 397 { "L2_RQSTS.PF_MISS", 0x24, 0x38, true }, 398 { "L2_RQSTS.MISS", 0x24, 0x3f, true }, 399 { "L2_RQSTS.DEMAND_DATA_RD_HIT", 0x24, 0x41, true }, 400 { "L2_RQSTS.RFO_HIT", 0x24, 0x42, true }, 401 { "L2_RQSTS.CODE_RD_HIT", 0x24, 0x44, true }, 402 { "L2_RQSTS.PF_HIT", 0x24, 0xd8, true }, 403 { "L2_RQSTS.ALL_DEMAND_DATA_RD", 0x24, 0xe1, true }, 404 { "L2_RQSTS.ALL_RFO", 0x24, 0xe2, true }, 405 { "L2_RQSTS.ALL_CODE_RD", 0x24, 0xe4, true }, 406 { "L2_RQSTS.ALL_DEMAND_REFERENCES", 0x24, 0xe7, true }, 407 { "L2_RQSTS.ALL_PF", 0x24, 0xf8, true }, 408 { "L2_RQSTS.REFERENCES", 0x24, 0xff, true }, 409 { "SW_PREFETCH_ACCESS.NTA", 0x32, 0x01, true }, 410 { "SW_PREFETCH_ACCESS.T0", 0x32, 0x02, true }, 411 { "SW_PREFETCH_ACCESS.T1_T2", 0x32, 0x04, true }, 412 { "SW_PREFETCH_ACCESS.PREFETCHW", 0x32, 0x08, true }, 413 { "CPU_CLK_THREAD_UNHALTED.ONE_THREAD_ACTIVE", 0x3c, 0x02, true }, 414 { "CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE", 0x3c, 0x02, true }, 415 { "L1D_PEND_MISS.PENDING", 0x48, 0x01, true }, 416 { "L1D_PEND_MISS.FB_FULL", 0x48, 0x02, true }, 417 { "DTLB_STORE_MISSES.MISS_CAUSES_A_WALK", 0x49, 0x01, true }, 418 { "DTLB_STORE_MISSES.WALK_COMPLETED_4K", 0x49, 0x02, true }, 419 { "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", 0x49, 0x04, true }, 420 { "DTLB_STORE_MISSES.WALK_COMPLETED_1G", 0x49, 0x08, true }, 421 { "DTLB_STORE_MISSES.WALK_COMPLETED", 0x49, 0x0e, true }, 422 { "DTLB_STORE_MISSES.WALK_PENDING", 0x49, 0x10, true }, 423 { "DTLB_STORE_MISSES.STLB_HIT", 0x49, 0x20, true }, 424 { "LOAD_HIT_PRE.SW_PF", 0x4c, 0x01, true }, 425 { "EPT.WALK_PENDING", 0x4f, 0x10, true }, 426 { "L1D.REPLACEMENT", 0x51, 0x01, true }, 427 { "RS_EVENTS.EMPTY_CYCLES", 0x5e, 0x01, true }, 428 { "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD", 0x60, 0x01, true }, 429 { "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_CODE_RD", 0x60, 0x02, true }, 430 { "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_RFO", 0x60, 0x04, true }, 431 { "OFFCORE_REQUESTS_OUTSTANDING.ALL_DATA_RD", 0x60, 0x08, true }, 432 { "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD", 433 0x60, 0x10, true }, 434 { "IDQ.MITE_UOPS", 0x79, 0x04, true }, 435 { "IDQ.DSB_UOPS", 0x79, 0x08, true }, 436 { "IDQ.MS_MITE_UOPS", 0x79, 0x20, true }, 437 { "IDQ.MS_UOPS", 0x79, 0x30, true }, 438 { "ICACHE_16B.IFDATA_STALL", 0x80, 0x04, true }, 439 { "ICACHE_64B.IFTAG_HIT", 0x83, 0x01, true }, 440 { "ICACHE_64B.IFTAG_MISS", 0x83, 0x02, true }, 441 { "ICACHE_64B.IFTAG_STALL", 0x83, 0x04, true }, 442 { "ITLB_MISSES.MISS_CAUSES_A_WALK", 0x85, 0x01, true }, 443 { "ITLB_MISSES.WALK_COMPLETED_4K", 0x85, 0x02, true }, 444 { "ITLB_MISSES.WALK_COMPLETED_2M_4M", 0x85, 0x04, true }, 445 { "ITLB_MISSES.WALK_COMPLETED_1G", 0x85, 0x08, true }, 446 { "ITLB_MISSES.WALK_COMPLETED", 0x85, 0x0e, true }, 447 { "ITLB_MISSES.WALK_PENDING", 0x85, 0x10, true }, 448 { "ITLB_MISSES.STLB_HIT", 0x85, 0x20, true }, 449 { "ILD_STALL.LCP", 0x87, 0x01, true }, 450 { "IDQ_UOPS_NOT_DELIVERED.CORE", 0x9c, 0x01, true }, 451 { "RESOURCE_STALLS.ANY", 0xa2, 0x01, true }, 452 { "RESOURCE_STALLS.SB", 0xa2, 0x08, true }, 453 { "EXE_ACTIVITY.EXE_BOUND_0_PORTS", 0xa6, 0x01, true }, 454 { "EXE_ACTIVITY.1_PORTS_UTIL", 0xa6, 0x02, true }, 455 { "EXE_ACTIVITY.2_PORTS_UTIL", 0xa6, 0x04, true }, 456 { "EXE_ACTIVITY.3_PORTS_UTIL", 0xa6, 0x08, true }, 457 { "EXE_ACTIVITY.4_PORTS_UTIL", 0xa6, 0x10, true }, 458 { "EXE_ACTIVITY.BOUND_ON_STORES", 0xa6, 0x40, true }, 459 { "LSD.UOPS", 0xa8, 0x01, true }, 460 { "DSB2MITE_SWITCHES.PENALTY_CYCLES", 0xab, 0x02, true }, 461 { "ITLB.ITLB_FLUSH", 0xae, 0x01, true }, 462 { "OFFCORE_REQUESTS.DEMAND_DATA_RD", 0xb0, 0x01, true }, 463 { "OFFCORE_REQUESTS.DEMAND_CODE_RD", 0xb0, 0x02, true }, 464 { "OFFCORE_REQUESTS.DEMAND_RFO", 0xb0, 0x04, true }, 465 { "OFFCORE_REQUESTS.ALL_DATA_RD", 0xb0, 0x08, true }, 466 { "OFFCORE_REQUESTS.L3_MISS_DEMAND_DATA_RD", 0xb0, 0x10, true }, 467 { "OFFCORE_REQUESTS.ALL_REQUESTS", 0xb0, 0x80, true }, 468 { "UOPS_EXECUTED.THREAD", 0xb1, 0x01, true }, 469 { "UOPS_EXECUTED.CORE", 0xb1, 0x02, true }, 470 { "UOPS_EXECUTED.X87", 0xb1, 0x10, true }, 471 { "OFFCORE_REQUESTS_BUFFER.SQ_FULL", 0xb2, 0x01, true }, 472 { "TLB_FLUSH.DTLB_THREAD", 0xbd, 0x01, true }, 473 { "TLB_FLUSH.STLB_ANY", 0xbd, 0x20, true }, 474 { "INST_RETIRED.PREC_DIST", 0xc0, 0x01, true }, 475 { "OTHER_ASSISTS.ANY", 0xc1, 0x3f, true }, 476 { "UOPS_RETIRED.RETIRE_SLOTS", 0xc2, 0x02, true }, 477 { "MACHINE_CLEARS.MEMORY_ORDERING", 0xc3, 0x02, true }, 478 { "MACHINE_CLEARS.SMC", 0xc3, 0x04, true }, 479 { "BR_INST_RETIRED.CONDITIONAL", 0xc4, 0x01, true }, 480 { "BR_INST_RETIRED.NEAR_CALL", 0xc4, 0x02, true }, 481 { "BR_INST_RETIRED.NEAR_RETURN", 0xc4, 0x08, true }, 482 { "BR_INST_RETIRED.NOT_TAKEN", 0xc4, 0x10, true }, 483 { "BR_INST_RETIRED.NEAR_TAKEN", 0xc4, 0x20, true }, 484 { "BR_INST_RETIRED.FAR_BRANCH", 0xc4, 0x40, true }, 485 { "BR_MISP_RETIRED.CONDITIONAL", 0xc5, 0x01, true }, 486 { "BR_MISP_RETIRED.NEAR_CALL", 0xc5, 0x02, true }, 487 { "BR_MISP_RETIRED.NEAR_TAKEN", 0xc5, 0x20, true }, 488 { "HW_INTERRUPTS.RECEIVED", 0xcb, 0x01, true }, 489 { "MEM_INST_RETIRED.STLB_MISS_LOADS", 0xd0, 0x11, true }, 490 { "MEM_INST_RETIRED.STLB_MISS_STORES", 0xd0, 0x12, true }, 491 { "MEM_INST_RETIRED.LOCK_LOADS", 0xd0, 0x21, true }, 492 { "MEM_INST_RETIRED.SPLIT_LOADS", 0xd0, 0x41, true }, 493 { "MEM_INST_RETIRED.SPLIT_STORES", 0xd0, 0x42, true }, 494 { "MEM_INST_RETIRED.ALL_LOADS", 0xd0, 0x81, true }, 495 { "MEM_INST_RETIRED.ALL_STORES", 0xd0, 0x82, true }, 496 { "MEM_LOAD_RETIRED.L1_HIT", 0xd1, 0x01, true }, 497 { "MEM_LOAD_RETIRED.L2_HIT", 0xd1, 0x02, true }, 498 { "MEM_LOAD_RETIRED.L3_HIT", 0xd1, 0x04, true }, 499 { "MEM_LOAD_RETIRED.L1_MISS", 0xd1, 0x08, true }, 500 { "MEM_LOAD_RETIRED.L2_MISS", 0xd1, 0x10, true }, 501 { "MEM_LOAD_RETIRED.L3_MISS", 0xd1, 0x20, true }, 502 { "MEM_LOAD_RETIRED.FB_HIT", 0xd1, 0x40, true }, 503 { "MEM_LOAD_L3_HIT_RETIRED.XSNP_MISS", 0xd2, 0x01, true }, 504 { "MEM_LOAD_L3_HIT_RETIRED.XSNP_HIT", 0xd2, 0x02, true }, 505 { "MEM_LOAD_L3_HIT_RETIRED.XSNP_HITM", 0xd2, 0x04, true }, 506 { "MEM_LOAD_L3_HIT_RETIRED.XSNP_NONE", 0xd2, 0x08, true }, 507 { "MEM_LOAD_MISC_RETIRED.UC", 0xd4, 0x04, true }, 508 { "BACLEARS.ANY", 0xe6, 0x01, true }, 509 { "L2_TRANS.L2_WB", 0xf0, 0x40, true }, 510 { "L2_LINES_IN.ALL", 0xf1, 0x1f, true }, 511 { "L2_LINES_OUT.SILENT", 0xf2, 0x01, true }, 512 { "L2_LINES_OUT.NON_SILENT", 0xf2, 0x02, true }, 513 { "L2_LINES_OUT.USELESS_HWPF", 0xf2, 0x04, true }, 514 { "SQ_MISC.SPLIT_LOCK", 0xf4, 0x10, true }, 515 }; 516 517 static struct event_table intel_skylake_kabylake = { 518 .tablename = "Intel Skylake/Kabylake", 519 .names = intel_skylake_kabylake_names, 520 .nevents = sizeof(intel_skylake_kabylake_names) / 521 sizeof(struct name_to_event), 522 .next = NULL 523 }; 524 525 static struct event_table * 526 init_intel_skylake_kabylake(void) 527 { 528 529 return &intel_skylake_kabylake; 530 } 531 532 /* 533 * Intel Skylake-X (and Cascade Lake). 534 */ 535 static struct name_to_event intel_skylake_x_names[] = { 536 { "INST_RETIRED.ANY", 0x00, 0x01, true }, 537 { "CPU_CLK_UNHALTED.THREAD", 0x00, 0x02, true }, 538 { "CPU_CLK_UNHALTED.REF_TSC", 0x00, 0x03, true }, 539 { "LD_BLOCKS.STORE_FORWARD", 0x03, 0x02, true }, 540 { "LD_BLOCKS.NO_SR", 0x03, 0x08, true }, 541 { "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", 0x07, 0x01, true }, 542 { "DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK", 0x08, 0x01, true }, 543 { "DTLB_LOAD_MISSES.WALK_COMPLETED_4K", 0x08, 0x02, true }, 544 { "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M", 0x08, 0x04, true }, 545 { "DTLB_LOAD_MISSES.WALK_COMPLETED_1G", 0x08, 0x08, true }, 546 { "DTLB_LOAD_MISSES.WALK_COMPLETED", 0x08, 0x0E, true }, 547 { "DTLB_LOAD_MISSES.WALK_PENDING", 0x08, 0x10, true }, 548 { "DTLB_LOAD_MISSES.STLB_HIT", 0x08, 0x20, true }, 549 { "INT_MISC.RECOVERY_CYCLES", 0x0D, 0x01, true }, 550 { "INT_MISC.CLEAR_RESTEER_CYCLES", 0x0D, 0x80, true }, 551 { "UOPS_ISSUED.ANY", 0x0E, 0x01, true }, 552 { "UOPS_ISSUED.VECTOR_WIDTH_MISMATCH", 0x0E, 0x02, true }, 553 { "UOPS_ISSUED.SLOW_LEA", 0x0E, 0x20, true }, 554 { "ARITH.DIVIDER_ACTIVE", 0x14, 0x01, true }, 555 { "L2_RQSTS.DEMAND_DATA_RD_MISS", 0x24, 0x21, true }, 556 { "L2_RQSTS.RFO_MISS", 0x24, 0x22, true }, 557 { "L2_RQSTS.CODE_RD_MISS", 0x24, 0x24, true }, 558 { "L2_RQSTS.ALL_DEMAND_MISS", 0x24, 0x27, true }, 559 { "L2_RQSTS.PF_MISS", 0x24, 0x38, true }, 560 { "L2_RQSTS.MISS", 0x24, 0x3F, true }, 561 { "L2_RQSTS.DEMAND_DATA_RD_HIT", 0x24, 0x41, true }, 562 { "L2_RQSTS.RFO_HIT", 0x24, 0x42, true }, 563 { "L2_RQSTS.CODE_RD_HIT", 0x24, 0x44, true }, 564 { "L2_RQSTS.PF_HIT", 0x24, 0xD8, true }, 565 { "L2_RQSTS.ALL_DEMAND_DATA_RD", 0x24, 0xE1, true }, 566 { "L2_RQSTS.ALL_RFO", 0x24, 0xE2, true }, 567 { "L2_RQSTS.ALL_CODE_RD", 0x24, 0xE4, true }, 568 { "L2_RQSTS.ALL_DEMAND_REFERENCES", 0x24, 0xE7, true }, 569 { "L2_RQSTS.ALL_PF", 0x24, 0xF8, true }, 570 { "L2_RQSTS.REFERENCES All L2", 0x24, 0xFF, true }, 571 { "CORE_POWER.LVL0_TURBO_LICENSE", 0x28, 0x07, true }, 572 { "CORE_POWER.LVL1_TURBO_LICENSE", 0x28, 0x18, true }, 573 { "CORE_POWER.LVL2_TURBO_LICENSE", 0x28, 0x20, true }, 574 { "CORE_POWER.THROTTLE", 0x28, 0x40, true }, 575 { "LONGEST_LAT_CACHE.MISS", 0x2E, 0x41, true }, 576 { "LONGEST_LAT_CACHE.REFERENCE", 0x2E, 0x4F, true }, 577 { "CPU_CLK_UNHALTED.THREAD_P", 0x3C, 0x00, true }, 578 { "CPU_CLK_THREAD_UNHALTED.REF_XCLK", 0x3C, 0x01, true }, 579 { "CPU_CLK_THREAD_UNHALTED.ONE_THREAD_ACTIVE", 0x3C, 0x02, true }, 580 { "L1D_PEND_MISS.PENDING", 0x48, 0x01, true }, 581 { "L1D_PEND_MISS.FB_FULL", 0x48, 0x02, true }, 582 { "DTLB_STORE_MISSES.MISS_CAUSES_A_WALK", 0x49, 0x01, true }, 583 { "DTLB_STORE_MISSES.WALK_COMPLETED_4K", 0x49, 0x02, true }, 584 { "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", 0x49, 0x04, true }, 585 { "DTLB_STORE_MISSES.WALK_COMPLETED_1G", 0x49, 0x08, true }, 586 { "DTLB_STORE_MISSES.WALK_COMPLETED", 0x49, 0x0E, true }, 587 { "DTLB_STORE_MISSES.WALK_PENDING", 0x49, 0x10, true }, 588 { "DTLB_STORE_MISSES.STLB_HIT", 0x49, 0x20, true }, 589 { "LOAD_HIT_PRE.SW_PF", 0x4C, 0x01, true }, 590 { "EPT.WALK_PENDING", 0x4F, 0x10, true }, 591 { "L1D.REPLACEMENT", 0x51, 0x01, true }, 592 { "TX_MEM.ABORT_CONFLICT", 0x54, 0x01, true }, 593 { "TX_MEM.ABORT_CAPACITY", 0x54, 0x02, true }, 594 { "TX_MEM.ABORT_HLE_STORE_TO_ELIDED_LOCK", 0x54, 0x04, true }, 595 { "TX_MEM.ABORT_HLE_ELISION_BUFFER_NOT_EMPTY", 0x54, 0x08, true }, 596 { "TX_MEM.ABORT_HLE_ELISION_BUFFER_MISMATCH", 0x54, 0x10, true }, 597 { "TX_MEM.ABORT_HLE_ELISION_BUFFER_UNSUPPORTED_ALIGNMENT", 598 0x54, 0x20, true }, 599 { "TX_MEM.HLE_ELISION_BUFFER_FULL", 0x54, 0x40, true }, 600 { "TX_EXEC.MISC1", 0x5D, 0x01, true }, 601 { "TX_EXEC.MISC2", 0x5D, 0x02, true }, 602 { "TX_EXEC.MISC3", 0x5D, 0x04, true }, 603 { "TX_EXEC.MISC4", 0x5D, 0x08, true }, 604 { "TX_EXEC.MISC5", 0x5D, 0x10, true }, 605 { "RS_EVENTS.EMPTY_CYCLES", 0x5E, 0x01, true }, 606 { "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD", 607 0x60, 0x01, true }, 608 { "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_CODE_RD", 609 0x60, 0x02, true }, 610 { "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_RFO", 0x60, 0x04, true }, 611 { "OFFCORE_REQUESTS_OUTSTANDING.ALL_DATA_RD", 0x60, 0x08, true }, 612 { "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD", 613 0x60, 0x10, true }, 614 { "IDQ.MITE_UOPS", 0x79, 0x04, true }, 615 { "IDQ.DSB_UOPS", 0x79, 0x08, true }, 616 { "IDQ.MS_DSB_CYCLES", 0x79, 0x10, true }, 617 { "IDQ.ALL_DSB_CYCLES_4_UOPS", 0x79, 0x18, true }, 618 { "IDQ.MS_MITE_UOPS", 0x79, 0x20, true }, 619 { "IDQ.ALL_MITE_CYCLES_4_UOPS", 0x79, 0x24, true }, 620 { "IDQ.MS_CYCLES", 0x79, 0x30, true }, 621 { "ICACHE_16B.IFDATA_STALL", 0x80, 0x04, true }, 622 { "ICACHE_64B.IFTAG_HIT", 0x83, 0x01, true }, 623 { "ICACHE_64B.IFTAG_MISS", 0x83, 0x02, true }, 624 { "ICACHE_64B.IFTAG_STALL", 0x83, 0x04, true }, 625 { "ITLB_MISSES.MISS_CAUSES_A_WALK", 0x85, 0x01, true }, 626 { "ITLB_MISSES.WALK_COMPLETED_4K", 0x85, 0x02, true }, 627 { "ITLB_MISSES.WALK_COMPLETED_2M_4M", 0x85, 0x04, true }, 628 { "ITLB_MISSES.WALK_COMPLETED_1G", 0x85, 0x08, true }, 629 { "ITLB_MISSES.WALK_COMPLETED", 0x85, 0x0E, true }, 630 { "ITLB_MISSES.WALK_PENDING", 0x85, 0x10, true }, 631 { "ITLB_MISSES.STLB_HIT", 0x85, 0x20, true }, 632 { "ILD_STALL.LCP", 0x87, 0x01, true }, 633 { "IDQ_UOPS_NOT_DELIVERED.CORE", 0x9C, 0x01, true }, 634 { "UOPS_DISPATCHED_PORT.PORT_0", 0xa1, 0x01, true }, 635 { "UOPS_DISPATCHED_PORT.PORT_1", 0xa1, 0x02, true }, 636 { "UOPS_DISPATCHED_PORT.PORT_2", 0xa1, 0x04, true }, 637 { "UOPS_DISPATCHED_PORT.PORT_3", 0xa1, 0x08, true }, 638 { "UOPS_DISPATCHED_PORT.PORT_4", 0xa1, 0x10, true }, 639 { "UOPS_DISPATCHED_PORT.PORT_5", 0xa1, 0x20, true }, 640 { "UOPS_DISPATCHED_PORT.PORT_6", 0xa1, 0x40, true }, 641 { "UOPS_DISPATCHED_PORT.PORT_7", 0xa1, 0x80, true }, 642 { "RESOURCE_STALLS.ANY", 0xa2, 0x01, true }, 643 { "RESOURCE_STALLS.SB", 0xa2, 0x08, true }, 644 { "CYCLE_ACTIVITY.CYCLES_L2_MISS", 0xa3, 0x01, true }, 645 { "CYCLE_ACTIVITY.CYCLES_L3_MISS", 0xa3, 0x02, true }, 646 { "CYCLE_ACTIVITY.STALLS_TOTAL", 0xa3, 0x04, true }, 647 { "CYCLE_ACTIVITY.STALLS_L2_MISS", 0xa3, 0x05, true }, 648 { "CYCLE_ACTIVITY.STALLS_L3_MISS", 0xa3, 0x06, true }, 649 { "CYCLE_ACTIVITY.CYCLES_L1D_MISS", 0xa3, 0x08, true }, 650 { "CYCLE_ACTIVITY.STALLS_L1D_MISS", 0xa3, 0x0C, true }, 651 { "CYCLE_ACTIVITY.CYCLES_MEM_ANY", 0xa3, 0x10, true }, 652 { "CYCLE_ACTIVITY.STALLS_MEM_ANY", 0xa3, 0x14, true }, 653 { "EXE_ACTIVITY.EXE_BOUND_0_PORTS", 0xa6, 0x01, true }, 654 { "EXE_ACTIVITY.1_PORTS_UTIL", 0xa6, 0x02, true }, 655 { "EXE_ACTIVITY.2_PORTS_UTIL", 0xa6, 0x04, true }, 656 { "EXE_ACTIVITY.3_PORTS_UTIL", 0xa6, 0x08, true }, 657 { "EXE_ACTIVITY.4_PORTS_UTIL", 0xa6, 0x10, true }, 658 { "EXE_ACTIVITY.BOUND_ON_STORES", 0xa6, 0x40, true }, 659 { "LSD.UOPS", 0xa8, 0x01, true }, 660 { "DSB2MITE_SWITCHES.PENALTY_CYCLES", 0xaB, 0x02, true }, 661 { "ITLB.ITLB_FLUSH", 0xaE, 0x01, true }, 662 { "OFFCORE_REQUESTS.DEMAND_DATA_RD", 0xb0, 0x01, true }, 663 { "OFFCORE_REQUESTS.DEMAND_CODE_RD", 0xb0, 0x02, true }, 664 { "OFFCORE_REQUESTS.DEMAND_RFO", 0xb0, 0x04, true }, 665 { "OFFCORE_REQUESTS.ALL_DATA_RD", 0xb0, 0x08, true }, 666 { "OFFCORE_REQUESTS.L3_MISS_DEMAND_DATA_RD", 0xb0, 0x10, true }, 667 { "OFFCORE_REQUESTS.ALL_REQUESTS", 0xb0, 0x80, true }, 668 { "UOPS_EXECUTED.THREAD", 0xb1, 0x01, true }, 669 { "UOPS_EXECUTED.CORE", 0xb1, 0x02, true }, 670 { "UOPS_EXECUTED.X87", 0xb1, 0x10, true }, 671 { "OFFCORE_REQUESTS_BUFFER.SQ_FULL", 0xb2, 0x01, true }, 672 { "TLB_FLUSH.DTLB_THREAD", 0xbD, 0x01, true }, 673 { "TLB_FLUSH.STLB_ANY", 0xbD, 0x20, true }, 674 { "INST_RETIRED.ANY_P", 0xc0, 0x00, true }, 675 { "INST_RETIRED.PREC_DIST", 0xc0, 0x01, true }, 676 { "OTHER_ASSISTS.ANY", 0xc1, 0x3F, true }, 677 { "UOPS_RETIRED.STALL_CYCLES", 0xc2, 0x01, true }, 678 { "UOPS_RETIRED.RETIRE_SLOTS", 0xc2, 0x02, true }, 679 { "MACHINE_CLEARS.COUNT", 0xc3, 0x01, true }, 680 { "MACHINE_CLEARS.MEMORY_ORDERING", 0xc3, 0x02, true }, 681 { "MACHINE_CLEARS.SMC", 0xc3, 0x04, true }, 682 { "BR_INST_RETIRED.ALL_BRANCHES", 0xc4, 0x00, true }, 683 { "BR_INST_RETIRED.CONDITIONAL", 0xc4, 0x01, true }, 684 { "BR_INST_RETIRED.NEAR_CALL", 0xc4, 0x02, true }, 685 { "BR_INST_RETIRED.NEAR_RETURN", 0xc4, 0x08, true }, 686 { "BR_INST_RETIRED.NOT_TAKEN", 0xc4, 0x10, true }, 687 { "BR_INST_RETIRED.NEAR_TAKEN", 0xc4, 0x20, true }, 688 { "BR_INST_RETIRED.FAR_BRANCH", 0xc4, 0x40, true }, 689 { "BR_MISP_RETIRED.ALL_BRANCHES", 0xc5, 0x00, true }, 690 { "BR_MISP_RETIRED.CONDITIONAL", 0xc5, 0x01, true }, 691 { "BR_MISP_RETIRED.NEAR_CALL", 0xc5, 0x02, true }, 692 { "BR_MISP_RETIRED.NEAR_TAKEN", 0xc5, 0x20, true }, 693 { "FRONTEND_RETIRED.DSB_MISS", 0xc6, 0x01, true }, 694 { "FP_ARITH_INST_RETIRED.SCALAR_DOUBLE", 0xc7, 0x01, true }, 695 { "FP_ARITH_INST_RETIRED.SCALAR_SINGLE", 0xc7, 0x02, true }, 696 { "FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE", 0xc7, 0x04, true }, 697 { "FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE", 0xc7, 0x08, true }, 698 { "FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE", 0xc7, 0x10, true }, 699 { "FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE", 0xc7, 0x20, true }, 700 { "FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE", 0xc7, 0x40, true }, 701 { "FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE", 0xc7, 0x80, true }, 702 { "HLE_RETIRED.START", 0xc8, 0x01, true }, 703 { "HLE_RETIRED.COMMIT", 0xc8, 0x02, true }, 704 { "HLE_RETIRED.ABORTED", 0xc8, 0x04, true }, 705 { "HLE_RETIRED.ABORTED_MEM", 0xc8, 0x08, true }, 706 { "HLE_RETIRED.ABORTED_TIMER", 0xc8, 0x10, true }, 707 { "HLE_RETIRED.ABORTED_UNFRIENDLY", 0xc8, 0x20, true }, 708 { "HLE_RETIRED.ABORTED_MEMTYPE", 0xc8, 0x40, true }, 709 { "HLE_RETIRED.ABORTED_EVENTS", 0xc8, 0x80, true }, 710 { "RTM_RETIRED.START", 0xc9, 0x01, true }, 711 { "RTM_RETIRED.COMMIT", 0xc9, 0x02, true }, 712 { "RTM_RETIRED.ABORTED", 0xc9, 0x04, true }, 713 { "RTM_RETIRED.ABORTED_MEM", 0xc9, 0x08, true }, 714 { "RTM_RETIRED.ABORTED_TIMER", 0xc9, 0x10, true }, 715 { "RTM_RETIRED.ABORTED_UNFRIENDLY", 0xc9, 0x20, true }, 716 { "RTM_RETIRED.ABORTED_MEMTYPE", 0xc9, 0x40, true }, 717 { "RTM_RETIRED.ABORTED_EVENTS", 0xc9, 0x80, true }, 718 { "FP_ASSIST.ANY", 0xca, 0x1e, true }, 719 { "HW_INTERRUPTS.RECEIVED", 0xcb, 0x01, true }, 720 { "ROB_MISC_EVENTS.LBR_INSERTS", 0xcc, 0x20, true }, 721 { "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_4", 0xcd, 0x01, true }, 722 { "MEM_INST_RETIRED.STLB_MISS_LOADS", 0xd0, 0x11, true }, 723 { "MEM_INST_RETIRED.STLB_MISS_STORES", 0xd0, 0x12, true }, 724 { "MEM_INST_RETIRED.LOCK_LOADS", 0xd0, 0x21, true }, 725 { "MEM_INST_RETIRED.SPLIT_LOADS", 0xd0, 0x41, true }, 726 { "MEM_INST_RETIRED.SPLIT_STORES", 0xd0, 0x42, true }, 727 { "MEM_INST_RETIRED.ALL_LOADS", 0xd0, 0x81, true }, 728 { "MEM_INST_RETIRED.ALL_STORES", 0xd0, 0x82, true }, 729 { "MEM_LOAD_RETIRED.L1_HIT", 0xd1, 0x01, true }, 730 { "MEM_LOAD_RETIRED.L2_HIT", 0xd1, 0x02, true }, 731 { "MEM_LOAD_RETIRED.L3_HIT", 0xd1, 0x04, true }, 732 { "MEM_LOAD_RETIRED.L1_MISS", 0xd1, 0x08, true }, 733 { "MEM_LOAD_RETIRED.L2_MISS", 0xd1, 0x10, true }, 734 { "MEM_LOAD_RETIRED.L3_MISS", 0xd1, 0x20, true }, 735 { "MEM_LOAD_RETIRED.FB_HIT", 0xd1, 0x40, true }, 736 { "MEM_LOAD_L3_HIT_RETIRED.XSNP_MISS", 0xd2, 0x01, true }, 737 { "MEM_LOAD_L3_HIT_RETIRED.XSNP_HIT", 0xd2, 0x02, true }, 738 { "MEM_LOAD_L3_HIT_RETIRED.XSNP_HITM", 0xd2, 0x04, true }, 739 { "MEM_LOAD_L3_HIT_RETIRED.XSNP_NONE", 0xd2, 0x08, true }, 740 { "MEM_LOAD_L3_MISS_RETIRED.LOCAL_DRAM", 0xd3, 0x01, true }, 741 { "MEM_LOAD_L3_MISS_RETIRED.REMOTE_DRAM", 0xd3, 0x02, true }, 742 { "MEM_LOAD_L3_MISS_RETIRED.REMOTE_HITM", 0xd3, 0x04, true }, 743 { "MEM_LOAD_L3_MISS_RETIRED.REMOTE_FWD", 0xd3, 0x08, true }, 744 { "MEM_LOAD_MISC_RETIRED.UC", 0xd4, 0x04, true }, 745 { "BACLEARS.ANY", 0xe6, 0x01, true }, 746 { "L2_TRANS.L2_WB", 0xf0, 0x40, true }, 747 { "L2_LINES_IN.ALL", 0xf1, 0x1f, true }, 748 { "L2_LINES_OUT.SILENT", 0xf2, 0x01, true }, 749 { "L2_LINES_OUT.NON_SILENT", 0xf2, 0x02, true }, 750 { "L2_LINES_OUT.USELESS_PREF", 0xf2, 0x04, true }, 751 { "SQ_MISC.SPLIT_LOCK", 0xf4, 0x10, true }, 752 { "IDI_MISC.WB_UPGRADE", 0xfe, 0x02, true }, 753 { "IDI_MISC.WB_DOWNGRADE", 0xfe, 0x04, true }, 754 }; 755 756 static struct event_table intel_skylake_x = { 757 .tablename = "Intel Skylake-X", 758 .names = intel_skylake_x_names, 759 .nevents = sizeof(intel_skylake_x_names) / 760 sizeof(struct name_to_event), 761 .next = NULL 762 }; 763 764 static struct event_table * 765 init_intel_skylake_x(void) 766 { 767 768 return &intel_skylake_x; 769 } 770 771 /* 772 * Intel Cascade Lake. 773 */ 774 static struct name_to_event intel_cascadelake_names[] = { 775 { "MEM_LOAD_RETIRED.LOCAL_PMM", 0xd1, 0x80, true }, 776 { "MEM_LOAD_L3_MISS_RETIRED.REMOTE_PMM", 0xd3, 0x10, true }, 777 }; 778 779 static struct event_table intel_cascadelake = { 780 .tablename = "Intel Cascade Lake", 781 .names = intel_cascadelake_names, 782 .nevents = sizeof(intel_cascadelake_names) / 783 sizeof(struct name_to_event), 784 .next = NULL 785 }; 786 787 static struct event_table * 788 init_intel_cascadelake(void) 789 { 790 791 intel_skylake_x.next = &intel_cascadelake; 792 793 return &intel_skylake_x; 794 } 795 796 static struct event_table * 797 init_intel_generic(void) 798 { 799 unsigned int eax, ebx, ecx, edx; 800 struct event_table *table; 801 uint8_t stepping; 802 803 /* 804 * The kernel made sure the Architectural Version 1 PMCs were 805 * present. 806 */ 807 table = init_intel_arch1(); 808 809 /* 810 * Now query the additional (non-architectural) events. They 811 * depend on the CPU model. 812 */ 813 eax = 0x01; 814 ebx = 0; 815 ecx = 0; 816 edx = 0; 817 x86_cpuid(&eax, &ebx, &ecx, &edx); 818 819 if (CPUID_TO_FAMILY(eax) == 6) { 820 switch (CPUID_TO_MODEL(eax)) { 821 case 0x37: /* Silvermont (Bay Trail) */ 822 case 0x4a: /* Silvermont (Tangier) */ 823 case 0x4c: /* Airmont (Braswell, Cherry Trail) */ 824 case 0x4d: /* Silvermont (Avoton, Rangeley) */ 825 case 0x5a: /* Silvermont (Anniedale) */ 826 case 0x5d: /* Silvermont (SoFIA) */ 827 table->next = init_intel_silvermont_airmont(); 828 break; 829 case 0x5c: /* Goldmont (Apollo Lake) */ 830 case 0x5f: /* Goldmont (Denverton) */ 831 table->next = init_intel_goldmont(); 832 break; 833 case 0x7a: /* Goldmont Plus (Gemini Lake) */ 834 table->next = init_intel_goldmontplus(); 835 break; 836 case 0x4e: /* Skylake */ 837 case 0x5e: /* Skylake */ 838 case 0x8e: /* Kaby Lake */ 839 case 0x9e: /* Kaby Lake */ 840 case 0xa5: /* Comet Lake */ 841 case 0xa6: /* Comet Lake */ 842 table->next = init_intel_skylake_kabylake(); 843 break; 844 845 case 0x55: /* Skylake-X, Cascade Lake */ 846 stepping = CPUID_TO_STEPPING(eax); 847 if (stepping <= 4) 848 table->next = init_intel_skylake_x(); 849 else 850 table->next = init_intel_cascadelake(); 851 break; 852 853 } 854 } 855 856 return table; 857 } 858 859 /* ------------------------------------------------------------------------- */ 860 861 /* 862 * AMD Family 10h 863 */ 864 static struct name_to_event amd_f10h_names[] = { 865 { "seg-load-all", 0x20, 0x7f, true }, 866 { "seg-load-es", 0x20, 0x01, true }, 867 { "seg-load-cs", 0x20, 0x02, true }, 868 { "seg-load-ss", 0x20, 0x04, true }, 869 { "seg-load-ds", 0x20, 0x08, true }, 870 { "seg-load-fs", 0x20, 0x10, true }, 871 { "seg-load-gs", 0x20, 0x20, true }, 872 { "seg-load-hs", 0x20, 0x40, true }, 873 { "l1cache-access", 0x40, 0x00, true }, 874 { "l1cache-miss", 0x41, 0x00, true }, 875 { "l1cache-refill", 0x42, 0x1f, true }, 876 { "l1cache-refill-invalid", 0x42, 0x01, true }, 877 { "l1cache-refill-shared", 0x42, 0x02, true }, 878 { "l1cache-refill-exclusive", 0x42, 0x04, true }, 879 { "l1cache-refill-owner", 0x42, 0x08, true }, 880 { "l1cache-refill-modified", 0x42, 0x10, true }, 881 { "l1cache-load", 0x43, 0x1f, true }, 882 { "l1cache-load-invalid", 0x43, 0x01, true }, 883 { "l1cache-load-shared", 0x43, 0x02, true }, 884 { "l1cache-load-exclusive", 0x43, 0x04, true }, 885 { "l1cache-load-owner", 0x43, 0x08, true }, 886 { "l1cache-load-modified", 0x43, 0x10, true }, 887 { "l1cache-writeback", 0x44, 0x1f, true }, 888 { "l1cache-writeback-invalid", 0x44, 0x01, true }, 889 { "l1cache-writeback-shared", 0x44, 0x02, true }, 890 { "l1cache-writeback-exclusive",0x44, 0x04, true }, 891 { "l1cache-writeback-owner", 0x44, 0x08, true }, 892 { "l1cache-writeback-modified", 0x44, 0x10, true }, 893 { "l1DTLB-hit-all", 0x4d, 0x07, true }, 894 { "l1DTLB-hit-4Kpage", 0x4d, 0x01, true }, 895 { "l1DTLB-hit-2Mpage", 0x4d, 0x02, true }, 896 { "l1DTLB-hit-1Gpage", 0x4d, 0x04, true }, 897 { "l1DTLB-miss-all", 0x45, 0x07, true }, 898 { "l1DTLB-miss-4Kpage", 0x45, 0x01, true }, 899 { "l1DTLB-miss-2Mpage", 0x45, 0x02, true }, 900 { "l1DTLB-miss-1Gpage", 0x45, 0x04, true }, 901 { "l2DTLB-miss-all", 0x46, 0x03, true }, 902 { "l2DTLB-miss-4Kpage", 0x46, 0x01, true }, 903 { "l2DTLB-miss-2Mpage", 0x46, 0x02, true }, 904 /* l2DTLB-miss-1Gpage: reserved on some revisions, so disabled */ 905 { "l1ITLB-miss", 0x84, 0x00, true }, 906 { "l2ITLB-miss-all", 0x85, 0x03, true }, 907 { "l2ITLB-miss-4Kpage", 0x85, 0x01, true }, 908 { "l2ITLB-miss-2Mpage", 0x85, 0x02, true }, 909 { "mem-misalign-ref", 0x47, 0x00, true }, 910 { "ins-fetch", 0x80, 0x00, true }, 911 { "ins-fetch-miss", 0x81, 0x00, true }, 912 { "ins-refill-l2", 0x82, 0x00, true }, 913 { "ins-refill-sys", 0x83, 0x00, true }, 914 { "ins-fetch-stall", 0x87, 0x00, true }, 915 { "ins-retired", 0xc0, 0x00, true }, 916 { "ins-empty", 0xd0, 0x00, true }, 917 { "ops-retired", 0xc1, 0x00, true }, 918 { "branch-retired", 0xc2, 0x00, true }, 919 { "branch-miss-retired", 0xc3, 0x00, true }, 920 { "branch-taken-retired", 0xc4, 0x00, true }, 921 { "branch-taken-miss-retired", 0xc5, 0x00, true }, 922 { "branch-far-retired", 0xc6, 0x00, true }, 923 { "branch-resync-retired", 0xc7, 0x00, true }, 924 { "branch-near-retired", 0xc8, 0x00, true }, 925 { "branch-near-miss-retired", 0xc9, 0x00, true }, 926 { "branch-indirect-miss-retired", 0xca, 0x00, true }, 927 { "int-hw", 0xcf, 0x00, true }, 928 { "int-cycles-masked", 0xcd, 0x00, true }, 929 { "int-cycles-masked-pending", 0xce, 0x00, true }, 930 { "fpu-exceptions", 0xdb, 0x00, true }, 931 { "break-match0", 0xdc, 0x00, true }, 932 { "break-match1", 0xdd, 0x00, true }, 933 { "break-match2", 0xde, 0x00, true }, 934 { "break-match3", 0xdf, 0x00, true }, 935 }; 936 937 static struct event_table amd_f10h = { 938 .tablename = "AMD Family 10h", 939 .names = amd_f10h_names, 940 .nevents = sizeof(amd_f10h_names) / 941 sizeof(struct name_to_event), 942 .next = NULL 943 }; 944 945 /* 946 * AMD Family 15h 947 */ 948 static struct name_to_event amd_f15h_names[] = { 949 { "FpPipeAssignment", 0x000, 0x77, true }, 950 { "FpSchedulerEmpty", 0x001, 0x00, true }, 951 { "FpRetSseAvxOps", 0x003, 0xff, true }, 952 { "FpNumMovElim", 0x004, 0x0f, true }, 953 { "FpRetiredSerOps", 0x005, 0x0f, true }, 954 { "LsSegRegLoads", 0x020, 0x7f, true }, 955 { "LsPipeRestartSelfMod", 0x021, 0x00, true }, 956 { "LsPipeRestartVarious", 0x022, 0x1f, true }, 957 { "LsLoadQueueStoreQFull", 0x023, 0x03, true }, 958 { "LsLockedOps", 0x024, 0x00, true }, 959 { "LsRetClflushInstr", 0x026, 0x00, true }, 960 { "LsRetCpuidInstr", 0x027, 0x00, true }, 961 { "LsDispatch", 0x029, 0x07, true }, 962 { "LsCanStoreToLoadFwOps", 0x02a, 0x03, true }, 963 { "LsSmisReceived", 0x02b, 0x00, true }, 964 { "LsExecClflushInstr", 0x030, 0x00, true }, 965 { "LsMisalignStore", 0x032, 0x00, true }, 966 { "LsFpLoadBufStall", 0x034, 0x00, true }, 967 { "LsStlf", 0x035, 0x00, true }, 968 { "DcCacheAccess", 0x040, 0x00, true }, 969 { "DcCacheMiss", 0x041, 0x00, true }, 970 { "DcCacheFillL2Sys", 0x042, 0x1f, true }, 971 { "DcCacheFillSys", 0x043, 0x00, true }, 972 { "DcUnifiedTlbHit", 0x045, 0x77, true }, 973 { "DcUnifiedTlbMiss", 0x046, 0x77, true }, 974 { "DcMisalignAccess", 0x047, 0x00, true }, 975 { "DcPrefetchInstrDisp", 0x04b, 0x07, true }, 976 { "DcIneffSwPrefetch", 0x052, 0x09, true }, 977 { "CuCmdVictimBuf", 0x060, 0x98, true }, 978 { "CuCmdMaskedOps", 0x061, 0x65, true }, 979 { "CuCmdReadBlkOps", 0x062, 0x77, true }, 980 { "CuCmdChgDirtyOps", 0x063, 0x08, true }, 981 { "CuDramSysReq", 0x064, 0x00, true }, 982 { "CuMemReqByType", 0x065, 0x83, true }, 983 { "CuDataCachePrefetch", 0x067, 0x03, true }, 984 { "CuMabReq", 0x068, 0xff, true }, 985 { "CuMabWaitCyc", 0x069, 0xff, true }, 986 { "CuSysRespCacheFill", 0x06c, 0x3f, true }, 987 { "CuOctwordsWritten", 0x06d, 0x01, true }, 988 { "CuCacheXInv", 0x075, 0x0f, true }, 989 { "CuCpuClkNotHalted", 0x076, 0x00, true }, 990 { "CuL2Req", 0x07d, 0x5f, true }, 991 { "CuL2Miss", 0x07e, 0x17, true }, 992 { "CuL2FillWb", 0x07f, 0x07, true }, 993 { "CuPageSplintering", 0x165, 0x07, true }, 994 { "CuL2PrefetchTrigEv", 0x16c, 0x03, true }, 995 { "CuXabAllocStall", 0x177, 0x03, true }, 996 { "CuFreeXabEntries", 0x17f, 0x01, true }, 997 { "IcCacheFetch", 0x080, 0x00, true }, 998 { "IcCacheMiss", 0x081, 0x00, true }, 999 { "IcCacheFillL2", 0x082, 0x00, true }, 1000 { "IcCacheFillSys", 0x083, 0x00, true }, 1001 { "IcL1TlbMissL2Hit", 0x084, 0x00, true }, 1002 { "IcL1TlbMissL2Miss", 0x085, 0x07, true }, 1003 { "IcPipeRestartInstrStrProbe", 0x086, 0x00, true }, 1004 { "IcFetchStall", 0x087, 0x00, true }, 1005 { "IcRetStackHits", 0x088, 0x00, true }, 1006 { "IcRetStackOver", 0x089, 0x00, true }, 1007 { "IcCacheVictims", 0x08b, 0x00, true }, 1008 { "IcCacheLinesInv", 0x08c, 0x0f, true }, 1009 { "IcTlbReload", 0x099, 0x00, true }, 1010 { "IcTlbReloadAbort", 0x09a, 0x00, true }, 1011 { "IcUopsDispatched", 0x186, 0x01, true }, 1012 { "ExRetInstr", 0x0c0, 0x00, true }, 1013 { "ExRetCops", 0x0c1, 0x00, true }, 1014 { "ExRetBrn", 0x0c2, 0x00, true }, 1015 { "ExRetBrnMisp", 0x0c3, 0x00, true }, 1016 { "ExRetBrnTkn", 0x0c4, 0x00, true }, 1017 { "ExRetBrnTknMisp", 0x0c5, 0x00, true }, 1018 { "ExRetBrnFar", 0x0c6, 0x00, true }, 1019 { "ExRetBrnResync", 0x0c7, 0x00, true }, 1020 { "ExRetNearRet", 0x0c8, 0x00, true }, 1021 { "ExRetNearRetMispred", 0x0c9, 0x00, true }, 1022 { "ExRetBrnIndMisp", 0x0ca, 0x00, true }, 1023 { "ExRetMmxFpInstr@X87", 0x0cb, 0x01, true }, 1024 { "ExRetMmxFpInstr@Mmx", 0x0cb, 0x02, true }, 1025 { "ExRetMmxFpInstr@Sse", 0x0cb, 0x04, true }, 1026 { "ExIntMaskedCyc", 0x0cd, 0x00, true }, 1027 { "ExIntMaskedCycIntPend", 0x0ce, 0x00, true }, 1028 { "ExIntTaken", 0x0cf, 0x00, true }, 1029 { "ExDecEmpty", 0x0d0, 0x00, true }, 1030 { "ExDispStall", 0x0d1, 0x00, true }, 1031 { "ExUseqStallSer", 0x0d2, 0x00, true }, 1032 { "ExDispStallInstrRetQFull", 0x0d5, 0x00, true }, 1033 { "ExDispStallIntSchedQFull", 0x0d6, 0x00, true }, 1034 { "ExDispStallFpSchedQFull", 0x0d7, 0x00, true }, 1035 { "ExDispStallLdqFull", 0x0d8, 0x00, true }, 1036 { "ExUseqStallAllQuiet", 0x0d9, 0x00, true }, 1037 { "ExFpuEx", 0x0db, 0x1f, true }, 1038 { "ExBpDr0", 0x0dc, 0x8f, true }, 1039 { "ExBpDr1", 0x0dd, 0x8f, true }, 1040 { "ExBpDr2", 0x0de, 0x8f, true }, 1041 { "ExBpDr3", 0x0df, 0x8f, true }, 1042 { "ExRetx87FpOps", 0x1c0, 0x07, true }, 1043 { "ExTaggedIbsOps", 0x1cf, 0x07, true }, 1044 { "ExRetFusBrInstr", 0x1d0, 0x00, true }, 1045 { "ExDispStallStqFull", 0x1d8, 0x00, true }, 1046 { "ExCycNoDispIntPrfTok", 0x1dd, 0x00, true }, 1047 { "ExCycNoDispfpPrfTok", 0x1de, 0x00, true }, 1048 { "ExFpDispContention", 0x1df, 0x0f, true }, 1049 }; 1050 1051 static struct event_table amd_f15h = { 1052 .tablename = "AMD Family 15h", 1053 .names = amd_f15h_names, 1054 .nevents = sizeof(amd_f15h_names) / 1055 sizeof(struct name_to_event), 1056 .next = NULL 1057 }; 1058 1059 /* 1060 * AMD Family 17h 1061 */ 1062 static struct name_to_event amd_f17h_names[] = { 1063 { "FpRetx87FpOps", 0x02, __BITS(2,0), true }, 1064 { "FpRetSseAvxOps", 0x03, __BITS(7,0), true }, 1065 { "FpRetiredSerOps", 0x05, __BITS(3,0), true }, 1066 { "LsL1DTlbMiss", 0x45, __BITS(7,0), true }, 1067 { "LsTableWalker", 0x46, __BITS(3,0), true }, 1068 { "LsMisalAccesses", 0x47, 0x00, true }, 1069 { "LsInefSwPref", 0x52, __BITS(1,0), true }, 1070 { "LsNotHaltedCyc", 0x76, 0x00, true }, 1071 { "IcFw32", 0x80, 0x00, true }, 1072 { "IcFw32Miss", 0x81, 0x00, true }, 1073 { "IcCacheFillL2", 0x82, 0x00, true }, 1074 { "IcCacheFillSys", 0x83, 0x00, true }, 1075 { "IcFetchStall", 0x87, __BITS(2,0), true }, 1076 { "IcCacheInval", 0x8c, __BITS(1,0), true }, 1077 { "BpL1TlbMissL2Hit", 0x84, 0x00, true }, 1078 { "BpL1TlbMissL2Miss", 0x85, 0x00, true }, 1079 { "BpSnpReSync", 0x86, 0x00, true }, 1080 { "BpL1BTBCorrect", 0x8a, 0x00, true }, 1081 { "BpL2BTBCorrect", 0x8b, 0x00, true }, 1082 { "BpTlbRel", 0x99, 0x00, true }, 1083 { "ExRetInstr", 0xc0, 0x00, true }, 1084 { "ExRetCops", 0xc1, 0x00, true }, 1085 { "ExRetBrn", 0xc2, 0x00, true }, 1086 { "ExRetBrnMisp", 0xc3, 0x00, true }, 1087 { "ExRetBrnTkn", 0xc4, 0x00, true }, 1088 { "ExRetBrnTknMisp", 0xc5, 0x00, true }, 1089 { "ExRetBrnFar", 0xc6, 0x00, true }, 1090 { "ExRetBrnResync", 0xc7, 0x00, true }, 1091 { "ExRetBrnIndMisp", 0xca, 0x00, true }, 1092 { "ExRetNearRet", 0xc8, 0x00, true }, 1093 { "ExRetNearRetMispred", 0xc9, 0x00, true }, 1094 { "ExRetMmxFpInstr@X87", 0xcb, __BIT(0), true }, 1095 { "ExRetMmxFpInstr@Mmx", 0xcb, __BIT(1), true }, 1096 { "ExRetMmxFpInstr@Sse", 0xcb, __BIT(2), true }, 1097 { "ExRetCond", 0xd1, 0x00, true }, 1098 { "ExRetCondMisp", 0xd2, 0x00, true }, 1099 { "ExDivBusy", 0xd3, 0x00, true }, 1100 { "ExDivCount", 0xd4, 0x00, true }, 1101 }; 1102 1103 static struct event_table amd_f17h = { 1104 .tablename = "AMD Family 17h", 1105 .names = amd_f17h_names, 1106 .nevents = sizeof(amd_f17h_names) / 1107 sizeof(struct name_to_event), 1108 .next = NULL 1109 }; 1110 1111 /* 1112 * AMD Family 19h 1113 * From PPR: 1114 * - f19h model 01h B1 (zen3) 1115 * - f19h model 11h B1 (zen4) 1116 * - f19h model 21h B1 (zen3) 1117 * - f19h model 51h A1 (zen3) 1118 */ 1119 static struct name_to_event amd_f19h_names[] = { 1120 /* Model 1x only */ 1121 { "FpRetx87FpOps", 0x02, __BITS(2,0), true }, 1122 1123 /* Only model 1x has bit 4 */ 1124 { "FpRetSseAvxOps", 0x03, __BITS(4,0), true }, 1125 1126 { "FpRetiredSerOps", 0x05, __BITS(3,0), true }, 1127 1128 /* Model 1x only */ 1129 { "FpOpsRetiredByWidth", 0x08, __BITS(5,0), true }, 1130 { "FpOpsRetiredByType", 0x0a, __BITS(7,0), true }, 1131 { "SseAvxOpsRetired", 0x0b, __BITS(7,0), true }, 1132 { "FpPackOpsRetired", 0x0c, __BITS(7,0), true }, 1133 { "PackedIntOpType", 0x0d, __BITS(7,0), true }, 1134 1135 { "FpDispFaults", 0x0e, __BITS(3,0), true }, 1136 { "LsBadStatus2", 0x24, __BIT(1), true }, 1137 { "LsLocks", 0x25, __BIT(0), true }, 1138 { "LsRetClClush", 0x26, 0x00, true }, 1139 { "LsRetCpuid", 0x27, 0x00, true }, 1140 { "LsDispatch", 0x29, __BITS(2,0), true }, 1141 { "LsSmiRx", 0x2b, 0x00, true }, 1142 { "LsIntTaken", 0x2c, 0x00, true }, 1143 { "LsSTLF", 0x35, 0x00, true }, 1144 { "LsStCommitCancel2", 0x37, __BIT(0), true }, 1145 { "LsMabAlloc-ls", 0x41, 0x3f, true }, 1146 { "LsMabAlloc-hp", 0x41, 0x40, true }, 1147 { "LsMabAlloc-all", 0x41, 0x7f, true }, 1148 { "LsDmndFillsFromSys", 0x43, 0x5f, true }, 1149 1150 /* Only model 1x has bit 7 */ 1151 { "LsAnyFillsFromSys", 0x44, 0xdf, true }, 1152 1153 { "LsL1DTlbMiss", 0x45, __BITS(7,0), true }, 1154 { "LsMisalLoads-MA64", 0x47, __BIT(0), true }, 1155 { "LsMisalLoads-MA4K", 0x47, __BIT(1), true }, 1156 { "LsMisalLoads-all", 0x47, __BITS(1,0), true }, 1157 { "LsPrefInstrDisp", 0x4b, __BITS(2,0), true }, 1158 { "LsInefSwPref", 0x52, __BITS(1,0), true }, 1159 1160 /* Only model 1x has bit 7 */ 1161 { "LsSwPfDcFills", 0x59, 0xdf, true }, 1162 { "LsHwPfDcFills", 0x5a, 0xdf, true }, 1163 1164 { "LsAllocMabCount", 0x5f, 0x00, true }, 1165 { "LsNotHaltedCyc", 0x76, 0x00, true }, 1166 1167 /* Model 0x, 1x and 2x only */ 1168 { "LsTlbFlush", 0x78, 0xff, true }, 1169 1170 /* Model 1x only */ 1171 { "LsNotHaltedP0Cyc", 0x120, __BIT(0), true }, 1172 1173 { "IcCacheFillL2", 0x82, 0x00, true }, 1174 { "IcCacheFillSys", 0x83, 0x00, true }, 1175 { "BpL1TlbMissL2TlbHit", 0x84, 0x00, true }, 1176 { "BpL1TlbMissL2TlbMiss-IF4K", 0x85, __BIT(0), true }, 1177 { "BpL1TlbMissL2TlbMiss-IF2M", 0x85, __BIT(1), true }, 1178 { "BpL1TlbMissL2TlbMiss-IF1G", 0x85, __BIT(2), true }, 1179 { "BpL1TlbMissL2TlbMiss-Coalesced4K", 0x85, __BIT(3), true }, 1180 { "BpL1TlbMissL2TlbMiss-all", 0x85, __BITS(3,0), true }, 1181 1182 { "BpL2BTBCorrect", 0x8b, 0x00, true }, 1183 { "BpDynIndPred", 0x8e, 0x00, true }, 1184 { "BpDeReDirect", 0x91, 0x00, true }, 1185 { "BpL1TlbFetchHit-IF4K", 0x94, __BIT(0), true }, 1186 { "BpL1TlbFetchHit-IF2M", 0x94, __BIT(1), true }, 1187 { "BpL1TlbFetchHit-IF1G", 0x94, __BIT(2), true }, 1188 { "BpL1TlbFetchHit-all", 0x94, __BITS(2,0), true }, 1189 1190 /* Model 1x only */ 1191 { "ResyncsOrNcRedirects", 0x96, 0x00, true }, 1192 1193 { "IcTagHitMiss-hit", 0x18e, 0x07, true }, 1194 { "IcTagHitMiss-miss", 0x18e, 0x18, true }, 1195 { "IcTagHitMiss-all", 0x18e, 0x1f, true }, 1196 { "OpCacheHitMiss-hit", 0x28f, 0x03, true }, 1197 { "OpCacheHitMiss-miss", 0x28f, 0x04, true }, 1198 { "OpCacheHitMiss-all", 0x28f, 0x07, true }, 1199 { "DeOpQueueEmpty", 0xa9, 0x00, true }, 1200 1201 /* 1202 * Model 0x and 1x only. 1203 * Only model 1x has bit 2. 1204 */ 1205 { "DeSrcOpDisp", 0xaa, __BITS(2,0), true }, 1206 1207 { "DeDisOpsFromDecoder-Fp-Ibs", 0xab, 0x04, true }, 1208 { "DeDisOpsFromDecoder-Int-Ibs", 0xab, 0x08, true }, 1209 1210 /* Model 0x, 2x and newer */ 1211 { "DeDisOpsFromDecoder-Fp-Ret", 0xab, 0x84, true }, 1212 { "DeDisOpsFromDecoder-Int-Ret", 0xab, 0x88, true }, 1213 1214 { "DeDisDispatchTokenStalls1", 0xae, 0xf7, true }, 1215 { "DeDisDispatchTokenStalls2", 0xaf, 0x2f, true }, 1216 1217 /* Model 1x only */ 1218 { "DeNoDispatchPerSolt-empty", 0x1a0, 0x01, true }, 1219 { "DeNoDispatchPerSolt-backend", 0x1a0, 0x1e, true }, 1220 { "DeNoDispatchPerSolt-otherSMT", 0x1a0, 0x60, true }, 1221 { "DeAdditionalResourceStalls", 0x1a2, 0x30, true }, 1222 1223 { "ExRetInstr", 0xc0, 0x00, true }, 1224 { "ExRetCops", 0xc1, 0x00, true }, 1225 { "ExRetBrn", 0xc2, 0x00, true }, 1226 { "ExRetBrnMisp", 0xc3, 0x00, true }, 1227 { "ExRetBrnTkn", 0xc4, 0x00, true }, 1228 { "ExRetBrnTknMisp", 0xc5, 0x00, true }, 1229 { "ExRetBrnFar", 0xc6, 0x00, true }, 1230 { "ExRetBrnIndMisp", 0xca, 0x00, true }, 1231 { "ExRetNearRet", 0xc8, 0x00, true }, 1232 { "ExRetNearRetMispred", 0xc9, 0x00, true }, 1233 { "ExRetMmxFpInstr@X87", 0xcb, __BIT(0), true }, 1234 { "ExRetMmxFpInstr@Mmx", 0xcb, __BIT(1), true }, 1235 { "ExRetMmxFpInstr@Sse", 0xcb, __BIT(2), true }, 1236 { "ExRetIndBrchInstr", 0xcc, 0x00, true }, 1237 { "ExRetCond", 0xd1, 0x00, true }, 1238 { "ExDivBusy", 0xd3, 0x00, true }, 1239 { "ExDivCount", 0xd4, 0x00, true }, 1240 1241 /* Model 1x only */ 1242 { "ExDivCount-LoadAndALU", 0xd6, 0x1f, true }, 1243 { "ExDivCount-Load", 0xd6, 0xbf, true }, 1244 { "ExRetUcodeInstr", 0x1c1, 0x00, true }, 1245 { "ExRetUcodeOps", 0x1c2, 0x00, true }, 1246 1247 { "ExRetMsprdBrnchInstrDirMsmtch", 0x1c7, 0x00, true }, 1248 1249 /* Model 1x only */ 1250 { "ExRetUncondBrnchInstrMspred", 0x1c8, 0x00, true }, 1251 { "ExRetUncondBrnchInstr", 0x1c8, 0x00, true }, 1252 1253 { "ExTaggedIbsOps", 0x1cf, __BITS(2,0), true }, 1254 { "ExRetFusedInstr", 0x1d0, 0x00, true }, 1255 1256 /* Only model 1x has bit 0 */ 1257 { "L2RequestG1", 0x60, __BITS(7,1), true }, 1258 1259 { "L2CacheReqStart", 0x64, __BITS(7,0), true }, 1260 { "L2PfHitL2-L2", 0x70, __BITS(4,0), true }, 1261 { "L2PfHitL2-L1", 0x70, __BITS(7,5), true }, 1262 { "L2PfHitL2-all", 0x70, __BITS(7,0), true }, 1263 { "L2PfMissL2HitL3-L2", 0x71, __BITS(4,0), true }, 1264 { "L2PfMissL2HitL3-L1", 0x71, __BITS(7,5), true }, 1265 { "L2PfMIssL2HitL3-all", 0x71, __BITS(7,0), true }, 1266 { "L2PfMissL2L3-L2", 0x72, __BITS(4,0), true }, 1267 { "L2PfMissL2L3-L1", 0x72, __BITS(7,5), true }, 1268 { "L2PfMIssL2L3-all", 0x72, __BITS(7,0), true }, 1269 1270 { "L3LookupState-L3Miss", 0x04, __BIT(0), true }, 1271 { "L3LookupState-L3Hit", 0x04, __BITS(7,1), true }, 1272 { "L3LookupState-all", 0x04, __BITS(7,0), true }, 1273 1274 /* Model 0x, 2x and newer */ 1275 { "XiSysFillLatency", 0x90, 0x00, true }, 1276 { "XiCcxSdpReq1", 0x9a, 0x00, true }, 1277 1278 /* Model 1x only */ 1279 { "XiSampledLatency", 0xac, 0x00, true }, 1280 { "XiSampledLatencyRequests", 0xad, 0x00, true }, 1281 }; 1282 1283 static struct event_table amd_f19h = { 1284 .tablename = "AMD Family 19h", 1285 .names = amd_f19h_names, 1286 .nevents = sizeof(amd_f19h_names) / 1287 sizeof(struct name_to_event), 1288 .next = NULL 1289 }; 1290 1291 static struct event_table * 1292 init_amd_generic(void) 1293 { 1294 unsigned int eax, ebx, ecx, edx; 1295 1296 eax = 0x01; 1297 ebx = 0; 1298 ecx = 0; 1299 edx = 0; 1300 x86_cpuid(&eax, &ebx, &ecx, &edx); 1301 1302 switch (CPUID_TO_FAMILY(eax)) { 1303 case 0x10: 1304 return &amd_f10h; 1305 case 0x15: 1306 return &amd_f15h; 1307 case 0x17: 1308 return &amd_f17h; 1309 case 0x19: 1310 return &amd_f19h; 1311 } 1312 1313 return NULL; 1314 } 1315 1316 /* ------------------------------------------------------------------------- */ 1317 1318 int 1319 tprof_event_init(uint32_t ident) 1320 { 1321 1322 switch (ident) { 1323 case TPROF_IDENT_NONE: 1324 return -1; 1325 case TPROF_IDENT_INTEL_GENERIC: 1326 cpuevents = init_intel_generic(); 1327 break; 1328 case TPROF_IDENT_AMD_GENERIC: 1329 cpuevents = init_amd_generic(); 1330 break; 1331 } 1332 return (cpuevents == NULL) ? -1 : 0; 1333 } 1334 1335 static void 1336 recursive_event_list(struct event_table *table) 1337 { 1338 size_t i; 1339 1340 printf("%s:\n", table->tablename); 1341 for (i = 0; i < table->nevents; i++) { 1342 if (!table->names[i].enabled) 1343 continue; 1344 printf("\t%s\n", table->names[i].name); 1345 } 1346 1347 if (table->next != NULL) 1348 recursive_event_list(table->next); 1349 } 1350 1351 void 1352 tprof_event_list(void) 1353 { 1354 1355 recursive_event_list(cpuevents); 1356 } 1357 1358 static void 1359 recursive_event_lookup(struct event_table *table, const char *name, 1360 struct tprof_param *param) 1361 { 1362 size_t i; 1363 1364 for (i = 0; i < table->nevents; i++) { 1365 if (!table->names[i].enabled) 1366 continue; 1367 if (!strcmp(table->names[i].name, name)) { 1368 param->p_event = table->names[i].event; 1369 param->p_unit = table->names[i].unit; 1370 return; 1371 } 1372 } 1373 1374 if (table->next != NULL) 1375 recursive_event_lookup(table->next, name, param); 1376 else 1377 errx(EXIT_FAILURE, "event '%s' unknown", name); 1378 } 1379 1380 void 1381 tprof_event_lookup(const char *name, struct tprof_param *param) 1382 { 1383 1384 recursive_event_lookup(cpuevents, name, param); 1385 } 1386