18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file op_pmu.c 38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Setup and handling of IA64 Performance Monitoring Unit (PMU) 48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2002 OProfile authors 68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING 78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Bob Montgomery 98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Will Cohen 108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author John Levon 118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Philippe Elie 128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "oprofile.h" 168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_util.h" 178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <asm/perfmon.h> 188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_ia64_model.h" 198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* number of counters physically present */ 218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic uint op_nr_counters = 4; 228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* performance counters are in pairs: pmcN and pmdN. The pmc register acts 248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * as the event selection; the pmd register is the counter. */ 258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define perf_reg(c) ((c)+4) 268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define IA64_1_PMD_MASK_VAL ((1UL << 32) - 1) 288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define IA64_2_PMD_MASK_VAL ((1UL << 47) - 1) 298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* The appropriate value is selected in pmu_init() */ 318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddunsigned long pmd_mask = IA64_2_PMD_MASK_VAL; 328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define pmd_overflowed(r, c) ((r) & (1 << perf_reg(c))) 348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define set_pmd_neg(v, c) do { \ 358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_set_pmd(perf_reg(c), -(ulong)(v) & pmd_mask); \ 368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_srlz_d(); } while (0) 378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define set_pmd(v, c) do { \ 388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_set_pmd(perf_reg(c), (v) & pmd_mask); \ 398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_srlz_d(); } while (0) 408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define set_pmc(v, c) do { ia64_set_pmc(perf_reg(c), (v)); ia64_srlz_d(); } while (0) 418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define get_pmd(c) ia64_get_pmd(perf_reg(c)) 428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define get_pmc(c) ia64_get_pmc(perf_reg(c)) 438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* ---------------- IRQ handler ------------------ */ 458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* The args match the args for pfm_overflow_handler in perfmon.c. 478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * The task_struct is currently filled in with the perfmon "owner" of 488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * the PMU. This might change. I'm not sure it makes sense in perfmon 498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * either with system-wide profiling. 508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * pmc0 is a bit mask for overflowed counters (bits 4-7) 518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * This routine should return 0 to resume interrupts. 528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddinline static void 548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddop_do_pmu_interrupt(u64 pmc0, struct pt_regs * regs) 558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd uint cpu = op_cpu_id(); 578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int ctr; 588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (ctr = 0 ; ctr < op_nr_counters ; ++ctr) { 608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (pmd_overflowed(pmc0, ctr)) { 618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd op_do_profile(cpu, regs->cr_iip, 1, ctr); 628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd set_pmd_neg(oprof_data[cpu].ctr_count[ctr], ctr); 638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void 708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddop_raw_pmu_interrupt(int irq, void * arg, struct pt_regs * regs) 718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd u64 pmc0; 738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd pmc0 = ia64_get_pmc(0); 758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if ((pmc0 & ~0x1UL) != 0UL) { 778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd op_do_pmu_interrupt(pmc0, regs); 788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_set_pmc(0, 0); 798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_srlz_d(); 808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define MY_OPROFILE_VECTOR (IA64_PERFMON_VECTOR - 2) 858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void 878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddop_set_pmv(void * dummy) 888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_set_pmv(MY_OPROFILE_VECTOR); 908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_srlz_d(); 918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void 958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddop_restore_pmv(void* dummy) 968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_set_pmv(IA64_PERFMON_VECTOR); 988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_srlz_d(); 998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic int 1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddinstall_handler(void) 1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int err = 0; 1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* Try it legally - confusion about vec vs irq */ 1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd err = request_irq(MY_OPROFILE_VECTOR, op_raw_pmu_interrupt, 1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd SA_INTERRUPT | SA_PERCPU_IRQ, "oprofile", NULL); 1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (err) { 1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd printk(KERN_ALERT "oprofile_IA64: request_irq fails, " 1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "returns %d\n", err); 1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return err; 1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if ((smp_call_function(op_set_pmv, NULL, 0, 1))) { 1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd printk(KERN_ALERT "oprofile_IA64: unexpected failure " 1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "of smp_call_function(op_set_pmv)\n"); 1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd op_set_pmv(NULL); 1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return err; 1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic int 1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddrestore_handler(void) 1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int err = 0; 1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if ((smp_call_function(op_restore_pmv, NULL, 0, 1))) { 1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd printk(KERN_ALERT "oprofile_IA64: unexpected failure " 1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "of smp_call_function(op_restore_pmv)\n"); 1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd op_restore_pmv(NULL); 1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free_irq(MY_OPROFILE_VECTOR, NULL); 1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return err; 1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* ---------------- PMU setup ------------------ */ 1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* This is kind of artificial. The proc interface might really want to 1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * accept register values directly. There are other features not exposed 1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * by this limited interface. Of course that might require all sorts of 1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * validity checking??? */ 1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void 1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpmc_fill_in(ulong * val, u8 kernel, u8 user, u8 event, u8 um) 1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* enable interrupt generation */ 1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *val |= (1 << 5); 1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* setup as a privileged monitor */ 1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *val |= (1 << 6); 1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* McKinley requires pmc4 to have bit 23 set (enable PMU). 1618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * It is supposedly ignored in other pmc registers. 1628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Try assuming it's ignored in Itanium, too, and just 1638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * set it for everyone. 1648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 1658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *val |= (1 << 23); 1678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* enable/disable chosen OS and USR counting */ 1698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd (user) ? (*val |= (1 << 3)) 1708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd : (*val &= ~(1 << 3)); 1718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd (kernel) ? (*val |= (1 << 0)) 1738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd : (*val &= ~(1 << 0)); 1748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* what are we counting ? */ 1768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *val &= ~(0xff << 8); 1778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *val |= ((event & 0xff) << 8); 1788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *val &= ~(0xf << 16); 1798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *val |= ((um & 0xf) << 16); 1808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void 1848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpmu_setup(void * dummy) 1858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ulong pmc_val; 1878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int ii; 1888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* setup each counter */ 1908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (ii = 0 ; ii < op_nr_counters ; ++ii) { 1918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (sysctl.ctr[ii].enabled) { 1928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd pmc_val = 0; 1938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd set_pmd_neg(sysctl.ctr[ii].count, ii); 1958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd pmc_fill_in(&pmc_val, sysctl.ctr[ii].kernel, 1968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sysctl.ctr[ii].user, sysctl.ctr[ii].event, 1978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sysctl.ctr[ii].unit_mask); 1988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd set_pmc(pmc_val, ii); 2008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 2038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid 2068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodddisable_psr(void * dummy) 2078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 2088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct pt_regs * regs; 2098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* disable profiling for my saved state */ 2108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd regs = (struct pt_regs *)((unsigned long) current + IA64_STK_OFFSET); 2118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd regs--; 2128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_psr(regs)->pp = 0; 2138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* shouldn't need to */ 2148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_psr(regs)->up = 0; 2158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* disable profiling for my current state */ 2178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd __asm__ __volatile__ ("rsm psr.pp;;"::: "memory"); 2188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#if defined(CONFIG_PERFMON) && defined(CONFIG_SMP) 2208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#if V_AT_LEAST(2, 4, 21) 2218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd local_cpu_data->pfm_syst_info |= PFM_CPUINFO_SYST_WIDE; 2228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd local_cpu_data->pfm_syst_info &= ~PFM_CPUINFO_DCR_PP; 2238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* FIXME: what todo with the 3rd flags PFM_CPUINFO_EXCL_IDLE 0x4 */ 2248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#else 2258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* disable profiling for everyone else */ 2268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd local_cpu_data->pfm_syst_wide = 1; 2278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd local_cpu_data->pfm_dcr_pp = 0; 2288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif 2298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif 2308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_set_pmc(0, 0); 2318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_srlz_d(); 2328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 2338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic int 2368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpmu_setup_all(void) 2378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 2388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* This would be a great place to reserve all cpus with 2408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * some sort of call to perfmonctl (something like the 2418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * CREATE_CONTEXT command). The current interface to 2428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * perfmonctl wants to be called from a different task id 2438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * for each CPU to be set up (and doesn't allow calls from 2448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * modules. 2458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 2468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* disable profiling with the psr.pp bit */ 2488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if ((smp_call_function(disable_psr, NULL, 0, 1))) 2498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return -EFAULT; 2508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd disable_psr(NULL); 2528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* now I've reserved the PMUs and they should be quiet */ 2548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if ((smp_call_function(pmu_setup, NULL, 0, 1))) 2568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return -EFAULT; 2578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd pmu_setup(NULL); 2598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return 0; 2608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 2618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#ifndef CONFIG_SMP 2648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* from linux/arch/ia64/kernel/perfmon.c */ 2658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* 2668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Originaly Written by Ganesh Venkitachalam, IBM Corp. 2678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Copyright (C) 1999 Ganesh Venkitachalam <venkitac@us.ibm.com> 2688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 2698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Modifications by Stephane Eranian, Hewlett-Packard Co. 2708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Modifications by David Mosberger-Tang, Hewlett-Packard Co. 2718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 2728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Copyright (C) 1999-2002 Hewlett Packard Co 2738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Stephane Eranian <eranian@hpl.hp.com> 2748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * David Mosberger-Tang <davidm@hpl.hp.com> 2758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 2768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* 2788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * On UP kernels, we do not need to constantly set the psr.pp bit 2798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * when a task is scheduled. The psr.pp bit can only be changed in 2808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * the kernel because of a user request. Given we are on a UP non preeemptive 2818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * kernel we know that no other task is running, so we cna simply update their 2828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * psr.pp from their saved state. There is this no impact on the context switch 2838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * code compared to the SMP case. 2848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 2858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void 2868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddop_tasklist_toggle_pp(unsigned int val) 2878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 2888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct task_struct * p; 2898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct pt_regs * regs; 2908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd read_lock(&tasklist_lock); 2928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for_each_task(p) { 2948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd regs = (struct pt_regs *)((unsigned long) p + IA64_STK_OFFSET); 2958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* 2978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * position on pt_regs saved on stack on 1st entry into the kernel 2988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 2998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd regs--; 3008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* 3028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * update psr.pp 3038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 3048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_psr(regs)->pp = val; 3058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd read_unlock(&tasklist_lock); 3078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif 3098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void 3128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpmu_start(void * info) 3138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct pt_regs * regs; 3158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (info && (*((uint *)info) != op_cpu_id())) 3178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 3188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* printk(KERN_ALERT "oprofile_IA64: pmu_start on cpu %d\n", 3208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd op_cpu_id()); */ 3218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* The default control register pp value is copied into psr.pp 3228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * on an interrupt. This allows interrupt service routines to 3238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * be monitored. 3248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 3258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_set_dcr(ia64_get_dcr() | IA64_DCR_PP); 3268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#ifdef CONFIG_PERFMON 3288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#ifdef CONFIG_SMP 3298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#if V_AT_LEAST(2, 4, 21) 3308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd local_cpu_data->pfm_syst_info |= PFM_CPUINFO_SYST_WIDE; 3318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd local_cpu_data->pfm_syst_info |= PFM_CPUINFO_DCR_PP; 3328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* FIXME: what todo with the 3rd flags PFM_CPUINFO_EXCL_IDLE 0x4 */ 3338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#else 3348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd local_cpu_data->pfm_syst_wide = 1; 3358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd local_cpu_data->pfm_dcr_pp = 1; 3368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif 3378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#else 3388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd op_tasklist_toggle_pp(1); 3398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif 3408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif 3418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* set it in my saved state */ 3428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd regs = (struct pt_regs *)((unsigned long) current + IA64_STK_OFFSET); 3438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd regs--; 3448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_psr(regs)->pp = 1; 3458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* set it in my current state */ 3478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd __asm__ __volatile__ ("ssm psr.pp;;"::: "memory"); 3488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_srlz_d(); 3498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void 3538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpmu_stop(void * info) 3548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct pt_regs * regs; 3568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (info && (*((uint *)info) != op_cpu_id())) 3588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 3598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* stop in my current state */ 3618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd __asm__ __volatile__ ("rsm psr.pp;;"::: "memory"); 3628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* disable the dcr pp */ 3648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP); 3658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#ifdef CONFIG_PERFMON 3678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#ifdef CONFIG_SMP 3688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#if V_AT_LEAST(2, 4, 21) 3698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd local_cpu_data->pfm_syst_info &= ~PFM_CPUINFO_SYST_WIDE; 3708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd local_cpu_data->pfm_syst_info &= ~PFM_CPUINFO_DCR_PP; 3718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* FIXME: what todo with the 3rd flags PFM_CPUINFO_EXCL_IDLE 0x4 */ 3728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#else 3738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd local_cpu_data->pfm_syst_wide = 0; 3748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd local_cpu_data->pfm_dcr_pp = 0; 3758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif 3768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#else 3778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd pfm_tasklist_toggle_pp(0); 3788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif 3798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif 3808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* disable in my saved state */ 3828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd regs = (struct pt_regs *)((unsigned long) current + IA64_STK_OFFSET); 3838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd regs--; 3848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ia64_psr(regs)->pp = 0; 3858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void 3898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpmu_select_start(uint cpu) 3908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (cpu == op_cpu_id()) 3928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd pmu_start(NULL); 3938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd else 3948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd smp_call_function(pmu_start, &cpu, 0, 1); 3958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void 3998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpmu_select_stop(uint cpu) 4008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 4018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (cpu == op_cpu_id()) 4028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd pmu_stop(NULL); 4038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd else 4048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd smp_call_function(pmu_stop, &cpu, 0, 1); 4058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 4068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void 4098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpmu_start_all(void) 4108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 4118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int cpu, i; 4128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (cpu=0; cpu < smp_num_cpus; cpu++) { 4148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct _oprof_data * data = &oprof_data[cpu]; 4158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (i = 0 ; i < op_nr_counters ; ++i) { 4178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (sysctl.ctr[i].enabled) { 4188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd data->ctr_count[i] = sysctl.ctr[i].count; 4198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else { 4208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd data->ctr_count[i] = 0; 4218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!install_handler()) { 4268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd smp_call_function(pmu_start, NULL, 0, 1); 4278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd pmu_start(NULL); 4288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* FIXME need some way to fail here */; 4308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 4318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void 4348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpmu_stop_all(void) 4358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 4368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd smp_call_function(pmu_stop, NULL, 0, 1); 4378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd pmu_stop(NULL); 4388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd restore_handler(); 4398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 4408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic int 4438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpmu_check_params(void) 4448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 4458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int i; 4468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int enabled = 0; 4478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (i = 0; i < op_nr_counters ; i++) { 4498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!sysctl.ctr[i].enabled) 4508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd continue; 4518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd enabled = 1; 4538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!sysctl.ctr[i].user && !sysctl.ctr[i].kernel) { 4558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd printk(KERN_ERR "oprofile: neither kernel nor user " 4568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "set for counter %d\n", i); 4578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return -EINVAL; 4588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (check_range(sysctl.ctr[i].count, 1, OP_MAX_PERF_COUNT, 4618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "ctr count value %d not in range (%d %ld)\n")) 4628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return -EINVAL; 4638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!enabled) { 4668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd printk(KERN_ERR "oprofile: no counters have been enabled.\n"); 4678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return -EINVAL; 4688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return 0; 4718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 4728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct op_msrs cpu_msrs[NR_CPUS]; 4758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void free_msr_group(struct op_msr_group * group) 4788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 4798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (group->addrs) 4808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd kfree(group->addrs); 4818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (group->saved) 4828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd kfree(group->saved); 4838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd group->addrs = NULL; 4848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd group->saved = NULL; 4858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 4868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void pmu_save_registers(void * dummy) 4898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 4908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd uint i; 4918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd uint const cpu = op_cpu_id(); 4928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct op_msr_group * counters = &cpu_msrs[cpu].counters; 4938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct op_msr_group * controls = &cpu_msrs[cpu].controls; 4948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd counters->addrs = NULL; 4968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd counters->saved = NULL; 4978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd controls->addrs = NULL; 4988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd controls->saved = NULL; 4998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd counters->saved = kmalloc( 5018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd op_nr_counters * sizeof(struct op_saved_msr), GFP_KERNEL); 5028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!counters->saved) 5038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd goto fault; 5048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd controls->saved = kmalloc( 5068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd op_nr_counters * sizeof(struct op_saved_msr), GFP_KERNEL); 5078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!controls->saved) 5088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd goto fault; 5098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (i = 0; i < op_nr_counters; ++i) { 5118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd controls->saved[i].low = get_pmc(i); 5128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd counters->saved[i].low = get_pmd(i); 5138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 5148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 5158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddfault: 5178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free_msr_group(counters); 5188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free_msr_group(controls); 5198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 5208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void pmu_restore_registers(void * dummy) 5238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 5248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd uint i; 5258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd uint const cpu = op_cpu_id(); 5268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct op_msr_group * counters = &cpu_msrs[cpu].counters; 5278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct op_msr_group * controls = &cpu_msrs[cpu].controls; 5288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (i = 0; i < op_nr_counters; ++i) { 5308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd set_pmc(controls->saved[i].low, i); 5318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd set_pmd(counters->saved[i].low, i); 5328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 5338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free_msr_group(counters); 5358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free_msr_group(controls); 5368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 5378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic int 5418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpmu_init(void) 5428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 5438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int err = 0; 5448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* figure out processor type configure number of bits in pmd 5468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd and number of counters */ 5478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd switch (get_cpu_type()) { 5488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd case CPU_IA64_1: 5498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd pmd_mask = IA64_1_PMD_MASK_VAL; break; 5508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd case CPU_IA64_2: 5518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd case CPU_IA64: 5528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd pmd_mask = IA64_2_PMD_MASK_VAL; break; 5538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd default: 5548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd err = -EIO; break; 5558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 5568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd op_nr_counters = 4; 5588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if ((err = smp_call_function(pmu_save_registers, NULL, 0, 1))) 5608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd goto out; 5618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd pmu_save_registers(NULL); 5638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddout: 5658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return err; 5668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 5678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void 5708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpmu_deinit(void) 5718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 5728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd smp_call_function(pmu_restore_registers, NULL, 0, 1); 5738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd pmu_restore_registers(NULL); 5748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 5758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic char * names[] = { "0", "1", "2", "3", }; 5788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic int 5818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpmu_add_sysctls(ctl_table * next) 5828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 5838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ctl_table * start = next; 5848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ctl_table * tab; 5858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int i, j; 5868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (i=0; i < op_nr_counters; i++) { 5888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd next->ctl_name = 1; 5898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd next->procname = names[i]; 5908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd next->mode = 0700; 5918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!(tab = kmalloc(sizeof(ctl_table)*7, GFP_KERNEL))) 5938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd goto cleanup; 5948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd next->child = tab; 5968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd memset(tab, 0, sizeof(ctl_table)*7); 5988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd tab[0] = ((ctl_table) { 1, "enabled", &sysctl_parms.ctr[i].enabled, sizeof(int), 0600, NULL, lproc_dointvec, NULL, }); 5998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd tab[1] = ((ctl_table) { 1, "event", &sysctl_parms.ctr[i].event, sizeof(int), 0600, NULL, lproc_dointvec, NULL, }); 6008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd tab[2] = ((ctl_table) { 1, "count", &sysctl_parms.ctr[i].count, sizeof(int), 0600, NULL, lproc_dointvec, NULL, }); 6018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd tab[3] = ((ctl_table) { 1, "unit_mask", &sysctl_parms.ctr[i].unit_mask, sizeof(int), 0600, NULL, lproc_dointvec, NULL, }); 6028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd tab[4] = ((ctl_table) { 1, "kernel", &sysctl_parms.ctr[i].kernel, sizeof(int), 0600, NULL, lproc_dointvec, NULL, }); 6038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd tab[5] = ((ctl_table) { 1, "user", &sysctl_parms.ctr[i].user, sizeof(int), 0600, NULL, lproc_dointvec, NULL, }); 6048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd next++; 6058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 6068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 6078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return 0; 6088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 6098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddcleanup: 6108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd next = start; 6118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (j = 0; j < i; j++) { 6128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd kfree(next->child); 6138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd next++; 6148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 6158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return -EFAULT; 6168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 6178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 6188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 6198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void pmu_remove_sysctls(ctl_table * next) 6208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 6218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int ii; 6228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 6238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (ii=0; ii < op_nr_counters; ii++) { 6248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd kfree(next->child); 6258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd next++; 6268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 6278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 6288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 6298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 6308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstruct op_int_operations op_nmi_ops = { 6318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd init: pmu_init, 6328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd deinit: pmu_deinit, 6338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd add_sysctls: pmu_add_sysctls, 6348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd remove_sysctls: pmu_remove_sysctls, 6358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd check_params: pmu_check_params, 6368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd setup: pmu_setup_all, 6378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd start: pmu_start_all, 6388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd stop: pmu_stop_all, 6398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd start_cpu: pmu_select_start, 6408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd stop_cpu: pmu_select_stop, 6418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}; 6428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 6438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 6448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstruct op_int_operations const * op_int_interface() 6458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 6468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return &op_nmi_ops; 6478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 6488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 6498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* Need this dummy so module/oprofile.c links */ 6508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstruct op_int_operations op_rtc_ops = { 6518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd init: NULL, 6528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd deinit: NULL, 6538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd add_sysctls: NULL, 6548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd remove_sysctls: NULL, 6558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd check_params: NULL, 6568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd setup: NULL, 6578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd start: NULL, 6588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd stop: NULL, 6598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd start_cpu: NULL, 6608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd stop_cpu: NULL, 6618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}; 662