PAPI 7.1.0.0
Loading...
Searching...
No Matches
pfmlib_gen_ia32.c File Reference
Include dependency graph for pfmlib_gen_ia32.c:

Go to the source code of this file.

Macros

#define sel_event_select   perfevtsel.sel_event_select
 
#define sel_unit_mask   perfevtsel.sel_unit_mask
 
#define sel_usr   perfevtsel.sel_usr
 
#define sel_os   perfevtsel.sel_os
 
#define sel_edge   perfevtsel.sel_edge
 
#define sel_pc   perfevtsel.sel_pc
 
#define sel_int   perfevtsel.sel_int
 
#define sel_any   perfevtsel.sel_any
 
#define sel_en   perfevtsel.sel_en
 
#define sel_inv   perfevtsel.sel_inv
 
#define sel_cnt_mask   perfevtsel.sel_cnt_mask
 
#define GEN_IA32_SEL_BASE   0x186
 
#define GEN_IA32_CTR_BASE   0xc1
 
#define GEN_IA32_FIXED_CTR_BASE   0x309
 
#define FIXED_PMD_BASE   16
 
#define PFMLIB_GEN_IA32_ALL_FLAGS    (PFM_GEN_IA32_SEL_INV|PFM_GEN_IA32_SEL_EDGE|PFM_GEN_IA32_SEL_ANYTHR)
 
#define MAX_EVENT_NAMES   (sizeof(fixed_event_names)/sizeof(char *))
 
#define HAS_OPTIONS(x)   (cntrs && (cntrs[i].flags || cntrs[i].cnt_mask))
 
#define is_fixed_pmc(a)   (a > 15)
 

Functions

static char * pfm_gen_ia32_get_event_name (unsigned int i)
 
