1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2013 Justin Hibbits
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 */
29
30 #include <sys/cdefs.h>
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 PPC970_MAX_PMCS 8
43 #define PMC_PPC970_FLAG_PMCS 0x000000ff
44
45 /* MMCR0, PMC1 is 8 bytes in, PMC2 is 1 byte in. */
46 #define PPC970_SET_MMCR0_PMCSEL(r, x, i) \
47 ((r & ~(0x1f << (7 * (1 - i) + 1))) | (x << (7 * (1 - i) + 1)))
48 /* MMCR1 has 6 PMC*SEL items (PMC3->PMC8), in sequence. */
49 #define PPC970_SET_MMCR1_PMCSEL(r, x, i) \
50 ((r & ~(0x1f << (5 * (7 - i) + 2))) | (x << (5 * (7 - i) + 2)))
51
52 /* How PMC works on PPC970:
53 *
54 * Any PMC can count a direct event. Indirect events are handled specially.
55 * Direct events: As published.
56 *
57 * Encoding 00 000 -- Add byte lane bit counters
58 * MMCR1[24:31] -- select bit matching PMC being an adder.
59 * Bus events:
60 * PMCxSEL: 1x -- select from byte lane: 10 == lower lane (0/1), 11 == upper
61 * lane (2/3).
62 * PMCxSEL[2:4] -- bit in the byte lane selected.
63 *
64 * PMC[1,2,5,6] == lane 0/lane 2
65 * PMC[3,4,7,8] == lane 1,3
66 *
67 *
68 * Lanes:
69 * Lane 0 -- TTM0(FPU,ISU,IFU,VPU)
70 * TTM1(IDU,ISU,STS)
71 * LSU0 byte 0
72 * LSU1 byte 0
73 * Lane 1 -- TTM0
74 * TTM1
75 * LSU0 byte 1
76 * LSU1 byte 1
77 * Lane 2 -- TTM0
78 * TTM1
79 * LSU0 byte 2
80 * LSU1 byte 2 or byte 6
81 * Lane 3 -- TTM0
82 * TTM1
83 * LSU0 byte 3
84 * LSU1 byte 3 or byte 7
85 *
86 * Adders:
87 * Add byte lane for PMC (above), bit 0+4, 1+5, 2+6, 3+7
88 */
89
90 static struct pmc_ppc_event ppc970_event_codes[] = {
91 {PMC_EV_PPC970_INSTR_COMPLETED,
92 .pe_flags = PMC_PPC970_FLAG_PMCS,
93 .pe_code = 0x09
94 },
95 {PMC_EV_PPC970_MARKED_GROUP_DISPATCH,
96 .pe_flags = PMC_FLAG_PMC1,
97 .pe_code = 0x2
98 },
99 {PMC_EV_PPC970_MARKED_STORE_COMPLETED,
100 .pe_flags = PMC_FLAG_PMC1,
101 .pe_code = 0x03
102 },
103 {PMC_EV_PPC970_GCT_EMPTY,
104 .pe_flags = PMC_FLAG_PMC1,
105 .pe_code = 0x04
106 },
107 {PMC_EV_PPC970_RUN_CYCLES,
108 .pe_flags = PMC_FLAG_PMC1,
109 .pe_code = 0x05
110 },
111 {PMC_EV_PPC970_OVERFLOW,
112 .pe_flags = PMC_PPC970_FLAG_PMCS,
113 .pe_code = 0x0a
114 },
115 {PMC_EV_PPC970_CYCLES,
116 .pe_flags = PMC_PPC970_FLAG_PMCS,
117 .pe_code = 0x0f
118 },
119 {PMC_EV_PPC970_THRESHOLD_TIMEOUT,
120 .pe_flags = PMC_FLAG_PMC2,
121 .pe_code = 0x3
122 },
123 {PMC_EV_PPC970_GROUP_DISPATCH,
124 .pe_flags = PMC_FLAG_PMC2,
125 .pe_code = 0x4
126 },
127 {PMC_EV_PPC970_BR_MARKED_INSTR_FINISH,
128 .pe_flags = PMC_FLAG_PMC2,
129 .pe_code = 0x5
130 },
131 {PMC_EV_PPC970_GCT_EMPTY_BY_SRQ_FULL,
132 .pe_flags = PMC_FLAG_PMC2,
133 .pe_code = 0xb
134 },
135 {PMC_EV_PPC970_STOP_COMPLETION,
136 .pe_flags = PMC_FLAG_PMC3,
137 .pe_code = 0x1
138 },
139 {PMC_EV_PPC970_LSU_EMPTY,
140 .pe_flags = PMC_FLAG_PMC3,
141 .pe_code = 0x2
142 },
143 {PMC_EV_PPC970_MARKED_STORE_WITH_INTR,
144 .pe_flags = PMC_FLAG_PMC3,
145 .pe_code = 0x3
146 },
147 {PMC_EV_PPC970_CYCLES_IN_SUPER,
148 .pe_flags = PMC_FLAG_PMC3,
149 .pe_code = 0x4
150 },
151 {PMC_EV_PPC970_VPU_MARKED_INSTR_COMPLETED,
152 .pe_flags = PMC_FLAG_PMC3,
153 .pe_code = 0x5
154 },
155 {PMC_EV_PPC970_FXU0_IDLE_FXU1_BUSY,
156 .pe_flags = PMC_FLAG_PMC4,
157 .pe_code = 0x2
158 },
159 {PMC_EV_PPC970_SRQ_EMPTY,
160 .pe_flags = PMC_FLAG_PMC4,
161 .pe_code = 0x3
162 },
163 {PMC_EV_PPC970_MARKED_GROUP_COMPLETED,
164 .pe_flags = PMC_FLAG_PMC4,
165 .pe_code = 0x4
166 },
167 {PMC_EV_PPC970_CR_MARKED_INSTR_FINISH,
168 .pe_flags = PMC_FLAG_PMC4,
169 .pe_code = 0x5
170 },
171 {PMC_EV_PPC970_DISPATCH_SUCCESS,
172 .pe_flags = PMC_FLAG_PMC5,
173 .pe_code = 0x1
174 },
175 {PMC_EV_PPC970_FXU0_IDLE_FXU1_IDLE,
176 .pe_flags = PMC_FLAG_PMC5,
177 .pe_code = 0x2
178 },
179 {PMC_EV_PPC970_ONE_PLUS_INSTR_COMPLETED,
180 .pe_flags = PMC_FLAG_PMC5,
181 .pe_code = 0x3
182 },
183 {PMC_EV_PPC970_GROUP_MARKED_IDU,
184 .pe_flags = PMC_FLAG_PMC5,
185 .pe_code = 0x4
186 },
187 {PMC_EV_PPC970_MARKED_GROUP_COMPLETE_TIMEOUT,
188 .pe_flags = PMC_FLAG_PMC5,
189 .pe_code = 0x5
190 },
191 {PMC_EV_PPC970_FXU0_BUSY_FXU1_BUSY,
192 .pe_flags = PMC_FLAG_PMC6,
193 .pe_code = 0x2
194 },
195 {PMC_EV_PPC970_MARKED_STORE_SENT_TO_STS,
196 .pe_flags = PMC_FLAG_PMC6,
197 .pe_code = 0x3
198 },
199 {PMC_EV_PPC970_FXU_MARKED_INSTR_FINISHED,
200 .pe_flags = PMC_FLAG_PMC6,
201 .pe_code = 0x4
202 },
203 {PMC_EV_PPC970_MARKED_GROUP_ISSUED,
204 .pe_flags = PMC_FLAG_PMC6,
205 .pe_code = 0x5
206 },
207 {PMC_EV_PPC970_FXU0_BUSY_FXU1_IDLE,
208 .pe_flags = PMC_FLAG_PMC7,
209 .pe_code = 0x2
210 },
211 {PMC_EV_PPC970_GROUP_COMPLETED,
212 .pe_flags = PMC_FLAG_PMC7,
213 .pe_code = 0x3
214 },
215 {PMC_EV_PPC970_FPU_MARKED_INSTR_COMPLETED,
216 .pe_flags = PMC_FLAG_PMC7,
217 .pe_code = 0x4
218 },
219 {PMC_EV_PPC970_MARKED_INSTR_FINISH_ANY_UNIT,
220 .pe_flags = PMC_FLAG_PMC7,
221 .pe_code = 0x5
222 },
223 {PMC_EV_PPC970_EXTERNAL_INTERRUPT,
224 .pe_flags = PMC_FLAG_PMC8,
225 .pe_code = 0x2
226 },
227 {PMC_EV_PPC970_GROUP_DISPATCH_REJECT,
228 .pe_flags = PMC_FLAG_PMC8,
229 .pe_code = 0x3
230 },
231 {PMC_EV_PPC970_LSU_MARKED_INSTR_FINISH,
232 .pe_flags = PMC_FLAG_PMC8,
233 .pe_code = 0x4
234 },
235 {PMC_EV_PPC970_TIMEBASE_EVENT,
236 .pe_flags = PMC_FLAG_PMC8,
237 .pe_code = 0x5
238 },
239 #if 0
240 {PMC_EV_PPC970_LSU_COMPLETION_STALL, },
241 {PMC_EV_PPC970_FXU_COMPLETION_STALL, },
242 {PMC_EV_PPC970_DCACHE_MISS_COMPLETION_STALL, },
243 {PMC_EV_PPC970_FPU_COMPLETION_STALL, },
244 {PMC_EV_PPC970_FXU_LONG_INSTR_COMPLETION_STALL, },
245 {PMC_EV_PPC970_REJECT_COMPLETION_STALL, },
246 {PMC_EV_PPC970_FPU_LONG_INSTR_COMPLETION_STALL, },
247 {PMC_EV_PPC970_GCT_EMPTY_BY_ICACHE_MISS, },
248 {PMC_EV_PPC970_REJECT_COMPLETION_STALL_ERAT_MISS, },
249 {PMC_EV_PPC970_GCT_EMPTY_BY_BRANCH_MISS_PREDICT, },
250 #endif
251 };
252 static size_t ppc970_event_codes_size = nitems(ppc970_event_codes);
253
254 static void
ppc970_set_pmc(int cpu,int ri,int config)255 ppc970_set_pmc(int cpu, int ri, int config)
256 {
257 register_t pmc_mmcr;
258 int config_mask;
259
260 if (config == PMCN_NONE)
261 config = PMC970N_NONE;
262
263 /*
264 * The mask is inverted (enable is 1) compared to the flags in MMCR0,
265 * which are Freeze flags.
266 */
267 config_mask = ~config & POWERPC_PMC_ENABLE;
268 config &= ~POWERPC_PMC_ENABLE;
269
270 /*
271 * Disable the PMCs.
272 */
273 switch (ri) {
274 case 0:
275 case 1:
276 pmc_mmcr = mfspr(SPR_MMCR0);
277 pmc_mmcr = PPC970_SET_MMCR0_PMCSEL(pmc_mmcr, config, ri);
278 mtspr(SPR_MMCR0, pmc_mmcr);
279 break;
280 case 2:
281 case 3:
282 case 4:
283 case 5:
284 case 6:
285 case 7:
286 pmc_mmcr = mfspr(SPR_MMCR1);
287 pmc_mmcr = PPC970_SET_MMCR1_PMCSEL(pmc_mmcr, config, ri);
288 mtspr(SPR_MMCR1, pmc_mmcr);
289 break;
290 }
291
292 if (config != PMC970N_NONE) {
293 pmc_mmcr = mfspr(SPR_MMCR0);
294 pmc_mmcr &= ~SPR_MMCR0_FC;
295 pmc_mmcr |= config_mask;
296 mtspr(SPR_MMCR0, pmc_mmcr);
297 }
298 }
299
300 static int
ppc970_pcpu_init(struct pmc_mdep * md,int cpu)301 ppc970_pcpu_init(struct pmc_mdep *md, int cpu)
302 {
303 powerpc_pcpu_init(md, cpu);
304
305 /* Clear the MMCRs, and set FC, to disable all PMCs. */
306 /* 970 PMC is not counted when set to 0x08 */
307 mtspr(SPR_MMCR0, SPR_MMCR0_FC | SPR_MMCR0_PMXE |
308 SPR_MMCR0_FCECE | SPR_MMCR0_PMC1CE | SPR_MMCR0_PMCNCE |
309 SPR_MMCR0_PMC1SEL(0x8) | SPR_MMCR0_PMC2SEL(0x8));
310 mtspr(SPR_MMCR1, 0x4218420);
311
312 return (0);
313 }
314
315 static int
ppc970_pcpu_fini(struct pmc_mdep * md,int cpu)316 ppc970_pcpu_fini(struct pmc_mdep *md, int cpu)
317 {
318 register_t mmcr0;
319
320 /* Freeze counters, disable interrupts */
321 mmcr0 = mfspr(SPR_MMCR0);
322 mmcr0 &= ~SPR_MMCR0_PMXE;
323 mmcr0 |= SPR_MMCR0_FC;
324 mtspr(SPR_MMCR0, mmcr0);
325
326 return (powerpc_pcpu_fini(md, cpu));
327 }
328
329 static void
ppc970_resume_pmc(bool ie)330 ppc970_resume_pmc(bool ie)
331 {
332 register_t mmcr0;
333
334 /* Unfreeze counters and re-enable PERF exceptions if requested. */
335 mmcr0 = mfspr(SPR_MMCR0);
336 mmcr0 &= ~(SPR_MMCR0_FC | SPR_MMCR0_PMXE);
337 if (ie)
338 mmcr0 |= SPR_MMCR0_PMXE;
339 mtspr(SPR_MMCR0, mmcr0);
340 }
341
342 int
pmc_ppc970_initialize(struct pmc_mdep * pmc_mdep)343 pmc_ppc970_initialize(struct pmc_mdep *pmc_mdep)
344 {
345 struct pmc_classdep *pcd;
346
347 pmc_mdep->pmd_cputype = PMC_CPU_PPC_970;
348
349 pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_POWERPC];
350 pcd->pcd_caps = POWERPC_PMC_CAPS;
351 pcd->pcd_class = PMC_CLASS_PPC970;
352 pcd->pcd_num = PPC970_MAX_PMCS;
353 pcd->pcd_ri = pmc_mdep->pmd_npmc;
354 pcd->pcd_width = 32;
355
356 pcd->pcd_allocate_pmc = powerpc_allocate_pmc;
357 pcd->pcd_config_pmc = powerpc_config_pmc;
358 pcd->pcd_pcpu_fini = ppc970_pcpu_fini;
359 pcd->pcd_pcpu_init = ppc970_pcpu_init;
360 pcd->pcd_describe = powerpc_describe;
361 pcd->pcd_get_config = powerpc_get_config;
362 pcd->pcd_read_pmc = powerpc_read_pmc;
363 pcd->pcd_release_pmc = powerpc_release_pmc;
364 pcd->pcd_start_pmc = powerpc_start_pmc;
365 pcd->pcd_stop_pmc = powerpc_stop_pmc;
366 pcd->pcd_write_pmc = powerpc_write_pmc;
367
368 pmc_mdep->pmd_npmc += PPC970_MAX_PMCS;
369 pmc_mdep->pmd_intr = powerpc_pmc_intr;
370
371 ppc_event_codes = ppc970_event_codes;
372 ppc_event_codes_size = ppc970_event_codes_size;
373 ppc_event_first = PMC_EV_PPC970_FIRST;
374 ppc_event_last = PMC_EV_PPC970_LAST;
375 ppc_max_pmcs = PPC970_MAX_PMCS;
376 ppc_class = pcd->pcd_class;
377
378 powerpc_set_pmc = ppc970_set_pmc;
379 powerpc_pmcn_read = powerpc_pmcn_read_default;
380 powerpc_pmcn_write = powerpc_pmcn_write_default;
381 powerpc_resume_pmc = ppc970_resume_pmc;
382
383 return (0);
384 }
385