1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2011 Justin Hibbits 5 * Copyright (c) 2005, Joseph Koshy 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 */ 30 31 #include <sys/cdefs.h> 32 #include <sys/param.h> 33 #include <sys/pmc.h> 34 #include <sys/pmckern.h> 35 #include <sys/systm.h> 36 37 #include <machine/pmc_mdep.h> 38 #include <machine/spr.h> 39 #include <machine/cpu.h> 40 41 #include "hwpmc_powerpc.h" 42 43 #define PPC_SET_PMC1SEL(r, x) ((r & ~(SPR_MMCR0_74XX_PMC1SEL(0x3f))) | \ 44 SPR_MMCR0_74XX_PMC1SEL(x)) 45 #define PPC_SET_PMC2SEL(r, x) ((r & ~(SPR_MMCR0_74XX_PMC2SEL(0x3f))) | \ 46 SPR_MMCR0_74XX_PMC2SEL(x)) 47 #define PPC_SET_PMC3SEL(r, x) ((r & ~(SPR_MMCR1_PMC3SEL(0x1f))) | SPR_MMCR1_PMC3SEL(x)) 48 #define PPC_SET_PMC4SEL(r, x) ((r & ~(SPR_MMCR1_PMC4SEL(0x1f))) | SPR_MMCR1_PMC4SEL(x)) 49 #define PPC_SET_PMC5SEL(r, x) ((r & ~(SPR_MMCR1_PMC5SEL(0x1f))) | SPR_MMCR1_PMC5SEL(x)) 50 #define PPC_SET_PMC6SEL(r, x) ((r & ~(SPR_MMCR1_74XX_PMC6SEL(0x3f))) | \ 51 SPR_MMCR1_74XX_PMC6SEL(x)) 52 53 /* Change this when we support more than just the 7450. */ 54 #define MPC7XXX_MAX_PMCS 6 55 56 /* 57 * Things to improve on this: 58 * - It stops (clears to 0) the PMC and resets it at every context switch 59 * currently. 60 */ 61 62 /* 63 * This should work for every 32-bit PowerPC implementation I know of (G3 and G4 64 * specifically). 65 */ 66 67 #define PPC_PMC_MASK_ALL 0x3f 68 #define PMC_POWERPC_EVENT(id, mask, number) \ 69 { .pe_event = PMC_EV_PPC7450_##id, .pe_flags = mask, .pe_code = number } 70 71 static struct pmc_ppc_event mpc7xxx_event_codes[] = { 72 PMC_POWERPC_EVENT(CYCLE,PPC_PMC_MASK_ALL, 1), 73 PMC_POWERPC_EVENT(INSTR_COMPLETED, 0x0f, 2), 74 PMC_POWERPC_EVENT(TLB_BIT_TRANSITIONS, 0x0f, 3), 75 PMC_POWERPC_EVENT(INSTR_DISPATCHED, 0x0f, 4), 76 PMC_POWERPC_EVENT(PMON_EXCEPT, 0x0f, 5), 77 PMC_POWERPC_EVENT(PMON_SIG, 0x0f, 7), 78 PMC_POWERPC_EVENT(VPU_INSTR_COMPLETED, 0x03, 8), 79 PMC_POWERPC_EVENT(VFPU_INSTR_COMPLETED, 0x03, 9), 80 PMC_POWERPC_EVENT(VIU1_INSTR_COMPLETED, 0x03, 10), 81 PMC_POWERPC_EVENT(VIU2_INSTR_COMPLETED, 0x03, 11), 82 PMC_POWERPC_EVENT(MTVSCR_INSTR_COMPLETED, 0x03, 12), 83 PMC_POWERPC_EVENT(MTVRSAVE_INSTR_COMPLETED, 0x03, 13), 84 PMC_POWERPC_EVENT(VPU_INSTR_WAIT_CYCLES, 0x03, 14), 85 PMC_POWERPC_EVENT(VFPU_INSTR_WAIT_CYCLES, 0x03, 15), 86 PMC_POWERPC_EVENT(VIU1_INSTR_WAIT_CYCLES, 0x03, 16), 87 PMC_POWERPC_EVENT(VIU2_INSTR_WAIT_CYCLES, 0x03, 17), 88 PMC_POWERPC_EVENT(MFVSCR_SYNC_CYCLES, 0x03, 18), 89 PMC_POWERPC_EVENT(VSCR_SAT_SET, 0x03, 19), 90 PMC_POWERPC_EVENT(STORE_INSTR_COMPLETED, 0x03, 20), 91 PMC_POWERPC_EVENT(L1_INSTR_CACHE_MISSES, 0x03, 21), 92 PMC_POWERPC_EVENT(L1_DATA_SNOOPS, 0x03, 22), 93 PMC_POWERPC_EVENT(UNRESOLVED_BRANCHES, 0x01, 23), 94 PMC_POWERPC_EVENT(SPEC_BUFFER_CYCLES, 0x01, 24), 95 PMC_POWERPC_EVENT(BRANCH_UNIT_STALL_CYCLES, 0x01, 25), 96 PMC_POWERPC_EVENT(TRUE_BRANCH_TARGET_HITS, 0x01, 26), 97 PMC_POWERPC_EVENT(BRANCH_LINK_STAC_PREDICTED, 0x01, 27), 98 PMC_POWERPC_EVENT(GPR_ISSUE_QUEUE_DISPATCHES, 0x01, 28), 99 PMC_POWERPC_EVENT(CYCLES_THREE_INSTR_DISPATCHED, 0x01, 29), 100 PMC_POWERPC_EVENT(THRESHOLD_INSTR_QUEUE_ENTRIES_CYCLES, 0x01, 30), 101 PMC_POWERPC_EVENT(THRESHOLD_VEC_INSTR_QUEUE_ENTRIES_CYCLES, 0x01, 31), 102 PMC_POWERPC_EVENT(CYCLES_NO_COMPLETED_INSTRS, 0x01, 32), 103 PMC_POWERPC_EVENT(IU2_INSTR_COMPLETED, 0x01, 33), 104 PMC_POWERPC_EVENT(BRANCHES_COMPLETED, 0x01, 34), 105 PMC_POWERPC_EVENT(EIEIO_INSTR_COMPLETED, 0x01, 35), 106 PMC_POWERPC_EVENT(MTSPR_INSTR_COMPLETED, 0x01, 36), 107 PMC_POWERPC_EVENT(SC_INSTR_COMPLETED, 0x01, 37), 108 PMC_POWERPC_EVENT(LS_LM_COMPLETED, 0x01, 38), 109 PMC_POWERPC_EVENT(ITLB_HW_TABLE_SEARCH_CYCLES, 0x01, 39), 110 PMC_POWERPC_EVENT(DTLB_HW_SEARCH_CYCLES_OVER_THRESHOLD, 0x01, 40), 111 PMC_POWERPC_EVENT(L1_INSTR_CACHE_ACCESSES, 0x01, 41), 112 PMC_POWERPC_EVENT(INSTR_BKPT_MATCHES, 0x01, 42), 113 PMC_POWERPC_EVENT(L1_DATA_CACHE_LOAD_MISS_CYCLES_OVER_THRESHOLD, 0x01, 43), 114 PMC_POWERPC_EVENT(L1_DATA_SNOOP_HIT_ON_MODIFIED, 0x01, 44), 115 PMC_POWERPC_EVENT(LOAD_MISS_ALIAS, 0x01, 45), 116 PMC_POWERPC_EVENT(LOAD_MISS_ALIAS_ON_TOUCH, 0x01, 46), 117 PMC_POWERPC_EVENT(TOUCH_ALIAS, 0x01, 47), 118 PMC_POWERPC_EVENT(L1_DATA_SNOOP_HIT_CASTOUT_QUEUE, 0x01, 48), 119 PMC_POWERPC_EVENT(L1_DATA_SNOOP_HIT_CASTOUT, 0x01, 49), 120 PMC_POWERPC_EVENT(L1_DATA_SNOOP_HITS, 0x01, 50), 121 PMC_POWERPC_EVENT(WRITE_THROUGH_STORES, 0x01, 51), 122 PMC_POWERPC_EVENT(CACHE_INHIBITED_STORES, 0x01, 52), 123 PMC_POWERPC_EVENT(L1_DATA_LOAD_HIT, 0x01, 53), 124 PMC_POWERPC_EVENT(L1_DATA_TOUCH_HIT, 0x01, 54), 125 PMC_POWERPC_EVENT(L1_DATA_STORE_HIT, 0x01, 55), 126 PMC_POWERPC_EVENT(L1_DATA_TOTAL_HITS, 0x01, 56), 127 PMC_POWERPC_EVENT(DST_INSTR_DISPATCHED, 0x01, 57), 128 PMC_POWERPC_EVENT(REFRESHED_DSTS, 0x01, 58), 129 PMC_POWERPC_EVENT(SUCCESSFUL_DST_TABLE_SEARCHES, 0x01, 59), 130 PMC_POWERPC_EVENT(DSS_INSTR_COMPLETED, 0x01, 60), 131 PMC_POWERPC_EVENT(DST_STREAM_0_CACHE_LINE_FETCHES, 0x01, 61), 132 PMC_POWERPC_EVENT(VTQ_SUSPENDS_DUE_TO_CTX_CHANGE, 0x01, 62), 133 PMC_POWERPC_EVENT(VTQ_LINE_FETCH_HIT, 0x01, 63), 134 PMC_POWERPC_EVENT(VEC_LOAD_INSTR_COMPLETED, 0x01, 64), 135 PMC_POWERPC_EVENT(FP_STORE_INSTR_COMPLETED_IN_LSU, 0x01, 65), 136 PMC_POWERPC_EVENT(FPU_RENORMALIZATION, 0x01, 66), 137 PMC_POWERPC_EVENT(FPU_DENORMALIZATION, 0x01, 67), 138 PMC_POWERPC_EVENT(FP_STORE_CAUSES_STALL_IN_LSU, 0x01, 68), 139 PMC_POWERPC_EVENT(LD_ST_TRUE_ALIAS_STALL, 0x01, 70), 140 PMC_POWERPC_EVENT(LSU_INDEXED_ALIAS_STALL, 0x01, 71), 141 PMC_POWERPC_EVENT(LSU_ALIAS_VS_FSQ_WB0_WB1, 0x01, 72), 142 PMC_POWERPC_EVENT(LSU_ALIAS_VS_CSQ, 0x01, 73), 143 PMC_POWERPC_EVENT(LSU_LOAD_HIT_LINE_ALIAS_VS_CSQ0, 0x01, 74), 144 PMC_POWERPC_EVENT(LSU_LOAD_MISS_LINE_ALIAS_VS_CSQ0, 0x01, 75), 145 PMC_POWERPC_EVENT(LSU_TOUCH_LINE_ALIAS_VS_FSQ_WB0_WB1, 0x01, 76), 146 PMC_POWERPC_EVENT(LSU_TOUCH_ALIAS_VS_CSQ, 0x01, 77), 147 PMC_POWERPC_EVENT(LSU_LMQ_FULL_STALL, 0x01, 78), 148 PMC_POWERPC_EVENT(FP_LOAD_INSTR_COMPLETED_IN_LSU, 0x01, 79), 149 PMC_POWERPC_EVENT(FP_LOAD_SINGLE_INSTR_COMPLETED_IN_LSU, 0x01, 80), 150 PMC_POWERPC_EVENT(FP_LOAD_DOUBLE_COMPLETED_IN_LSU, 0x01, 81), 151 PMC_POWERPC_EVENT(LSU_RA_LATCH_STALL, 0x01, 82), 152 PMC_POWERPC_EVENT(LSU_LOAD_VS_STORE_QUEUE_ALIAS_STALL, 0x01, 83), 153 PMC_POWERPC_EVENT(LSU_LMQ_INDEX_ALIAS, 0x01, 84), 154 PMC_POWERPC_EVENT(LSU_STORE_QUEUE_INDEX_ALIAS, 0x01, 85), 155 PMC_POWERPC_EVENT(LSU_CSQ_FORWARDING, 0x01, 86), 156 PMC_POWERPC_EVENT(LSU_MISALIGNED_LOAD_FINISH, 0x01, 87), 157 PMC_POWERPC_EVENT(LSU_MISALIGN_STORE_COMPLETED, 0x01, 88), 158 PMC_POWERPC_EVENT(LSU_MISALIGN_STALL, 0x01, 89), 159 PMC_POWERPC_EVENT(FP_ONE_QUARTER_FPSCR_RENAMES_BUSY, 0x01, 90), 160 PMC_POWERPC_EVENT(FP_ONE_HALF_FPSCR_RENAMES_BUSY, 0x01, 91), 161 PMC_POWERPC_EVENT(FP_THREE_QUARTERS_FPSCR_RENAMES_BUSY, 0x01, 92), 162 PMC_POWERPC_EVENT(FP_ALL_FPSCR_RENAMES_BUSY, 0x01, 93), 163 PMC_POWERPC_EVENT(FP_DENORMALIZED_RESULT, 0x01, 94), 164 PMC_POWERPC_EVENT(L1_DATA_TOTAL_MISSES, 0x02, 23), 165 PMC_POWERPC_EVENT(DISPATCHES_TO_FPR_ISSUE_QUEUE, 0x02, 24), 166 PMC_POWERPC_EVENT(LSU_INSTR_COMPLETED, 0x02, 25), 167 PMC_POWERPC_EVENT(LOAD_INSTR_COMPLETED, 0x02, 26), 168 PMC_POWERPC_EVENT(SS_SM_INSTR_COMPLETED, 0x02, 27), 169 PMC_POWERPC_EVENT(TLBIE_INSTR_COMPLETED, 0x02, 28), 170 PMC_POWERPC_EVENT(LWARX_INSTR_COMPLETED, 0x02, 29), 171 PMC_POWERPC_EVENT(MFSPR_INSTR_COMPLETED, 0x02, 30), 172 PMC_POWERPC_EVENT(REFETCH_SERIALIZATION, 0x02, 31), 173 PMC_POWERPC_EVENT(COMPLETION_QUEUE_ENTRIES_OVER_THRESHOLD, 0x02, 32), 174 PMC_POWERPC_EVENT(CYCLES_ONE_INSTR_DISPATCHED, 0x02, 33), 175 PMC_POWERPC_EVENT(CYCLES_TWO_INSTR_COMPLETED, 0x02, 34), 176 PMC_POWERPC_EVENT(ITLB_NON_SPECULATIVE_MISSES, 0x02, 35), 177 PMC_POWERPC_EVENT(CYCLES_WAITING_FROM_L1_INSTR_CACHE_MISS, 0x02, 36), 178 PMC_POWERPC_EVENT(L1_DATA_LOAD_ACCESS_MISS, 0x02, 37), 179 PMC_POWERPC_EVENT(L1_DATA_TOUCH_MISS, 0x02, 38), 180 PMC_POWERPC_EVENT(L1_DATA_STORE_MISS, 0x02, 39), 181 PMC_POWERPC_EVENT(L1_DATA_TOUCH_MISS_CYCLES, 0x02, 40), 182 PMC_POWERPC_EVENT(L1_DATA_CYCLES_USED, 0x02, 41), 183 PMC_POWERPC_EVENT(DST_STREAM_1_CACHE_LINE_FETCHES, 0x02, 42), 184 PMC_POWERPC_EVENT(VTQ_STREAM_CANCELED_PREMATURELY, 0x02, 43), 185 PMC_POWERPC_EVENT(VTQ_RESUMES_DUE_TO_CTX_CHANGE, 0x02, 44), 186 PMC_POWERPC_EVENT(VTQ_LINE_FETCH_MISS, 0x02, 45), 187 PMC_POWERPC_EVENT(VTQ_LINE_FETCH, 0x02, 46), 188 PMC_POWERPC_EVENT(TLBIE_SNOOPS, 0x02, 47), 189 PMC_POWERPC_EVENT(L1_INSTR_CACHE_RELOADS, 0x02, 48), 190 PMC_POWERPC_EVENT(L1_DATA_CACHE_RELOADS, 0x02, 49), 191 PMC_POWERPC_EVENT(L1_DATA_CACHE_CASTOUTS_TO_L2, 0x02, 50), 192 PMC_POWERPC_EVENT(STORE_MERGE_GATHER, 0x02, 51), 193 PMC_POWERPC_EVENT(CACHEABLE_STORE_MERGE_TO_32_BYTES, 0x02, 52), 194 PMC_POWERPC_EVENT(DATA_BKPT_MATCHES, 0x02, 53), 195 PMC_POWERPC_EVENT(FALL_THROUGH_BRANCHES_PROCESSED, 0x02, 54), 196 PMC_POWERPC_EVENT(FIRST_SPECULATIVE_BRANCH_BUFFER_RESOLVED_CORRECTLY, 0x02, 55), 197 PMC_POWERPC_EVENT(SECOND_SPECULATION_BUFFER_ACTIVE, 0x02, 56), 198 PMC_POWERPC_EVENT(BPU_STALL_ON_LR_DEPENDENCY, 0x02, 57), 199 PMC_POWERPC_EVENT(BTIC_MISS, 0x02, 58), 200 PMC_POWERPC_EVENT(BRANCH_LINK_STACK_CORRECTLY_RESOLVED, 0x02, 59), 201 PMC_POWERPC_EVENT(FPR_ISSUE_STALLED, 0x02, 60), 202 PMC_POWERPC_EVENT(SWITCHES_BETWEEN_PRIV_USER, 0x02, 61), 203 PMC_POWERPC_EVENT(LSU_COMPLETES_FP_STORE_SINGLE, 0x02, 62), 204 PMC_POWERPC_EVENT(CYCLES_TWO_INSTR_COMPLETED, 0x04, 8), 205 PMC_POWERPC_EVENT(CYCLES_ONE_INSTR_DISPATCHED, 0x04, 9), 206 PMC_POWERPC_EVENT(VR_ISSUE_QUEUE_DISPATCHES, 0x04, 10), 207 PMC_POWERPC_EVENT(VR_STALLS, 0x04, 11), 208 PMC_POWERPC_EVENT(GPR_RENAME_BUFFER_ENTRIES_OVER_THRESHOLD, 0x04, 12), 209 PMC_POWERPC_EVENT(FPR_ISSUE_QUEUE_ENTRIES, 0x04, 13), 210 PMC_POWERPC_EVENT(FPU_INSTR_COMPLETED, 0x04, 14), 211 PMC_POWERPC_EVENT(STWCX_INSTR_COMPLETED, 0x04, 15), 212 PMC_POWERPC_EVENT(LS_LM_INSTR_PIECES, 0x04, 16), 213 PMC_POWERPC_EVENT(ITLB_HW_SEARCH_CYCLES_OVER_THRESHOLD, 0x04, 17), 214 PMC_POWERPC_EVENT(DTLB_MISSES, 0x04, 18), 215 PMC_POWERPC_EVENT(CANCELLED_L1_INSTR_CACHE_MISSES, 0x04, 19), 216 PMC_POWERPC_EVENT(L1_DATA_CACHE_OP_HIT, 0x04, 20), 217 PMC_POWERPC_EVENT(L1_DATA_LOAD_MISS_CYCLES, 0x04, 21), 218 PMC_POWERPC_EVENT(L1_DATA_PUSHES, 0x04, 22), 219 PMC_POWERPC_EVENT(L1_DATA_TOTAL_MISS, 0x04, 23), 220 PMC_POWERPC_EVENT(VT2_FETCHES, 0x04, 24), 221 PMC_POWERPC_EVENT(TAKEN_BRANCHES_PROCESSED, 0x04, 25), 222 PMC_POWERPC_EVENT(BRANCH_FLUSHES, 0x04, 26), 223 PMC_POWERPC_EVENT(SECOND_SPECULATIVE_BRANCH_BUFFER_RESOLVED_CORRECTLY, 0x04, 27), 224 PMC_POWERPC_EVENT(THIRD_SPECULATION_BUFFER_ACTIVE, 0x04, 28), 225 PMC_POWERPC_EVENT(BRANCH_UNIT_STALL_ON_CTR_DEPENDENCY, 0x04, 29), 226 PMC_POWERPC_EVENT(FAST_BTIC_HIT, 0x04, 30), 227 PMC_POWERPC_EVENT(BRANCH_LINK_STACK_MISPREDICTED, 0x04, 31), 228 PMC_POWERPC_EVENT(CYCLES_THREE_INSTR_COMPLETED, 0x08, 14), 229 PMC_POWERPC_EVENT(CYCLES_NO_INSTR_DISPATCHED, 0x08, 15), 230 PMC_POWERPC_EVENT(GPR_ISSUE_QUEUE_ENTRIES_OVER_THRESHOLD, 0x08, 16), 231 PMC_POWERPC_EVENT(GPR_ISSUE_QUEUE_STALLED, 0x08, 17), 232 PMC_POWERPC_EVENT(IU1_INSTR_COMPLETED, 0x08, 18), 233 PMC_POWERPC_EVENT(DSSALL_INSTR_COMPLETED, 0x08, 19), 234 PMC_POWERPC_EVENT(TLBSYNC_INSTR_COMPLETED, 0x08, 20), 235 PMC_POWERPC_EVENT(SYNC_INSTR_COMPLETED, 0x08, 21), 236 PMC_POWERPC_EVENT(SS_SM_INSTR_PIECES, 0x08, 22), 237 PMC_POWERPC_EVENT(DTLB_HW_SEARCH_CYCLES, 0x08, 23), 238 PMC_POWERPC_EVENT(SNOOP_RETRIES, 0x08, 24), 239 PMC_POWERPC_EVENT(SUCCESSFUL_STWCX, 0x08, 25), 240 PMC_POWERPC_EVENT(DST_STREAM_3_CACHE_LINE_FETCHES, 0x08, 26), 241 PMC_POWERPC_EVENT(THIRD_SPECULATIVE_BRANCH_BUFFER_RESOLVED_CORRECTLY, 0x08, 27), 242 PMC_POWERPC_EVENT(MISPREDICTED_BRANCHES, 0x08, 28), 243 PMC_POWERPC_EVENT(FOLDED_BRANCHES, 0x08, 29), 244 PMC_POWERPC_EVENT(FP_STORE_DOUBLE_COMPLETES_IN_LSU, 0x08, 30), 245 PMC_POWERPC_EVENT(L2_CACHE_HITS, 0x30, 2), 246 PMC_POWERPC_EVENT(L3_CACHE_HITS, 0x30, 3), 247 PMC_POWERPC_EVENT(L2_INSTR_CACHE_MISSES, 0x30, 4), 248 PMC_POWERPC_EVENT(L3_INSTR_CACHE_MISSES, 0x30, 5), 249 PMC_POWERPC_EVENT(L2_DATA_CACHE_MISSES, 0x30, 6), 250 PMC_POWERPC_EVENT(L3_DATA_CACHE_MISSES, 0x30, 7), 251 PMC_POWERPC_EVENT(L2_LOAD_HITS, 0x10, 8), 252 PMC_POWERPC_EVENT(L2_STORE_HITS, 0x10, 9), 253 PMC_POWERPC_EVENT(L3_LOAD_HITS, 0x10, 10), 254 PMC_POWERPC_EVENT(L3_STORE_HITS, 0x10, 11), 255 PMC_POWERPC_EVENT(L2_TOUCH_HITS, 0x30, 13), 256 PMC_POWERPC_EVENT(L3_TOUCH_HITS, 0x30, 14), 257 PMC_POWERPC_EVENT(SNOOP_RETRIES, 0x30, 15), 258 PMC_POWERPC_EVENT(SNOOP_MODIFIED, 0x10, 16), 259 PMC_POWERPC_EVENT(SNOOP_VALID, 0x10, 17), 260 PMC_POWERPC_EVENT(INTERVENTION, 0x30, 18), 261 PMC_POWERPC_EVENT(L2_CACHE_MISSES, 0x10, 19), 262 PMC_POWERPC_EVENT(L3_CACHE_MISSES, 0x10, 20), 263 PMC_POWERPC_EVENT(L2_CACHE_CASTOUTS, 0x20, 8), 264 PMC_POWERPC_EVENT(L3_CACHE_CASTOUTS, 0x20, 9), 265 PMC_POWERPC_EVENT(L2SQ_FULL_CYCLES, 0x20, 10), 266 PMC_POWERPC_EVENT(L3SQ_FULL_CYCLES, 0x20, 11), 267 PMC_POWERPC_EVENT(RAQ_FULL_CYCLES, 0x20, 16), 268 PMC_POWERPC_EVENT(WAQ_FULL_CYCLES, 0x20, 17), 269 PMC_POWERPC_EVENT(L1_EXTERNAL_INTERVENTIONS, 0x20, 19), 270 PMC_POWERPC_EVENT(L2_EXTERNAL_INTERVENTIONS, 0x20, 20), 271 PMC_POWERPC_EVENT(L3_EXTERNAL_INTERVENTIONS, 0x20, 21), 272 PMC_POWERPC_EVENT(EXTERNAL_INTERVENTIONS, 0x20, 22), 273 PMC_POWERPC_EVENT(EXTERNAL_PUSHES, 0x20, 23), 274 PMC_POWERPC_EVENT(EXTERNAL_SNOOP_RETRY, 0x20, 24), 275 PMC_POWERPC_EVENT(DTQ_FULL_CYCLES, 0x20, 25), 276 PMC_POWERPC_EVENT(BUS_RETRY, 0x20, 26), 277 PMC_POWERPC_EVENT(L2_VALID_REQUEST, 0x20, 27), 278 PMC_POWERPC_EVENT(BORDQ_FULL, 0x20, 28), 279 PMC_POWERPC_EVENT(BUS_TAS_FOR_READS, 0x20, 42), 280 PMC_POWERPC_EVENT(BUS_TAS_FOR_WRITES, 0x20, 43), 281 PMC_POWERPC_EVENT(BUS_READS_NOT_RETRIED, 0x20, 44), 282 PMC_POWERPC_EVENT(BUS_WRITES_NOT_RETRIED, 0x20, 45), 283 PMC_POWERPC_EVENT(BUS_READS_WRITES_NOT_RETRIED, 0x20, 46), 284 PMC_POWERPC_EVENT(BUS_RETRY_DUE_TO_L1_RETRY, 0x20, 47), 285 PMC_POWERPC_EVENT(BUS_RETRY_DUE_TO_PREVIOUS_ADJACENT, 0x20, 48), 286 PMC_POWERPC_EVENT(BUS_RETRY_DUE_TO_COLLISION, 0x20, 49), 287 PMC_POWERPC_EVENT(BUS_RETRY_DUE_TO_INTERVENTION_ORDERING, 0x20, 50), 288 PMC_POWERPC_EVENT(SNOOP_REQUESTS, 0x20, 51), 289 PMC_POWERPC_EVENT(PREFETCH_ENGINE_REQUEST, 0x20, 52), 290 PMC_POWERPC_EVENT(PREFETCH_ENGINE_COLLISION_VS_LOAD, 0x20, 53), 291 PMC_POWERPC_EVENT(PREFETCH_ENGINE_COLLISION_VS_STORE, 0x20, 54), 292 PMC_POWERPC_EVENT(PREFETCH_ENGINE_COLLISION_VS_INSTR_FETCH, 0x20, 55), 293 PMC_POWERPC_EVENT(PREFETCH_ENGINE_COLLISION_VS_LOAD_STORE_INSTR_FETCH, 0x20, 56), 294 PMC_POWERPC_EVENT(PREFETCH_ENGINE_FULL, 0x20, 57) 295 }; 296 static size_t mpc7xxx_event_codes_size = nitems(mpc7xxx_event_codes); 297 298 static pmc_value_t 299 mpc7xxx_pmcn_read(unsigned int pmc) 300 { 301 switch (pmc) { 302 case 0: 303 return (mfspr(SPR_PMC1_74XX)); 304 case 1: 305 return (mfspr(SPR_PMC2_74XX)); 306 case 2: 307 return (mfspr(SPR_PMC3_74XX)); 308 case 3: 309 return (mfspr(SPR_PMC4_74XX)); 310 case 4: 311 return (mfspr(SPR_PMC5_74XX)); 312 case 5: 313 return (mfspr(SPR_PMC6_74XX)); 314 default: 315 panic("Invalid PMC number: %d\n", pmc); 316 } 317 } 318 319 static void 320 mpc7xxx_pmcn_write(unsigned int pmc, uint32_t val) 321 { 322 switch (pmc) { 323 case 0: 324 mtspr(SPR_PMC1_74XX, val); 325 break; 326 case 1: 327 mtspr(SPR_PMC2_74XX, val); 328 break; 329 case 2: 330 mtspr(SPR_PMC3_74XX, val); 331 break; 332 case 3: 333 mtspr(SPR_PMC4_74XX, val); 334 break; 335 case 4: 336 mtspr(SPR_PMC5_74XX, val); 337 break; 338 case 5: 339 mtspr(SPR_PMC6_74XX, val); 340 break; 341 default: 342 panic("Invalid PMC number: %d\n", pmc); 343 } 344 } 345 346 static void 347 mpc7xxx_set_pmc(int cpu, int ri, int config) 348 { 349 register_t pmc_mmcr; 350 351 /* The mask is inverted (enable is 1) compared to the flags in 352 * MMCR0, which are Freeze flags. 353 */ 354 config &= ~POWERPC_PMC_ENABLE; 355 356 /* Enable/disable the PMC. */ 357 switch (ri) { 358 case 0: 359 pmc_mmcr = mfspr(SPR_MMCR0_74XX); 360 pmc_mmcr = PPC_SET_PMC1SEL(pmc_mmcr, config); 361 mtspr(SPR_MMCR0_74XX, pmc_mmcr); 362 break; 363 case 1: 364 pmc_mmcr = mfspr(SPR_MMCR0_74XX); 365 pmc_mmcr = PPC_SET_PMC2SEL(pmc_mmcr, config); 366 mtspr(SPR_MMCR0_74XX, pmc_mmcr); 367 break; 368 case 2: 369 pmc_mmcr = mfspr(SPR_MMCR1_74XX); 370 pmc_mmcr = PPC_SET_PMC3SEL(pmc_mmcr, config); 371 mtspr(SPR_MMCR1_74XX, pmc_mmcr); 372 break; 373 case 3: 374 pmc_mmcr = mfspr(SPR_MMCR0_74XX); 375 pmc_mmcr = PPC_SET_PMC4SEL(pmc_mmcr, config); 376 mtspr(SPR_MMCR0_74XX, pmc_mmcr); 377 break; 378 case 4: 379 pmc_mmcr = mfspr(SPR_MMCR1_74XX); 380 pmc_mmcr = PPC_SET_PMC5SEL(pmc_mmcr, config); 381 mtspr(SPR_MMCR1_74XX, pmc_mmcr); 382 break; 383 case 5: 384 pmc_mmcr = mfspr(SPR_MMCR1_74XX); 385 pmc_mmcr = PPC_SET_PMC6SEL(pmc_mmcr, config); 386 mtspr(SPR_MMCR1_74XX, pmc_mmcr); 387 break; 388 } 389 390 if (config != PMCN_NONE) { 391 pmc_mmcr = mfspr(SPR_MMCR0_74XX); 392 pmc_mmcr &= ~SPR_MMCR0_FC; 393 pmc_mmcr |= config; 394 mtspr(SPR_MMCR0_74XX, pmc_mmcr); 395 } 396 } 397 398 static int 399 mpc7xxx_pcpu_init(struct pmc_mdep *md, int cpu) 400 { 401 powerpc_pcpu_init(md, cpu); 402 403 /* Clear the MMCRs, and set FC, to disable all PMCs. */ 404 mtspr(SPR_MMCR0_74XX, SPR_MMCR0_FC | SPR_MMCR0_PMXE | 405 SPR_MMCR0_FCECE | SPR_MMCR0_PMC1CE | SPR_MMCR0_PMCNCE); 406 mtspr(SPR_MMCR1_74XX, 0); 407 408 return (0); 409 } 410 411 static int 412 mpc7xxx_pcpu_fini(struct pmc_mdep *md, int cpu) 413 { 414 uint32_t mmcr0 = mfspr(SPR_MMCR0_74XX); 415 416 mtmsr(mfmsr() & ~PSL_PMM); 417 mmcr0 |= SPR_MMCR0_FC; 418 mtspr(SPR_MMCR0_74XX, mmcr0); 419 420 return (powerpc_pcpu_fini(md, cpu)); 421 } 422 423 static void 424 mpc7xxx_resume_pmc(bool ie) 425 { 426 /* Re-enable PERF exceptions. */ 427 if (ie) 428 mtspr(SPR_MMCR0_74XX, 429 (mfspr(SPR_MMCR0_74XX) & ~SPR_MMCR0_FC) | SPR_MMCR0_PMXE); 430 } 431 432 int 433 pmc_mpc7xxx_initialize(struct pmc_mdep *pmc_mdep) 434 { 435 struct pmc_classdep *pcd; 436 437 pmc_mdep->pmd_cputype = PMC_CPU_PPC_7450; 438 439 pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_POWERPC]; 440 pcd->pcd_caps = POWERPC_PMC_CAPS; 441 pcd->pcd_class = PMC_CLASS_PPC7450; 442 pcd->pcd_num = MPC7XXX_MAX_PMCS; 443 pcd->pcd_ri = pmc_mdep->pmd_npmc; 444 pcd->pcd_width = 32; /* All PMCs, even in ppc970, are 32-bit */ 445 446 pcd->pcd_allocate_pmc = powerpc_allocate_pmc; 447 pcd->pcd_config_pmc = powerpc_config_pmc; 448 pcd->pcd_pcpu_fini = mpc7xxx_pcpu_fini; 449 pcd->pcd_pcpu_init = mpc7xxx_pcpu_init; 450 pcd->pcd_describe = powerpc_describe; 451 pcd->pcd_get_config = powerpc_get_config; 452 pcd->pcd_read_pmc = powerpc_read_pmc; 453 pcd->pcd_release_pmc = powerpc_release_pmc; 454 pcd->pcd_start_pmc = powerpc_start_pmc; 455 pcd->pcd_stop_pmc = powerpc_stop_pmc; 456 pcd->pcd_write_pmc = powerpc_write_pmc; 457 458 pmc_mdep->pmd_npmc += MPC7XXX_MAX_PMCS; 459 pmc_mdep->pmd_intr = powerpc_pmc_intr; 460 461 ppc_event_codes = mpc7xxx_event_codes; 462 ppc_event_codes_size = mpc7xxx_event_codes_size; 463 ppc_event_first = PMC_EV_PPC7450_FIRST; 464 ppc_event_last = PMC_EV_PPC7450_LAST; 465 ppc_max_pmcs = MPC7XXX_MAX_PMCS; 466 ppc_class = pcd->pcd_class; 467 468 powerpc_set_pmc = mpc7xxx_set_pmc; 469 powerpc_pmcn_read = mpc7xxx_pmcn_read; 470 powerpc_pmcn_write = mpc7xxx_pmcn_write; 471 powerpc_resume_pmc = mpc7xxx_resume_pmc; 472 473 return (0); 474 } 475