1 /* 2 * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code. 3 * 4 * ARMv7 support: Jean Pihet <jpihet@mvista.com> 5 * 2010 (c) MontaVista Software, LLC. 6 * 7 * Copied from ARMv6 code, with the low level code inspired 8 * by the ARMv7 Oprofile code. 9 * 10 * Cortex-A8 has up to 4 configurable performance counters and 11 * a single cycle counter. 12 * Cortex-A9 has up to 31 configurable performance counters and 13 * a single cycle counter. 14 * 15 * All counters can be enabled/disabled and IRQ masked separately. The cycle 16 * counter and all 4 performance counters together can be reset separately. 17 */ 18 19 #ifdef CONFIG_CPU_V7 20 /* 21 * Common ARMv7 event types 22 * 23 * Note: An implementation may not be able to count all of these events 24 * but the encodings are considered to be `reserved' in the case that 25 * they are not available. 26 */ 27 enum armv7_perf_types { 28 ARMV7_PERFCTR_PMNC_SW_INCR = 0x00, 29 ARMV7_PERFCTR_IFETCH_MISS = 0x01, 30 ARMV7_PERFCTR_ITLB_MISS = 0x02, 31 ARMV7_PERFCTR_DCACHE_REFILL = 0x03, /* L1 */ 32 ARMV7_PERFCTR_DCACHE_ACCESS = 0x04, /* L1 */ 33 ARMV7_PERFCTR_DTLB_REFILL = 0x05, 34 ARMV7_PERFCTR_DREAD = 0x06, 35 ARMV7_PERFCTR_DWRITE = 0x07, 36 ARMV7_PERFCTR_INSTR_EXECUTED = 0x08, 37 ARMV7_PERFCTR_EXC_TAKEN = 0x09, 38 ARMV7_PERFCTR_EXC_EXECUTED = 0x0A, 39 ARMV7_PERFCTR_CID_WRITE = 0x0B, 40 /* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS. 41 * It counts: 42 * - all branch instructions, 43 * - instructions that explicitly write the PC, 44 * - exception generating instructions. 45 */ 46 ARMV7_PERFCTR_PC_WRITE = 0x0C, 47 ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D, 48 ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E, 49 ARMV7_PERFCTR_UNALIGNED_ACCESS = 0x0F, 50 51 /* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */ 52 ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10, 53 ARMV7_PERFCTR_CLOCK_CYCLES = 0x11, 54 ARMV7_PERFCTR_PC_BRANCH_PRED = 0x12, 55 ARMV7_PERFCTR_MEM_ACCESS = 0x13, 56 ARMV7_PERFCTR_L1_ICACHE_ACCESS = 0x14, 57 ARMV7_PERFCTR_L1_DCACHE_WB = 0x15, 58 ARMV7_PERFCTR_L2_DCACHE_ACCESS = 0x16, 59 ARMV7_PERFCTR_L2_DCACHE_REFILL = 0x17, 60 ARMV7_PERFCTR_L2_DCACHE_WB = 0x18, 61 ARMV7_PERFCTR_BUS_ACCESS = 0x19, 62 ARMV7_PERFCTR_MEMORY_ERROR = 0x1A, 63 ARMV7_PERFCTR_INSTR_SPEC = 0x1B, 64 ARMV7_PERFCTR_TTBR_WRITE = 0x1C, 65 ARMV7_PERFCTR_BUS_CYCLES = 0x1D, 66 67 ARMV7_PERFCTR_CPU_CYCLES = 0xFF 68 }; 69 70 /* ARMv7 Cortex-A8 specific event types */ 71 enum armv7_a8_perf_types { 72 ARMV7_PERFCTR_WRITE_BUFFER_FULL = 0x40, 73 ARMV7_PERFCTR_L2_STORE_MERGED = 0x41, 74 ARMV7_PERFCTR_L2_STORE_BUFF = 0x42, 75 ARMV7_PERFCTR_L2_ACCESS = 0x43, 76 ARMV7_PERFCTR_L2_CACH_MISS = 0x44, 77 ARMV7_PERFCTR_AXI_READ_CYCLES = 0x45, 78 ARMV7_PERFCTR_AXI_WRITE_CYCLES = 0x46, 79 ARMV7_PERFCTR_MEMORY_REPLAY = 0x47, 80 ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY = 0x48, 81 ARMV7_PERFCTR_L1_DATA_MISS = 0x49, 82 ARMV7_PERFCTR_L1_INST_MISS = 0x4A, 83 ARMV7_PERFCTR_L1_DATA_COLORING = 0x4B, 84 ARMV7_PERFCTR_L1_NEON_DATA = 0x4C, 85 ARMV7_PERFCTR_L1_NEON_CACH_DATA = 0x4D, 86 ARMV7_PERFCTR_L2_NEON = 0x4E, 87 ARMV7_PERFCTR_L2_NEON_HIT = 0x4F, 88 ARMV7_PERFCTR_L1_INST = 0x50, 89 ARMV7_PERFCTR_PC_RETURN_MIS_PRED = 0x51, 90 ARMV7_PERFCTR_PC_BRANCH_FAILED = 0x52, 91 ARMV7_PERFCTR_PC_BRANCH_TAKEN = 0x53, 92 ARMV7_PERFCTR_PC_BRANCH_EXECUTED = 0x54, 93 ARMV7_PERFCTR_OP_EXECUTED = 0x55, 94 ARMV7_PERFCTR_CYCLES_INST_STALL = 0x56, 95 ARMV7_PERFCTR_CYCLES_INST = 0x57, 96 ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL = 0x58, 97 ARMV7_PERFCTR_CYCLES_NEON_INST_STALL = 0x59, 98 ARMV7_PERFCTR_NEON_CYCLES = 0x5A, 99 100 ARMV7_PERFCTR_PMU0_EVENTS = 0x70, 101 ARMV7_PERFCTR_PMU1_EVENTS = 0x71, 102 ARMV7_PERFCTR_PMU_EVENTS = 0x72, 103 }; 104 105 /* ARMv7 Cortex-A9 specific event types */ 106 enum armv7_a9_perf_types { 107 ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC = 0x40, 108 ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC = 0x41, 109 ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC = 0x42, 110 111 ARMV7_PERFCTR_COHERENT_LINE_MISS = 0x50, 112 ARMV7_PERFCTR_COHERENT_LINE_HIT = 0x51, 113 114 ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES = 0x60, 115 ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES = 0x61, 116 ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES = 0x62, 117 ARMV7_PERFCTR_STREX_EXECUTED_PASSED = 0x63, 118 ARMV7_PERFCTR_STREX_EXECUTED_FAILED = 0x64, 119 ARMV7_PERFCTR_DATA_EVICTION = 0x65, 120 ARMV7_PERFCTR_ISSUE_STAGE_NO_INST = 0x66, 121 ARMV7_PERFCTR_ISSUE_STAGE_EMPTY = 0x67, 122 ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE = 0x68, 123 124 ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS = 0x6E, 125 126 ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST = 0x70, 127 ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST = 0x71, 128 ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST = 0x72, 129 ARMV7_PERFCTR_FP_EXECUTED_INST = 0x73, 130 ARMV7_PERFCTR_NEON_EXECUTED_INST = 0x74, 131 132 ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES = 0x80, 133 ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES = 0x81, 134 ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES = 0x82, 135 ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES = 0x83, 136 ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES = 0x84, 137 ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES = 0x85, 138 ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES = 0x86, 139 140 ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES = 0x8A, 141 ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES = 0x8B, 142 143 ARMV7_PERFCTR_ISB_INST = 0x90, 144 ARMV7_PERFCTR_DSB_INST = 0x91, 145 ARMV7_PERFCTR_DMB_INST = 0x92, 146 ARMV7_PERFCTR_EXT_INTERRUPTS = 0x93, 147 148 ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED = 0xA0, 149 ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED = 0xA1, 150 ARMV7_PERFCTR_PLE_FIFO_FLUSH = 0xA2, 151 ARMV7_PERFCTR_PLE_RQST_COMPLETED = 0xA3, 152 ARMV7_PERFCTR_PLE_FIFO_OVERFLOW = 0xA4, 153 ARMV7_PERFCTR_PLE_RQST_PROG = 0xA5 154 }; 155 156 /* ARMv7 Cortex-A5 specific event types */ 157 enum armv7_a5_perf_types { 158 ARMV7_PERFCTR_IRQ_TAKEN = 0x86, 159 ARMV7_PERFCTR_FIQ_TAKEN = 0x87, 160 161 ARMV7_PERFCTR_EXT_MEM_RQST = 0xc0, 162 ARMV7_PERFCTR_NC_EXT_MEM_RQST = 0xc1, 163 ARMV7_PERFCTR_PREFETCH_LINEFILL = 0xc2, 164 ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP = 0xc3, 165 ARMV7_PERFCTR_ENTER_READ_ALLOC = 0xc4, 166 ARMV7_PERFCTR_READ_ALLOC = 0xc5, 167 168 ARMV7_PERFCTR_STALL_SB_FULL = 0xc9, 169 }; 170 171 /* ARMv7 Cortex-A15 specific event types */ 172 enum armv7_a15_perf_types { 173 ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS = 0x40, 174 ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS = 0x41, 175 ARMV7_PERFCTR_L1_DCACHE_READ_REFILL = 0x42, 176 ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL = 0x43, 177 178 ARMV7_PERFCTR_L1_DTLB_READ_REFILL = 0x4C, 179 ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL = 0x4D, 180 181 ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS = 0x50, 182 ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS = 0x51, 183 ARMV7_PERFCTR_L2_DCACHE_READ_REFILL = 0x52, 184 ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL = 0x53, 185 186 ARMV7_PERFCTR_SPEC_PC_WRITE = 0x76, 187 }; 188 189 /* 190 * Cortex-A8 HW events mapping 191 * 192 * The hardware events that we support. We do support cache operations but 193 * we have harvard caches and no way to combine instruction and data 194 * accesses/misses in hardware. 195 */ 196 static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = { 197 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, 198 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED, 199 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, 200 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, 201 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, 202 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, 203 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES, 204 }; 205 206 static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] 207 [PERF_COUNT_HW_CACHE_OP_MAX] 208 [PERF_COUNT_HW_CACHE_RESULT_MAX] = { 209 [C(L1D)] = { 210 /* 211 * The performance counters don't differentiate between read 212 * and write accesses/misses so this isn't strictly correct, 213 * but it's the best we can do. Writes and reads get 214 * combined. 215 */ 216 [C(OP_READ)] = { 217 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, 218 [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, 219 }, 220 [C(OP_WRITE)] = { 221 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, 222 [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, 223 }, 224 [C(OP_PREFETCH)] = { 225 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 226 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 227 }, 228 }, 229 [C(L1I)] = { 230 [C(OP_READ)] = { 231 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST, 232 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS, 233 }, 234 [C(OP_WRITE)] = { 235 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST, 236 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS, 237 }, 238 [C(OP_PREFETCH)] = { 239 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 240 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 241 }, 242 }, 243 [C(LL)] = { 244 [C(OP_READ)] = { 245 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS, 246 [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS, 247 }, 248 [C(OP_WRITE)] = { 249 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS, 250 [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS, 251 }, 252 [C(OP_PREFETCH)] = { 253 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 254 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 255 }, 256 }, 257 [C(DTLB)] = { 258 [C(OP_READ)] = { 259 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 260 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, 261 }, 262 [C(OP_WRITE)] = { 263 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 264 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, 265 }, 266 [C(OP_PREFETCH)] = { 267 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 268 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 269 }, 270 }, 271 [C(ITLB)] = { 272 [C(OP_READ)] = { 273 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 274 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, 275 }, 276 [C(OP_WRITE)] = { 277 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 278 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, 279 }, 280 [C(OP_PREFETCH)] = { 281 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 282 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 283 }, 284 }, 285 [C(BPU)] = { 286 [C(OP_READ)] = { 287 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, 288 [C(RESULT_MISS)] 289 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, 290 }, 291 [C(OP_WRITE)] = { 292 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, 293 [C(RESULT_MISS)] 294 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, 295 }, 296 [C(OP_PREFETCH)] = { 297 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 298 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 299 }, 300 }, 301 [C(NODE)] = { 302 [C(OP_READ)] = { 303 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 304 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 305 }, 306 [C(OP_WRITE)] = { 307 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 308 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 309 }, 310 [C(OP_PREFETCH)] = { 311 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 312 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 313 }, 314 }, 315 }; 316 317 /* 318 * Cortex-A9 HW events mapping 319 */ 320 static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = { 321 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, 322 [PERF_COUNT_HW_INSTRUCTIONS] = 323 ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE, 324 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_COHERENT_LINE_HIT, 325 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_COHERENT_LINE_MISS, 326 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, 327 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, 328 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES, 329 }; 330 331 static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] 332 [PERF_COUNT_HW_CACHE_OP_MAX] 333 [PERF_COUNT_HW_CACHE_RESULT_MAX] = { 334 [C(L1D)] = { 335 /* 336 * The performance counters don't differentiate between read 337 * and write accesses/misses so this isn't strictly correct, 338 * but it's the best we can do. Writes and reads get 339 * combined. 340 */ 341 [C(OP_READ)] = { 342 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, 343 [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, 344 }, 345 [C(OP_WRITE)] = { 346 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, 347 [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, 348 }, 349 [C(OP_PREFETCH)] = { 350 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 351 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 352 }, 353 }, 354 [C(L1I)] = { 355 [C(OP_READ)] = { 356 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 357 [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, 358 }, 359 [C(OP_WRITE)] = { 360 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 361 [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, 362 }, 363 [C(OP_PREFETCH)] = { 364 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 365 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 366 }, 367 }, 368 [C(LL)] = { 369 [C(OP_READ)] = { 370 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 371 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 372 }, 373 [C(OP_WRITE)] = { 374 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 375 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 376 }, 377 [C(OP_PREFETCH)] = { 378 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 379 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 380 }, 381 }, 382 [C(DTLB)] = { 383 [C(OP_READ)] = { 384 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 385 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, 386 }, 387 [C(OP_WRITE)] = { 388 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 389 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, 390 }, 391 [C(OP_PREFETCH)] = { 392 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 393 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 394 }, 395 }, 396 [C(ITLB)] = { 397 [C(OP_READ)] = { 398 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 399 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, 400 }, 401 [C(OP_WRITE)] = { 402 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 403 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, 404 }, 405 [C(OP_PREFETCH)] = { 406 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 407 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 408 }, 409 }, 410 [C(BPU)] = { 411 [C(OP_READ)] = { 412 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, 413 [C(RESULT_MISS)] 414 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, 415 }, 416 [C(OP_WRITE)] = { 417 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, 418 [C(RESULT_MISS)] 419 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, 420 }, 421 [C(OP_PREFETCH)] = { 422 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 423 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 424 }, 425 }, 426 [C(NODE)] = { 427 [C(OP_READ)] = { 428 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 429 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 430 }, 431 [C(OP_WRITE)] = { 432 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 433 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 434 }, 435 [C(OP_PREFETCH)] = { 436 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 437 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 438 }, 439 }, 440 }; 441 442 /* 443 * Cortex-A5 HW events mapping 444 */ 445 static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX] = { 446 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, 447 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED, 448 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, 449 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, 450 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, 451 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, 452 [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, 453 }; 454 455 static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] 456 [PERF_COUNT_HW_CACHE_OP_MAX] 457 [PERF_COUNT_HW_CACHE_RESULT_MAX] = { 458 [C(L1D)] = { 459 [C(OP_READ)] = { 460 [C(RESULT_ACCESS)] 461 = ARMV7_PERFCTR_DCACHE_ACCESS, 462 [C(RESULT_MISS)] 463 = ARMV7_PERFCTR_DCACHE_REFILL, 464 }, 465 [C(OP_WRITE)] = { 466 [C(RESULT_ACCESS)] 467 = ARMV7_PERFCTR_DCACHE_ACCESS, 468 [C(RESULT_MISS)] 469 = ARMV7_PERFCTR_DCACHE_REFILL, 470 }, 471 [C(OP_PREFETCH)] = { 472 [C(RESULT_ACCESS)] 473 = ARMV7_PERFCTR_PREFETCH_LINEFILL, 474 [C(RESULT_MISS)] 475 = ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP, 476 }, 477 }, 478 [C(L1I)] = { 479 [C(OP_READ)] = { 480 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, 481 [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, 482 }, 483 [C(OP_WRITE)] = { 484 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, 485 [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, 486 }, 487 /* 488 * The prefetch counters don't differentiate between the I 489 * side and the D side. 490 */ 491 [C(OP_PREFETCH)] = { 492 [C(RESULT_ACCESS)] 493 = ARMV7_PERFCTR_PREFETCH_LINEFILL, 494 [C(RESULT_MISS)] 495 = ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP, 496 }, 497 }, 498 [C(LL)] = { 499 [C(OP_READ)] = { 500 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 501 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 502 }, 503 [C(OP_WRITE)] = { 504 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 505 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 506 }, 507 [C(OP_PREFETCH)] = { 508 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 509 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 510 }, 511 }, 512 [C(DTLB)] = { 513 [C(OP_READ)] = { 514 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 515 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, 516 }, 517 [C(OP_WRITE)] = { 518 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 519 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, 520 }, 521 [C(OP_PREFETCH)] = { 522 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 523 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 524 }, 525 }, 526 [C(ITLB)] = { 527 [C(OP_READ)] = { 528 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 529 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, 530 }, 531 [C(OP_WRITE)] = { 532 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 533 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, 534 }, 535 [C(OP_PREFETCH)] = { 536 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 537 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 538 }, 539 }, 540 [C(BPU)] = { 541 [C(OP_READ)] = { 542 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, 543 [C(RESULT_MISS)] 544 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, 545 }, 546 [C(OP_WRITE)] = { 547 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, 548 [C(RESULT_MISS)] 549 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, 550 }, 551 [C(OP_PREFETCH)] = { 552 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 553 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 554 }, 555 }, 556 }; 557 558 /* 559 * Cortex-A15 HW events mapping 560 */ 561 static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = { 562 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, 563 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED, 564 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, 565 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, 566 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_SPEC_PC_WRITE, 567 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, 568 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES, 569 }; 570 571 static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] 572 [PERF_COUNT_HW_CACHE_OP_MAX] 573 [PERF_COUNT_HW_CACHE_RESULT_MAX] = { 574 [C(L1D)] = { 575 [C(OP_READ)] = { 576 [C(RESULT_ACCESS)] 577 = ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS, 578 [C(RESULT_MISS)] 579 = ARMV7_PERFCTR_L1_DCACHE_READ_REFILL, 580 }, 581 [C(OP_WRITE)] = { 582 [C(RESULT_ACCESS)] 583 = ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS, 584 [C(RESULT_MISS)] 585 = ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL, 586 }, 587 [C(OP_PREFETCH)] = { 588 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 589 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 590 }, 591 }, 592 [C(L1I)] = { 593 /* 594 * Not all performance counters differentiate between read 595 * and write accesses/misses so we're not always strictly 596 * correct, but it's the best we can do. Writes and reads get 597 * combined in these cases. 598 */ 599 [C(OP_READ)] = { 600 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, 601 [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, 602 }, 603 [C(OP_WRITE)] = { 604 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, 605 [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, 606 }, 607 [C(OP_PREFETCH)] = { 608 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 609 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 610 }, 611 }, 612 [C(LL)] = { 613 [C(OP_READ)] = { 614 [C(RESULT_ACCESS)] 615 = ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS, 616 [C(RESULT_MISS)] 617 = ARMV7_PERFCTR_L2_DCACHE_READ_REFILL, 618 }, 619 [C(OP_WRITE)] = { 620 [C(RESULT_ACCESS)] 621 = ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS, 622 [C(RESULT_MISS)] 623 = ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL, 624 }, 625 [C(OP_PREFETCH)] = { 626 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 627 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 628 }, 629 }, 630 [C(DTLB)] = { 631 [C(OP_READ)] = { 632 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 633 [C(RESULT_MISS)] 634 = ARMV7_PERFCTR_L1_DTLB_READ_REFILL, 635 }, 636 [C(OP_WRITE)] = { 637 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 638 [C(RESULT_MISS)] 639 = ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL, 640 }, 641 [C(OP_PREFETCH)] = { 642 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 643 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 644 }, 645 }, 646 [C(ITLB)] = { 647 [C(OP_READ)] = { 648 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 649 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, 650 }, 651 [C(OP_WRITE)] = { 652 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 653 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, 654 }, 655 [C(OP_PREFETCH)] = { 656 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 657 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 658 }, 659 }, 660 [C(BPU)] = { 661 [C(OP_READ)] = { 662 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, 663 [C(RESULT_MISS)] 664 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, 665 }, 666 [C(OP_WRITE)] = { 667 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, 668 [C(RESULT_MISS)] 669 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, 670 }, 671 [C(OP_PREFETCH)] = { 672 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 673 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 674 }, 675 }, 676 }; 677 678 /* 679 * Perf Events counters 680 */ 681 enum armv7_counters { 682 ARMV7_CYCLE_COUNTER = 1, /* Cycle counter */ 683 ARMV7_COUNTER0 = 2, /* First event counter */ 684 }; 685 686 /* 687 * The cycle counter is ARMV7_CYCLE_COUNTER. 688 * The first event counter is ARMV7_COUNTER0. 689 * The last event counter is (ARMV7_COUNTER0 + armpmu->num_events - 1). 690 */ 691 #define ARMV7_COUNTER_LAST (ARMV7_COUNTER0 + armpmu->num_events - 1) 692 693 /* 694 * ARMv7 low level PMNC access 695 */ 696 697 /* 698 * Per-CPU PMNC: config reg 699 */ 700 #define ARMV7_PMNC_E (1 << 0) /* Enable all counters */ 701 #define ARMV7_PMNC_P (1 << 1) /* Reset all counters */ 702 #define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */ 703 #define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */ 704 #define ARMV7_PMNC_X (1 << 4) /* Export to ETM */ 705 #define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/ 706 #define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */ 707 #define ARMV7_PMNC_N_MASK 0x1f 708 #define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */ 709 710 /* 711 * Available counters 712 */ 713 #define ARMV7_CNT0 0 /* First event counter */ 714 #define ARMV7_CCNT 31 /* Cycle counter */ 715 716 /* Perf Event to low level counters mapping */ 717 #define ARMV7_EVENT_CNT_TO_CNTx (ARMV7_COUNTER0 - ARMV7_CNT0) 718 719 /* 720 * CNTENS: counters enable reg 721 */ 722 #define ARMV7_CNTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) 723 #define ARMV7_CNTENS_C (1 << ARMV7_CCNT) 724 725 /* 726 * CNTENC: counters disable reg 727 */ 728 #define ARMV7_CNTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) 729 #define ARMV7_CNTENC_C (1 << ARMV7_CCNT) 730 731 /* 732 * INTENS: counters overflow interrupt enable reg 733 */ 734 #define ARMV7_INTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) 735 #define ARMV7_INTENS_C (1 << ARMV7_CCNT) 736 737 /* 738 * INTENC: counters overflow interrupt disable reg 739 */ 740 #define ARMV7_INTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) 741 #define ARMV7_INTENC_C (1 << ARMV7_CCNT) 742 743 /* 744 * EVTSEL: Event selection reg 745 */ 746 #define ARMV7_EVTSEL_MASK 0xff /* Mask for writable bits */ 747 748 /* 749 * SELECT: Counter selection reg 750 */ 751 #define ARMV7_SELECT_MASK 0x1f /* Mask for writable bits */ 752 753 /* 754 * FLAG: counters overflow flag status reg 755 */ 756 #define ARMV7_FLAG_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) 757 #define ARMV7_FLAG_C (1 << ARMV7_CCNT) 758 #define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */ 759 #define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK 760 761 static inline unsigned long armv7_pmnc_read(void) 762 { 763 u32 val; 764 asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val)); 765 return val; 766 } 767 768 static inline void armv7_pmnc_write(unsigned long val) 769 { 770 val &= ARMV7_PMNC_MASK; 771 isb(); 772 asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val)); 773 } 774 775 static inline int armv7_pmnc_has_overflowed(unsigned long pmnc) 776 { 777 return pmnc & ARMV7_OVERFLOWED_MASK; 778 } 779 780 static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc, 781 enum armv7_counters counter) 782 { 783 int ret = 0; 784 785 if (counter == ARMV7_CYCLE_COUNTER) 786 ret = pmnc & ARMV7_FLAG_C; 787 else if ((counter >= ARMV7_COUNTER0) && (counter <= ARMV7_COUNTER_LAST)) 788 ret = pmnc & ARMV7_FLAG_P(counter); 789 else 790 pr_err("CPU%u checking wrong counter %d overflow status\n", 791 smp_processor_id(), counter); 792 793 return ret; 794 } 795 796 static inline int armv7_pmnc_select_counter(unsigned int idx) 797 { 798 u32 val; 799 800 if ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST)) { 801 pr_err("CPU%u selecting wrong PMNC counter" 802 " %d\n", smp_processor_id(), idx); 803 return -1; 804 } 805 806 val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK; 807 asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val)); 808 isb(); 809 810 return idx; 811 } 812 813 static inline u32 armv7pmu_read_counter(int idx) 814 { 815 unsigned long value = 0; 816 817 if (idx == ARMV7_CYCLE_COUNTER) 818 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value)); 819 else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) { 820 if (armv7_pmnc_select_counter(idx) == idx) 821 asm volatile("mrc p15, 0, %0, c9, c13, 2" 822 : "=r" (value)); 823 } else 824 pr_err("CPU%u reading wrong counter %d\n", 825 smp_processor_id(), idx); 826 827 return value; 828 } 829 830 static inline void armv7pmu_write_counter(int idx, u32 value) 831 { 832 if (idx == ARMV7_CYCLE_COUNTER) 833 asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value)); 834 else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) { 835 if (armv7_pmnc_select_counter(idx) == idx) 836 asm volatile("mcr p15, 0, %0, c9, c13, 2" 837 : : "r" (value)); 838 } else 839 pr_err("CPU%u writing wrong counter %d\n", 840 smp_processor_id(), idx); 841 } 842 843 static inline void armv7_pmnc_write_evtsel(unsigned int idx, u32 val) 844 { 845 if (armv7_pmnc_select_counter(idx) == idx) { 846 val &= ARMV7_EVTSEL_MASK; 847 asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val)); 848 } 849 } 850 851 static inline u32 armv7_pmnc_enable_counter(unsigned int idx) 852 { 853 u32 val; 854 855 if ((idx != ARMV7_CYCLE_COUNTER) && 856 ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { 857 pr_err("CPU%u enabling wrong PMNC counter" 858 " %d\n", smp_processor_id(), idx); 859 return -1; 860 } 861 862 if (idx == ARMV7_CYCLE_COUNTER) 863 val = ARMV7_CNTENS_C; 864 else 865 val = ARMV7_CNTENS_P(idx); 866 867 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val)); 868 869 return idx; 870 } 871 872 static inline u32 armv7_pmnc_disable_counter(unsigned int idx) 873 { 874 u32 val; 875 876 877 if ((idx != ARMV7_CYCLE_COUNTER) && 878 ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { 879 pr_err("CPU%u disabling wrong PMNC counter" 880 " %d\n", smp_processor_id(), idx); 881 return -1; 882 } 883 884 if (idx == ARMV7_CYCLE_COUNTER) 885 val = ARMV7_CNTENC_C; 886 else 887 val = ARMV7_CNTENC_P(idx); 888 889 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val)); 890 891 return idx; 892 } 893 894 static inline u32 armv7_pmnc_enable_intens(unsigned int idx) 895 { 896 u32 val; 897 898 if ((idx != ARMV7_CYCLE_COUNTER) && 899 ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { 900 pr_err("CPU%u enabling wrong PMNC counter" 901 " interrupt enable %d\n", smp_processor_id(), idx); 902 return -1; 903 } 904 905 if (idx == ARMV7_CYCLE_COUNTER) 906 val = ARMV7_INTENS_C; 907 else 908 val = ARMV7_INTENS_P(idx); 909 910 asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val)); 911 912 return idx; 913 } 914 915 static inline u32 armv7_pmnc_disable_intens(unsigned int idx) 916 { 917 u32 val; 918 919 if ((idx != ARMV7_CYCLE_COUNTER) && 920 ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { 921 pr_err("CPU%u disabling wrong PMNC counter" 922 " interrupt enable %d\n", smp_processor_id(), idx); 923 return -1; 924 } 925 926 if (idx == ARMV7_CYCLE_COUNTER) 927 val = ARMV7_INTENC_C; 928 else 929 val = ARMV7_INTENC_P(idx); 930 931 asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val)); 932 933 return idx; 934 } 935 936 static inline u32 armv7_pmnc_getreset_flags(void) 937 { 938 u32 val; 939 940 /* Read */ 941 asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val)); 942 943 /* Write to clear flags */ 944 val &= ARMV7_FLAG_MASK; 945 asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val)); 946 947 return val; 948 } 949 950 #ifdef DEBUG 951 static void armv7_pmnc_dump_regs(void) 952 { 953 u32 val; 954 unsigned int cnt; 955 956 printk(KERN_INFO "PMNC registers dump:\n"); 957 958 asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val)); 959 printk(KERN_INFO "PMNC =0x%08x\n", val); 960 961 asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val)); 962 printk(KERN_INFO "CNTENS=0x%08x\n", val); 963 964 asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val)); 965 printk(KERN_INFO "INTENS=0x%08x\n", val); 966 967 asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val)); 968 printk(KERN_INFO "FLAGS =0x%08x\n", val); 969 970 asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val)); 971 printk(KERN_INFO "SELECT=0x%08x\n", val); 972 973 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); 974 printk(KERN_INFO "CCNT =0x%08x\n", val); 975 976 for (cnt = ARMV7_COUNTER0; cnt < ARMV7_COUNTER_LAST; cnt++) { 977 armv7_pmnc_select_counter(cnt); 978 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val)); 979 printk(KERN_INFO "CNT[%d] count =0x%08x\n", 980 cnt-ARMV7_EVENT_CNT_TO_CNTx, val); 981 asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val)); 982 printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n", 983 cnt-ARMV7_EVENT_CNT_TO_CNTx, val); 984 } 985 } 986 #endif 987 988 static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx) 989 { 990 unsigned long flags; 991 992 /* 993 * Enable counter and interrupt, and set the counter to count 994 * the event that we're interested in. 995 */ 996 raw_spin_lock_irqsave(&pmu_lock, flags); 997 998 /* 999 * Disable counter 1000 */ 1001 armv7_pmnc_disable_counter(idx); 1002 1003 /* 1004 * Set event (if destined for PMNx counters) 1005 * We don't need to set the event if it's a cycle count 1006 */ 1007 if (idx != ARMV7_CYCLE_COUNTER) 1008 armv7_pmnc_write_evtsel(idx, hwc->config_base); 1009 1010 /* 1011 * Enable interrupt for this counter 1012 */ 1013 armv7_pmnc_enable_intens(idx); 1014 1015 /* 1016 * Enable counter 1017 */ 1018 armv7_pmnc_enable_counter(idx); 1019 1020 raw_spin_unlock_irqrestore(&pmu_lock, flags); 1021 } 1022 1023 static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx) 1024 { 1025 unsigned long flags; 1026 1027 /* 1028 * Disable counter and interrupt 1029 */ 1030 raw_spin_lock_irqsave(&pmu_lock, flags); 1031 1032 /* 1033 * Disable counter 1034 */ 1035 armv7_pmnc_disable_counter(idx); 1036 1037 /* 1038 * Disable interrupt for this counter 1039 */ 1040 armv7_pmnc_disable_intens(idx); 1041 1042 raw_spin_unlock_irqrestore(&pmu_lock, flags); 1043 } 1044 1045 static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) 1046 { 1047 unsigned long pmnc; 1048 struct perf_sample_data data; 1049 struct cpu_hw_events *cpuc; 1050 struct pt_regs *regs; 1051 int idx; 1052 1053 /* 1054 * Get and reset the IRQ flags 1055 */ 1056 pmnc = armv7_pmnc_getreset_flags(); 1057 1058 /* 1059 * Did an overflow occur? 1060 */ 1061 if (!armv7_pmnc_has_overflowed(pmnc)) 1062 return IRQ_NONE; 1063 1064 /* 1065 * Handle the counter(s) overflow(s) 1066 */ 1067 regs = get_irq_regs(); 1068 1069 perf_sample_data_init(&data, 0); 1070 1071 cpuc = &__get_cpu_var(cpu_hw_events); 1072 for (idx = 0; idx <= armpmu->num_events; ++idx) { 1073 struct perf_event *event = cpuc->events[idx]; 1074 struct hw_perf_event *hwc; 1075 1076 if (!test_bit(idx, cpuc->active_mask)) 1077 continue; 1078 1079 /* 1080 * We have a single interrupt for all counters. Check that 1081 * each counter has overflowed before we process it. 1082 */ 1083 if (!armv7_pmnc_counter_has_overflowed(pmnc, idx)) 1084 continue; 1085 1086 hwc = &event->hw; 1087 armpmu_event_update(event, hwc, idx, 1); 1088 data.period = event->hw.last_period; 1089 if (!armpmu_event_set_period(event, hwc, idx)) 1090 continue; 1091 1092 if (perf_event_overflow(event, &data, regs)) 1093 armpmu->disable(hwc, idx); 1094 } 1095 1096 /* 1097 * Handle the pending perf events. 1098 * 1099 * Note: this call *must* be run with interrupts disabled. For 1100 * platforms that can have the PMU interrupts raised as an NMI, this 1101 * will not work. 1102 */ 1103 irq_work_run(); 1104 1105 return IRQ_HANDLED; 1106 } 1107 1108 static void armv7pmu_start(void) 1109 { 1110 unsigned long flags; 1111 1112 raw_spin_lock_irqsave(&pmu_lock, flags); 1113 /* Enable all counters */ 1114 armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E); 1115 raw_spin_unlock_irqrestore(&pmu_lock, flags); 1116 } 1117 1118 static void armv7pmu_stop(void) 1119 { 1120 unsigned long flags; 1121 1122 raw_spin_lock_irqsave(&pmu_lock, flags); 1123 /* Disable all counters */ 1124 armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E); 1125 raw_spin_unlock_irqrestore(&pmu_lock, flags); 1126 } 1127 1128 static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc, 1129 struct hw_perf_event *event) 1130 { 1131 int idx; 1132 1133 /* Always place a cycle counter into the cycle counter. */ 1134 if (event->config_base == ARMV7_PERFCTR_CPU_CYCLES) { 1135 if (test_and_set_bit(ARMV7_CYCLE_COUNTER, cpuc->used_mask)) 1136 return -EAGAIN; 1137 1138 return ARMV7_CYCLE_COUNTER; 1139 } else { 1140 /* 1141 * For anything other than a cycle counter, try and use 1142 * the events counters 1143 */ 1144 for (idx = ARMV7_COUNTER0; idx <= armpmu->num_events; ++idx) { 1145 if (!test_and_set_bit(idx, cpuc->used_mask)) 1146 return idx; 1147 } 1148 1149 /* The counters are all in use. */ 1150 return -EAGAIN; 1151 } 1152 } 1153 1154 static void armv7pmu_reset(void *info) 1155 { 1156 u32 idx, nb_cnt = armpmu->num_events; 1157 1158 /* The counter and interrupt enable registers are unknown at reset. */ 1159 for (idx = 1; idx < nb_cnt; ++idx) 1160 armv7pmu_disable_event(NULL, idx); 1161 1162 /* Initialize & Reset PMNC: C and P bits */ 1163 armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C); 1164 } 1165 1166 static struct arm_pmu armv7pmu = { 1167 .handle_irq = armv7pmu_handle_irq, 1168 .enable = armv7pmu_enable_event, 1169 .disable = armv7pmu_disable_event, 1170 .read_counter = armv7pmu_read_counter, 1171 .write_counter = armv7pmu_write_counter, 1172 .get_event_idx = armv7pmu_get_event_idx, 1173 .start = armv7pmu_start, 1174 .stop = armv7pmu_stop, 1175 .reset = armv7pmu_reset, 1176 .raw_event_mask = 0xFF, 1177 .max_period = (1LLU << 32) - 1, 1178 }; 1179 1180 static u32 __init armv7_read_num_pmnc_events(void) 1181 { 1182 u32 nb_cnt; 1183 1184 /* Read the nb of CNTx counters supported from PMNC */ 1185 nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK; 1186 1187 /* Add the CPU cycles counter and return */ 1188 return nb_cnt + 1; 1189 } 1190 1191 static const struct arm_pmu *__init armv7_a8_pmu_init(void) 1192 { 1193 armv7pmu.id = ARM_PERF_PMU_ID_CA8; 1194 armv7pmu.name = "ARMv7 Cortex-A8"; 1195 armv7pmu.cache_map = &armv7_a8_perf_cache_map; 1196 armv7pmu.event_map = &armv7_a8_perf_map; 1197 armv7pmu.num_events = armv7_read_num_pmnc_events(); 1198 return &armv7pmu; 1199 } 1200 1201 static const struct arm_pmu *__init armv7_a9_pmu_init(void) 1202 { 1203 armv7pmu.id = ARM_PERF_PMU_ID_CA9; 1204 armv7pmu.name = "ARMv7 Cortex-A9"; 1205 armv7pmu.cache_map = &armv7_a9_perf_cache_map; 1206 armv7pmu.event_map = &armv7_a9_perf_map; 1207 armv7pmu.num_events = armv7_read_num_pmnc_events(); 1208 return &armv7pmu; 1209 } 1210 1211 static const struct arm_pmu *__init armv7_a5_pmu_init(void) 1212 { 1213 armv7pmu.id = ARM_PERF_PMU_ID_CA5; 1214 armv7pmu.name = "ARMv7 Cortex-A5"; 1215 armv7pmu.cache_map = &armv7_a5_perf_cache_map; 1216 armv7pmu.event_map = &armv7_a5_perf_map; 1217 armv7pmu.num_events = armv7_read_num_pmnc_events(); 1218 return &armv7pmu; 1219 } 1220 1221 static const struct arm_pmu *__init armv7_a15_pmu_init(void) 1222 { 1223 armv7pmu.id = ARM_PERF_PMU_ID_CA15; 1224 armv7pmu.name = "ARMv7 Cortex-A15"; 1225 armv7pmu.cache_map = &armv7_a15_perf_cache_map; 1226 armv7pmu.event_map = &armv7_a15_perf_map; 1227 armv7pmu.num_events = armv7_read_num_pmnc_events(); 1228 return &armv7pmu; 1229 } 1230 #else 1231 static const struct arm_pmu *__init armv7_a8_pmu_init(void) 1232 { 1233 return NULL; 1234 } 1235 1236 static const struct arm_pmu *__init armv7_a9_pmu_init(void) 1237 { 1238 return NULL; 1239 } 1240 1241 static const struct arm_pmu *__init armv7_a5_pmu_init(void) 1242 { 1243 return NULL; 1244 } 1245 1246 static const struct arm_pmu *__init armv7_a15_pmu_init(void) 1247 { 1248 return NULL; 1249 } 1250 #endif /* CONFIG_CPU_V7 */ 1251