1 
2 // Performance monitoring counters API
3 
4 /*---------------------------------------------------------------------------*
5   Project:     PMCPU Library
6   File:        pmcpu.c
7 
8   Copyright (C) Nintendo.  All rights reserved.
9 
10   These coded instructions, statements, and computer programs contain
11   proprietary information of Nintendo of America Inc. and/or Nintendo
12   Company Ltd., and are protected by Federal copyright law.  They may
13   not be disclosed to third parties or copied or duplicated in any form,
14   in whole or in part, without the prior written consent of Nintendo.
15 
16  *---------------------------------------------------------------------------*/
17 
18 
19 #include <cafe.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <cafe/os/OSPerformanceMonitor.h>
23 #include <cafe/pmcpu.h>
24 
PMCPUSetGroup(PMCPUGroup * pmc_g,u32 e1,u32 e2,u32 e3,u32 e4)25 void PMCPUSetGroup(PMCPUGroup *pmc_g, u32 e1, u32 e2, u32 e3, u32 e4) {
26   u32 pm_mask = 0;
27   pmc_g->pmc_e1     = e1;
28   pmc_g->pmc_e2     = e2;
29   pmc_g->pmc_e3     = e3;
30   pmc_g->pmc_e4     = e4;
31 
32   if(pmc_g->pmc_e1) {
33     pm_mask    |= PM_MASK_MMCR0;
34   }
35   if(pmc_g->pmc_e2) {
36     pm_mask    |= PM_MASK_MMCR0;
37   }
38   if(pmc_g->pmc_e3) {
39     pm_mask    |= PM_MASK_MMCR1;
40   }
41   if(pmc_g->pmc_e4) {
42     pm_mask    |= PM_MASK_MMCR1;
43   }
44   pmc_g->pm_mask = pm_mask;
45 }
46 
47 
PMCPUStartGroup(PMCPUGroup * pmc_g)48 void PMCPUStartGroup(PMCPUGroup *pmc_g) {
49   u32 pm_mask=0;
50   u32 mmcr0_val=0;
51   u32 mmcr1_val=0;
52 
53   if(pmc_g->pmc_e1) {
54     pm_mask    |= PM_MASK_MMCR0;
55     mmcr0_val  |= pmc_g->pmc_e1;
56   }
57   if(pmc_g->pmc_e2) {
58     pm_mask    |= PM_MASK_MMCR0;
59     mmcr0_val  |= pmc_g->pmc_e2;
60   }
61   if(pmc_g->pmc_e3) {
62     pm_mask    |= PM_MASK_MMCR1;
63     mmcr1_val  |= pmc_g->pmc_e3;
64   }
65   if(pmc_g->pmc_e4) {
66     pm_mask    |= PM_MASK_MMCR1;
67     mmcr1_val  |= pmc_g->pmc_e4;
68   }
69   pmc_g->pm_mask = pm_mask;
70   OSSetPerformanceMonitor(pm_mask, mmcr0_val, mmcr1_val, 0, 0, 0, 0);
71 }
72 
PMCPUStopGroup(PMCPUGroup * pmc_g)73 void  PMCPUStopGroup(PMCPUGroup *pmc_g) {
74   OSSetPerformanceMonitor(pmc_g->pm_mask, 0, 0, 0, 0, 0, 0);
75 }
76 
77 
PMCPUReadGroup(PMCPUGroup * pmc_g)78 void  PMCPUReadGroup(PMCPUGroup *pmc_g) {
79   if(pmc_g->pmc_e1)
80     pmc_g->pmc1 = __MFSPR(UPMC1);
81   if(pmc_g->pmc_e2)
82     pmc_g->pmc2 = __MFSPR(UPMC2);
83   if(pmc_g->pmc_e3)
84     pmc_g->pmc3 = __MFSPR(UPMC3);
85   if(pmc_g->pmc_e4)
86     pmc_g->pmc4 = __MFSPR(UPMC4);
87 }
88 
PMCPUResetGroup(PMCPUGroup * pmc_g)89 void  PMCPUResetGroup(PMCPUGroup *pmc_g) {
90   u32 pmc_mask=0;
91 
92   if(pmc_g->pmc_e1)
93     pmc_mask |= PM_MASK_PMC1;
94   if(pmc_g->pmc_e2)
95     pmc_mask |= PM_MASK_PMC2;
96   if(pmc_g->pmc_e3)
97     pmc_mask |= PM_MASK_PMC3;
98   if(pmc_g->pmc_e4)
99     pmc_mask |= PM_MASK_PMC4;
100 
101   OSSetPerformanceMonitor(pmc_mask, 0, 0, 0, 0, 0, 0);
102 }
103 
PMCPUResetStartGroup(PMCPUGroup * pmc_g)104 void PMCPUResetStartGroup(PMCPUGroup *pmc_g) {
105   u32 pm_mask=0;
106   u32 pmcr_mask=0;
107   u32 mmcr0_val=0;
108   u32 mmcr1_val=0;
109 
110   if(pmc_g->pmc_e1) {
111     pm_mask    |= PM_MASK_MMCR0;
112     mmcr0_val  |= pmc_g->pmc_e1;
113     pmcr_mask  |= PM_MASK_PMC1;
114   }
115   if(pmc_g->pmc_e2) {
116     pm_mask    |= PM_MASK_MMCR0;
117     mmcr0_val  |= pmc_g->pmc_e2;
118     pmcr_mask  |= PM_MASK_PMC2;
119   }
120   if(pmc_g->pmc_e3) {
121     pm_mask    |= PM_MASK_MMCR1;
122     mmcr1_val  |= pmc_g->pmc_e3;
123     pmcr_mask  |= PM_MASK_PMC3;
124   }
125   if(pmc_g->pmc_e4) {
126     pm_mask    |= PM_MASK_MMCR1;
127     mmcr1_val  |= pmc_g->pmc_e4;
128     pmcr_mask  |= PM_MASK_PMC4;
129   }
130   pmc_g->pm_mask = pm_mask;
131   OSSetPerformanceMonitor(pm_mask|pmcr_mask, mmcr0_val, mmcr1_val, 0, 0, 0, 0);
132 }
133 
134 
135