1 #include <linux/perf_event.h> 2 #include <linux/types.h> 3 4 #include "../perf_event.h" 5 6 /* 7 * Not sure about some of these 8 */ 9 static const u64 p6_perfmon_event_map[] = 10 { 11 [PERF_COUNT_HW_CPU_CYCLES] = 0x0079, /* CPU_CLK_UNHALTED */ 12 [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, /* INST_RETIRED */ 13 [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0f2e, /* L2_RQSTS:M:E:S:I */ 14 [PERF_COUNT_HW_CACHE_MISSES] = 0x012e, /* L2_RQSTS:I */ 15 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, /* BR_INST_RETIRED */ 16 [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, /* BR_MISS_PRED_RETIRED */ 17 [PERF_COUNT_HW_BUS_CYCLES] = 0x0062, /* BUS_DRDY_CLOCKS */ 18 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00a2, /* RESOURCE_STALLS */ 19 20 }; 21 22 static const u64 __initconst p6_hw_cache_event_ids 23 [PERF_COUNT_HW_CACHE_MAX] 24 [PERF_COUNT_HW_CACHE_OP_MAX] 25 [PERF_COUNT_HW_CACHE_RESULT_MAX] = 26 { 27 [ C(L1D) ] = { 28 [ C(OP_READ) ] = { 29 [ C(RESULT_ACCESS) ] = 0x0043, /* DATA_MEM_REFS */ 30 [ C(RESULT_MISS) ] = 0x0045, /* DCU_LINES_IN */ 31 }, 32 [ C(OP_WRITE) ] = { 33 [ C(RESULT_ACCESS) ] = 0, 34 [ C(RESULT_MISS) ] = 0x0f29, /* L2_LD:M:E:S:I */ 35 }, 36 [ C(OP_PREFETCH) ] = { 37 [ C(RESULT_ACCESS) ] = 0, 38 [ C(RESULT_MISS) ] = 0, 39 }, 40 }, 41 [ C(L1I ) ] = { 42 [ C(OP_READ) ] = { 43 [ C(RESULT_ACCESS) ] = 0x0080, /* IFU_IFETCH */ 44 [ C(RESULT_MISS) ] = 0x0f28, /* L2_IFETCH:M:E:S:I */ 45 }, 46 [ C(OP_WRITE) ] = { 47 [ C(RESULT_ACCESS) ] = -1, 48 [ C(RESULT_MISS) ] = -1, 49 }, 50 [ C(OP_PREFETCH) ] = { 51 [ C(RESULT_ACCESS) ] = 0, 52 [ C(RESULT_MISS) ] = 0, 53 }, 54 }, 55 [ C(LL ) ] = { 56 [ C(OP_READ) ] = { 57 [ C(RESULT_ACCESS) ] = 0, 58 [ C(RESULT_MISS) ] = 0, 59 }, 60 [ C(OP_WRITE) ] = { 61 [ C(RESULT_ACCESS) ] = 0, 62 [ C(RESULT_MISS) ] = 0x0025, /* L2_M_LINES_INM */ 63 }, 64 [ C(OP_PREFETCH) ] = { 65 [ C(RESULT_ACCESS) ] = 0, 66 [ C(RESULT_MISS) ] = 0, 67 }, 68 }, 69 [ C(DTLB) ] = { 70 [ C(OP_READ) ] = { 71 [ C(RESULT_ACCESS) ] = 0x0043, /* DATA_MEM_REFS */ 72 [ C(RESULT_MISS) ] = 0, 73 }, 74 [ C(OP_WRITE) ] = { 75 [ C(RESULT_ACCESS) ] = 0, 76 [ C(RESULT_MISS) ] = 0, 77 }, 78 [ C(OP_PREFETCH) ] = { 79 [ C(RESULT_ACCESS) ] = 0, 80 [ C(RESULT_MISS) ] = 0, 81 }, 82 }, 83 [ C(ITLB) ] = { 84 [ C(OP_READ) ] = { 85 [ C(RESULT_ACCESS) ] = 0x0080, /* IFU_IFETCH */ 86 [ C(RESULT_MISS) ] = 0x0085, /* ITLB_MISS */ 87 }, 88 [ C(OP_WRITE) ] = { 89 [ C(RESULT_ACCESS) ] = -1, 90 [ C(RESULT_MISS) ] = -1, 91 }, 92 [ C(OP_PREFETCH) ] = { 93 [ C(RESULT_ACCESS) ] = -1, 94 [ C(RESULT_MISS) ] = -1, 95 }, 96 }, 97 [ C(BPU ) ] = { 98 [ C(OP_READ) ] = { 99 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED */ 100 [ C(RESULT_MISS) ] = 0x00c5, /* BR_MISS_PRED_RETIRED */ 101 }, 102 [ C(OP_WRITE) ] = { 103 [ C(RESULT_ACCESS) ] = -1, 104 [ C(RESULT_MISS) ] = -1, 105 }, 106 [ C(OP_PREFETCH) ] = { 107 [ C(RESULT_ACCESS) ] = -1, 108 [ C(RESULT_MISS) ] = -1, 109 }, 110 }, 111 }; 112 113 static u64 p6_pmu_event_map(int hw_event) 114 { 115 return p6_perfmon_event_map[hw_event]; 116 } 117 118 /* 119 * Event setting that is specified not to count anything. 120 * We use this to effectively disable a counter. 121 * 122 * L2_RQSTS with 0 MESI unit mask. 123 */ 124 #define P6_NOP_EVENT 0x0000002EULL 125 126 static struct event_constraint p6_event_constraints[] = 127 { 128 INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FLOPS */ 129 INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */ 130 INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */ 131 INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */ 132 INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */ 133 INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */ 134 EVENT_CONSTRAINT_END 135 }; 136 137 static void p6_pmu_disable_all(void) 138 { 139 u64 val; 140 141 /* p6 only has one enable register */ 142 rdmsrl(MSR_P6_EVNTSEL0, val); 143 val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; 144 wrmsrl(MSR_P6_EVNTSEL0, val); 145 } 146 147 static void p6_pmu_enable_all(int added) 148 { 149 unsigned long val; 150 151 /* p6 only has one enable register */ 152 rdmsrl(MSR_P6_EVNTSEL0, val); 153 val |= ARCH_PERFMON_EVENTSEL_ENABLE; 154 wrmsrl(MSR_P6_EVNTSEL0, val); 155 } 156 157 static inline void 158 p6_pmu_disable_event(struct perf_event *event) 159 { 160 struct hw_perf_event *hwc = &event->hw; 161 u64 val = P6_NOP_EVENT; 162 163 (void)wrmsrl_safe(hwc->config_base, val); 164 } 165 166 static void p6_pmu_enable_event(struct perf_event *event) 167 { 168 struct hw_perf_event *hwc = &event->hw; 169 u64 val; 170 171 val = hwc->config; 172 173 /* 174 * p6 only has a global event enable, set on PerfEvtSel0 175 * We "disable" events by programming P6_NOP_EVENT 176 * and we rely on p6_pmu_enable_all() being called 177 * to actually enable the events. 178 */ 179 180 (void)wrmsrl_safe(hwc->config_base, val); 181 } 182 183 PMU_FORMAT_ATTR(event, "config:0-7" ); 184 PMU_FORMAT_ATTR(umask, "config:8-15" ); 185 PMU_FORMAT_ATTR(edge, "config:18" ); 186 PMU_FORMAT_ATTR(pc, "config:19" ); 187 PMU_FORMAT_ATTR(inv, "config:23" ); 188 PMU_FORMAT_ATTR(cmask, "config:24-31" ); 189 190 static struct attribute *intel_p6_formats_attr[] = { 191 &format_attr_event.attr, 192 &format_attr_umask.attr, 193 &format_attr_edge.attr, 194 &format_attr_pc.attr, 195 &format_attr_inv.attr, 196 &format_attr_cmask.attr, 197 NULL, 198 }; 199 200 static __initconst const struct x86_pmu p6_pmu = { 201 .name = "p6", 202 .handle_irq = x86_pmu_handle_irq, 203 .disable_all = p6_pmu_disable_all, 204 .enable_all = p6_pmu_enable_all, 205 .enable = p6_pmu_enable_event, 206 .disable = p6_pmu_disable_event, 207 .hw_config = x86_pmu_hw_config, 208 .schedule_events = x86_schedule_events, 209 .eventsel = MSR_P6_EVNTSEL0, 210 .perfctr = MSR_P6_PERFCTR0, 211 .event_map = p6_pmu_event_map, 212 .max_events = ARRAY_SIZE(p6_perfmon_event_map), 213 .apic = 1, 214 .max_period = (1ULL << 31) - 1, 215 .version = 0, 216 .num_counters = 2, 217 /* 218 * Events have 40 bits implemented. However they are designed such 219 * that bits [32-39] are sign extensions of bit 31. As such the 220 * effective width of a event for P6-like PMU is 32 bits only. 221 * 222 * See IA-32 Intel Architecture Software developer manual Vol 3B 223 */ 224 .cntval_bits = 32, 225 .cntval_mask = (1ULL << 32) - 1, 226 .get_event_constraints = x86_get_event_constraints, 227 .event_constraints = p6_event_constraints, 228 229 .format_attrs = intel_p6_formats_attr, 230 .events_sysfs_show = intel_event_sysfs_show, 231 232 }; 233 234 static __init void p6_pmu_rdpmc_quirk(void) 235 { 236 if (boot_cpu_data.x86_mask < 9) { 237 /* 238 * PPro erratum 26; fixed in stepping 9 and above. 239 */ 240 pr_warn("Userspace RDPMC support disabled due to a CPU erratum\n"); 241 x86_pmu.attr_rdpmc_broken = 1; 242 x86_pmu.attr_rdpmc = 0; 243 } 244 } 245 246 __init int p6_pmu_init(void) 247 { 248 x86_pmu = p6_pmu; 249 250 switch (boot_cpu_data.x86_model) { 251 case 1: /* Pentium Pro */ 252 x86_add_quirk(p6_pmu_rdpmc_quirk); 253 break; 254 255 case 3: /* Pentium II - Klamath */ 256 case 5: /* Pentium II - Deschutes */ 257 case 6: /* Pentium II - Mendocino */ 258 break; 259 260 case 7: /* Pentium III - Katmai */ 261 case 8: /* Pentium III - Coppermine */ 262 case 10: /* Pentium III Xeon */ 263 case 11: /* Pentium III - Tualatin */ 264 break; 265 266 case 9: /* Pentium M - Banias */ 267 case 13: /* Pentium M - Dothan */ 268 break; 269 270 default: 271 pr_cont("unsupported p6 CPU model %d ", boot_cpu_data.x86_model); 272 return -ENODEV; 273 } 274 275 memcpy(hw_cache_event_ids, p6_hw_cache_event_ids, 276 sizeof(hw_cache_event_ids)); 277 278 return 0; 279 } 280