609e674e3ae9849eb41c52b2e352f12c45ca698c
[15.05/openwrt.git] / target / linux / generic / files / crypto / ocf / kirkwood / mvHal / mv_hal / cpu / mvCpuCntrs.c
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 #include "mvOs.h"
18 #include "mvCpuCntrs.h"
19
20
21 const static MV_CPU_CNTRS_OPS  mvCpuCntrsOpsTbl[MV_CPU_CNTRS_NUM][MV_CPU_CNTRS_OPS_NUM] =
22 {   
23     /*0*/
24     {   
25         MV_CPU_CNTRS_CYCLES,            MV_CPU_CNTRS_DCACHE_READ_HIT,       MV_CPU_CNTRS_DCACHE_READ_MISS,
26         MV_CPU_CNTRS_DCACHE_WRITE_HIT,  MV_CPU_CNTRS_DCACHE_WRITE_MISS,     MV_CPU_CNTRS_INSTRUCTIONS, 
27         MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_INVALID,
28         MV_CPU_CNTRS_MMU_READ_LATENCY,  MV_CPU_CNTRS_ICACHE_READ_LATENCY,   MV_CPU_CNTRS_WB_WRITE_LATENCY,
29         MV_CPU_CNTRS_LDM_STM_HOLD,      MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_INVALID,
30         MV_CPU_CNTRS_DATA_WRITE_ACCESS, MV_CPU_CNTRS_DATA_READ_ACCESS,      MV_CPU_CNTRS_INVALID,
31         MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,
32     },
33     /*1*/
34     {   
35         MV_CPU_CNTRS_CYCLES,            MV_CPU_CNTRS_ICACHE_READ_MISS,      MV_CPU_CNTRS_DCACHE_READ_MISS,
36         MV_CPU_CNTRS_DCACHE_WRITE_MISS, MV_CPU_CNTRS_ITLB_MISS,             MV_CPU_CNTRS_SINGLE_ISSUE,
37         MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_BRANCH_RETIRED,        MV_CPU_CNTRS_INVALID, 
38         MV_CPU_CNTRS_MMU_READ_BEAT,     MV_CPU_CNTRS_ICACHE_READ_LATENCY,   MV_CPU_CNTRS_WB_WRITE_BEAT,
39         MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_IS_HOLD,               MV_CPU_CNTRS_DATA_READ_ACCESS,
40         MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_INVALID,
41         MV_CPU_CNTRS_INVALID,
42     },
43     /*2*/   
44     {
45         MV_CPU_CNTRS_CYCLES,            MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_DCACHE_ACCESS, 
46         MV_CPU_CNTRS_DTLB_MISS,         MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_INVALID,
47         MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_BRANCH_PREDICT_MISS,   MV_CPU_CNTRS_WB_WRITE_BEAT,
48         MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_DCACHE_READ_LATENCY,   MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,
49         MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_BIU_SIMULT_ACCESS,
50         MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_INVALID,
51         MV_CPU_CNTRS_INVALID,
52     },
53     /*3*/   
54     {
55         MV_CPU_CNTRS_CYCLES,            MV_CPU_CNTRS_DCACHE_READ_MISS,      MV_CPU_CNTRS_DCACHE_WRITE_MISS,
56         MV_CPU_CNTRS_TLB_MISS,          MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_INVALID, 
57         MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_BRANCH_TAKEN,          MV_CPU_CNTRS_WB_FULL_CYCLES,
58         MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_DCACHE_READ_BEAT,      MV_CPU_CNTRS_DCACHE_WRITE_BEAT,
59         MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_BIU_ANY_ACCESS,
60         MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_DATA_WRITE_ACCESS,
61         MV_CPU_CNTRS_INVALID,
62     }
63 };
64
65 MV_CPU_CNTRS_ENTRY  mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];
66
67 MV_CPU_CNTRS_EVENT*   mvCpuCntrsEventTbl[128];
68
69 void mvCpuCntrsReset(void)
70 {
71     MV_U32 reg = 0;
72    
73     MV_ASM ("mcr p15, 0, %0, c15, c13, 0" : : "r" (reg));
74     MV_ASM ("mcr p15, 0, %0, c15, c13, 1" : : "r" (reg));
75     MV_ASM ("mcr p15, 0, %0, c15, c13, 2" : : "r" (reg));
76     MV_ASM ("mcr p15, 0, %0, c15, c13, 3" : : "r" (reg));
77     MV_ASM ("mcr p15, 0, %0, c15, c13, 4" : : "r" (reg));
78     MV_ASM ("mcr p15, 0, %0, c15, c13, 5" : : "r" (reg));
79     MV_ASM ("mcr p15, 0, %0, c15, c13, 6" : : "r" (reg));
80     MV_ASM ("mcr p15, 0, %0, c15, c13, 7" : : "r" (reg));
81 }
82                
83 void program_counter(int counter, int op)
84 {
85     MV_U32 reg =  (1 << op) | 0x1; /*enable*/
86
87     switch(counter)
88     {
89         case 0:
90          __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 0" : : "r" (reg));
91          return;
92
93         case 1:
94          __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 1" : : "r" (reg));
95          return;
96
97         case 2:
98          __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 2" : : "r" (reg));
99          return;
100
101         case 3:
102          __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 3" : : "r" (reg));
103          return;
104
105         default:
106             mvOsPrintf("error in program_counter: bad counter number (%d)\n", counter);
107     }
108     return;
109 }
110
111 void mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent)
112 {
113     int i;
114
115     for(i=0; i<MV_CPU_CNTRS_NUM; i++)
116     {
117         pEvent->counters_sum[i] = 0;
118     }
119     pEvent->num_of_measurements = 0;
120 }
121
122                                                                                                               
123 MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold)
124 {
125     int                     i;
126     MV_CPU_CNTRS_EVENT*     event = mvOsMalloc(sizeof(MV_CPU_CNTRS_EVENT));
127
128     if(event)
129     {
130         strncpy(event->name, name, sizeof(event->name));
131         event->num_of_measurements = 0;
132         event->avg_sample_count = print_threshold;
133         for(i=0; i<MV_CPU_CNTRS_NUM; i++)
134         {
135             event->counters_before[i] = 0;
136             event->counters_after[i] = 0;
137             event->counters_sum[i] = 0;
138         }
139     }
140     return event;
141 }
142
143 void    mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event)
144 {
145     if(event != NULL)
146         mvOsFree(event);
147 }
148
149                                                                                      
150 MV_STATUS   mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op, 
151                                  char* name, MV_U32 overhead)
152 {
153     int     i;
154
155     /* Find required operations */
156     for(i=0; i<MV_CPU_CNTRS_OPS_NUM; i++)
157     {
158         if( mvCpuCntrsOpsTbl[counter][i] == op)
159         {
160             strncpy(mvCpuCntrsTbl[counter].name, name, sizeof(mvCpuCntrsTbl[counter].name));
161             mvCpuCntrsTbl[counter].operation = op;
162             mvCpuCntrsTbl[counter].opIdx = i+1;
163             mvCpuCntrsTbl[counter].overhead = overhead;
164             program_counter(counter, mvCpuCntrsTbl[counter].opIdx);
165             mvOsPrintf("Counter=%d, opIdx=%d, overhead=%d\n",
166                         counter, mvCpuCntrsTbl[counter].opIdx, mvCpuCntrsTbl[counter].overhead);
167             return MV_OK;
168         }
169     }
170     return MV_NOT_FOUND;
171 }
172
173 void    mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent)
174 {
175     int     i;
176     MV_U64  counters_avg;
177
178     if(pEvent->num_of_measurements < pEvent->avg_sample_count) 
179         return;
180
181     mvOsPrintf("%16s: ", pEvent->name);
182     for(i=0; i<MV_CPU_CNTRS_NUM; i++)
183     {
184         counters_avg = mvOsDivMod64(pEvent->counters_sum[i], 
185                                   pEvent->num_of_measurements, NULL);
186         if(counters_avg >= mvCpuCntrsTbl[i].overhead)
187             counters_avg -= mvCpuCntrsTbl[i].overhead;
188         else
189             counters_avg = 0;
190
191         mvOsPrintf("%s=%5llu, ", mvCpuCntrsTbl[i].name, counters_avg);
192     }
193     mvOsPrintf("\n");
194     mvCpuCntrsEventClear(pEvent);
195     mvCpuCntrsReset();
196 }
197
198 void    mvCpuCntrsStatus(void)
199 {
200     int i;
201
202     for(i=0; i<MV_CPU_CNTRS_NUM; i++)
203     {
204         mvOsPrintf("#%d: %s, overhead=%d\n", 
205             i, mvCpuCntrsTbl[i].name, mvCpuCntrsTbl[i].overhead);
206     }
207 }