static void cpuid (unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
 
static int create_arch_event_table (unsigned int mask)
 
static int check_arch_pmu (int family)
 
static int pfm_gen_ia32_detect (void)
 
static int pfm_gen_ia32_init (void)
 
static int pfm_gen_ia32_dispatch_counters_v1 (pfmlib_input_param_t *inp, pfmlib_gen_ia32_input_param_t *mod_in, pfmlib_output_param_t *outp)
 
static int pfm_gen_ia32_dispatch_counters_v23 (pfmlib_input_param_t *inp, pfmlib_gen_ia32_input_param_t *param, pfmlib_output_param_t *outp)
 
static int pfm_gen_ia32_dispatch_events (pfmlib_input_param_t *inp, void *model_in, pfmlib_output_param_t *outp, void *model_out)
 
static int pfm_gen_ia32_get_event_code (unsigned int i, unsigned int cnt, int *code)
 
static void pfm_gen_ia32_get_event_counters (unsigned int j, pfmlib_regmask_t *counters)
 
static void pfm_gen_ia32_get_impl_pmcs (pfmlib_regmask_t *impl_pmcs)
 
static void pfm_gen_ia32_get_impl_pmds (pfmlib_regmask_t *impl_pmds)
 
static void pfm_gen_ia32_get_impl_counters (pfmlib_regmask_t *impl_counters)
 
static void pfm_gen_ia32_get_hw_counter_width (unsigned int *width)
 
static int pfm_gen_ia32_get_event_description (unsigned int ev, char **str)
 
static char * pfm_gen_ia32_get_event_mask_name (unsigned int ev, unsigned int midx)
 
static int pfm_gen_ia32_get_event_mask_desc (unsigned int ev, unsigned int midx, char **str)
 
static unsigned int pfm_gen_ia32_get_num_event_masks (unsigned int ev)
 
static int pfm_gen_ia32_get_event_mask_code (unsigned int ev, unsigned int midx, unsigned int *code)
 
static int pfm_gen_ia32_get_cycle_event (pfmlib_event_t *e)
 
static int pfm_gen_ia32_get_inst_retired (pfmlib_event_t *e)
 

Variables

pfm_pmu_support_tgen_support
 
static pme_gen_ia32_entry_tgen_ia32_pe
 
static int gen_ia32_cycle_event
 
static int gen_ia32_inst_retired_event
 
static unsigned int num_fixed_cnt
 
static unsigned int num_gen_cnt
 
static unsigned int pmu_version
 
static pfmlib_regmask_t gen_ia32_impl_pmcs
 
static pfmlib_regmask_t gen_ia32_impl_pmds
 
static const char * fixed_event_names [] ={ "INSTRUCTIONS_RETIRED", "UNHALTED_CORE_CYCLES ", "UNHALTED_REFERENCE_CYCLES " }
 
pfm_pmu_support_t gen_ia32_support
 

Macro Definition Documentation

◆ FIXED_PMD_BASE

#define FIXED_PMD_BASE   16

Definition at line 102 of file pfmlib_gen_ia32.c.

◆ GEN_IA32_CTR_BASE

#define GEN_IA32_CTR_BASE   0xc1

Definition at line 99 of file pfmlib_gen_ia32.c.

◆ GEN_IA32_FIXED_CTR_BASE

#define GEN_IA32_FIXED_CTR_BASE   0x309

Definition at line 100 of file pfmlib_gen_ia32.c.

◆ GEN_IA32_SEL_BASE

#define GEN_IA32_SEL_BASE   0x186

Definition at line 98 of file pfmlib_gen_ia32.c.

◆ HAS_OPTIONS

#define HAS_OPTIONS (   x)    (cntrs && (cntrs[i].flags || cntrs[i].cnt_mask))

◆ is_fixed_pmc

#define is_fixed_pmc (   a)    (a > 15)

◆ MAX_EVENT_NAMES

#define MAX_EVENT_NAMES   (sizeof(fixed_event_names)/sizeof(char *))

Definition at line 470 of file pfmlib_gen_ia32.c.

◆ PFMLIB_GEN_IA32_ALL_FLAGS

#define PFMLIB_GEN_IA32_ALL_FLAGS    (PFM_GEN_IA32_SEL_INV|PFM_GEN_IA32_SEL_EDGE|PFM_GEN_IA32_SEL_ANYTHR)

Definition at line 104 of file pfmlib_gen_ia32.c.

◆ sel_any

#define sel_any   perfevtsel.sel_any

Definition at line 56 of file pfmlib_gen_ia32.c.

◆ sel_cnt_mask

#define sel_cnt_mask   perfevtsel.sel_cnt_mask

Definition at line 59 of file pfmlib_gen_ia32.c.

◆ sel_edge

#define sel_edge   perfevtsel.sel_edge

Definition at line 53 of file pfmlib_gen_ia32.c.

◆ sel_en

#define sel_en   perfevtsel.sel_en

Definition at line 57 of file pfmlib_gen_ia32.c.

◆ sel_event_select

#define sel_event_select   perfevtsel.sel_event_select

Definition at line 49 of file pfmlib_gen_ia32.c.

◆ sel_int

#define sel_int   perfevtsel.sel_int

Definition at line 55 of file pfmlib_gen_ia32.c.

◆ sel_inv

#define sel_inv   perfevtsel.sel_inv

Definition at line 58 of file pfmlib_gen_ia32.c.

◆ sel_os

#define sel_os   perfevtsel.sel_os

Definition at line 52 of file pfmlib_gen_ia32.c.

◆ sel_pc

#define sel_pc   perfevtsel.sel_pc

Definition at line 54 of file pfmlib_gen_ia32.c.

◆ sel_unit_mask

#define sel_unit_mask   perfevtsel.sel_unit_mask

Definition at line 50 of file pfmlib_gen_ia32.c.

◆ sel_usr

#define sel_usr   perfevtsel.sel_usr

Definition at line 51 of file pfmlib_gen_ia32.c.

Function Documentation

◆ check_arch_pmu()

static int check_arch_pmu ( int  family)
static

Definition at line 195 of file pfmlib_gen_ia32.c.

196{
197 union {
198 unsigned int val;
199 pmu_eax_t eax;
200 pmu_edx_t edx;
201 } eax, ecx, edx, ebx;
202
203 /*
204 * check family number to reject for processors
205 * older than Pentium (family=5). Those processors
206 * did not have the CPUID instruction
207 */
208 if (family < 5)
209 return PFMLIB_ERR_NOTSUPP;
210
211 /*
212 * check if CPU supports 0xa function of CPUID
213 * 0xa started with Core Duo. Needed to detect if
214 * architected PMU is present
215 */
216 cpuid(0x0, &eax.val, &ebx.val, &ecx.val, &edx.val);
217 if (eax.val < 0xa)
218 return PFMLIB_ERR_NOTSUPP;
219
220 /*
221 * extract architected PMU information
222 */
223 cpuid(0xa, &eax.val, &ebx.val, &ecx.val, &edx.val);
224
225 /*
226 * version must be greater than zero
227 */
228 return eax.eax.version < 1 ? PFMLIB_ERR_NOTSUPP : PFMLIB_SUCCESS;
229}
#define PFMLIB_SUCCESS
Definition: pfmlib.h:283
#define PFMLIB_ERR_NOTSUPP
Definition: pfmlib.h:284
int family
Definition: pfmlib_amd64.c:85
static void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cpuid()

static void cpuid ( unsigned int  op,
unsigned int eax,
unsigned int ebx,
unsigned int ecx,
unsigned int edx 
)
inlinestatic

Definition at line 135 of file pfmlib_gen_ia32.c.

137{
138 __asm__("cpuid"
139 : "=a" (*eax),
140 "=b" (*ebx),
141 "=c" (*ecx),
142 "=d" (*edx)
143 : "0" (op), "c"(0));
144}
Here is the caller graph for this function:

◆ create_arch_event_table()

static int create_arch_event_table ( unsigned int  mask)
static

Definition at line 153 of file pfmlib_gen_ia32.c.

154{
156 unsigned int i, num_events = 0;
157 unsigned int m;
158
159 /*
160 * first pass: count the number of supported events
161 */
162 m = mask;
163 for(i=0; i < 7; i++, m>>=1) {
164 if ((m & 0x1) == 0)
165 num_events++;
166 }
168
170 if (gen_ia32_pe == NULL)
171 return PFMLIB_ERR_NOTSUPP;
172
173 /*
174 * second pass: populate the table
175 */
177 m = mask;
178 for(i=0, pe = gen_ia32_pe; i < 7; i++, m>>=1) {
179 if ((m & 0x1) == 0) {
180 *pe = gen_ia32_all_pe[i];
181 /*
182 * setup default event: cycles and inst_retired
183 */
188 pe++;
189 }
190 }
191 return PFMLIB_SUCCESS;
192}
int i
static pme_gen_ia32_entry_t gen_ia32_all_pe[]
#define PME_GEN_IA32_INSTRUCTIONS_RETIRED
#define PME_GEN_IA32_UNHALTED_CORE_CYCLES
static int num_events
static int gen_ia32_inst_retired_event
static pme_gen_ia32_entry_t * gen_ia32_pe
static int gen_ia32_cycle_event
pfm_pmu_support_t gen_ia32_support
static const pme_power_entry_t * pe
unsigned int pme_count
Definition: pfmlib_priv.h:35
Here is the caller graph for this function:

◆ pfm_gen_ia32_detect()

static int pfm_gen_ia32_detect ( void  )
static

Definition at line 232 of file pfmlib_gen_ia32.c.

233{
234 int ret, family;
235 char buffer[128];
236
237 ret = __pfm_getcpuinfo_attr("vendor_id", buffer, sizeof(buffer));
238 if (ret == -1)
239 return PFMLIB_ERR_NOTSUPP;
240
241 if (strcmp(buffer, "GenuineIntel"))
242 return PFMLIB_ERR_NOTSUPP;
243
244 ret = __pfm_getcpuinfo_attr("cpu family", buffer, sizeof(buffer));
245 if (ret == -1)
246 return PFMLIB_ERR_NOTSUPP;
247
248 family = atoi(buffer);
249
250 return check_arch_pmu(family);
251}
static int check_arch_pmu(int family)
int __pfm_getcpuinfo_attr(const char *attr, char *ret_buf, size_t maxlen)
Here is the call graph for this function:

◆ pfm_gen_ia32_dispatch_counters_v1()

static int pfm_gen_ia32_dispatch_counters_v1 ( pfmlib_input_param_t inp,
pfmlib_gen_ia32_input_param_t mod_in,
pfmlib_output_param_t outp 
)
static

Definition at line 336 of file pfmlib_gen_ia32.c.

337{
338 pfmlib_gen_ia32_input_param_t *param = mod_in;
342 pfmlib_reg_t *pc, *pd;
343 pfmlib_regmask_t *r_pmcs;
344 unsigned long plm;
345 unsigned int i, j, cnt, k, ucode, val;
346 unsigned int assign[PMU_GEN_IA32_MAX_COUNTERS];
347
348 e = inp->pfp_events;
349 pc = outp->pfp_pmcs;
350 pd = outp->pfp_pmds;
351 cnt = inp->pfp_event_count;
352 r_pmcs = &inp->pfp_unavail_pmcs;
353 cntrs = param ? param->pfp_gen_ia32_counters : NULL;
354
355 if (PFMLIB_DEBUG()) {
356 for (j=0; j < cnt; j++) {
357 DPRINT("ev[%d]=%s\n", j, gen_ia32_pe[e[j].event].pme_name);
358 }
359 }
360
361 if (cnt > gen_support->pmd_count)
362 return PFMLIB_ERR_TOOMANY;
363
364 for(i=0, j=0; j < cnt; j++) {
365 if (e[j].plm & (PFM_PLM1|PFM_PLM2)) {
366 DPRINT("event=%d invalid plm=%d\n", e[j].event, e[j].plm);
367 return PFMLIB_ERR_INVAL;
368 }
369
370 if (e[j].flags & ~PFMLIB_GEN_IA32_ALL_FLAGS) {
371 DPRINT("event=%d invalid flags=0x%lx\n", e[j].event, e[j].flags);
372 return PFMLIB_ERR_INVAL;
373 }
374
375 if (cntrs && pmu_version != 3 && (cntrs[j].flags & PFM_GEN_IA32_SEL_ANYTHR)) {
376 DPRINT("event=%d anythread requires architectural perfmon v3", e[j].event);
377 return PFMLIB_ERR_INVAL;
378 }
379 /*
380 * exclude restricted registers from assignment
381 */
382 while(i < gen_support->pmc_count && pfm_regmask_isset(r_pmcs, i)) i++;
383
384 if (i == gen_support->pmc_count)
385 return PFMLIB_ERR_TOOMANY;
386
387 /*
388 * events can be assigned to any counter
389 */
390 assign[j] = i++;
391 }
392
393 for (j=0; j < cnt ; j++ ) {
394 reg.val = 0; /* assume reserved bits are zerooed */
395
396 /* if plm is 0, then assume not specified per-event and use default */
397 plm = e[j].plm ? e[j].plm : inp->pfp_dfl_plm;
398
399 val = gen_ia32_pe[e[j].event].pme_code;
400
401 reg.sel_event_select = val & 0xff;
402
403 ucode = (val >> 8) & 0xff;
404
405 for(k=0; k < e[j].num_masks; k++)
406 ucode |= gen_ia32_pe[e[j].event].pme_umasks[e[j].unit_masks[k]].pme_ucode;
407
408 val |= ucode << 8;
409
410 reg.sel_unit_mask = ucode; /* use 8 least significant bits */
411 reg.sel_usr = plm & PFM_PLM3 ? 1 : 0;
412 reg.sel_os = plm & PFM_PLM0 ? 1 : 0;
413 reg.sel_en = 1; /* force enable bit to 1 */
414 reg.sel_int = 1; /* force APIC int to 1 */
415
416 reg.sel_cnt_mask = val >>24;
417 reg.sel_inv = val >> 23;
418 reg.sel_any = val >> 21;;
419 reg.sel_edge = val >> 18;
420
421 if (cntrs) {
422 if (!reg.sel_cnt_mask) {
423 /*
424 * counter mask is 8-bit wide, do not silently
425 * wrap-around
426 */
427 if (cntrs[i].cnt_mask > 255)
428 return PFMLIB_ERR_INVAL;
429 reg.sel_cnt_mask = cntrs[j].cnt_mask;
430 }
431
432 if (!reg.sel_edge)
433 reg.sel_edge = cntrs[j].flags & PFM_GEN_IA32_SEL_EDGE ? 1 : 0;
434 if (!reg.sel_inv)
435 reg.sel_inv = cntrs[j].flags & PFM_GEN_IA32_SEL_INV ? 1 : 0;
436 }
437
438 pc[j].reg_num = assign[j];
439 pc[j].reg_addr = GEN_IA32_SEL_BASE+assign[j];
440 pc[j].reg_value = reg.val;
441
442 pd[j].reg_num = assign[j];
443 pd[j].reg_addr = GEN_IA32_CTR_BASE+assign[j];
444
445 __pfm_vbprintf("[PERFEVTSEL%u(pmc%u)=0x%llx event_sel=0x%x umask=0x%x os=%d usr=%d en=%d int=%d inv=%d edge=%d cnt_mask=%d] %s\n",
446 assign[j],
447 assign[j],
448 reg.val,
450 reg.sel_unit_mask,
451 reg.sel_os,
452 reg.sel_usr,
453 reg.sel_en,
454 reg.sel_int,
455 reg.sel_inv,
456 reg.sel_edge,
457 reg.sel_cnt_mask,
458 gen_ia32_pe[e[j].event].pme_name);
459
460 __pfm_vbprintf("[PMC%u(pmd%u)]\n", pd[j].reg_num, pd[j].reg_num);
461 }
462 /* number of evtsel registers programmed */
463 outp->pfp_pmc_count = cnt;
464 outp->pfp_pmd_count = cnt;
465
466 return PFMLIB_SUCCESS;
467}
#define PFM_PLM2
Definition: pfmlib.h:52
#define PFM_PLM3
Definition: pfmlib.h:53
#define PFMLIB_ERR_INVAL
Definition: pfmlib.h:285
#define PFMLIB_ERR_TOOMANY
Definition: pfmlib.h:295
#define PFM_PLM0
Definition: pfmlib.h:50
static int pfm_regmask_isset(pfmlib_regmask_t *h, unsigned int b)
Definition: pfmlib.h:313
#define PFM_PLM1
Definition: pfmlib.h:51
#define PFMLIB_GEN_IA32_ALL_FLAGS
#define GEN_IA32_CTR_BASE
pfm_pmu_support_t * gen_support
static unsigned int pmu_version
#define GEN_IA32_SEL_BASE
#define PFM_GEN_IA32_SEL_INV
#define PMU_GEN_IA32_MAX_COUNTERS
#define PFM_GEN_IA32_SEL_EDGE
#define PFM_GEN_IA32_SEL_ANYTHR
void __pfm_vbprintf(const char *fmt,...)
Definition: pfmlib_priv.c:52
#define DPRINT(fmt, a...)
Definition: pfmlib_priv.h:90
#define PFMLIB_DEBUG()
Definition: pfmlib_priv.h:76
unsigned int pmc_count
Definition: pfmlib_priv.h:37
unsigned int pmd_count
Definition: pfmlib_priv.h:36
unsigned int num_masks
Definition: pfmlib.h:90
unsigned int plm
Definition: pfmlib.h:87
unsigned int event
Definition: pfmlib.h:86
pfmlib_gen_ia32_counter_t pfp_gen_ia32_counters[PMU_GEN_IA32_MAX_COUNTERS]
unsigned int pfp_dfl_plm
Definition: pfmlib.h:110
pfmlib_regmask_t pfp_unavail_pmcs
Definition: pfmlib.h:114
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
unsigned int pme_code
unsigned long long val
unsigned long sel_event_select
unsigned long sel_cnt_mask
unsigned long sel_unit_mask
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pfm_gen_ia32_dispatch_counters_v23()

static int pfm_gen_ia32_dispatch_counters_v23 ( pfmlib_input_param_t inp,
pfmlib_gen_ia32_input_param_t param,
pfmlib_output_param_t outp 
)
static

Definition at line 473 of file pfmlib_gen_ia32.c.

474{
475#define HAS_OPTIONS(x) (cntrs && (cntrs[i].flags || cntrs[i].cnt_mask))
476#define is_fixed_pmc(a) (a > 15)
477
481 pfmlib_reg_t *pc, *pd;
482 pfmlib_regmask_t *r_pmcs;
483 uint64_t val;
484 unsigned long plm;
485 unsigned int fixed_ctr_mask;
486 unsigned int npc = 0;
487 unsigned int i, j, n, k, ucode;
488 unsigned int assign[PMU_GEN_IA32_MAX_COUNTERS];
489 unsigned int next_gen, last_gen;
490
491 e = inp->pfp_events;
492 pc = outp->pfp_pmcs;
493 pd = outp->pfp_pmds;
494 n = inp->pfp_event_count;
495 r_pmcs = &inp->pfp_unavail_pmcs;
496 cntrs = param ? param->pfp_gen_ia32_counters : NULL;
497
498 if (n > gen_support->pmd_count)
499 return PFMLIB_ERR_TOOMANY;
500
501 /*
502 * initilize to empty
503 */
504 for(i=0; i < n; i++)
505 assign[i] = -1;
506
507 /*
508 * error checking
509 */
510 for(j=0; j < n; j++) {
511 /*
512 * only supports two priv levels for perf counters
513 */
514 if (e[j].plm & (PFM_PLM1|PFM_PLM2))
515 return PFMLIB_ERR_INVAL;
516
517 /*
518 * check for valid flags
519 */
520 if (cntrs && cntrs[j].flags & ~PFMLIB_GEN_IA32_ALL_FLAGS)
521 return PFMLIB_ERR_INVAL;
522
523 if (cntrs && pmu_version != 3 && (cntrs[j].flags & PFM_GEN_IA32_SEL_ANYTHR)) {
524 DPRINT("event=%d anythread requires architectural perfmon v3", e[j].event);
525 return PFMLIB_ERR_INVAL;
526 }
527 }
528
529 next_gen = 0; /* first generic counter */
530 last_gen = num_gen_cnt - 1; /* last generic counter */
531
532 fixed_ctr_mask = (1 << num_fixed_cnt) - 1;
533 /*
534 * first constraint: fixed counters (try using them first)
535 */
536 if (fixed_ctr_mask) {
537 for(i=0; i < n; i++) {
538 /* fixed counters do not support event options (filters) */
539 if (HAS_OPTIONS(i)) {
540 if (pmu_version != 3)
541 continue;
542 if (cntrs[i].flags != PFM_GEN_IA32_SEL_ANYTHR)
543 continue;
544 /* ok for ANYTHR */
545 }
546 for(j=0; j < num_fixed_cnt; j++) {
547 if ((fixed_ctr_mask & (1<<j)) && gen_ia32_pe[e[i].event].pme_fixed == (FIXED_PMD_BASE+j)) {
548 assign[i] = FIXED_PMD_BASE+j;
549 fixed_ctr_mask &= ~(1<<j);
550 break;
551 }
552 }
553 }
554 }
555 /*
556 * assign what is left
557 */
558 for(i=0; i < n; i++) {
559 if (assign[i] == -1) {
560 for(; next_gen <= last_gen; next_gen++) {
561 if (!pfm_regmask_isset(r_pmcs, next_gen))
562 break;
563 }
564 if (next_gen <= last_gen)
565 assign[i] = next_gen++;
566 else
567 return PFMLIB_ERR_NOASSIGN;
568 }
569 }
570 j = 0;
571
572 /* setup fixed counters */
573 reg.val = 0;
574 k = 0;
575 for (i=0; i < n ; i++ ) {
576 if (!is_fixed_pmc(assign[i]))
577 continue;
578 val = 0;
579 /* if plm is 0, then assume not specified per-event and use default */
580 plm = e[i].plm ? e[i].plm : inp->pfp_dfl_plm;
581 if (plm & PFM_PLM0)
582 val |= 1ULL;
583 if (plm & PFM_PLM3)
584 val |= 2ULL;
585
586 /* only possible for v3 */
587 if (cntrs && cntrs[i].flags & PFM_GEN_IA32_SEL_ANYTHR)
588 val |= 4ULL;
589
590 val |= 1ULL << 3; /* force APIC int (kernel may force it anyway) */
591
592 reg.val |= val << ((assign[i]-FIXED_PMD_BASE)<<2);
593
594 /* setup pd array */
595 pd[i].reg_num = assign[i];
597 }
598
599 if (reg.val) {
600 pc[npc].reg_num = 16;
601 pc[npc].reg_value = reg.val;
602 pc[npc].reg_addr = 0x38D;
603
604 __pfm_vbprintf("[FIXED_CTRL(pmc%u)=0x%"PRIx64,
605 pc[npc].reg_num,
606 reg.val);
607
608 for(i=0; i < num_fixed_cnt; i++) {
609 if (pmu_version != 3)
610 __pfm_vbprintf(" pmi%d=1 en%d=0x%"PRIx64,
611 i, i,
612 (reg.val >> (i*4)) & 0x3ULL);
613 else
614 __pfm_vbprintf(" pmi%d=1 en%d=0x%"PRIx64 " any%d=%"PRId64,
615 i, i,
616 (reg.val >> (i*4)) & 0x3ULL,
617 i,
618 !!((reg.val >> (i*4)) & 0x4ULL));
619 }
620
621 __pfm_vbprintf("] ");
622 for(i=0; i < num_fixed_cnt; i++) {
623 if ((fixed_ctr_mask & (0x1 << i)) == 0) {
624 if (i < MAX_EVENT_NAMES)
626 else
627 __pfm_vbprintf("??? ");
628 }
629 }
630 __pfm_vbprintf("\n");
631
632 npc++;
633
634 for (i=0; i < n ; i++ ) {
635 if (!is_fixed_pmc(assign[i]))
636 continue;
637 __pfm_vbprintf("[FIXED_CTR%u(pmd%u)]\n", pd[i].reg_num, pd[i].reg_num);
638 }
639 }
640
641 for (i=0; i < n ; i++ ) {
642 /* skip fixed counters */
643 if (is_fixed_pmc(assign[i]))
644 continue;
645
646 reg.val = 0; /* assume reserved bits are zerooed */
647
648 /* if plm is 0, then assume not specified per-event and use default */
649 plm = e[i].plm ? e[i].plm : inp->pfp_dfl_plm;
650
651 val = gen_ia32_pe[e[i].event].pme_code;
652
653 reg.sel_event_select = val & 0xff;
654
655 ucode = (val >> 8) & 0xff;
656
657 for(k=0; k < e[i].num_masks; k++)
658 ucode |= gen_ia32_pe[e[i].event].pme_umasks[e[i].unit_masks[k]].pme_ucode;
659
660 val |= ucode << 8;
661
662 reg.sel_unit_mask = ucode;
663 reg.sel_usr = plm & PFM_PLM3 ? 1 : 0;
664 reg.sel_os = plm & PFM_PLM0 ? 1 : 0;
665 reg.sel_en = 1; /* force enable bit to 1 */
666 reg.sel_int = 1; /* force APIC int to 1 */
667
668 reg.sel_cnt_mask = val >>24;
669 reg.sel_inv = val >> 23;
670 reg.sel_any = val >> 21;;
671 reg.sel_edge = val >> 18;
672
673 if (cntrs) {
674 if (!reg.sel_cnt_mask) {
675 /*
676 * counter mask is 8-bit wide, do not silently
677 * wrap-around
678 */
679 if (cntrs[i].cnt_mask > 255)
680 return PFMLIB_ERR_INVAL;
681 reg.sel_cnt_mask = cntrs[i].cnt_mask;
682 }
683 if (!reg.sel_edge)
684 reg.sel_edge = cntrs[i].flags & PFM_GEN_IA32_SEL_EDGE ? 1 : 0;
685 if (!reg.sel_inv)
686 reg.sel_inv = cntrs[i].flags & PFM_GEN_IA32_SEL_INV ? 1 : 0;
687 if (!reg.sel_any)
688 reg.sel_any = cntrs[i].flags & PFM_GEN_IA32_SEL_ANYTHR? 1 : 0;
689 }
690
691 pc[npc].reg_num = assign[i];
692 pc[npc].reg_value = reg.val;
693 pc[npc].reg_addr = GEN_IA32_SEL_BASE+assign[i];
694 pd[i].reg_num = assign[i];
695 pd[i].reg_addr = GEN_IA32_CTR_BASE+assign[i];
696
697 if (pmu_version < 3)
698 __pfm_vbprintf("[PERFEVTSEL%u(pmc%u)=0x%"PRIx64" event_sel=0x%x umask=0x%x os=%d usr=%d en=%d int=%d inv=%d edge=%d cnt_mask=%d] %s\n",
699 pc[npc].reg_num,
700 pc[npc].reg_num,
701 reg.val,
703 reg.sel_unit_mask,
704 reg.sel_os,
705 reg.sel_usr,
706 reg.sel_en,
707 reg.sel_int,
708 reg.sel_inv,
709 reg.sel_edge,
710 reg.sel_cnt_mask,
711 gen_ia32_pe[e[i].event].pme_name);
712 else
713 __pfm_vbprintf("[PERFEVTSEL%u(pmc%u)=0x%"PRIx64" event_sel=0x%x umask=0x%x os=%d usr=%d en=%d int=%d inv=%d edge=%d cnt_mask=%d anythr=%d] %s\n",
714 pc[npc].reg_num,
715 pc[npc].reg_num,
716 reg.val,
718 reg.sel_unit_mask,
719 reg.sel_os,
720 reg.sel_usr,
721 reg.sel_en,
722 reg.sel_int,
723 reg.sel_inv,
724 reg.sel_edge,
725 reg.sel_cnt_mask,
726 reg.sel_any,
727 gen_ia32_pe[e[i].event].pme_name);
728
729 __pfm_vbprintf("[PMC%u(pmd%u)]\n",
730 pd[i].reg_num,
731 pd[i].reg_num);
732
733 npc++;
734 }
735 /* number of evtsel/ctr registers programmed */
736 outp->pfp_pmc_count = npc;
737 outp->pfp_pmd_count = n;
738 return PFMLIB_SUCCESS;
739}
#define PFMLIB_ERR_NOASSIGN
Definition: pfmlib.h:288
#define GEN_IA32_FIXED_CTR_BASE
#define HAS_OPTIONS(x)
static const char * fixed_event_names[]
#define is_fixed_pmc(a)
static unsigned int num_gen_cnt
#define MAX_EVENT_NAMES
#define FIXED_PMD_BASE
static unsigned int num_fixed_cnt
unsigned int pme_fixed
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pfm_gen_ia32_dispatch_events()

static int pfm_gen_ia32_dispatch_events ( pfmlib_input_param_t inp,
void *  model_in,
pfmlib_output_param_t outp,
void *  model_out 
)
static

Definition at line 742 of file pfmlib_gen_ia32.c.

743{
744 pfmlib_gen_ia32_input_param_t *mod_in = model_in;
745
746 if (inp->pfp_dfl_plm & (PFM_PLM1|PFM_PLM2)) {
747 DPRINT("invalid plm=%x\n", inp->pfp_dfl_plm);
748 return PFMLIB_ERR_INVAL;
749 }
750
751 /* simplfied v1 (no fixed counters */
752 if (pmu_version == 1)
753 return pfm_gen_ia32_dispatch_counters_v1(inp, mod_in, outp);
754 /* v2 or above */
755 return pfm_gen_ia32_dispatch_counters_v23(inp, mod_in, outp);
756}
static int pfm_gen_ia32_dispatch_counters_v23(pfmlib_input_param_t *inp, pfmlib_gen_ia32_input_param_t *param, pfmlib_output_param_t *outp)
static int pfm_gen_ia32_dispatch_counters_v1(pfmlib_input_param_t *inp, pfmlib_gen_ia32_input_param_t *mod_in, pfmlib_output_param_t *outp)
Here is the call graph for this function:

◆ pfm_gen_ia32_get_cycle_event()

static int pfm_gen_ia32_get_cycle_event ( pfmlib_event_t e)
static

Definition at line 868 of file pfmlib_gen_ia32.c.

869{
870 if (gen_ia32_cycle_event == -1)
871 return PFMLIB_ERR_NOTSUPP;
872
874 return PFMLIB_SUCCESS;
875
876}

◆ pfm_gen_ia32_get_event_code()

static int pfm_gen_ia32_get_event_code ( unsigned int  i,
unsigned int  cnt,
int code 
)
static

Definition at line 759 of file pfmlib_gen_ia32.c.

760{
761 if (cnt != PFMLIB_CNT_FIRST && cnt > gen_support->pmc_count)
762 return PFMLIB_ERR_INVAL;
763
764 *code = gen_ia32_pe[i].pme_code;
765
766 return PFMLIB_SUCCESS;
767}
#define PFMLIB_CNT_FIRST
Definition: pfmlib_priv.h:62

◆ pfm_gen_ia32_get_event_counters()

static void pfm_gen_ia32_get_event_counters ( unsigned int  j,
pfmlib_regmask_t counters 
)
static

Definition at line 770 of file pfmlib_gen_ia32.c.

771{
772 unsigned int i;
773
774 memset(counters, 0, sizeof(*counters));
775 for(i=0; i < num_gen_cnt; i++)
776 pfm_regmask_set(counters, i);
777
778 for(i=0; i < num_fixed_cnt; i++) {
779 if (gen_ia32_pe[j].pme_fixed == (FIXED_PMD_BASE+i))
781 }
782}
static int pfm_regmask_set(pfmlib_regmask_t *h, unsigned int b)
Definition: pfmlib.h:321
Here is the call graph for this function:

◆ pfm_gen_ia32_get_event_description()

static int pfm_gen_ia32_get_event_description ( unsigned int  ev,
char **  str 
)
static

Definition at line 822 of file pfmlib_gen_ia32.c.

823{
824 char *s;
825 s = gen_ia32_pe[ev].pme_desc;
826 if (s) {
827 *str = strdup(s);
828 } else {
829 *str = NULL;
830 }
831 return PFMLIB_SUCCESS;
832}
double s
Definition: byte_profile.c:36
char * pme_desc

◆ pfm_gen_ia32_get_event_mask_code()

static int pfm_gen_ia32_get_event_mask_code ( unsigned int  ev,
unsigned int  midx,
unsigned int code 
)
static

Definition at line 861 of file pfmlib_gen_ia32.c.

862{
863 *code =gen_ia32_pe[ev].pme_umasks[midx].pme_ucode;
864 return PFMLIB_SUCCESS;
865}
pme_gen_ia32_umask_t pme_umasks[PFMLIB_GEN_IA32_MAX_UMASK]

◆ pfm_gen_ia32_get_event_mask_desc()

static int pfm_gen_ia32_get_event_mask_desc ( unsigned int  ev,
unsigned int  midx,
char **  str 
)
static

Definition at line 841 of file pfmlib_gen_ia32.c.

842{
843 char *s;
844
845 s = gen_ia32_pe[ev].pme_umasks[midx].pme_udesc;
846 if (s) {
847 *str = strdup(s);
848 } else {
849 *str = NULL;
850 }
851 return PFMLIB_SUCCESS;
852}

◆ pfm_gen_ia32_get_event_mask_name()

static char * pfm_gen_ia32_get_event_mask_name ( unsigned int  ev,
unsigned int  midx 
)
static

Definition at line 835 of file pfmlib_gen_ia32.c.

836{
837 return gen_ia32_pe[ev].pme_umasks[midx].pme_uname;
838}

◆ pfm_gen_ia32_get_event_name()

static char * pfm_gen_ia32_get_event_name ( unsigned int  i)
static

Definition at line 816 of file pfmlib_gen_ia32.c.

817{
818 return gen_ia32_pe[i].pme_name;
819}

◆ pfm_gen_ia32_get_hw_counter_width()

static void pfm_gen_ia32_get_hw_counter_width ( unsigned int width)
static

Definition at line 804 of file pfmlib_gen_ia32.c.

805{
806 /*
807 * Even though, CPUID 0xa returns in eax the actual counter
808 * width, the architecture specifies that writes are limited
809 * to lower 32-bits. As such, only the lower 31 bits have full
810 * degree of freedom. That is the "useable" counter width.
811 */
813}
#define PMU_GEN_IA32_COUNTER_WIDTH

◆ pfm_gen_ia32_get_impl_counters()

static void pfm_gen_ia32_get_impl_counters ( pfmlib_regmask_t impl_counters)
static

Definition at line 797 of file pfmlib_gen_ia32.c.

798{
799 /* all pmds are counters */
800 *impl_counters = gen_ia32_impl_pmds;
801}
static pfmlib_regmask_t gen_ia32_impl_pmds

◆ pfm_gen_ia32_get_impl_pmcs()

static void pfm_gen_ia32_get_impl_pmcs ( pfmlib_regmask_t impl_pmcs)
static

Definition at line 785 of file pfmlib_gen_ia32.c.

786{
787 *impl_pmcs = gen_ia32_impl_pmcs;
788}
static pfmlib_regmask_t gen_ia32_impl_pmcs

◆ pfm_gen_ia32_get_impl_pmds()

static void pfm_gen_ia32_get_impl_pmds ( pfmlib_regmask_t impl_pmds)
static

Definition at line 791 of file pfmlib_gen_ia32.c.

792{
793 *impl_pmds = gen_ia32_impl_pmds;
794}

◆ pfm_gen_ia32_get_inst_retired()

static int pfm_gen_ia32_get_inst_retired ( pfmlib_event_t e)
static

Definition at line 879 of file pfmlib_gen_ia32.c.

880{
882 return PFMLIB_ERR_NOTSUPP;
883
885 return PFMLIB_SUCCESS;
886}

◆ pfm_gen_ia32_get_num_event_masks()

static unsigned int pfm_gen_ia32_get_num_event_masks ( unsigned int  ev)
static

Definition at line 855 of file pfmlib_gen_ia32.c.

856{
857 return gen_ia32_pe[ev].pme_numasks;
858}
unsigned int pme_numasks

◆ pfm_gen_ia32_init()

static int pfm_gen_ia32_init ( void  )
static

Definition at line 254 of file pfmlib_gen_ia32.c.

255{
256 union {
257 unsigned int val;
258 pmu_eax_t eax;
259 pmu_edx_t edx;
260 } eax, ecx, edx, ebx;
261 unsigned int num_cnt, i;
262 int ret;
263
264 /*
265 * extract architected PMU information
266 */
267 if (forced_pmu == PFMLIB_NO_PMU) {
268 cpuid(0xa, &eax.val, &ebx.val, &ecx.val, &edx.val);
269 } else {
270 /*
271 * when forced, simulate v2
272 * with 2 generic and 3 fixed counters
273 */
274 eax.eax.version = 3;
275 eax.eax.num_cnt = 2;
276 eax.eax.cnt_width = 40;
277 eax.eax.ebx_length = 0; /* unused */
278 ebx.val = 0;
279 edx.edx.num_cnt = 3;
280 edx.edx.cnt_width = 40;
281 }
282
283 num_cnt = eax.eax.num_cnt;
284 pmu_version = eax.eax.version;
285
286 /*
287 * populate impl_pm* bitmasks for generic counters
288 */
289 for(i=0; i < num_cnt; i++) {
292 }
293
294 /* check for fixed counters */
295 if (pmu_version >= 2) {
296 /*
297 * As described in IA-32 Developer's manual vol 3b
298 * in section 18.12.2.1, early processors supporting
299 * V2 may report invalid information concerning the fixed
300 * counters. So we compensate for this here by forcing
301 * num_cnt to 3.
302 */
303 if (edx.edx.num_cnt == 0)
304 edx.edx.num_cnt = 3;
305
306 for(i=0; i < edx.edx.num_cnt; i++)
308 if (i)
310
311 }
312
313 num_gen_cnt = eax.eax.num_cnt;
314 num_fixed_cnt = edx.edx.num_cnt;
315
319
320 __pfm_vbprintf("Intel architected PMU: version=%d num_gen=%u num_fixed=%u pmc=%u pmd=%d\n",
325
326 ret = create_arch_event_table(ebx.val);
327 if (ret != PFMLIB_SUCCESS)
328 return ret;
329
331
332 return PFMLIB_SUCCESS;
333}
#define PFMLIB_NO_PMU
Definition: pfmlib.h:221
int forced_pmu
static int create_arch_event_table(unsigned int mask)
unsigned int num_cnt
Definition: pfmlib_priv.h:38
Here is the call graph for this function:

Variable Documentation

◆ fixed_event_names

const char* fixed_event_names[] ={ "INSTRUCTIONS_RETIRED", "UNHALTED_CORE_CYCLES ", "UNHALTED_REFERENCE_CYCLES " }
static

Definition at line 469 of file pfmlib_gen_ia32.c.

◆ gen_ia32_cycle_event

int gen_ia32_cycle_event
static

Definition at line 111 of file pfmlib_gen_ia32.c.

◆ gen_ia32_impl_pmcs

pfmlib_regmask_t gen_ia32_impl_pmcs
static

Definition at line 147 of file pfmlib_gen_ia32.c.

◆ gen_ia32_impl_pmds

pfmlib_regmask_t gen_ia32_impl_pmds
static

Definition at line 147 of file pfmlib_gen_ia32.c.

◆ gen_ia32_inst_retired_event

int gen_ia32_inst_retired_event
static

Definition at line 111 of file pfmlib_gen_ia32.c.

◆ gen_ia32_pe

pme_gen_ia32_entry_t* gen_ia32_pe
static

Definition at line 109 of file pfmlib_gen_ia32.c.

◆ gen_ia32_support

pfm_pmu_support_t gen_ia32_support
Initial value:
={
.pmu_name = "Intel architectural PMU",
.pmu_type = PFMLIB_GEN_IA32_PMU,
.pme_count = 0,
.pmc_count = 0,
.pmd_count = 0,
.num_cnt = 0,
.get_event_code = pfm_gen_ia32_get_event_code,
.get_event_name = pfm_gen_ia32_get_event_name,
.get_event_counters = pfm_gen_ia32_get_event_counters,
.dispatch_events = pfm_gen_ia32_dispatch_events,
.pmu_detect = pfm_gen_ia32_detect,
.pmu_init = pfm_gen_ia32_init,
.get_impl_pmcs = pfm_gen_ia32_get_impl_pmcs,
.get_impl_pmds = pfm_gen_ia32_get_impl_pmds,
.get_impl_counters = pfm_gen_ia32_get_impl_counters,
.get_hw_counter_width = pfm_gen_ia32_get_hw_counter_width,
.get_cycle_event = pfm_gen_ia32_get_cycle_event,
.get_inst_retired_event = pfm_gen_ia32_get_inst_retired,
.get_num_event_masks = pfm_gen_ia32_get_num_event_masks,
.get_event_mask_name = pfm_gen_ia32_get_event_mask_name,
.get_event_mask_code = pfm_gen_ia32_get_event_mask_code,
.get_event_mask_desc = pfm_gen_ia32_get_event_mask_desc
}
#define PFMLIB_GEN_IA32_PMU
Definition: pfmlib.h:228
static char * pfm_gen_ia32_get_event_mask_name(unsigned int ev, unsigned int midx)
static int pfm_gen_ia32_get_event_description(unsigned int ev, char **str)
static void pfm_gen_ia32_get_impl_counters(pfmlib_regmask_t *impl_counters)
static char * pfm_gen_ia32_get_event_name(unsigned int i)
static int pfm_gen_ia32_dispatch_events(pfmlib_input_param_t *inp, void *model_in, pfmlib_output_param_t *outp, void *model_out)
static unsigned int pfm_gen_ia32_get_num_event_masks(unsigned int ev)
static void pfm_gen_ia32_get_impl_pmcs(pfmlib_regmask_t *impl_pmcs)
static int pfm_gen_ia32_get_cycle_event(pfmlib_event_t *e)
static void pfm_gen_ia32_get_hw_counter_width(unsigned int *width)
static int pfm_gen_ia32_get_event_code(unsigned int i, unsigned int cnt, int *code)
static int pfm_gen_ia32_init(void)
static int pfm_gen_ia32_get_event_mask_code(unsigned int ev, unsigned int midx, unsigned int *code)
static void pfm_gen_ia32_get_impl_pmds(pfmlib_regmask_t *impl_pmds)
static void pfm_gen_ia32_get_event_counters(unsigned int j, pfmlib_regmask_t *counters)
static int pfm_gen_ia32_get_inst_retired(pfmlib_event_t *e)
static int pfm_gen_ia32_detect(void)
static int pfm_gen_ia32_get_event_mask_desc(unsigned int ev, unsigned int midx, char **str)

Definition at line 889 of file pfmlib_gen_ia32.c.

◆ gen_support

pfm_pmu_support_t* gen_support

Definition at line 61 of file pfmlib_gen_ia32.c.

◆ num_fixed_cnt

unsigned int num_fixed_cnt
static

Definition at line 112 of file pfmlib_gen_ia32.c.

◆ num_gen_cnt

unsigned int num_gen_cnt
static

Definition at line 112 of file pfmlib_gen_ia32.c.

◆ pmu_version

unsigned int pmu_version
static

Definition at line 112 of file pfmlib_gen_ia32.c.