]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/dev/hwpmc/hwpmc_ppc970.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / dev / hwpmc / hwpmc_ppc970.c
1 /*-
2  * Copyright (c) 2013 Justin Hibbits
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
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 PPC970_MAX_PMCS 8
43
44 /* MMCR0, PMC1 is 8 bytes in, PMC2 is 1 byte in. */
45 #define PPC970_SET_MMCR0_PMCSEL(r, x, i) \
46         ((r & ~(0x1f << (7 * (1 - i) + 1))) | (x << (7 * (1 - i) + 1)))
47 /* MMCR1 has 6 PMC*SEL items (PMC3->PMC8), in sequence. */
48 #define PPC970_SET_MMCR1_PMCSEL(r, x, i) \
49         ((r & ~(0x1f << (5 * (7 - i) + 2))) | (x << (5 * (7 - i) + 2)))
50
51 #define PPC970_PMC_HAS_OVERFLOWED(x) (ppc970_pmcn_read(x) & (0x1 << 31))
52
53 /* How PMC works on PPC970:
54  *
55  * Any PMC can count a direct event.  Indirect events are handled specially.
56  * Direct events: As published.
57  *
58  * Encoding 00 000 -- Add byte lane bit counters
59  *   MMCR1[24:31] -- select bit matching PMC being an adder.
60  * Bus events:
61  * PMCxSEL: 1x -- select from byte lane: 10 == lower lane (0/1), 11 == upper
62  * lane (2/3).
63  * PMCxSEL[2:4] -- bit in the byte lane selected.
64  *
65  * PMC[1,2,5,6] == lane 0/lane 2
66  * PMC[3,4,7,8] == lane 1,3
67  *
68  *
69  * Lanes:
70  * Lane 0 -- TTM0(FPU,ISU,IFU,VPU)
71  *           TTM1(IDU,ISU,STS)
72  *           LSU0 byte 0
73  *           LSU1 byte 0
74  * Lane 1 -- TTM0
75  *           TTM1
76  *           LSU0 byte 1
77  *           LSU1 byte 1
78  * Lane 2 -- TTM0
79  *           TTM1
80  *           LSU0 byte 2
81  *           LSU1 byte 2 or byte 6
82  * Lane 3 -- TTM0
83  *           TTM1
84  *           LSU0 byte 3
85  *           LSU1 byte 3 or byte 7
86  *
87  * Adders:
88  *  Add byte lane for PMC (above), bit 0+4, 1+5, 2+6, 3+7
89  */
90
91 struct pmc_ppc970_event {
92         enum pmc_event pe_event;
93         uint32_t pe_flags;
94 #define PMC_PPC970_FLAG_PMCS    0x000000ff
95 #define  PMC_PPC970_FLAG_PMC1   0x01
96 #define  PMC_PPC970_FLAG_PMC2   0x02
97 #define  PMC_PPC970_FLAG_PMC3   0x04
98 #define  PMC_PPC970_FLAG_PMC4   0x08
99 #define  PMC_PPC970_FLAG_PMC5   0x10
100 #define  PMC_PPC970_FLAG_PMC6   0x20
101 #define  PMC_PPC970_FLAG_PMC7   0x40
102 #define  PMC_PPC970_FLAG_PMC8   0x80
103         uint32_t pe_code;
104 };
105
106 static struct pmc_ppc970_event ppc970_event_codes[] = {
107         {PMC_EV_PPC970_INSTR_COMPLETED,
108             .pe_flags = PMC_PPC970_FLAG_PMCS,
109             .pe_code = 0x09
110         },
111         {PMC_EV_PPC970_MARKED_GROUP_DISPATCH,
112                 .pe_flags = PMC_PPC970_FLAG_PMC1,
113                 .pe_code = 0x2
114         },
115         {PMC_EV_PPC970_MARKED_STORE_COMPLETED,
116                 .pe_flags = PMC_PPC970_FLAG_PMC1,
117                 .pe_code = 0x03
118         },
119         {PMC_EV_PPC970_GCT_EMPTY,
120                 .pe_flags = PMC_PPC970_FLAG_PMC1,
121                 .pe_code = 0x04
122         },
123         {PMC_EV_PPC970_RUN_CYCLES,
124                 .pe_flags = PMC_PPC970_FLAG_PMC1,
125                 .pe_code = 0x05
126         },
127         {PMC_EV_PPC970_OVERFLOW,
128                 .pe_flags = PMC_PPC970_FLAG_PMCS,
129                 .pe_code = 0x0a
130         },
131         {PMC_EV_PPC970_CYCLES,
132                 .pe_flags = PMC_PPC970_FLAG_PMCS,
133                 .pe_code = 0x0f
134         },
135         {PMC_EV_PPC970_THRESHOLD_TIMEOUT,
136                 .pe_flags = PMC_PPC970_FLAG_PMC2,
137                 .pe_code = 0x3
138         },
139         {PMC_EV_PPC970_GROUP_DISPATCH,
140                 .pe_flags = PMC_PPC970_FLAG_PMC2,
141                 .pe_code = 0x4
142         },
143         {PMC_EV_PPC970_BR_MARKED_INSTR_FINISH,
144                 .pe_flags = PMC_PPC970_FLAG_PMC2,
145                 .pe_code = 0x5
146         },
147         {PMC_EV_PPC970_GCT_EMPTY_BY_SRQ_FULL,
148                 .pe_flags = PMC_PPC970_FLAG_PMC2,
149                 .pe_code = 0xb
150         },
151         {PMC_EV_PPC970_STOP_COMPLETION,
152                 .pe_flags = PMC_PPC970_FLAG_PMC3,
153                 .pe_code = 0x1
154         },
155         {PMC_EV_PPC970_LSU_EMPTY,
156                 .pe_flags = PMC_PPC970_FLAG_PMC3,
157                 .pe_code = 0x2
158         },
159         {PMC_EV_PPC970_MARKED_STORE_WITH_INTR,
160                 .pe_flags = PMC_PPC970_FLAG_PMC3,
161                 .pe_code = 0x3
162         },
163         {PMC_EV_PPC970_CYCLES_IN_SUPER,
164                 .pe_flags = PMC_PPC970_FLAG_PMC3,
165                 .pe_code = 0x4
166         },
167         {PMC_EV_PPC970_VPU_MARKED_INSTR_COMPLETED,
168                 .pe_flags = PMC_PPC970_FLAG_PMC3,
169                 .pe_code = 0x5
170         },
171         {PMC_EV_PPC970_FXU0_IDLE_FXU1_BUSY,
172                 .pe_flags = PMC_PPC970_FLAG_PMC4,
173                 .pe_code = 0x2
174         },
175         {PMC_EV_PPC970_SRQ_EMPTY,
176                 .pe_flags = PMC_PPC970_FLAG_PMC4,
177                 .pe_code = 0x3
178         },
179         {PMC_EV_PPC970_MARKED_GROUP_COMPLETED,
180                 .pe_flags = PMC_PPC970_FLAG_PMC4,
181                 .pe_code = 0x4
182         },
183         {PMC_EV_PPC970_CR_MARKED_INSTR_FINISH,
184                 .pe_flags = PMC_PPC970_FLAG_PMC4,
185                 .pe_code = 0x5
186         },
187         {PMC_EV_PPC970_DISPATCH_SUCCESS,
188                 .pe_flags = PMC_PPC970_FLAG_PMC5,
189                 .pe_code = 0x1
190         },
191         {PMC_EV_PPC970_FXU0_IDLE_FXU1_IDLE,
192                 .pe_flags = PMC_PPC970_FLAG_PMC5,
193                 .pe_code = 0x2
194         },
195         {PMC_EV_PPC970_ONE_PLUS_INSTR_COMPLETED,
196                 .pe_flags = PMC_PPC970_FLAG_PMC5,
197                 .pe_code = 0x3
198         },
199         {PMC_EV_PPC970_GROUP_MARKED_IDU,
200                 .pe_flags = PMC_PPC970_FLAG_PMC5,
201                 .pe_code = 0x4
202         },
203         {PMC_EV_PPC970_MARKED_GROUP_COMPLETE_TIMEOUT,
204                 .pe_flags = PMC_PPC970_FLAG_PMC5,
205                 .pe_code = 0x5
206         },
207         {PMC_EV_PPC970_FXU0_BUSY_FXU1_BUSY,
208                 .pe_flags = PMC_PPC970_FLAG_PMC6,
209                 .pe_code = 0x2
210         },
211         {PMC_EV_PPC970_MARKED_STORE_SENT_TO_STS,
212                 .pe_flags = PMC_PPC970_FLAG_PMC6,
213                 .pe_code = 0x3
214         },
215         {PMC_EV_PPC970_FXU_MARKED_INSTR_FINISHED,
216                 .pe_flags = PMC_PPC970_FLAG_PMC6,
217                 .pe_code = 0x4
218         },
219         {PMC_EV_PPC970_MARKED_GROUP_ISSUED,
220                 .pe_flags = PMC_PPC970_FLAG_PMC6,
221                 .pe_code = 0x5
222         },
223         {PMC_EV_PPC970_FXU0_BUSY_FXU1_IDLE,
224                 .pe_flags = PMC_PPC970_FLAG_PMC7,
225                 .pe_code = 0x2
226         },
227         {PMC_EV_PPC970_GROUP_COMPLETED,
228                 .pe_flags = PMC_PPC970_FLAG_PMC7,
229                 .pe_code = 0x3
230         },
231         {PMC_EV_PPC970_FPU_MARKED_INSTR_COMPLETED,
232                 .pe_flags = PMC_PPC970_FLAG_PMC7,
233                 .pe_code = 0x4
234         },
235         {PMC_EV_PPC970_MARKED_INSTR_FINISH_ANY_UNIT,
236                 .pe_flags = PMC_PPC970_FLAG_PMC7,
237                 .pe_code = 0x5
238         },
239         {PMC_EV_PPC970_EXTERNAL_INTERRUPT,
240                 .pe_flags = PMC_PPC970_FLAG_PMC8,
241                 .pe_code = 0x2
242         },
243         {PMC_EV_PPC970_GROUP_DISPATCH_REJECT,
244                 .pe_flags = PMC_PPC970_FLAG_PMC8,
245                 .pe_code = 0x3
246         },
247         {PMC_EV_PPC970_LSU_MARKED_INSTR_FINISH,
248                 .pe_flags = PMC_PPC970_FLAG_PMC8,
249                 .pe_code = 0x4
250         },
251         {PMC_EV_PPC970_TIMEBASE_EVENT,
252                 .pe_flags = PMC_PPC970_FLAG_PMC8,
253                 .pe_code = 0x5
254         },
255 #if 0
256         {PMC_EV_PPC970_LSU_COMPLETION_STALL, },
257         {PMC_EV_PPC970_FXU_COMPLETION_STALL, },
258         {PMC_EV_PPC970_DCACHE_MISS_COMPLETION_STALL, },
259         {PMC_EV_PPC970_FPU_COMPLETION_STALL, },
260         {PMC_EV_PPC970_FXU_LONG_INSTR_COMPLETION_STALL, },
261         {PMC_EV_PPC970_REJECT_COMPLETION_STALL, },
262         {PMC_EV_PPC970_FPU_LONG_INSTR_COMPLETION_STALL, },
263         {PMC_EV_PPC970_GCT_EMPTY_BY_ICACHE_MISS, },
264         {PMC_EV_PPC970_REJECT_COMPLETION_STALL_ERAT_MISS, },
265         {PMC_EV_PPC970_GCT_EMPTY_BY_BRANCH_MISS_PREDICT, },
266 #endif
267 };
268 static size_t ppc970_event_codes_size = nitems(ppc970_event_codes);
269
270 static pmc_value_t
271 ppc970_pmcn_read(unsigned int pmc)
272 {
273         pmc_value_t val;
274
275         switch (pmc) {
276                 case 0:
277                         val = mfspr(SPR_970PMC1);
278                         break;
279                 case 1:
280                         val = mfspr(SPR_970PMC2);
281                         break;
282                 case 2:
283                         val = mfspr(SPR_970PMC3);
284                         break;
285                 case 3:
286                         val = mfspr(SPR_970PMC4);
287                         break;
288                 case 4:
289                         val = mfspr(SPR_970PMC5);
290                         break;
291                 case 5:
292                         val = mfspr(SPR_970PMC6);
293                         break;
294                 case 6:
295                         val = mfspr(SPR_970PMC7);
296                         break;
297                 case 7:
298                         val = mfspr(SPR_970PMC8);
299                         break;
300                 default:
301                         panic("Invalid PMC number: %d\n", pmc);
302         }
303
304         return (val);
305 }
306
307 static void
308 ppc970_pmcn_write(unsigned int pmc, uint32_t val)
309 {
310         switch (pmc) {
311                 case 0:
312                         mtspr(SPR_970PMC1, val);
313                         break;
314                 case 1:
315                         mtspr(SPR_970PMC2, val);
316                         break;
317                 case 2:
318                         mtspr(SPR_970PMC3, val);
319                         break;
320                 case 3:
321                         mtspr(SPR_970PMC4, val);
322                         break;
323                 case 4:
324                         mtspr(SPR_970PMC5, val);
325                         break;
326                 case 5:
327                         mtspr(SPR_970PMC6, val);
328                         break;
329                 case 6:
330                         mtspr(SPR_970PMC7, val);
331                         break;
332                 case 7:
333                         mtspr(SPR_970PMC8, val);
334                         break;
335                 default:
336                         panic("Invalid PMC number: %d\n", pmc);
337         }
338 }
339
340 static int
341 ppc970_config_pmc(int cpu, int ri, struct pmc *pm)
342 {
343         struct pmc_hw *phw;
344
345         PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
346
347         KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
348             ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu));
349         KASSERT(ri >= 0 && ri < PPC970_MAX_PMCS,
350             ("[powerpc,%d] illegal row-index %d", __LINE__, ri));
351
352         phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri];
353
354         KASSERT(pm == NULL || phw->phw_pmc == NULL,
355             ("[powerpc,%d] pm=%p phw->pm=%p hwpmc not unconfigured",
356             __LINE__, pm, phw->phw_pmc));
357
358         phw->phw_pmc = pm;
359
360         return 0;
361 }
362
363 static int
364 ppc970_set_pmc(int cpu, int ri, int config)
365 {
366         struct pmc *pm;
367         struct pmc_hw *phw;
368         register_t pmc_mmcr;
369
370         phw    = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri];
371         pm     = phw->phw_pmc;
372
373         /*
374          * Disable the PMCs.
375          */
376         switch (ri) {
377         case 0:
378         case 1:
379                 pmc_mmcr = mfspr(SPR_970MMCR0);
380                 pmc_mmcr = PPC970_SET_MMCR0_PMCSEL(pmc_mmcr, config, ri);
381                 mtspr(SPR_970MMCR0, pmc_mmcr);
382                 break;
383         case 2:
384         case 3:
385         case 4:
386         case 5:
387         case 6:
388         case 7:
389                 pmc_mmcr = mfspr(SPR_970MMCR1);
390                 pmc_mmcr = PPC970_SET_MMCR1_PMCSEL(pmc_mmcr, config, ri);
391                 mtspr(SPR_970MMCR1, pmc_mmcr);
392                 break;
393         }
394         return 0;
395 }
396
397 static int
398 ppc970_start_pmc(int cpu, int ri)
399 {
400         struct pmc *pm;
401         struct pmc_hw *phw;
402         register_t pmc_mmcr;
403         uint32_t config;
404         int error;
405
406         phw    = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri];
407         pm     = phw->phw_pmc;
408         config = pm->pm_md.pm_powerpc.pm_powerpc_evsel & ~POWERPC_PMC_ENABLE;
409
410         error = ppc970_set_pmc(cpu, ri, config);
411         
412         /* The mask is inverted (enable is 1) compared to the flags in MMCR0, which
413          * are Freeze flags.
414          */
415         config = ~pm->pm_md.pm_powerpc.pm_powerpc_evsel & POWERPC_PMC_ENABLE;
416
417         pmc_mmcr = mfspr(SPR_970MMCR0);
418         pmc_mmcr &= ~SPR_MMCR0_FC;
419         pmc_mmcr |= config;
420         mtspr(SPR_970MMCR0, pmc_mmcr);
421
422         return 0;
423 }
424
425 static int
426 ppc970_stop_pmc(int cpu, int ri)
427 {
428         return ppc970_set_pmc(cpu, ri, PMC970N_NONE);
429 }
430
431 static int
432 ppc970_read_pmc(int cpu, int ri, pmc_value_t *v)
433 {
434         struct pmc *pm;
435         pmc_value_t tmp;
436
437         KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
438             ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu));
439         KASSERT(ri >= 0 && ri < PPC970_MAX_PMCS,
440             ("[powerpc,%d] illegal row index %d", __LINE__, ri));
441
442         pm  = powerpc_pcpu[cpu]->pc_ppcpmcs[ri].phw_pmc;
443         KASSERT(pm,
444             ("[core,%d] cpu %d ri %d pmc not configured", __LINE__, cpu,
445                 ri));
446
447         tmp = ppc970_pmcn_read(ri);
448         PMCDBG2(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp);
449         if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
450                 *v = POWERPC_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
451         else
452                 *v = tmp;
453
454         return 0;
455 }
456
457 static int
458 ppc970_write_pmc(int cpu, int ri, pmc_value_t v)
459 {
460         struct pmc *pm;
461
462         KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
463             ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu));
464         KASSERT(ri >= 0 && ri < PPC970_MAX_PMCS,
465             ("[powerpc,%d] illegal row-index %d", __LINE__, ri));
466
467         pm  = powerpc_pcpu[cpu]->pc_ppcpmcs[ri].phw_pmc;
468
469         if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
470                 v = POWERPC_RELOAD_COUNT_TO_PERFCTR_VALUE(v);
471         
472         PMCDBG3(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v);
473
474         ppc970_pmcn_write(ri, v);
475
476         return 0;
477 }
478
479 static int
480 ppc970_intr(int cpu, struct trapframe *tf)
481 {
482         struct pmc *pm;
483         struct powerpc_cpu *pac;
484         pmc_value_t v;
485         uint32_t config;
486         int i, error, retval;
487
488         KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
489             ("[powerpc,%d] out of range CPU %d", __LINE__, cpu));
490
491         PMCDBG3(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf,
492             TRAPF_USERMODE(tf));
493
494         retval = 0;
495
496         pac = powerpc_pcpu[cpu];
497
498         /*
499          * look for all PMCs that have interrupted:
500          * - look for a running, sampling PMC which has overflowed
501          *   and which has a valid 'struct pmc' association
502          *
503          * If found, we call a helper to process the interrupt.
504          */
505
506         config  = mfspr(SPR_970MMCR0);
507         mtspr(SPR_970MMCR0, config | SPR_MMCR0_FC);
508         for (i = 0; i < PPC970_MAX_PMCS; i++) {
509                 if ((pm = pac->pc_ppcpmcs[i].phw_pmc) == NULL ||
510                     !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) {
511                         continue;
512                 }
513
514                 if (!PPC970_PMC_HAS_OVERFLOWED(i))
515                         continue;
516
517                 retval = 1;     /* Found an interrupting PMC. */
518
519                 if (pm->pm_state != PMC_STATE_RUNNING)
520                         continue;
521
522                 /* Stop the PMC, reload count. */
523                 v       = pm->pm_sc.pm_reloadcount;
524
525                 ppc970_pmcn_write(i, v);
526
527                 /* Restart the counter if logging succeeded. */
528                 error = pmc_process_interrupt(cpu, PMC_HR, pm, tf,
529                     TRAPF_USERMODE(tf));
530                 mtspr(SPR_970MMCR0, config);
531                 if (error != 0)
532                         ppc970_stop_pmc(cpu, i);
533                 atomic_add_int(retval ? &pmc_stats.pm_intr_processed :
534                                 &pmc_stats.pm_intr_ignored, 1);
535
536         }
537
538         /* Re-enable PERF exceptions. */
539         mtspr(SPR_970MMCR0, mfspr(SPR_970MMCR0) | SPR_MMCR0_PMXE);
540
541         return (retval);
542 }
543
544 static int
545 ppc970_pcpu_init(struct pmc_mdep *md, int cpu)
546 {
547         struct pmc_cpu *pc;
548         struct powerpc_cpu *pac;
549         struct pmc_hw  *phw;
550         int first_ri, i;
551
552         KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
553             ("[powerpc,%d] wrong cpu number %d", __LINE__, cpu));
554         PMCDBG1(MDP,INI,1,"powerpc-init cpu=%d", cpu);
555
556         powerpc_pcpu[cpu] = pac = malloc(sizeof(struct powerpc_cpu), M_PMC,
557             M_WAITOK|M_ZERO);
558         pac->pc_ppcpmcs = malloc(sizeof(struct pmc_hw) * PPC970_MAX_PMCS,
559             M_PMC, M_WAITOK|M_ZERO);
560         pac->pc_class = PMC_CLASS_PPC970;
561
562         pc = pmc_pcpu[cpu];
563         first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_PPC970].pcd_ri;
564         KASSERT(pc != NULL, ("[powerpc,%d] NULL per-cpu pointer", __LINE__));
565
566         for (i = 0, phw = pac->pc_ppcpmcs; i < PPC970_MAX_PMCS; i++, phw++) {
567                 phw->phw_state    = PMC_PHW_FLAG_IS_ENABLED |
568                     PMC_PHW_CPU_TO_STATE(cpu) | PMC_PHW_INDEX_TO_STATE(i);
569                 phw->phw_pmc      = NULL;
570                 pc->pc_hwpmcs[i + first_ri] = phw;
571         }
572
573         /* Clear the MMCRs, and set FC, to disable all PMCs. */
574         /* 970 PMC is not counted when set to 0x08 */
575         mtspr(SPR_970MMCR0, SPR_MMCR0_FC | SPR_MMCR0_PMXE | SPR_MMCR0_PMC1CE |
576             SPR_MMCR0_PMCNCE | SPR_970MMCR0_PMC1SEL(0x8) | SPR_970MMCR0_PMC2SEL(0x8));
577         mtspr(SPR_970MMCR1, 0x4218420);
578
579         return 0;
580 }
581
582 static int
583 ppc970_pcpu_fini(struct pmc_mdep *md, int cpu)
584 {
585         register_t mmcr0 = mfspr(SPR_MMCR0);
586
587         mmcr0 |= SPR_MMCR0_FC;
588         mmcr0 &= ~SPR_MMCR0_PMXE;
589         mtspr(SPR_MMCR0, mmcr0);
590         free(powerpc_pcpu[cpu]->pc_ppcpmcs, M_PMC);
591         free(powerpc_pcpu[cpu], M_PMC);
592         return 0;
593 }
594
595 static int
596 ppc970_allocate_pmc(int cpu, int ri, struct pmc *pm,
597   const struct pmc_op_pmcallocate *a)
598 {
599         enum pmc_event pe;
600         uint32_t caps, config = 0, counter = 0;
601         int i;
602
603         KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
604             ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu));
605         KASSERT(ri >= 0 && ri < PPC970_MAX_PMCS,
606             ("[powerpc,%d] illegal row index %d", __LINE__, ri));
607
608         caps = a->pm_caps;
609
610         pe = a->pm_ev;
611
612         if (pe < PMC_EV_PPC970_FIRST || pe > PMC_EV_PPC970_LAST)
613                 return (EINVAL);
614
615         for (i = 0; i < ppc970_event_codes_size; i++) {
616                 if (ppc970_event_codes[i].pe_event == pe) {
617                         config = ppc970_event_codes[i].pe_code;
618                         counter =  ppc970_event_codes[i].pe_flags;
619                         break;
620                 }
621         }
622         if (i == ppc970_event_codes_size)
623                 return (EINVAL);
624
625         if ((counter & (1 << ri)) == 0)
626                 return (EINVAL);
627
628         if (caps & PMC_CAP_SYSTEM)
629                 config |= POWERPC_PMC_KERNEL_ENABLE;
630         if (caps & PMC_CAP_USER)
631                 config |= POWERPC_PMC_USER_ENABLE;
632         if ((caps & (PMC_CAP_USER | PMC_CAP_SYSTEM)) == 0)
633                 config |= POWERPC_PMC_ENABLE;
634
635         pm->pm_md.pm_powerpc.pm_powerpc_evsel = config;
636
637         PMCDBG2(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config);
638
639         return 0;
640 }
641
642 static int
643 ppc970_release_pmc(int cpu, int ri, struct pmc *pmc)
644 {
645         struct pmc_hw *phw;
646
647         KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
648             ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu));
649         KASSERT(ri >= 0 && ri < PPC970_MAX_PMCS,
650             ("[powerpc,%d] illegal row-index %d", __LINE__, ri));
651
652         phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri];
653         KASSERT(phw->phw_pmc == NULL,
654             ("[powerpc,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc));
655
656         return 0;
657 }
658
659 int
660 pmc_ppc970_initialize(struct pmc_mdep *pmc_mdep)
661 {
662         struct pmc_classdep *pcd;
663         
664         pmc_mdep->pmd_cputype = PMC_CPU_PPC_970;
665
666         pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_PPC970];
667         pcd->pcd_caps  = POWERPC_PMC_CAPS;
668         pcd->pcd_class = PMC_CLASS_PPC970;
669         pcd->pcd_num   = PPC970_MAX_PMCS;
670         pcd->pcd_ri    = pmc_mdep->pmd_npmc;
671         pcd->pcd_width = 32;
672
673         pcd->pcd_allocate_pmc   = ppc970_allocate_pmc;
674         pcd->pcd_config_pmc     = ppc970_config_pmc;
675         pcd->pcd_pcpu_fini      = ppc970_pcpu_fini;
676         pcd->pcd_pcpu_init      = ppc970_pcpu_init;
677         pcd->pcd_describe       = powerpc_describe;
678         pcd->pcd_get_config     = powerpc_get_config;
679         pcd->pcd_read_pmc       = ppc970_read_pmc;
680         pcd->pcd_release_pmc    = ppc970_release_pmc;
681         pcd->pcd_start_pmc      = ppc970_start_pmc;
682         pcd->pcd_stop_pmc       = ppc970_stop_pmc;
683         pcd->pcd_write_pmc      = ppc970_write_pmc;
684
685         pmc_mdep->pmd_npmc     += PPC970_MAX_PMCS;
686         pmc_mdep->pmd_intr      = ppc970_intr;
687
688         return (0);
689 }