13 #include <linux/ptrace.h>
16 #include <asm/fixmap.h>
25 #define NUM_COUNTERS_NON_HT 8
26 #define NUM_ESCRS_NON_HT 45
27 #define NUM_CCCRS_NON_HT 18
28 #define NUM_CONTROLS_NON_HT (NUM_ESCRS_NON_HT + NUM_CCCRS_NON_HT)
30 #define NUM_COUNTERS_HT2 4
31 #define NUM_ESCRS_HT2 23
32 #define NUM_CCCRS_HT2 9
33 #define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2)
35 #define OP_CTR_OVERFLOW (1ULL<<31)
43 static inline void setup_num_counters(
void)
53 static inline int addr_increment(
void)
83 #define CTR_BPU_0 (1 << 0)
84 #define CTR_MS_0 (1 << 1)
85 #define CTR_FLAME_0 (1 << 2)
86 #define CTR_IQ_4 (1 << 3)
87 #define CTR_BPU_2 (1 << 4)
88 #define CTR_MS_2 (1 << 5)
89 #define CTR_FLAME_2 (1 << 6)
90 #define CTR_IQ_5 (1 << 7)
103 #define NUM_UNUSED_CCCRS (NUM_CCCRS_NON_HT - NUM_COUNTERS_NON_HT)
345 #define MISC_PMC_ENABLED_P(x) ((x) & 1 << 7)
347 #define ESCR_RESERVED_BITS 0x80000003
348 #define ESCR_CLEAR(escr) ((escr) &= ESCR_RESERVED_BITS)
349 #define ESCR_SET_USR_0(escr, usr) ((escr) |= (((usr) & 1) << 2))
350 #define ESCR_SET_OS_0(escr, os) ((escr) |= (((os) & 1) << 3))
351 #define ESCR_SET_USR_1(escr, usr) ((escr) |= (((usr) & 1)))
352 #define ESCR_SET_OS_1(escr, os) ((escr) |= (((os) & 1) << 1))
353 #define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x3f) << 25))
354 #define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |= (((mask) & 0xffff) << 9))
356 #define CCCR_RESERVED_BITS 0x38030FFF
357 #define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS)
358 #define CCCR_SET_REQUIRED_BITS(cccr) ((cccr) |= 0x00030000)
359 #define CCCR_SET_ESCR_SELECT(cccr, sel) ((cccr) |= (((sel) & 0x07) << 13))
360 #define CCCR_SET_PMI_OVF_0(cccr) ((cccr) |= (1<<26))
361 #define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27))
362 #define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12))
363 #define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12))
364 #define CCCR_OVF_P(cccr) ((cccr) & (1U<<31))
365 #define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31)))
371 static unsigned int get_stagger(
void)
384 #define VIRT_CTR(stagger, i) ((i) + ((num_counters) * (stagger)))
388 static void p4_shutdown(
struct op_msrs const *
const msrs)
392 for (i = 0; i < num_counters; ++
i) {
401 for (i = num_counters; i < num_controls; ++
i) {
407 static int p4_fill_in_addresses(
struct op_msrs *
const msrs)
412 setup_num_counters();
413 stag = get_stagger();
416 for (i = 0; i < num_counters; ++
i) {
441 for (addr = MSR_P4_IQ_ESCR0 + stag;
475 }
else if (stag == 0) {
490 for (i = 0; i < num_counters; ++
i) {
495 op_x86_warn_reserved(i);
504 static void pmc_setup_one_p4_counter(
unsigned int ctr)
507 int const maxbind = 2;
508 unsigned int cccr = 0;
509 unsigned int escr = 0;
510 unsigned int high = 0;
511 unsigned int counter_bit;
515 stag = get_stagger();
518 counter_bit = 1 <<
VIRT_CTR(stag, ctr);
523 "oprofile: P4 event code 0x%lx out of range\n",
530 for (i = 0; i < maxbind; i++) {
531 if (ev->
bindings[i].virt_counter & counter_bit) {
564 "oprofile: P4 event code 0x%lx no binding, stag %d ctr %d\n",
570 struct op_msrs const *
const msrs)
576 stag = get_stagger();
585 for (i = 0; i < num_counters; i++) {
588 rdmsr(p4_counters[
VIRT_CTR(stag, i)].cccr_address, low, high);
591 wrmsr(p4_counters[
VIRT_CTR(stag, i)].cccr_address, low, high);
595 for (i = num_counters; i < num_controls; i++) {
602 for (i = 0; i < num_counters; ++
i) {
605 pmc_setup_one_p4_counter(i);
606 wrmsrl(p4_counters[
VIRT_CTR(stag, i)].counter_address,
615 static int p4_check_ctrs(
struct pt_regs *
const regs,
616 struct op_msrs const *
const msrs)
621 stag = get_stagger();
623 for (i = 0; i < num_counters; ++
i) {
647 rdmsr(p4_counters[real].cccr_address, low, high);
648 rdmsr(p4_counters[real].counter_address, ctr, high);
651 wrmsrl(p4_counters[real].counter_address,
652 -(
u64)reset_value[i]);
654 wrmsr(p4_counters[real].cccr_address, low, high);
655 wrmsrl(p4_counters[real].counter_address,
656 -(
u64)reset_value[i]);
668 static void p4_start(
struct op_msrs const *
const msrs)
673 stag = get_stagger();
675 for (i = 0; i < num_counters; ++
i) {
678 rdmsr(p4_counters[
VIRT_CTR(stag, i)].cccr_address, low, high);
680 wrmsr(p4_counters[
VIRT_CTR(stag, i)].cccr_address, low, high);
685 static void p4_stop(
struct op_msrs const *
const msrs)
690 stag = get_stagger();
692 for (i = 0; i < num_counters; ++
i) {
695 rdmsr(p4_counters[
VIRT_CTR(stag, i)].cccr_address, low, high);
697 wrmsr(p4_counters[
VIRT_CTR(stag, i)].cccr_address, low, high);
705 .fill_in_addresses = &p4_fill_in_addresses,
706 .setup_ctrs = &p4_setup_ctrs,
707 .check_ctrs = &p4_check_ctrs,
710 .shutdown = &p4_shutdown
717 .fill_in_addresses = &p4_fill_in_addresses,
718 .setup_ctrs = &p4_setup_ctrs,
719 .check_ctrs = &p4_check_ctrs,
722 .shutdown = &p4_shutdown