diff options
author | Srikant Patnaik | 2015-01-13 15:08:24 +0530 |
---|---|---|
committer | Srikant Patnaik | 2015-01-13 15:08:24 +0530 |
commit | 97327692361306d1e6259021bc425e32832fdb50 (patch) | |
tree | fe9088f3248ec61e24f404f21b9793cb644b7f01 /arch/alpha/oprofile/op_model_ev4.c | |
parent | 2d05a8f663478a44e088d122e0d62109bbc801d0 (diff) | |
parent | a3a8b90b61e21be3dde9101c4e86c881e0f06210 (diff) | |
download | FOSSEE-netbook-kernel-source-97327692361306d1e6259021bc425e32832fdb50.tar.gz FOSSEE-netbook-kernel-source-97327692361306d1e6259021bc425e32832fdb50.tar.bz2 FOSSEE-netbook-kernel-source-97327692361306d1e6259021bc425e32832fdb50.zip |
dirty fix to merging
Diffstat (limited to 'arch/alpha/oprofile/op_model_ev4.c')
-rw-r--r-- | arch/alpha/oprofile/op_model_ev4.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/arch/alpha/oprofile/op_model_ev4.c b/arch/alpha/oprofile/op_model_ev4.c new file mode 100644 index 00000000..18aa9b4f --- /dev/null +++ b/arch/alpha/oprofile/op_model_ev4.c @@ -0,0 +1,115 @@ +/** + * @file arch/alpha/oprofile/op_model_ev4.c + * + * @remark Copyright 2002 OProfile authors + * @remark Read the file COPYING + * + * @author Richard Henderson <rth@twiddle.net> + */ + +#include <linux/oprofile.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <asm/ptrace.h> + +#include "op_impl.h" + + +/* Compute all of the registers in preparation for enabling profiling. */ + +static void +ev4_reg_setup(struct op_register_config *reg, + struct op_counter_config *ctr, + struct op_system_config *sys) +{ + unsigned long ctl = 0, count, hilo; + + /* Select desired events. We've mapped the event numbers + such that they fit directly into the event selection fields. + + Note that there is no "off" setting. In both cases we select + the EXTERNAL event source, hoping that it'll be the lowest + frequency, and set the frequency counter to LOW. The interrupts + for these "disabled" counter overflows are ignored by the + interrupt handler. + + This is most irritating, because the hardware *can* enable and + disable the interrupts for these counters independently, but the + wrperfmon interface doesn't allow it. */ + + ctl |= (ctr[0].enabled ? ctr[0].event << 8 : 14 << 8); + ctl |= (ctr[1].enabled ? (ctr[1].event - 16) << 32 : 7ul << 32); + + /* EV4 can not read or write its counter registers. The only + thing one can do at all is see if you overflow and get an + interrupt. We can set the width of the counters, to some + extent. Take the interrupt count selected by the user, + map it onto one of the possible values, and write it back. */ + + count = ctr[0].count; + if (count <= 4096) + count = 4096, hilo = 1; + else + count = 65536, hilo = 0; + ctr[0].count = count; + ctl |= (ctr[0].enabled && hilo) << 3; + + count = ctr[1].count; + if (count <= 256) + count = 256, hilo = 1; + else + count = 4096, hilo = 0; + ctr[1].count = count; + ctl |= (ctr[1].enabled && hilo); + + reg->mux_select = ctl; + + /* Select performance monitoring options. */ + /* ??? Need to come up with some mechanism to trace only + selected processes. EV4 does not have a mechanism to + select kernel or user mode only. For now, enable always. */ + reg->proc_mode = 0; + + /* Frequency is folded into mux_select for EV4. */ + reg->freq = 0; + + /* See above regarding no writes. */ + reg->reset_values = 0; + reg->need_reset = 0; + +} + +/* Program all of the registers in preparation for enabling profiling. */ + +static void +ev4_cpu_setup(void *x) +{ + struct op_register_config *reg = x; + + wrperfmon(2, reg->mux_select); + wrperfmon(3, reg->proc_mode); +} + +static void +ev4_handle_interrupt(unsigned long which, struct pt_regs *regs, + struct op_counter_config *ctr) +{ + /* EV4 can't properly disable counters individually. + Discard "disabled" events now. */ + if (!ctr[which].enabled) + return; + + /* Record the sample. */ + oprofile_add_sample(regs, which); +} + + +struct op_axp_model op_model_ev4 = { + .reg_setup = ev4_reg_setup, + .cpu_setup = ev4_cpu_setup, + .reset_ctr = NULL, + .handle_interrupt = ev4_handle_interrupt, + .cpu_type = "alpha/ev4", + .num_counters = 2, + .can_set_proc_mode = 0, +}; |