perf_event_v7.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  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. #ifdef CONFIG_CPU_V7
  19. /* Common ARMv7 event types */
  20. enum armv7_perf_types {
  21. ARMV7_PERFCTR_PMNC_SW_INCR = 0x00,
  22. ARMV7_PERFCTR_IFETCH_MISS = 0x01,
  23. ARMV7_PERFCTR_ITLB_MISS = 0x02,
  24. ARMV7_PERFCTR_DCACHE_REFILL = 0x03,
  25. ARMV7_PERFCTR_DCACHE_ACCESS = 0x04,
  26. ARMV7_PERFCTR_DTLB_REFILL = 0x05,
  27. ARMV7_PERFCTR_DREAD = 0x06,
  28. ARMV7_PERFCTR_DWRITE = 0x07,
  29. ARMV7_PERFCTR_EXC_TAKEN = 0x09,
  30. ARMV7_PERFCTR_EXC_EXECUTED = 0x0A,
  31. ARMV7_PERFCTR_CID_WRITE = 0x0B,
  32. /* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
  33. * It counts:
  34. * - all branch instructions,
  35. * - instructions that explicitly write the PC,
  36. * - exception generating instructions.
  37. */
  38. ARMV7_PERFCTR_PC_WRITE = 0x0C,
  39. ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
  40. ARMV7_PERFCTR_UNALIGNED_ACCESS = 0x0F,
  41. ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
  42. ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
  43. ARMV7_PERFCTR_PC_BRANCH_MIS_USED = 0x12,
  44. ARMV7_PERFCTR_CPU_CYCLES = 0xFF
  45. };
  46. /* ARMv7 Cortex-A8 specific event types */
  47. enum armv7_a8_perf_types {
  48. ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
  49. ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
  50. ARMV7_PERFCTR_WRITE_BUFFER_FULL = 0x40,
  51. ARMV7_PERFCTR_L2_STORE_MERGED = 0x41,
  52. ARMV7_PERFCTR_L2_STORE_BUFF = 0x42,
  53. ARMV7_PERFCTR_L2_ACCESS = 0x43,
  54. ARMV7_PERFCTR_L2_CACH_MISS = 0x44,
  55. ARMV7_PERFCTR_AXI_READ_CYCLES = 0x45,
  56. ARMV7_PERFCTR_AXI_WRITE_CYCLES = 0x46,
  57. ARMV7_PERFCTR_MEMORY_REPLAY = 0x47,
  58. ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY = 0x48,
  59. ARMV7_PERFCTR_L1_DATA_MISS = 0x49,
  60. ARMV7_PERFCTR_L1_INST_MISS = 0x4A,
  61. ARMV7_PERFCTR_L1_DATA_COLORING = 0x4B,
  62. ARMV7_PERFCTR_L1_NEON_DATA = 0x4C,
  63. ARMV7_PERFCTR_L1_NEON_CACH_DATA = 0x4D,
  64. ARMV7_PERFCTR_L2_NEON = 0x4E,
  65. ARMV7_PERFCTR_L2_NEON_HIT = 0x4F,
  66. ARMV7_PERFCTR_L1_INST = 0x50,
  67. ARMV7_PERFCTR_PC_RETURN_MIS_PRED = 0x51,
  68. ARMV7_PERFCTR_PC_BRANCH_FAILED = 0x52,
  69. ARMV7_PERFCTR_PC_BRANCH_TAKEN = 0x53,
  70. ARMV7_PERFCTR_PC_BRANCH_EXECUTED = 0x54,
  71. ARMV7_PERFCTR_OP_EXECUTED = 0x55,
  72. ARMV7_PERFCTR_CYCLES_INST_STALL = 0x56,
  73. ARMV7_PERFCTR_CYCLES_INST = 0x57,
  74. ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL = 0x58,
  75. ARMV7_PERFCTR_CYCLES_NEON_INST_STALL = 0x59,
  76. ARMV7_PERFCTR_NEON_CYCLES = 0x5A,
  77. ARMV7_PERFCTR_PMU0_EVENTS = 0x70,
  78. ARMV7_PERFCTR_PMU1_EVENTS = 0x71,
  79. ARMV7_PERFCTR_PMU_EVENTS = 0x72,
  80. };
  81. /* ARMv7 Cortex-A9 specific event types */
  82. enum armv7_a9_perf_types {
  83. ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC = 0x40,
  84. ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC = 0x41,
  85. ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC = 0x42,
  86. ARMV7_PERFCTR_COHERENT_LINE_MISS = 0x50,
  87. ARMV7_PERFCTR_COHERENT_LINE_HIT = 0x51,
  88. ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES = 0x60,
  89. ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES = 0x61,
  90. ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES = 0x62,
  91. ARMV7_PERFCTR_STREX_EXECUTED_PASSED = 0x63,
  92. ARMV7_PERFCTR_STREX_EXECUTED_FAILED = 0x64,
  93. ARMV7_PERFCTR_DATA_EVICTION = 0x65,
  94. ARMV7_PERFCTR_ISSUE_STAGE_NO_INST = 0x66,
  95. ARMV7_PERFCTR_ISSUE_STAGE_EMPTY = 0x67,
  96. ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE = 0x68,
  97. ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS = 0x6E,
  98. ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST = 0x70,
  99. ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST = 0x71,
  100. ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST = 0x72,
  101. ARMV7_PERFCTR_FP_EXECUTED_INST = 0x73,
  102. ARMV7_PERFCTR_NEON_EXECUTED_INST = 0x74,
  103. ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES = 0x80,
  104. ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES = 0x81,
  105. ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES = 0x82,
  106. ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES = 0x83,
  107. ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES = 0x84,
  108. ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES = 0x85,
  109. ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES = 0x86,
  110. ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES = 0x8A,
  111. ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES = 0x8B,
  112. ARMV7_PERFCTR_ISB_INST = 0x90,
  113. ARMV7_PERFCTR_DSB_INST = 0x91,
  114. ARMV7_PERFCTR_DMB_INST = 0x92,
  115. ARMV7_PERFCTR_EXT_INTERRUPTS = 0x93,
  116. ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED = 0xA0,
  117. ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED = 0xA1,
  118. ARMV7_PERFCTR_PLE_FIFO_FLUSH = 0xA2,
  119. ARMV7_PERFCTR_PLE_RQST_COMPLETED = 0xA3,
  120. ARMV7_PERFCTR_PLE_FIFO_OVERFLOW = 0xA4,
  121. ARMV7_PERFCTR_PLE_RQST_PROG = 0xA5
  122. };
  123. /*
  124. * Cortex-A8 HW events mapping
  125. *
  126. * The hardware events that we support. We do support cache operations but
  127. * we have harvard caches and no way to combine instruction and data
  128. * accesses/misses in hardware.
  129. */
  130. static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
  131. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  132. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  133. [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
  134. [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
  135. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
  136. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  137. [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
  138. };
  139. static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  140. [PERF_COUNT_HW_CACHE_OP_MAX]
  141. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  142. [C(L1D)] = {
  143. /*
  144. * The performance counters don't differentiate between read
  145. * and write accesses/misses so this isn't strictly correct,
  146. * but it's the best we can do. Writes and reads get
  147. * combined.
  148. */
  149. [C(OP_READ)] = {
  150. [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
  151. [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
  152. },
  153. [C(OP_WRITE)] = {
  154. [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
  155. [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
  156. },
  157. [C(OP_PREFETCH)] = {
  158. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  159. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  160. },
  161. },
  162. [C(L1I)] = {
  163. [C(OP_READ)] = {
  164. [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST,
  165. [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS,
  166. },
  167. [C(OP_WRITE)] = {
  168. [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST,
  169. [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS,
  170. },
  171. [C(OP_PREFETCH)] = {
  172. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  173. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  174. },
  175. },
  176. [C(LL)] = {
  177. [C(OP_READ)] = {
  178. [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS,
  179. [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS,
  180. },
  181. [C(OP_WRITE)] = {
  182. [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS,
  183. [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS,
  184. },
  185. [C(OP_PREFETCH)] = {
  186. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  187. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  188. },
  189. },
  190. [C(DTLB)] = {
  191. /*
  192. * Only ITLB misses and DTLB refills are supported.
  193. * If users want the DTLB refills misses a raw counter
  194. * must be used.
  195. */
  196. [C(OP_READ)] = {
  197. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  198. [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  199. },
  200. [C(OP_WRITE)] = {
  201. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  202. [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  203. },
  204. [C(OP_PREFETCH)] = {
  205. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  206. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  207. },
  208. },
  209. [C(ITLB)] = {
  210. [C(OP_READ)] = {
  211. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  212. [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
  213. },
  214. [C(OP_WRITE)] = {
  215. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  216. [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
  217. },
  218. [C(OP_PREFETCH)] = {
  219. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  220. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  221. },
  222. },
  223. [C(BPU)] = {
  224. [C(OP_READ)] = {
  225. [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
  226. [C(RESULT_MISS)]
  227. = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  228. },
  229. [C(OP_WRITE)] = {
  230. [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
  231. [C(RESULT_MISS)]
  232. = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  233. },
  234. [C(OP_PREFETCH)] = {
  235. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  236. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  237. },
  238. },
  239. [C(NODE)] = {
  240. [C(OP_READ)] = {
  241. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  242. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  243. },
  244. [C(OP_WRITE)] = {
  245. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  246. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  247. },
  248. [C(OP_PREFETCH)] = {
  249. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  250. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  251. },
  252. },
  253. };
  254. /*
  255. * Cortex-A9 HW events mapping
  256. */
  257. static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
  258. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  259. [PERF_COUNT_HW_INSTRUCTIONS] =
  260. ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE,
  261. [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_COHERENT_LINE_HIT,
  262. [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_COHERENT_LINE_MISS,
  263. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
  264. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  265. [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
  266. };
  267. static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  268. [PERF_COUNT_HW_CACHE_OP_MAX]
  269. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  270. [C(L1D)] = {
  271. /*
  272. * The performance counters don't differentiate between read
  273. * and write accesses/misses so this isn't strictly correct,
  274. * but it's the best we can do. Writes and reads get
  275. * combined.
  276. */
  277. [C(OP_READ)] = {
  278. [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
  279. [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
  280. },
  281. [C(OP_WRITE)] = {
  282. [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
  283. [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
  284. },
  285. [C(OP_PREFETCH)] = {
  286. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  287. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  288. },
  289. },
  290. [C(L1I)] = {
  291. [C(OP_READ)] = {
  292. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  293. [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
  294. },
  295. [C(OP_WRITE)] = {
  296. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  297. [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
  298. },
  299. [C(OP_PREFETCH)] = {
  300. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  301. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  302. },
  303. },
  304. [C(LL)] = {
  305. [C(OP_READ)] = {
  306. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  307. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  308. },
  309. [C(OP_WRITE)] = {
  310. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  311. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  312. },
  313. [C(OP_PREFETCH)] = {
  314. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  315. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  316. },
  317. },
  318. [C(DTLB)] = {
  319. /*
  320. * Only ITLB misses and DTLB refills are supported.
  321. * If users want the DTLB refills misses a raw counter
  322. * must be used.
  323. */
  324. [C(OP_READ)] = {
  325. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  326. [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  327. },
  328. [C(OP_WRITE)] = {
  329. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  330. [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  331. },
  332. [C(OP_PREFETCH)] = {
  333. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  334. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  335. },
  336. },
  337. [C(ITLB)] = {
  338. [C(OP_READ)] = {
  339. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  340. [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
  341. },
  342. [C(OP_WRITE)] = {
  343. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  344. [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
  345. },
  346. [C(OP_PREFETCH)] = {
  347. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  348. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  349. },
  350. },
  351. [C(BPU)] = {
  352. [C(OP_READ)] = {
  353. [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
  354. [C(RESULT_MISS)]
  355. = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  356. },
  357. [C(OP_WRITE)] = {
  358. [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
  359. [C(RESULT_MISS)]
  360. = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  361. },
  362. [C(OP_PREFETCH)] = {
  363. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  364. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  365. },
  366. },
  367. [C(NODE)] = {
  368. [C(OP_READ)] = {
  369. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  370. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  371. },
  372. [C(OP_WRITE)] = {
  373. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  374. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  375. },
  376. [C(OP_PREFETCH)] = {
  377. [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
  378. [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
  379. },
  380. },
  381. };
  382. /*
  383. * Perf Events counters
  384. */
  385. enum armv7_counters {
  386. ARMV7_CYCLE_COUNTER = 1, /* Cycle counter */
  387. ARMV7_COUNTER0 = 2, /* First event counter */
  388. };
  389. /*
  390. * The cycle counter is ARMV7_CYCLE_COUNTER.
  391. * The first event counter is ARMV7_COUNTER0.
  392. * The last event counter is (ARMV7_COUNTER0 + armpmu->num_events - 1).
  393. */
  394. #define ARMV7_COUNTER_LAST (ARMV7_COUNTER0 + armpmu->num_events - 1)
  395. /*
  396. * ARMv7 low level PMNC access
  397. */
  398. /*
  399. * Per-CPU PMNC: config reg
  400. */
  401. #define ARMV7_PMNC_E (1 << 0) /* Enable all counters */
  402. #define ARMV7_PMNC_P (1 << 1) /* Reset all counters */
  403. #define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */
  404. #define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
  405. #define ARMV7_PMNC_X (1 << 4) /* Export to ETM */
  406. #define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
  407. #define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */
  408. #define ARMV7_PMNC_N_MASK 0x1f
  409. #define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */
  410. /*
  411. * Available counters
  412. */
  413. #define ARMV7_CNT0 0 /* First event counter */
  414. #define ARMV7_CCNT 31 /* Cycle counter */
  415. /* Perf Event to low level counters mapping */
  416. #define ARMV7_EVENT_CNT_TO_CNTx (ARMV7_COUNTER0 - ARMV7_CNT0)
  417. /*
  418. * CNTENS: counters enable reg
  419. */
  420. #define ARMV7_CNTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
  421. #define ARMV7_CNTENS_C (1 << ARMV7_CCNT)
  422. /*
  423. * CNTENC: counters disable reg
  424. */
  425. #define ARMV7_CNTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
  426. #define ARMV7_CNTENC_C (1 << ARMV7_CCNT)
  427. /*
  428. * INTENS: counters overflow interrupt enable reg
  429. */
  430. #define ARMV7_INTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
  431. #define ARMV7_INTENS_C (1 << ARMV7_CCNT)
  432. /*
  433. * INTENC: counters overflow interrupt disable reg
  434. */
  435. #define ARMV7_INTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
  436. #define ARMV7_INTENC_C (1 << ARMV7_CCNT)
  437. /*
  438. * EVTSEL: Event selection reg
  439. */
  440. #define ARMV7_EVTSEL_MASK 0xff /* Mask for writable bits */
  441. /*
  442. * SELECT: Counter selection reg
  443. */
  444. #define ARMV7_SELECT_MASK 0x1f /* Mask for writable bits */
  445. /*
  446. * FLAG: counters overflow flag status reg
  447. */
  448. #define ARMV7_FLAG_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
  449. #define ARMV7_FLAG_C (1 << ARMV7_CCNT)
  450. #define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */
  451. #define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK
  452. static inline unsigned long armv7_pmnc_read(void)
  453. {
  454. u32 val;
  455. asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
  456. return val;
  457. }
  458. static inline void armv7_pmnc_write(unsigned long val)
  459. {
  460. val &= ARMV7_PMNC_MASK;
  461. isb();
  462. asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
  463. }
  464. static inline int armv7_pmnc_has_overflowed(unsigned long pmnc)
  465. {
  466. return pmnc & ARMV7_OVERFLOWED_MASK;
  467. }
  468. static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc,
  469. enum armv7_counters counter)
  470. {
  471. int ret = 0;
  472. if (counter == ARMV7_CYCLE_COUNTER)
  473. ret = pmnc & ARMV7_FLAG_C;
  474. else if ((counter >= ARMV7_COUNTER0) && (counter <= ARMV7_COUNTER_LAST))
  475. ret = pmnc & ARMV7_FLAG_P(counter);
  476. else
  477. pr_err("CPU%u checking wrong counter %d overflow status\n",
  478. smp_processor_id(), counter);
  479. return ret;
  480. }
  481. static inline int armv7_pmnc_select_counter(unsigned int idx)
  482. {
  483. u32 val;
  484. if ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST)) {
  485. pr_err("CPU%u selecting wrong PMNC counter"
  486. " %d\n", smp_processor_id(), idx);
  487. return -1;
  488. }
  489. val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK;
  490. asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
  491. isb();
  492. return idx;
  493. }
  494. static inline u32 armv7pmu_read_counter(int idx)
  495. {
  496. unsigned long value = 0;
  497. if (idx == ARMV7_CYCLE_COUNTER)
  498. asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
  499. else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
  500. if (armv7_pmnc_select_counter(idx) == idx)
  501. asm volatile("mrc p15, 0, %0, c9, c13, 2"
  502. : "=r" (value));
  503. } else
  504. pr_err("CPU%u reading wrong counter %d\n",
  505. smp_processor_id(), idx);
  506. return value;
  507. }
  508. static inline void armv7pmu_write_counter(int idx, u32 value)
  509. {
  510. if (idx == ARMV7_CYCLE_COUNTER)
  511. asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
  512. else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
  513. if (armv7_pmnc_select_counter(idx) == idx)
  514. asm volatile("mcr p15, 0, %0, c9, c13, 2"
  515. : : "r" (value));
  516. } else
  517. pr_err("CPU%u writing wrong counter %d\n",
  518. smp_processor_id(), idx);
  519. }
  520. static inline void armv7_pmnc_write_evtsel(unsigned int idx, u32 val)
  521. {
  522. if (armv7_pmnc_select_counter(idx) == idx) {
  523. val &= ARMV7_EVTSEL_MASK;
  524. asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
  525. }
  526. }
  527. static inline u32 armv7_pmnc_enable_counter(unsigned int idx)
  528. {
  529. u32 val;
  530. if ((idx != ARMV7_CYCLE_COUNTER) &&
  531. ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
  532. pr_err("CPU%u enabling wrong PMNC counter"
  533. " %d\n", smp_processor_id(), idx);
  534. return -1;
  535. }
  536. if (idx == ARMV7_CYCLE_COUNTER)
  537. val = ARMV7_CNTENS_C;
  538. else
  539. val = ARMV7_CNTENS_P(idx);
  540. asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
  541. return idx;
  542. }
  543. static inline u32 armv7_pmnc_disable_counter(unsigned int idx)
  544. {
  545. u32 val;
  546. if ((idx != ARMV7_CYCLE_COUNTER) &&
  547. ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
  548. pr_err("CPU%u disabling wrong PMNC counter"
  549. " %d\n", smp_processor_id(), idx);
  550. return -1;
  551. }
  552. if (idx == ARMV7_CYCLE_COUNTER)
  553. val = ARMV7_CNTENC_C;
  554. else
  555. val = ARMV7_CNTENC_P(idx);
  556. asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
  557. return idx;
  558. }
  559. static inline u32 armv7_pmnc_enable_intens(unsigned int idx)
  560. {
  561. u32 val;
  562. if ((idx != ARMV7_CYCLE_COUNTER) &&
  563. ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
  564. pr_err("CPU%u enabling wrong PMNC counter"
  565. " interrupt enable %d\n", smp_processor_id(), idx);
  566. return -1;
  567. }
  568. if (idx == ARMV7_CYCLE_COUNTER)
  569. val = ARMV7_INTENS_C;
  570. else
  571. val = ARMV7_INTENS_P(idx);
  572. asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val));
  573. return idx;
  574. }
  575. static inline u32 armv7_pmnc_disable_intens(unsigned int idx)
  576. {
  577. u32 val;
  578. if ((idx != ARMV7_CYCLE_COUNTER) &&
  579. ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
  580. pr_err("CPU%u disabling wrong PMNC counter"
  581. " interrupt enable %d\n", smp_processor_id(), idx);
  582. return -1;
  583. }
  584. if (idx == ARMV7_CYCLE_COUNTER)
  585. val = ARMV7_INTENC_C;
  586. else
  587. val = ARMV7_INTENC_P(idx);
  588. asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val));
  589. return idx;
  590. }
  591. static inline u32 armv7_pmnc_getreset_flags(void)
  592. {
  593. u32 val;
  594. /* Read */
  595. asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
  596. /* Write to clear flags */
  597. val &= ARMV7_FLAG_MASK;
  598. asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
  599. return val;
  600. }
  601. #ifdef DEBUG
  602. static void armv7_pmnc_dump_regs(void)
  603. {
  604. u32 val;
  605. unsigned int cnt;
  606. printk(KERN_INFO "PMNC registers dump:\n");
  607. asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
  608. printk(KERN_INFO "PMNC =0x%08x\n", val);
  609. asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
  610. printk(KERN_INFO "CNTENS=0x%08x\n", val);
  611. asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
  612. printk(KERN_INFO "INTENS=0x%08x\n", val);
  613. asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
  614. printk(KERN_INFO "FLAGS =0x%08x\n", val);
  615. asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
  616. printk(KERN_INFO "SELECT=0x%08x\n", val);
  617. asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
  618. printk(KERN_INFO "CCNT =0x%08x\n", val);
  619. for (cnt = ARMV7_COUNTER0; cnt < ARMV7_COUNTER_LAST; cnt++) {
  620. armv7_pmnc_select_counter(cnt);
  621. asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
  622. printk(KERN_INFO "CNT[%d] count =0x%08x\n",
  623. cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
  624. asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
  625. printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n",
  626. cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
  627. }
  628. }
  629. #endif
  630. static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)
  631. {
  632. unsigned long flags;
  633. /*
  634. * Enable counter and interrupt, and set the counter to count
  635. * the event that we're interested in.
  636. */
  637. raw_spin_lock_irqsave(&pmu_lock, flags);
  638. /*
  639. * Disable counter
  640. */
  641. armv7_pmnc_disable_counter(idx);
  642. /*
  643. * Set event (if destined for PMNx counters)
  644. * We don't need to set the event if it's a cycle count
  645. */
  646. if (idx != ARMV7_CYCLE_COUNTER)
  647. armv7_pmnc_write_evtsel(idx, hwc->config_base);
  648. /*
  649. * Enable interrupt for this counter
  650. */
  651. armv7_pmnc_enable_intens(idx);
  652. /*
  653. * Enable counter
  654. */
  655. armv7_pmnc_enable_counter(idx);
  656. raw_spin_unlock_irqrestore(&pmu_lock, flags);
  657. }
  658. static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx)
  659. {
  660. unsigned long flags;
  661. /*
  662. * Disable counter and interrupt
  663. */
  664. raw_spin_lock_irqsave(&pmu_lock, flags);
  665. /*
  666. * Disable counter
  667. */
  668. armv7_pmnc_disable_counter(idx);
  669. /*
  670. * Disable interrupt for this counter
  671. */
  672. armv7_pmnc_disable_intens(idx);
  673. raw_spin_unlock_irqrestore(&pmu_lock, flags);
  674. }
  675. static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
  676. {
  677. unsigned long pmnc;
  678. struct perf_sample_data data;
  679. struct cpu_hw_events *cpuc;
  680. struct pt_regs *regs;
  681. int idx;
  682. /*
  683. * Get and reset the IRQ flags
  684. */
  685. pmnc = armv7_pmnc_getreset_flags();
  686. /*
  687. * Did an overflow occur?
  688. */
  689. if (!armv7_pmnc_has_overflowed(pmnc))
  690. return IRQ_NONE;
  691. /*
  692. * Handle the counter(s) overflow(s)
  693. */
  694. regs = get_irq_regs();
  695. perf_sample_data_init(&data, 0);
  696. cpuc = &__get_cpu_var(cpu_hw_events);
  697. for (idx = 0; idx <= armpmu->num_events; ++idx) {
  698. struct perf_event *event = cpuc->events[idx];
  699. struct hw_perf_event *hwc;
  700. if (!test_bit(idx, cpuc->active_mask))
  701. continue;
  702. /*
  703. * We have a single interrupt for all counters. Check that
  704. * each counter has overflowed before we process it.
  705. */
  706. if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
  707. continue;
  708. hwc = &event->hw;
  709. armpmu_event_update(event, hwc, idx, 1);
  710. data.period = event->hw.last_period;
  711. if (!armpmu_event_set_period(event, hwc, idx))
  712. continue;
  713. if (perf_event_overflow(event, &data, regs))
  714. armpmu->disable(hwc, idx);
  715. }
  716. /*
  717. * Handle the pending perf events.
  718. *
  719. * Note: this call *must* be run with interrupts disabled. For
  720. * platforms that can have the PMU interrupts raised as an NMI, this
  721. * will not work.
  722. */
  723. irq_work_run();
  724. return IRQ_HANDLED;
  725. }
  726. static void armv7pmu_start(void)
  727. {
  728. unsigned long flags;
  729. raw_spin_lock_irqsave(&pmu_lock, flags);
  730. /* Enable all counters */
  731. armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
  732. raw_spin_unlock_irqrestore(&pmu_lock, flags);
  733. }
  734. static void armv7pmu_stop(void)
  735. {
  736. unsigned long flags;
  737. raw_spin_lock_irqsave(&pmu_lock, flags);
  738. /* Disable all counters */
  739. armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
  740. raw_spin_unlock_irqrestore(&pmu_lock, flags);
  741. }
  742. static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc,
  743. struct hw_perf_event *event)
  744. {
  745. int idx;
  746. /* Always place a cycle counter into the cycle counter. */
  747. if (event->config_base == ARMV7_PERFCTR_CPU_CYCLES) {
  748. if (test_and_set_bit(ARMV7_CYCLE_COUNTER, cpuc->used_mask))
  749. return -EAGAIN;
  750. return ARMV7_CYCLE_COUNTER;
  751. } else {
  752. /*
  753. * For anything other than a cycle counter, try and use
  754. * the events counters
  755. */
  756. for (idx = ARMV7_COUNTER0; idx <= armpmu->num_events; ++idx) {
  757. if (!test_and_set_bit(idx, cpuc->used_mask))
  758. return idx;
  759. }
  760. /* The counters are all in use. */
  761. return -EAGAIN;
  762. }
  763. }
  764. static void armv7pmu_reset(void *info)
  765. {
  766. u32 idx, nb_cnt = armpmu->num_events;
  767. /* The counter and interrupt enable registers are unknown at reset. */
  768. for (idx = 1; idx < nb_cnt; ++idx)
  769. armv7pmu_disable_event(NULL, idx);
  770. /* Initialize & Reset PMNC: C and P bits */
  771. armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
  772. }
  773. static struct arm_pmu armv7pmu = {
  774. .handle_irq = armv7pmu_handle_irq,
  775. .enable = armv7pmu_enable_event,
  776. .disable = armv7pmu_disable_event,
  777. .read_counter = armv7pmu_read_counter,
  778. .write_counter = armv7pmu_write_counter,
  779. .get_event_idx = armv7pmu_get_event_idx,
  780. .start = armv7pmu_start,
  781. .stop = armv7pmu_stop,
  782. .reset = armv7pmu_reset,
  783. .raw_event_mask = 0xFF,
  784. .max_period = (1LLU << 32) - 1,
  785. };
  786. static u32 __init armv7_read_num_pmnc_events(void)
  787. {
  788. u32 nb_cnt;
  789. /* Read the nb of CNTx counters supported from PMNC */
  790. nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
  791. /* Add the CPU cycles counter and return */
  792. return nb_cnt + 1;
  793. }
  794. static const struct arm_pmu *__init armv7_a8_pmu_init(void)
  795. {
  796. armv7pmu.id = ARM_PERF_PMU_ID_CA8;
  797. armv7pmu.name = "ARMv7 Cortex-A8";
  798. armv7pmu.cache_map = &armv7_a8_perf_cache_map;
  799. armv7pmu.event_map = &armv7_a8_perf_map;
  800. armv7pmu.num_events = armv7_read_num_pmnc_events();
  801. return &armv7pmu;
  802. }
  803. static const struct arm_pmu *__init armv7_a9_pmu_init(void)
  804. {
  805. armv7pmu.id = ARM_PERF_PMU_ID_CA9;
  806. armv7pmu.name = "ARMv7 Cortex-A9";
  807. armv7pmu.cache_map = &armv7_a9_perf_cache_map;
  808. armv7pmu.event_map = &armv7_a9_perf_map;
  809. armv7pmu.num_events = armv7_read_num_pmnc_events();
  810. return &armv7pmu;
  811. }
  812. #else
  813. static const struct arm_pmu *__init armv7_a8_pmu_init(void)
  814. {
  815. return NULL;
  816. }
  817. static const struct arm_pmu *__init armv7_a9_pmu_init(void)
  818. {
  819. return NULL;
  820. }
  821. #endif /* CONFIG_CPU_V7 */