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