Path: blob/master/arch/alpha/oprofile/op_model_ev4.c
10817 views
/**1* @file arch/alpha/oprofile/op_model_ev4.c2*3* @remark Copyright 2002 OProfile authors4* @remark Read the file COPYING5*6* @author Richard Henderson <[email protected]>7*/89#include <linux/oprofile.h>10#include <linux/init.h>11#include <linux/smp.h>12#include <asm/ptrace.h>13#include <asm/system.h>1415#include "op_impl.h"161718/* Compute all of the registers in preparation for enabling profiling. */1920static void21ev4_reg_setup(struct op_register_config *reg,22struct op_counter_config *ctr,23struct op_system_config *sys)24{25unsigned long ctl = 0, count, hilo;2627/* Select desired events. We've mapped the event numbers28such that they fit directly into the event selection fields.2930Note that there is no "off" setting. In both cases we select31the EXTERNAL event source, hoping that it'll be the lowest32frequency, and set the frequency counter to LOW. The interrupts33for these "disabled" counter overflows are ignored by the34interrupt handler.3536This is most irritating, because the hardware *can* enable and37disable the interrupts for these counters independently, but the38wrperfmon interface doesn't allow it. */3940ctl |= (ctr[0].enabled ? ctr[0].event << 8 : 14 << 8);41ctl |= (ctr[1].enabled ? (ctr[1].event - 16) << 32 : 7ul << 32);4243/* EV4 can not read or write its counter registers. The only44thing one can do at all is see if you overflow and get an45interrupt. We can set the width of the counters, to some46extent. Take the interrupt count selected by the user,47map it onto one of the possible values, and write it back. */4849count = ctr[0].count;50if (count <= 4096)51count = 4096, hilo = 1;52else53count = 65536, hilo = 0;54ctr[0].count = count;55ctl |= (ctr[0].enabled && hilo) << 3;5657count = ctr[1].count;58if (count <= 256)59count = 256, hilo = 1;60else61count = 4096, hilo = 0;62ctr[1].count = count;63ctl |= (ctr[1].enabled && hilo);6465reg->mux_select = ctl;6667/* Select performance monitoring options. */68/* ??? Need to come up with some mechanism to trace only69selected processes. EV4 does not have a mechanism to70select kernel or user mode only. For now, enable always. */71reg->proc_mode = 0;7273/* Frequency is folded into mux_select for EV4. */74reg->freq = 0;7576/* See above regarding no writes. */77reg->reset_values = 0;78reg->need_reset = 0;7980}8182/* Program all of the registers in preparation for enabling profiling. */8384static void85ev4_cpu_setup(void *x)86{87struct op_register_config *reg = x;8889wrperfmon(2, reg->mux_select);90wrperfmon(3, reg->proc_mode);91}9293static void94ev4_handle_interrupt(unsigned long which, struct pt_regs *regs,95struct op_counter_config *ctr)96{97/* EV4 can't properly disable counters individually.98Discard "disabled" events now. */99if (!ctr[which].enabled)100return;101102/* Record the sample. */103oprofile_add_sample(regs, which);104}105106107struct op_axp_model op_model_ev4 = {108.reg_setup = ev4_reg_setup,109.cpu_setup = ev4_cpu_setup,110.reset_ctr = NULL,111.handle_interrupt = ev4_handle_interrupt,112.cpu_type = "alpha/ev4",113.num_counters = 2,114.can_set_proc_mode = 0,115};116117118