PAPI 7.1.0.0
Loading...
Searching...
No Matches
pfmlib_amd64.c
Go to the documentation of this file.
1/*
2 * pfmlib_amd64.c : support for the AMD64 architected PMU
3 * (for both 64 and 32 bit modes)
4 *
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 <stdlib.h>
30
31/* public headers */
33
34/* private headers */
35#include "pfmlib_priv.h" /* library private */
36#include "pfmlib_amd64_priv.h" /* architecture private */
37#include "amd64_events.h" /* PMU private */
38
39/* let's define some handy shortcuts! */
40#define sel_event_mask perfsel.sel_event_mask
41#define sel_unit_mask perfsel.sel_unit_mask
42#define sel_usr perfsel.sel_usr
43#define sel_os perfsel.sel_os
44#define sel_edge perfsel.sel_edge
45#define sel_pc perfsel.sel_pc
46#define sel_int perfsel.sel_int
47#define sel_en perfsel.sel_en
48#define sel_inv perfsel.sel_inv
49#define sel_cnt_mask perfsel.sel_cnt_mask
50#define sel_event_mask2 perfsel.sel_event_mask2
51#define sel_guest perfsel.sel_guest
52#define sel_host perfsel.sel_host
53
54#define CHECK_AMD_ARCH(reg) \
55 ((reg).sel_event_mask2 || (reg).sel_guest || (reg).sel_host)
56
57#define PFMLIB_AMD64_HAS_COMBO(_e) \
58 ((pfm_amd64_get_event_entry(_e)->pme_flags & PFMLIB_AMD64_UMASK_COMBO) != 0)
59
60
61#define PFMLIB_AMD64_ALL_FLAGS \
62 (PFM_AMD64_SEL_INV|PFM_AMD64_SEL_EDGE|PFM_AMD64_SEL_GUEST|PFM_AMD64_SEL_HOST)
63/*
64 * Description of the PMC register mappings use by
65 * this module:
66 * pfp_pmcs[].reg_num:
67 * 0 -> PMC0 -> PERFEVTSEL0 -> MSR @ 0xc0010000
68 * 1 -> PMC1 -> PERFEVTSEL1 -> MSR @ 0xc0010001
69 * ...
70 * pfp_pmds[].reg_num:
71 * 0 -> PMD0 -> PERCTR0 -> MSR @ 0xc0010004
72 * 1 -> PMD1 -> PERCTR1 -> MSR @ 0xc0010005
73 * ...
74 */
75#define AMD64_SEL_BASE 0xc0010000
76#define AMD64_CTR_BASE 0xc0010004
77#define AMD64_SEL_BASE_F15H 0xc0010200
78#define AMD64_CTR_BASE_F15H 0xc0010201
79
80static struct {
82 char *name;
83 unsigned int cpu_clks;
84 unsigned int ret_inst;
85 int family;
86 int model;
90
92 .pme_name = "<unsupported>",
93 .pme_desc = "This event is not supported be this cpu revision.",
94 .pme_code = ~0,
95 .pme_flags = PFMLIB_AMD64_NOT_SUPP,
96};
97
99
100#define amd64_revision amd64_pmu.revision
101#define amd64_event_count amd64_support.pme_count
102#define amd64_cpu_clks amd64_pmu.cpu_clks
103#define amd64_ret_inst amd64_pmu.ret_inst
104#define amd64_events amd64_pmu.events
105#define amd64_family amd64_pmu.family
106#define amd64_model amd64_pmu.model
107#define amd64_stepping amd64_pmu.stepping
108
109/* AMD architectural pmu features starts with family 10h */
110#define IS_AMD_ARCH() (amd64_pmu.family >= 0x10)
111
112static amd64_rev_t
114{
115 switch (family) {
116 case 6:
117 return AMD64_K7;
118 case 0x0f:
119 switch (model >> 4) {
120 case 0:
121 if (model == 5 && stepping < 2)
122 return AMD64_K8_REV_B;
123 if (model == 4 && stepping == 0)
124 return AMD64_K8_REV_B;
125 return AMD64_K8_REV_C;
126 case 1:
127 return AMD64_K8_REV_D;
128 case 2:
129 case 3:
130 return AMD64_K8_REV_E;
131 case 4:
132 case 5:
133 case 0xc:
134 return AMD64_K8_REV_F;
135 case 6:
136 case 7:
137 case 8:
138 return AMD64_K8_REV_G;
139 }
140 return AMD64_K8_REV_B;
141 case 0x10:
142 switch (model) {
143 case 4:
144 case 5:
145 case 6:
146 return AMD64_FAM10H_REV_C;
147 case 8:
148 case 9:
149 return AMD64_FAM10H_REV_D;
150 case 10:
151 return AMD64_FAM10H_REV_E;
152 }
153 return AMD64_FAM10H_REV_B;
154 case 0x15:
155 return AMD64_FAM15H_REV_B;
156 }
157
158 return AMD64_CPU_UN;
159}
160
161/*
162 * .byte 0x53 == push ebx. it's universal for 32 and 64 bit
163 * .byte 0x5b == pop ebx.
164 * Some gcc's (4.1.2 on Core2) object to pairing push/pop and ebx in 64 bit mode.
165 * Using the opcode directly avoids this problem.
166 */
167static inline void cpuid(unsigned int op, unsigned int *a, unsigned int *b,
168 unsigned int *c, unsigned int *d)
169{
170 __asm__ __volatile__ (".byte 0x53\n\tcpuid\n\tmovl %%ebx, %%esi\n\t.byte 0x5b"
171 : "=a" (*a),
172 "=S" (*b),
173 "=c" (*c),
174 "=d" (*d)
175 : "a" (op));
176}
177
178static void
180{
181 amd64_pmu.revision = revision;
182 amd64_pmu.name = (char *)amd64_cpu_strs[revision];
184
185 /* K8 (default) */
194
195 switch (amd64_pmu.family) {
196 case 6:
197 /* K7 */
202 return;
203 case 0x10:
204 /* Family 10h */
211 return;
212 case 0x15:
213 /* Family 15h */
221 return;
222 }
223}
224
225static int
227{
228 unsigned int a, b, c, d;
229 char buffer[128];
230
231 cpuid(0, &a, &b, &c, &d);
232 strncpy(&buffer[0], (char *)(&b), 4);
233 strncpy(&buffer[4], (char *)(&d), 4);
234 strncpy(&buffer[8], (char *)(&c), 4);
235 buffer[12] = '\0';
236
237 if (strcmp(buffer, "AuthenticAMD"))
238 return PFMLIB_ERR_NOTSUPP;
239
240 cpuid(1, &a, &b, &c, &d);
241 amd64_family = (a >> 8) & 0x0000000f; // bits 11 - 8
242 amd64_model = (a >> 4) & 0x0000000f; // Bits 7 - 4
243 if (amd64_family == 0xf) {
244 amd64_family += (a >> 20) & 0x000000ff; // Extended family
245 amd64_model |= (a >> 12) & 0x000000f0; // Extended model
246 }
247 amd64_stepping = a & 0x0000000f; // bits 3 - 0
248
250
252 return PFMLIB_ERR_NOTSUPP;
253
254 return PFMLIB_SUCCESS;
255}
256
257static void
259{
260 char *str;
261 int pmu_type;
262
263 /* parses LIBPFM_FORCE_PMU=16,<family>,<model>,<stepping> */
264 str = getenv("LIBPFM_FORCE_PMU");
265 if (!str)
266 goto failed;
267 pmu_type = strtol(str, &str, 10);
268 if (pmu_type != PFMLIB_AMD64_PMU)
269 goto failed;
270 if (!*str || *str++ != ',')
271 goto failed;
272 amd64_family = strtol(str, &str, 10);
273 if (!*str || *str++ != ',')
274 goto failed;
275 amd64_model = strtol(str, &str, 10);
276 if (!*str || *str++ != ',')
277 goto failed;
278 amd64_stepping = strtol(str, &str, 10);
279 if (!*str)
280 goto done;
281failed:
282 DPRINT("force failed at: %s\n", str ? str : "<NULL>");
283 /* force AMD64 = force to Barcelona */
284 amd64_family = 16;
285 amd64_model = 2;
286 amd64_stepping = 2;
287done:
290}
291
292static int
294{
297
298 __pfm_vbprintf("AMD family=%d model=0x%x stepping=0x%x rev=%s, %s\n",
304
306
307 return PFMLIB_SUCCESS;
308}
309
310static int
311is_valid_rev(unsigned int flags, int revision)
312{
313 if (revision < from_revision(flags))
314 return 0;
315
316 if (revision > till_revision(flags))
317 return 0;
318
319 /* no restrictions or matches restrictions */
320 return 1;
321}
322
323static inline pme_amd64_entry_t
324*pfm_amd64_get_event_entry(unsigned int index)
325{
326 /*
327 * Since there are no NULL pointer checks for the return
328 * value, &unsupported_event is returned instead. Function
329 * is_valid_index() may be used to validate the index.
330 */
331 pme_amd64_entry_t *event;
332 if (index >= amd64_event_count)
333 return &unsupported_event;
334 event = &amd64_events[index];
336 return &unsupported_event;
337 return event;
338}
339
340static inline int
341is_valid_index(unsigned int index)
342{
344}
345
346/*
347 * Automatically dispatch events to corresponding counters following constraints.
348 */
349static int
351{
352 pfmlib_amd64_input_param_t *param = mod_in;
356 pfmlib_reg_t *pc, *pd;
357 pfmlib_regmask_t *r_pmcs;
358 unsigned long plm;
359 unsigned int i, j, k, cnt, umask;
360 unsigned int assign[PMU_AMD64_MAX_COUNTERS];
361
362 e = inp->pfp_events;
363 pc = outp->pfp_pmcs;
364 pd = outp->pfp_pmds;
365 cnt = inp->pfp_event_count;
366 r_pmcs = &inp->pfp_unavail_pmcs;
367 cntrs = param ? param->pfp_amd64_counters : NULL;
368
369 /* priviledge level 1 and 2 are not supported */
370 if (inp->pfp_dfl_plm & (PFM_PLM1|PFM_PLM2)) {
371 DPRINT("invalid plm=%x\n", inp->pfp_dfl_plm);
372 return PFMLIB_ERR_INVAL;
373 }
374
375 if (PFMLIB_DEBUG()) {
376 for (j=0; j < cnt; j++) {
377 DPRINT("ev[%d]=%s\n", j, pfm_amd64_get_event_entry(e[j].event)->pme_name);
378 }
379 }
380
381 if (cnt > amd64_support.num_cnt) return PFMLIB_ERR_TOOMANY;
382
383 for(i=0, j=0; j < cnt; j++, i++) {
384 /*
385 * AMD64 only supports two priv levels for perf counters
386 */
387 if (e[j].plm & (PFM_PLM1|PFM_PLM2)) {
388 DPRINT("event=%d invalid plm=%d\n", e[j].event, e[j].plm);
389 return PFMLIB_ERR_INVAL;
390 }
391 /*
392 * check illegal unit masks combination
393 */
394 if (e[j].num_masks > 1 && PFMLIB_AMD64_HAS_COMBO(e[j].event) == 0) {
395 DPRINT("event does not supports unit mask combination\n");
396 return PFMLIB_ERR_FEATCOMB;
397 }
398
399 /*
400 * check revision restrictions at the event level
401 * (check at the umask level later)
402 */
403 if (!is_valid_rev(pfm_amd64_get_event_entry(e[i].event)->pme_flags,
405 DPRINT("CPU does not have correct revision level\n");
406 return PFMLIB_ERR_BADHOST;
407 }
408 if (cntrs && (cntrs[j].flags & ~PFMLIB_AMD64_ALL_FLAGS)) {
409 DPRINT("invalid AMD64 flags\n");
410 return PFMLIB_ERR_INVAL;
411 }
412
413 if (cntrs && (cntrs[j].cnt_mask >= PMU_AMD64_CNT_MASK_MAX)) {
414 DPRINT("event=%d invalid cnt_mask=%d: must be < %u\n",
415 e[j].event,
416 cntrs[j].cnt_mask,
418 return PFMLIB_ERR_INVAL;
419 }
420
421 /*
422 * exclude unavailable registers from assignment
423 */
424 while(i < amd64_support.num_cnt && pfm_regmask_isset(r_pmcs, i))
425 i++;
426
427 if (i == amd64_support.num_cnt)
428 return PFMLIB_ERR_NOASSIGN;
429
430 assign[j] = i;
431 }
432
433 for (j=0; j < cnt ; j++ ) {
434 reg.val = 0; /* assume reserved bits are zerooed */
435
436 /* if plm is 0, then assume not specified per-event and use default */
437 plm = e[j].plm ? e[j].plm : inp->pfp_dfl_plm;
438
439 if (!is_valid_rev(pfm_amd64_get_event_entry(e[j].event)->pme_flags,
441 return PFMLIB_ERR_BADHOST;
442
444 reg.sel_event_mask2 = pfm_amd64_get_event_entry(e[j].event)->pme_code >> 8;
445
446 umask = 0;
447 for(k=0; k < e[j].num_masks; k++) {
448 /* check unit mask revision restrictions */
449 if (!is_valid_rev(pfm_amd64_get_event_entry(e[j].event)->pme_umasks[e[j].unit_masks[k]].pme_uflags,
451 return PFMLIB_ERR_BADHOST;
452
453 umask |= pfm_amd64_get_event_entry(e[j].event)->pme_umasks[e[j].unit_masks[k]].pme_ucode;
454 }
455 if (e[j].event == PME_AMD64_IBSOP) {
456 ibsopctl_t ibsopctl;
457
458 ibsopctl.val = 0;
459 ibsopctl.reg.ibsopen = 1;
460
462 DPRINT("IBSOP:UOPS available on Rev C and later processors\n");
463 return PFMLIB_ERR_BADHOST;
464 }
465
466 /*
467 * 1: cycles
468 * 2: uops
469 */
470 ibsopctl.reg.ibsopcntl = umask == 0x1 ? 0 : 1;
471
472 pc[j].reg_value = ibsopctl.val;
474 pc[j].reg_addr = 0xc0011033;
475
476 __pfm_vbprintf("[IBSOPCTL(pmc%u)=0x%llx en=%d uops=%d maxcnt=0x%x]\n",
478 ibsopctl.val,
479 ibsopctl.reg.ibsopen,
480 ibsopctl.reg.ibsopcntl,
481 ibsopctl.reg.ibsopmaxcnt);
482
484 pd[j].reg_addr = 0xc0011033;
485 __pfm_vbprintf("[IBSOPCTL(pmd%u)]\n", PMU_AMD64_IBSOPCTL_PMD);
486
487 } else if (e[j].event == PME_AMD64_IBSFETCH) {
488 ibsfetchctl_t ibsfetchctl;
489
490 ibsfetchctl.val = 0;
491 ibsfetchctl.reg.ibsfetchen = 1;
492 ibsfetchctl.reg.ibsranden = umask == 0x1 ? 1 : 0;
493
494 pc[j].reg_value = ibsfetchctl.val;
496 pc[j].reg_addr = 0xc0011031;
497
499 pd[j].reg_addr = 0xc0011031;
500
501 __pfm_vbprintf("[IBSFETCHCTL(pmc%u)=0x%llx en=%d maxcnt=0x%x rand=%u]\n",
503 ibsfetchctl.val,
504 ibsfetchctl.reg.ibsfetchen,
505 ibsfetchctl.reg.ibsfetchmaxcnt,
506 ibsfetchctl.reg.ibsranden);
507
508 __pfm_vbprintf("[IBSOPFETCH(pmd%u)]\n", PMU_AMD64_IBSFETCHCTL_PMD);
509
510 } else {
511 reg.sel_unit_mask = umask;
512 reg.sel_usr = plm & PFM_PLM3 ? 1 : 0;
513 reg.sel_os = plm & PFM_PLM0 ? 1 : 0;
514 reg.sel_en = 1; /* force enable bit to 1 */
515 reg.sel_int = 1; /* force APIC int to 1 */
516 if (cntrs) {
517 reg.sel_cnt_mask = cntrs[j].cnt_mask;
518 reg.sel_edge = cntrs[j].flags & PFM_AMD64_SEL_EDGE ? 1 : 0;
519 reg.sel_inv = cntrs[j].flags & PFM_AMD64_SEL_INV ? 1 : 0;
520 reg.sel_guest = cntrs[j].flags & PFM_AMD64_SEL_GUEST ? 1 : 0;
521 reg.sel_host = cntrs[j].flags & PFM_AMD64_SEL_HOST ? 1 : 0;
522 }
523 pc[j].reg_num = assign[j];
524
525 if ((CHECK_AMD_ARCH(reg)) && !IS_AMD_ARCH())
526 return PFMLIB_ERR_BADHOST;
527
529 pc[j].reg_addr = AMD64_SEL_BASE_F15H + (assign[j] << 1);
530 pd[j].reg_addr = AMD64_CTR_BASE_F15H + (assign[j] << 1);
531 } else {
532 pc[j].reg_addr = AMD64_SEL_BASE + assign[j];
533 pd[j].reg_addr = AMD64_CTR_BASE + assign[j];
534 }
535
536 pc[j].reg_value = reg.val;
537 pc[j].reg_alt_addr = pc[j].reg_addr;
538
539 pd[j].reg_num = assign[j];
540 pd[j].reg_alt_addr = assign[j]; /* index to use with RDPMC */
541
542 __pfm_vbprintf("[PERFSEL%u(pmc%u)=0x%llx emask=0x%x umask=0x%x os=%d usr=%d inv=%d en=%d int=%d edge=%d cnt_mask=%d] %s\n",
543 assign[j],
544 assign[j],
545 reg.val,
546 reg.sel_event_mask,
547 reg.sel_unit_mask,
548 reg.sel_os,
549 reg.sel_usr,
550 reg.sel_inv,
551 reg.sel_en,
552 reg.sel_int,
553 reg.sel_edge,
554 reg.sel_cnt_mask,
555 pfm_amd64_get_event_entry(e[j].event)->pme_name);
556
557 __pfm_vbprintf("[PERFCTR%u(pmd%u)]\n", pd[j].reg_num, pd[j].reg_num);
558 }
559
560 }
561 /* number of evtsel/ctr registers programmed */
562 outp->pfp_pmc_count = cnt;
563 outp->pfp_pmd_count = cnt;
564
565 return PFMLIB_SUCCESS;
566}
567
572{
573 unsigned int pmc_base, pmd_base;
574 ibsfetchctl_t ibsfetchctl;
575 ibsopctl_t ibsopctl;
576
577 if (!inp_mod || !outp || !outp_mod)
578 return PFMLIB_ERR_INVAL;
579
580 if (!IS_AMD_ARCH())
581 return PFMLIB_ERR_BADHOST;
582
583 /* IBS fetch profiling */
584 if (inp_mod->flags & PFMLIB_AMD64_USE_IBSFETCH) {
585
586 /* check availability of a PMC and PMD */
587 if (outp->pfp_pmc_count >= PFMLIB_MAX_PMCS)
588 return PFMLIB_ERR_NOASSIGN;
589
590 if (outp->pfp_pmd_count >= PFMLIB_MAX_PMDS)
591 return PFMLIB_ERR_NOASSIGN;
592
593 pmc_base = outp->pfp_pmc_count;
594 pmd_base = outp->pfp_pmd_count;
595
597
598 ibsfetchctl.val = 0;
599 ibsfetchctl.reg.ibsfetchen = 1;
600 ibsfetchctl.reg.ibsfetchmaxcnt = inp_mod->ibsfetch.maxcnt >> 4;
601
602 if (inp_mod->ibsfetch.options & IBS_OPTIONS_RANDEN)
603 ibsfetchctl.reg.ibsranden = 1;
604
605 outp->pfp_pmcs[pmc_base].reg_value = ibsfetchctl.val;
607 outp_mod->ibsfetch_base = pmd_base;
608
609 ++outp->pfp_pmc_count;
610 ++outp->pfp_pmd_count;
611 }
612
613 /* IBS execution profiling */
614 if (inp_mod->flags & PFMLIB_AMD64_USE_IBSOP) {
615
616 /* check availability of a PMC and PMD */
617 if (outp->pfp_pmc_count >= PFMLIB_MAX_PMCS)
618 return PFMLIB_ERR_NOASSIGN;
619
620 if (outp->pfp_pmd_count >= PFMLIB_MAX_PMDS)
621 return PFMLIB_ERR_NOASSIGN;
622
623 pmc_base = outp->pfp_pmc_count;
624 pmd_base = outp->pfp_pmd_count;
625
626 outp->pfp_pmcs[pmc_base].reg_num = PMU_AMD64_IBSOPCTL_PMC;
627
628 ibsopctl.val = 0;
629 ibsopctl.reg.ibsopen = 1;
630 ibsopctl.reg.ibsopmaxcnt = inp_mod->ibsop.maxcnt >> 4;
631
632 if (inp_mod->ibsop.options & IBS_OPTIONS_UOPS) {
634 DPRINT("IBSOP:UOPS available on Rev C and later processors\n");
635 return PFMLIB_ERR_BADHOST;
636 }
637 ibsopctl.reg.ibsopcntl = 1;
638 }
639 outp->pfp_pmcs[pmc_base].reg_value = ibsopctl.val;
640 outp->pfp_pmds[pmd_base].reg_num = PMU_AMD64_IBSOPCTL_PMD;
641
642 outp_mod->ibsop_base = pmd_base;
643 ++outp->pfp_pmc_count;
644 ++outp->pfp_pmd_count;
645 }
646
647 return PFMLIB_SUCCESS;
648}
649
650static int
652 pfmlib_input_param_t *inp, void *_inp_mod,
653 pfmlib_output_param_t *outp, void *outp_mod)
654{
655 pfmlib_amd64_input_param_t *inp_mod = _inp_mod;
656 int ret = PFMLIB_ERR_INVAL;
657
658 if (!outp)
659 return PFMLIB_ERR_INVAL;
660
661 /*
662 * At least one of the dispatch function calls must return
663 * PFMLIB_SUCCESS
664 */
665
666 if (inp && inp->pfp_event_count) {
667 ret = pfm_amd64_dispatch_counters(inp, inp_mod, outp);
668 if (ret != PFMLIB_SUCCESS)
669 return ret;
670 }
671
672 if (inp_mod && inp_mod->flags & (PFMLIB_AMD64_USE_IBSOP | PFMLIB_AMD64_USE_IBSFETCH))
673 ret = pfm_amd64_dispatch_ibs(inp, inp_mod, outp, outp_mod);
674
675 return ret;
676}
677
678static int
679pfm_amd64_get_event_code(unsigned int i, unsigned int cnt, int *code)
680{
681 if (cnt != PFMLIB_CNT_FIRST && cnt >= amd64_support.num_cnt)
682 return PFMLIB_ERR_INVAL;
683
685
686 return PFMLIB_SUCCESS;
687}
688
689/*
690 * This function is accessible directly to the user
691 */
692int
693pfm_amd64_get_event_umask(unsigned int i, unsigned long *umask)
694{
695 if (i >= amd64_event_count || umask == NULL) return PFMLIB_ERR_INVAL;
696 *umask = 0; //evt_umask(i);
697 return PFMLIB_SUCCESS;
698}
699
700static void
702{
703 unsigned int i;
704
705 memset(counters, 0, sizeof(*counters));
706
707 for(i=0; i < amd64_support.num_cnt; i++)
708 pfm_regmask_set(counters, i);
709}
710
711static void
713{
714 unsigned int i = 0;
715
716 /* all pmcs are contiguous */
717 for(i=0; i < amd64_support.pmc_count; i++)
718 pfm_regmask_set(impl_pmcs, i);
719}
720
721static void
723{
724 unsigned int i = 0;
725
726 /* all pmds are contiguous */
727 for(i=0; i < amd64_support.pmd_count; i++)
728 pfm_regmask_set(impl_pmds, i);
729}
730
731static void
733{
734 unsigned int i = 0;
735
736 /* counting pmds are contiguous */
737 for(i=0; i < amd64_support.num_cnt; i++)
738 pfm_regmask_set(impl_counters, i);
739}
740
741static void
743{
745}
746
747static char *
749{
750 if (!is_valid_index(i))
751 return NULL;
753}
754
755static int
756pfm_amd64_get_event_desc(unsigned int ev, char **str)
757{
758 char *s;
760 if (s) {
761 *str = strdup(s);
762 } else {
763 *str = NULL;
764 }
765 return PFMLIB_SUCCESS;
766}
767
768static char *
769pfm_amd64_get_event_mask_name(unsigned int ev, unsigned int midx)
770{
771 pme_amd64_umask_t *umask;
772 umask = &pfm_amd64_get_event_entry(ev)->pme_umasks[midx];
774 return NULL;
775 return umask->pme_uname;
776}
777
778static int
779pfm_amd64_get_event_mask_desc(unsigned int ev, unsigned int midx, char **str)
780{
781 char *s;
782
784 if (s) {
785 *str = strdup(s);
786 } else {
787 *str = NULL;
788 }
789 return PFMLIB_SUCCESS;
790}
791
792static unsigned int
794{
796}
797
798static int
799pfm_amd64_get_event_mask_code(unsigned int ev, unsigned int midx, unsigned int *code)
800{
802 return PFMLIB_SUCCESS;
803}
804
805static int
807{
809 return PFMLIB_SUCCESS;
810
811}
812
813static int
815{
817 return PFMLIB_SUCCESS;
818}
819
821 .pmu_name = "AMD64",
822 .pmu_type = PFMLIB_AMD64_PMU,
823 .pme_count = 0,
824 .pmc_count = PMU_AMD64_NUM_COUNTERS,
825 .pmd_count = PMU_AMD64_NUM_COUNTERS,
826 .num_cnt = PMU_AMD64_NUM_COUNTERS,
827 .get_event_code = pfm_amd64_get_event_code,
828 .get_event_name = pfm_amd64_get_event_name,
829 .get_event_counters = pfm_amd64_get_event_counters,
830 .dispatch_events = pfm_amd64_dispatch_events,
831 .pmu_detect = pfm_amd64_detect,
832 .pmu_init = pfm_amd64_init,
833 .get_impl_pmcs = pfm_amd64_get_impl_perfsel,
834 .get_impl_pmds = pfm_amd64_get_impl_perfctr,
835 .get_impl_counters = pfm_amd64_get_impl_counters,
836 .get_hw_counter_width = pfm_amd64_get_hw_counter_width,
837 .get_event_desc = pfm_amd64_get_event_desc,
838 .get_num_event_masks = pfm_amd64_get_num_event_masks,
839 .get_event_mask_name = pfm_amd64_get_event_mask_name,
840 .get_event_mask_code = pfm_amd64_get_event_mask_code,
841 .get_event_mask_desc = pfm_amd64_get_event_mask_desc,
842 .get_cycle_event = pfm_amd64_get_cycle_event,
843 .get_inst_retired_event = pfm_amd64_get_inst_retired
844};
int i
static struct pme_amd64_table amd64_fam15h_table
Definition: amd64_events.h:60
static struct pme_amd64_table amd64_k7_table
Definition: amd64_events.h:39
static struct pme_amd64_table amd64_k8_table
Definition: amd64_events.h:46
static struct pme_amd64_table amd64_fam10h_table
Definition: amd64_events.h:53
#define PME_AMD64_IBSFETCH
#define PME_AMD64_IBSOP
double s
Definition: byte_profile.c:36
static double a[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:38
static double b[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:39
static double c[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:40
#define PFMLIB_ERR_FEATCOMB
Definition: pfmlib.h:292
#define PFMLIB_AMD64_PMU
Definition: pfmlib.h:227
#define PFM_PLM2
Definition: pfmlib.h:52
#define PFMLIB_MAX_PMCS
Definition: pfmlib.h:41
#define PFMLIB_ERR_BADHOST
Definition: pfmlib.h:303
static int pfm_regmask_set(pfmlib_regmask_t *h, unsigned int b)
Definition: pfmlib.h:321
#define PFMLIB_SUCCESS
Definition: pfmlib.h:283
#define PFM_PLM3
Definition: pfmlib.h:53
#define PFMLIB_MAX_PMDS
Definition: pfmlib.h:42
#define PFMLIB_NO_PMU
Definition: pfmlib.h:221
#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 PFMLIB_ERR_NOASSIGN
Definition: pfmlib.h:288
#define PFM_PLM1
Definition: pfmlib.h:51
#define PFMLIB_ERR_NOTSUPP
Definition: pfmlib.h:284
int model
Definition: pfmlib_amd64.c:86
static int is_valid_rev(unsigned int flags, int revision)
Definition: pfmlib_amd64.c:311
static int pfm_amd64_dispatch_ibs(pfmlib_input_param_t *inp, pfmlib_amd64_input_param_t *inp_mod, pfmlib_output_param_t *outp, pfmlib_amd64_output_param_t *outp_mod)
Definition: pfmlib_amd64.c:568
static int pfm_amd64_get_event_code(unsigned int i, unsigned int cnt, int *code)
Definition: pfmlib_amd64.c:679
static void pfm_amd64_get_impl_perfctr(pfmlib_regmask_t *impl_pmds)
Definition: pfmlib_amd64.c:722
static int pfm_amd64_get_event_mask_code(unsigned int ev, unsigned int midx, unsigned int *code)
Definition: pfmlib_amd64.c:799
static int pfm_amd64_get_event_desc(unsigned int ev, char **str)
Definition: pfmlib_amd64.c:756
static struct @95 amd64_pmu
pme_amd64_entry_t unsupported_event
Definition: pfmlib_amd64.c:91
#define PFMLIB_AMD64_ALL_FLAGS
Definition: pfmlib_amd64.c:61
static amd64_rev_t amd64_get_revision(int family, int model, int stepping)
Definition: pfmlib_amd64.c:113
#define CHECK_AMD_ARCH(reg)
Definition: pfmlib_amd64.c:54
pfm_pmu_support_t amd64_support
Definition: pfmlib_amd64.c:98
#define amd64_events
Definition: pfmlib_amd64.c:104
#define AMD64_SEL_BASE
Definition: pfmlib_amd64.c:75
int family
Definition: pfmlib_amd64.c:85
#define AMD64_CTR_BASE
Definition: pfmlib_amd64.c:76
static int pfm_amd64_detect(void)
Definition: pfmlib_amd64.c:226
#define PFMLIB_AMD64_HAS_COMBO(_e)
Definition: pfmlib_amd64.c:57
static void pfm_amd64_force(void)
Definition: pfmlib_amd64.c:258
#define amd64_cpu_clks
Definition: pfmlib_amd64.c:102
static unsigned int pfm_amd64_get_num_event_masks(unsigned int ev)
Definition: pfmlib_amd64.c:793
static int pfm_amd64_dispatch_counters(pfmlib_input_param_t *inp, pfmlib_amd64_input_param_t *mod_in, pfmlib_output_param_t *outp)
Definition: pfmlib_amd64.c:350
char * name
Definition: pfmlib_amd64.c:82
#define AMD64_SEL_BASE_F15H
Definition: pfmlib_amd64.c:77
unsigned int cpu_clks
Definition: pfmlib_amd64.c:83
static int is_valid_index(unsigned int index)
Definition: pfmlib_amd64.c:341
#define amd64_model
Definition: pfmlib_amd64.c:106
static char * pfm_amd64_get_event_name(unsigned int i)
Definition: pfmlib_amd64.c:748
static void cpuid(unsigned int op, unsigned int *a, unsigned int *b, unsigned int *c, unsigned int *d)
Definition: pfmlib_amd64.c:167
static char * pfm_amd64_get_event_mask_name(unsigned int ev, unsigned int midx)
Definition: pfmlib_amd64.c:769
#define amd64_revision
Definition: pfmlib_amd64.c:100
static void pfm_amd64_get_impl_counters(pfmlib_regmask_t *impl_counters)
Definition: pfmlib_amd64.c:732
int pfm_amd64_get_event_umask(unsigned int i, unsigned long *umask)
Definition: pfmlib_amd64.c:693
static void pfm_amd64_get_hw_counter_width(unsigned int *width)
Definition: pfmlib_amd64.c:742
static void pfm_amd64_setup(amd64_rev_t revision)
Definition: pfmlib_amd64.c:179
#define amd64_event_count
Definition: pfmlib_amd64.c:101
#define amd64_family
Definition: pfmlib_amd64.c:105
static int pfm_amd64_dispatch_events(pfmlib_input_param_t *inp, void *_inp_mod, pfmlib_output_param_t *outp, void *outp_mod)
Definition: pfmlib_amd64.c:651
static int pfm_amd64_get_event_mask_desc(unsigned int ev, unsigned int midx, char **str)
Definition: pfmlib_amd64.c:779
#define AMD64_CTR_BASE_F15H
Definition: pfmlib_amd64.c:78
static int pfm_amd64_init(void)
Definition: pfmlib_amd64.c:293
#define IS_AMD_ARCH()
Definition: pfmlib_amd64.c:110
static void pfm_amd64_get_impl_perfsel(pfmlib_regmask_t *impl_pmcs)
Definition: pfmlib_amd64.c:712
pme_amd64_entry_t * events
Definition: pfmlib_amd64.c:88
int stepping
Definition: pfmlib_amd64.c:87
static void pfm_amd64_get_event_counters(unsigned int j, pfmlib_regmask_t *counters)
Definition: pfmlib_amd64.c:701
unsigned int ret_inst
Definition: pfmlib_amd64.c:84
#define amd64_ret_inst
Definition: pfmlib_amd64.c:103
static int pfm_amd64_get_inst_retired(pfmlib_event_t *e)
Definition: pfmlib_amd64.c:814
static pme_amd64_entry_t * pfm_amd64_get_event_entry(unsigned int index)
Definition: pfmlib_amd64.c:324
amd64_rev_t revision
Definition: pfmlib_amd64.c:81
#define amd64_stepping
Definition: pfmlib_amd64.c:107
static int pfm_amd64_get_cycle_event(pfmlib_event_t *e)
Definition: pfmlib_amd64.c:806
#define PFM_AMD64_SEL_GUEST
Definition: pfmlib_amd64.h:175
#define PFM_AMD64_SEL_HOST
Definition: pfmlib_amd64.h:176
#define PFMLIB_AMD64_USE_IBSFETCH
Definition: pfmlib_amd64.h:205
#define PFMLIB_AMD64_USE_IBSOP
Definition: pfmlib_amd64.h:206
#define PFM_AMD64_SEL_EDGE
Definition: pfmlib_amd64.h:174
#define IBS_OPTIONS_RANDEN
Definition: pfmlib_amd64.h:192
#define IBS_OPTIONS_UOPS
Definition: pfmlib_amd64.h:193
#define PMU_AMD64_MAX_COUNTERS
Definition: pfmlib_amd64.h:43
#define PFM_AMD64_SEL_INV
Definition: pfmlib_amd64.h:173
#define PMU_AMD64_IBSOPCTL_PMC
static int from_revision(unsigned int flags)
#define PMU_AMD64_COUNTER_WIDTH
#define PMU_AMD64_IBSOPCTL_PMD
#define PMU_AMD64_NUM_PERFCTR
static const char * amd64_cpu_strs[]
#define PMU_AMD64_NUM_PERFSEL
#define PMU_AMD64_IBSFETCHCTL_PMD
#define PMU_AMD64_NUM_COUNTERS_F15H
static const char * amd64_rev_strs[]
amd64_rev_t
@ AMD64_K8_REV_E
@ AMD64_FAM10H_REV_D
@ AMD64_FAM10H_REV_B
@ AMD64_FAM10H_REV_C
@ AMD64_K8_REV_F
@ AMD64_K8_REV_C
@ AMD64_CPU_UN
@ AMD64_K7
@ AMD64_FAM10H_REV_E
@ AMD64_FAM15H_REV_B
@ AMD64_K8_REV_D
@ AMD64_K8_REV_G
@ AMD64_K8_REV_B
#define PMU_AMD64_CNT_MASK_MAX
#define PMU_AMD64_IBSFETCHCTL_PMC
#define PMU_AMD64_NUM_COUNTERS
#define PFMLIB_AMD64_NOT_SUPP
#define PFMLIB_AMD64_FAM10H_REV_C
static int till_revision(unsigned int flags)
int forced_pmu
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
#define PFMLIB_CNT_FIRST
Definition: pfmlib_priv.h:62
unsigned int options
Definition: pfmlib_amd64.h:186
unsigned int maxcnt
Definition: pfmlib_amd64.h:185
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
pfmlib_amd64_counter_t pfp_amd64_counters[PMU_AMD64_MAX_COUNTERS]
Definition: pfmlib_amd64.h:196
unsigned int num_masks
Definition: pfmlib.h:90
unsigned int plm
Definition: pfmlib.h:87
unsigned int unit_masks[PFMLIB_MAX_MASKS_PER_EVENT]
Definition: pfmlib.h:89
unsigned int event
Definition: pfmlib.h:86
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 reg_alt_addr
Definition: pfmlib.h:102
unsigned long long reg_addr
Definition: pfmlib.h:99
unsigned int pme_code
char * pme_name
char * pme_desc
unsigned int pme_flags
unsigned int pme_numasks
pme_amd64_umask_t pme_umasks[PFMLIB_AMD64_MAX_UMASK]
unsigned int cpu_clks
Definition: amd64_events.h:35
pme_amd64_entry_t * events
Definition: amd64_events.h:34
unsigned int num
Definition: amd64_events.h:33
unsigned int ret_inst
Definition: amd64_events.h:36
unsigned int pme_ucode
unsigned int pme_uflags
struct ibsfetchctl_t::@13 reg
uint64_t val
Definition: pfmlib_amd64.h:80
uint64_t ibsfetchen
Definition: pfmlib_amd64.h:85
uint64_t ibsfetchmaxcnt
Definition: pfmlib_amd64.h:82
uint64_t ibsranden
Definition: pfmlib_amd64.h:93
struct ibsopctl_t::@14 reg
uint64_t ibsopmaxcnt
Definition: pfmlib_amd64.h:101
uint64_t ibsopen
Definition: pfmlib_amd64.h:103
uint64_t ibsopcntl
Definition: pfmlib_amd64.h:105
uint64_t val
Definition: pfmlib_amd64.h:99
uint64_t sel_event_mask
Definition: pfmlib_amd64.h:52
uint64_t sel_unit_mask
Definition: pfmlib_amd64.h:53
uint64_t sel_event_mask2
Definition: pfmlib_amd64.h:63