1
2
3
4
5
6
7
8
9
10#include <linux/oprofile.h>
11#include <linux/init.h>
12#include <linux/smp.h>
13#include <asm/ptrace.h>
14#include <asm/system.h>
15
16#include "op_impl.h"
17
18
19
20
21static void
22ev6_reg_setup(struct op_register_config *reg,
23 struct op_counter_config *ctr,
24 struct op_system_config *sys)
25{
26 unsigned long ctl, reset, need_reset, i;
27
28
29
30 ctl = 0;
31 if (ctr[0].enabled && ctr[0].event)
32 ctl |= (ctr[0].event & 1) << 4;
33 if (ctr[1].enabled)
34 ctl |= (ctr[1].event - 2) & 15;
35 reg->mux_select = ctl;
36
37
38
39
40
41 reg->proc_mode = 0;
42
43
44
45
46
47 reset = need_reset = 0;
48 for (i = 0; i < 2; ++i) {
49 unsigned long count = ctr[i].count;
50 if (!ctr[i].enabled)
51 continue;
52
53 if (count > 0x100000)
54 count = 0x100000;
55 ctr[i].count = count;
56 reset |= (0x100000 - count) << (i ? 6 : 28);
57 if (count != 0x100000)
58 need_reset |= 1 << i;
59 }
60 reg->reset_values = reset;
61 reg->need_reset = need_reset;
62}
63
64
65
66static void
67ev6_cpu_setup (void *x)
68{
69 struct op_register_config *reg = x;
70
71 wrperfmon(2, reg->mux_select);
72 wrperfmon(3, reg->proc_mode);
73 wrperfmon(6, reg->reset_values | 3);
74}
75
76
77
78
79
80static void
81ev6_reset_ctr(struct op_register_config *reg, unsigned long ctr)
82{
83 wrperfmon(6, reg->reset_values | (1 << ctr));
84}
85
86static void
87ev6_handle_interrupt(unsigned long which, struct pt_regs *regs,
88 struct op_counter_config *ctr)
89{
90
91 oprofile_add_sample(regs, which);
92}
93
94
95struct op_axp_model op_model_ev6 = {
96 .reg_setup = ev6_reg_setup,
97 .cpu_setup = ev6_cpu_setup,
98 .reset_ctr = ev6_reset_ctr,
99 .handle_interrupt = ev6_handle_interrupt,
100 .cpu_type = "alpha/ev6",
101 .num_counters = 2,
102 .can_set_proc_mode = 0,
103};
104