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