PAPI 7.1.0.0
Loading...
Searching...
No Matches
pfmlib_gen_mips64.c
Go to the documentation of this file.
1/*
2 * pfmlib_gen_mips64.c : support for the generic MIPS64 PMU family
3 *
4 * Contributed by Philip Mucci <mucci@cs.utk.edu> based on code from
5 * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
6 * Contributed by Stephane Eranian <eranian@hpl.hp.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 * of the Software, and to permit persons to whom the Software is furnished to do so,
13 * subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in all
16 * copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
19 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
22 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
23 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25#include <sys/types.h>
26#include <ctype.h>
27#include <string.h>
28#include <stdio.h>
29#include <unistd.h>
30#include <sys/types.h>
31#include <sys/stat.h>
32#include <fcntl.h>
33
34/* public headers */
36
37/* private headers */
38#include "pfmlib_priv.h" /* library private */
39#include "pfmlib_gen_mips64_priv.h" /* architecture private */
40#include "gen_mips64_events.h" /* PMU private */
41
42/* let's define some handy shortcuts! */
43#define sel_event_mask perfsel.sel_event_mask
44#define sel_exl perfsel.sel_exl
45#define sel_os perfsel.sel_os
46#define sel_usr perfsel.sel_usr
47#define sel_sup perfsel.sel_sup
48#define sel_int perfsel.sel_int
49
51
53
54static int
56{
57 static char mips_name[64] = "";
58 int ret;
59 char buffer[128];
60
61 ret = __pfm_getcpuinfo_attr("cpu model", buffer, sizeof(buffer));
62 if (ret == -1)
63 return PFMLIB_ERR_NOTSUPP;
64
67 if (strstr(buffer,"MIPS 20Kc"))
68 {
70 strcpy(generic_mips64_support.pmu_name,"MIPS20KC"),
75 }
76 else if (strstr(buffer,"MIPS 24K"))
77 {
79 strcpy(generic_mips64_support.pmu_name,"MIPS24K"),
84 }
85 else if (strstr(buffer,"MIPS 25Kf"))
86 {
88 strcpy(generic_mips64_support.pmu_name,"MIPS25KF"),
93 }
94 else if (strstr(buffer,"MIPS 34K"))
95 {
97 strcpy(generic_mips64_support.pmu_name,"MIPS34K"),
102 }
103 else if (strstr(buffer,"MIPS 5Kc"))
104 {
106 strcpy(generic_mips64_support.pmu_name,"MIPS5KC"),
111 }
112#if 0
113 else if (strstr(buffer,"MIPS 74K"))
114 {
115 gen_mips64_pe = gen_mips64_74K_pe;
116 strcpy(generic_mips64_support.pmu_name,"MIPS74K"),
117 generic_mips64_support.pme_count = (sizeof(gen_mips64_74K_pe)/sizeof(pme_gen_mips64_entry_t));
121 }
122#endif
123 else if (strstr(buffer,"R10000"))
124 {
126 strcpy(generic_mips64_support.pmu_name,"MIPSR10000"),
131 }
132 else if (strstr(buffer,"R12000"))
133 {
135 strcpy(generic_mips64_support.pmu_name,"MIPSR12000"),
140 }
141 else if (strstr(buffer,"RM7000"))
142 {
144 strcpy(generic_mips64_support.pmu_name,"MIPSRM7000"),
149 }
150 else if (strstr(buffer,"RM9000"))
151 {
153 strcpy(generic_mips64_support.pmu_name,"MIPSRM9000"),
158 }
159 else if (strstr(buffer,"SB1"))
160 {
162 strcpy(generic_mips64_support.pmu_name,"MIPSSB1"),
167 }
168 else if (strstr(buffer,"VR5432"))
169 {
172 strcpy(generic_mips64_support.pmu_name,"MIPSVR5432"),
176 }
177 else if (strstr(buffer,"VR5500"))
178 {
181 strcpy(generic_mips64_support.pmu_name,"MIPSVR5500"),
185 }
186 else
187 return PFMLIB_ERR_NOTSUPP;
188
191
192 return PFMLIB_SUCCESS;
193}
194
195static void stuff_regs(pfmlib_event_t *e, int plm, pfmlib_reg_t *pc, pfmlib_reg_t *pd, int cntr, int j, pfmlib_gen_mips64_input_param_t *mod_in)
196{
198
199 reg.val = 0; /* assume reserved bits are zerooed */
200
201 /* if plm is 0, then assume not specified per-event and use default */
202 plm = e[j].plm ? e[j].plm : plm;
203 reg.sel_usr = plm & PFM_PLM3 ? 1 : 0;
204 reg.sel_os = plm & PFM_PLM0 ? 1 : 0;
205 reg.sel_sup = plm & PFM_PLM1 ? 1 : 0;
206 reg.sel_exl = plm & PFM_PLM2 ? 1 : 0;
207 reg.sel_int = 1; /* force int to 1 */
208
209 reg.sel_event_mask = (gen_mips64_pe[e[j].event].pme_code >> (cntr*8)) & 0xff;
210 pc[j].reg_value = reg.val;
211 pc[j].reg_addr = cntr*2;
212 pc[j].reg_num = cntr;
213
214 __pfm_vbprintf("[CP0_25_%"PRIx64"(pmc%u)=0x%"PRIx64" event_mask=0x%x usr=%d os=%d sup=%d exl=%d int=1] %s\n",
215 pc[j].reg_addr,
216 pc[j].reg_num,
217 pc[j].reg_value,
218 reg.sel_event_mask,
219 reg.sel_usr,
220 reg.sel_os,
221 reg.sel_sup,
222 reg.sel_exl,
224
225 pd[j].reg_num = cntr;
226 pd[j].reg_addr = cntr*2 + 1;
227
228 __pfm_vbprintf("[CP0_25_%u(pmd%u)]\n",
229 pc[j].reg_addr,
230 pc[j].reg_num);
231}
232/*
233 * Automatically dispatch events to corresponding counters following constraints.
234 * Upon return the pfarg_regt structure is ready to be submitted to kernel
235 */
236static int
238{
239 /* pfmlib_gen_mips64_input_param_t *param = mod_in; */
240 pfmlib_event_t *e = inp->pfp_events;
241 pfmlib_reg_t *pc, *pd;
242 unsigned int i, j, cnt = inp->pfp_event_count;
243 unsigned int used = 0;
245
246 pc = outp->pfp_pmcs;
247 pd = outp->pfp_pmds;
248
249 /* Degree 2 rank based allocation */
251
252 if (PFMLIB_DEBUG()) {
253 for (j=0; j < cnt; j++) {
254 DPRINT("ev[%d]=%s, counters=0x%x\n", j, gen_mips64_pe[e[j].event].pme_name,gen_mips64_pe[e[j].event].pme_counters);
255 }
256 }
257
258 /* Do rank based allocation, counters that live on 1 reg
259 before counters that live on 2 regs etc. */
261 {
262 for (j=0; j < cnt;j++)
263 {
264 unsigned int cntr, avail;
265 if (pfmlib_popcnt(gen_mips64_pe[e[j].event].pme_counters) == i)
266 {
267 /* These counters can be used for this event */
268 avail = ~used & gen_mips64_pe[e[j].event].pme_counters;
269 DPRINT("Rank %d: Counters available 0x%x\n",i,avail);
270 if (avail == 0x0)
271 return PFMLIB_ERR_NOASSIGN;
272
273 /* Pick one, mark as used*/
274 cntr = ffs(avail) - 1;
275 DPRINT("Rank %d: Chose counter %d\n",i,cntr);
276
277 /* Update registers */
278 stuff_regs(e,inp->pfp_dfl_plm,pc,pd,cntr,j,mod_in);
279
280 used |= (1 << cntr);
281 DPRINT("%d: Used counters 0x%x\n",i, used);
282 }
283 }
284 }
285
286 /* number of evtsel registers programmed */
287 outp->pfp_pmc_count = cnt;
288 outp->pfp_pmd_count = cnt;
289
290 return PFMLIB_SUCCESS;
291}
292
293static int
295{
297
298 return pfm_gen_mips64_dispatch_counters(inp, mod_in, outp);
299}
300
301static int
302pfm_gen_mips64_get_event_code(unsigned int i, unsigned int cnt, int *code)
303{
305
306 /* check validity of counter index */
307 if (cnt != PFMLIB_CNT_FIRST) {
308 if (cnt < 0 || cnt >= generic_mips64_support.pmc_count)
309 return PFMLIB_ERR_INVAL; }
310 else {
311 cnt = ffs(gen_mips64_pe[i].pme_counters)-1;
312 if (cnt == -1)
313 return(PFMLIB_ERR_INVAL);
314 }
315
316 /* if cnt == 1, shift right by 0, if cnt == 2, shift right by 8 */
317 /* Works on both 5k anf 20K */
318
319 if (gen_mips64_pe[i].pme_counters & (1<< cnt))
320 *code = 0xff & (gen_mips64_pe[i].pme_code >> (cnt*8));
321 else
322 return PFMLIB_ERR_INVAL;
323
324 return PFMLIB_SUCCESS;
325}
326
327static void
329{
331 unsigned int tmp;
332
333 memset(counters, 0, sizeof(*counters));
335
336 while (tmp)
337 {
338 int t = ffs(tmp) - 1;
339 pfm_regmask_set(counters, t);
340 tmp = tmp ^ (1 << t);
341 }
342 }
343
344static void
346{
347 unsigned int i = 0;
349
350 /* all pmcs are contiguous */
351 for(i=0; i < generic_mips64_support.pmc_count; i++) pfm_regmask_set(impl_pmcs, i);
352}
353
354static void
356{
357 unsigned int i = 0;
359
360 /* all pmds are contiguous */
361 for(i=0; i < generic_mips64_support.pmd_count; i++) pfm_regmask_set(impl_pmds, i);
362}
363
364static void
366{
367 unsigned int i = 0;
369
371 pfm_regmask_set(impl_counters, i);
372}
373
374static void
376{
378}
379
380static char *
382{
383 return gen_mips64_pe[i].pme_name;
384}
385
386static int
387pfm_gen_mips64_get_event_description(unsigned int ev, char **str)
388{
389 char *s;
391 if (s) {
392 *str = strdup(s);
393 } else {
394 *str = NULL;
395 }
396 return PFMLIB_SUCCESS;
397}
398
399static int
401{
402 return pfm_find_full_event("CYCLES",e);
403}
404
405static int
407{
408 if (pfm_current == NULL)
409 return(PFMLIB_ERR_NOINIT);
410
411 switch (pfm_current->pmu_type)
412 {
414 return pfm_find_full_event("INSNS_COMPLETED",e);
416 return pfm_find_full_event("INSTRUCTIONS",e);
418 return pfm_find_full_event("INSNS_COMPLETE",e);
420 return pfm_find_full_event("INSTRUCTIONS",e);
422 return pfm_find_full_event("INSNS_EXECD",e);
425 return pfm_find_full_event("INSTRUCTIONS_GRADUATED",e);
428 return pfm_find_full_event("INSTRUCTIONS_ISSUED",e);
431 return pfm_find_full_event("INSTRUCTIONS_EXECUTED",e);
433 return pfm_find_full_event("INSN_SURVIVED_STAGE7",e);
434 default:
435 return(PFMLIB_ERR_NOTFOUND);
436 }
437}
438
439/* SiCortex specific functions */
440
442 .pmu_name = NULL,
443 .pmu_type = PFMLIB_UNKNOWN_PMU,
444 .pme_count = 0,
445 .pmc_count = 0,
446 .pmd_count = 0,
447 .num_cnt = 0,
448 .flags = PFMLIB_MULT_CODE_EVENT,
449 .get_event_code = pfm_gen_mips64_get_event_code,
450 .get_event_name = pfm_gen_mips64_get_event_name,
451 .get_event_counters = pfm_gen_mips64_get_event_counters,
452 .dispatch_events = pfm_gen_mips64_dispatch_events,
453 .pmu_detect = pfm_gen_mips64_detect,
454 .get_impl_pmcs = pfm_gen_mips64_get_impl_perfsel,
455 .get_impl_pmds = pfm_gen_mips64_get_impl_perfctr,
456 .get_impl_counters = pfm_gen_mips64_get_impl_counters,
457 .get_hw_counter_width = pfm_gen_mips64_get_hw_counter_width,
458 .get_event_desc = pfm_gen_mips64_get_event_description,
459 .get_cycle_event = pfm_gen_mips64_get_cycle_event,
460 .get_inst_retired_event = pfm_gen_mips64_get_inst_retired
461};
double tmp
int i
double s
Definition: byte_profile.c:36
static pme_gen_mips64_entry_t gen_mips64_r12000_pe[]
static pme_gen_mips64_entry_t gen_mips64_5K_pe[]
static pme_gen_mips64_entry_t gen_mips64_34K_pe[]
static pme_gen_mips64_entry_t gen_mips64_rm9000_pe[]
static pme_gen_mips64_entry_t gen_mips64_sb1_pe[]
static pme_gen_mips64_entry_t gen_mips64_r10000_pe[]
static pme_gen_mips64_entry_t gen_mips64_25K_pe[]
static pme_gen_mips64_entry_t gen_mips64_vr5500_pe[]
static pme_gen_mips64_entry_t gen_mips64_rm7000_pe[]
static pme_gen_mips64_entry_t gen_mips64_vr5432_pe[]
static pme_gen_mips64_entry_t gen_mips64_20K_pe[]
static pme_gen_mips64_entry_t gen_mips64_24K_pe[]
#define PFMLIB_MIPS_20KC_PMU
Definition: pfmlib.h:241
#define PFM_PLM2
Definition: pfmlib.h:52
#define PFMLIB_MIPS_74K_PMU
Definition: pfmlib.h:246
#define PFMLIB_MIPS_SB1_PMU
Definition: pfmlib.h:251
static int pfm_regmask_set(pfmlib_regmask_t *h, unsigned int b)
Definition: pfmlib.h:321
#define PFMLIB_SUCCESS
Definition: pfmlib.h:283
#define PFMLIB_MIPS_R12000_PMU
Definition: pfmlib.h:248
#define PFM_PLM3
Definition: pfmlib.h:53
#define PFMLIB_ERR_NOTFOUND
Definition: pfmlib.h:287
#define PFMLIB_MIPS_25KF_PMU
Definition: pfmlib.h:243
#define PFMLIB_ERR_INVAL
Definition: pfmlib.h:285
#define PFMLIB_MIPS_RM9000_PMU
Definition: pfmlib.h:250
#define PFMLIB_MIPS_R10000_PMU
Definition: pfmlib.h:247
#define PFMLIB_MIPS_5KC_PMU
Definition: pfmlib.h:245
#define PFMLIB_ERR_TOOMANY
Definition: pfmlib.h:295
#define PFM_PLM0
Definition: pfmlib.h:50
#define PFMLIB_MIPS_VR5500_PMU
Definition: pfmlib.h:253
#define PFMLIB_ERR_NOINIT
Definition: pfmlib.h:286
pfm_err_t pfm_find_full_event(const char *str, pfmlib_event_t *e)
#define PFMLIB_ERR_NOASSIGN
Definition: pfmlib.h:288
#define PFMLIB_MIPS_24K_PMU
Definition: pfmlib.h:242
#define PFMLIB_MIPS_34K_PMU
Definition: pfmlib.h:244
#define PFM_PLM1
Definition: pfmlib.h:51
#define PFMLIB_ERR_NOTSUPP
Definition: pfmlib.h:284
#define PFMLIB_UNKNOWN_PMU
Definition: pfmlib.h:222
#define PFMLIB_MIPS_VR5432_PMU
Definition: pfmlib.h:252
#define PFMLIB_MIPS_RM7000_PMU
Definition: pfmlib.h:249
#define pfmlib_popcnt
static void pfm_gen_mips64_get_impl_perfctr(pfmlib_regmask_t *impl_pmds)
static pme_gen_mips64_entry_t * gen_mips64_pe
static int pfm_gen_mips64_get_event_code(unsigned int i, unsigned int cnt, int *code)
pfm_pmu_support_t generic_mips64_support
static void pfm_gen_mips64_get_impl_counters(pfmlib_regmask_t *impl_counters)
static void pfm_gen_mips64_get_hw_counter_width(unsigned int *width)
static int pfm_gen_mips64_get_event_description(unsigned int ev, char **str)
static int pfm_gen_mips64_detect(void)
static void pfm_gen_mips64_get_impl_perfsel(pfmlib_regmask_t *impl_pmcs)
static char * pfm_gen_mips64_get_event_name(unsigned int i)
static void stuff_regs(pfmlib_event_t *e, int plm, pfmlib_reg_t *pc, pfmlib_reg_t *pd, int cntr, int j, pfmlib_gen_mips64_input_param_t *mod_in)
static int pfm_gen_mips64_dispatch_events(pfmlib_input_param_t *inp, void *model_in, pfmlib_output_param_t *outp, void *model_out)
static void pfm_gen_mips64_get_event_counters(unsigned int j, pfmlib_regmask_t *counters)
static int pfm_gen_mips64_dispatch_counters(pfmlib_input_param_t *inp, pfmlib_gen_mips64_input_param_t *mod_in, pfmlib_output_param_t *outp)
static int pfm_gen_mips64_get_cycle_event(pfmlib_event_t *e)
static int pfm_gen_mips64_get_inst_retired(pfmlib_event_t *e)
#define PMU_GEN_MIPS64_NUM_COUNTERS
#define PMU_GEN_MIPS64_COUNTER_WIDTH
int __pfm_getcpuinfo_attr(const char *attr, char *ret_buf, size_t maxlen)
void __pfm_vbprintf(const char *fmt,...)
Definition: pfmlib_priv.c:52
#define pfm_current
Definition: pfmlib_priv.h:78
#define DPRINT(fmt, a...)
Definition: pfmlib_priv.h:90
#define PFMLIB_DEBUG()
Definition: pfmlib_priv.h:76
#define PFMLIB_MULT_CODE_EVENT
Definition: pfmlib_priv.h:60
#define PFMLIB_CNT_FIRST
Definition: pfmlib_priv.h:62
unsigned int pmc_count
Definition: pfmlib_priv.h:37
unsigned int num_cnt
Definition: pfmlib_priv.h:38
unsigned int pmd_count
Definition: pfmlib_priv.h:36
unsigned int pme_count
Definition: pfmlib_priv.h:35
unsigned int plm
Definition: pfmlib.h:87
unsigned int event
Definition: pfmlib.h:86
unsigned int pfp_dfl_plm
Definition: pfmlib.h:110
pfmlib_event_t pfp_events[PFMLIB_MAX_PMCS]
Definition: pfmlib.h:113
unsigned int pfp_event_count
Definition: pfmlib.h:109
pfmlib_reg_t pfp_pmds[PFMLIB_MAX_PMDS]
Definition: pfmlib.h:130
pfmlib_reg_t pfp_pmcs[PFMLIB_MAX_PMCS]
Definition: pfmlib.h:129
unsigned int pfp_pmc_count
Definition: pfmlib.h:127
unsigned int pfp_pmd_count
Definition: pfmlib.h:128
unsigned long long reg_value
Definition: pfmlib.h:98
unsigned int reg_num
Definition: pfmlib.h:100
unsigned long long reg_addr
Definition: pfmlib.h:99
char * pme_name
char * pme_desc
unsigned int pme_counters
unsigned int pme_code