Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
alpha
oprofile
common.c
Go to the documentation of this file.
1
10
#include <
linux/oprofile.h
>
11
#include <
linux/init.h
>
12
#include <
linux/smp.h
>
13
#include <linux/errno.h>
14
#include <asm/ptrace.h>
15
#include <asm/special_insns.h>
16
17
#include "
op_impl.h
"
18
19
extern
struct
op_axp_model
op_model_ev4
__attribute__
((weak));
20
extern
struct
op_axp_model
op_model_ev5
__attribute__
((weak));
21
extern
struct
op_axp_model
op_model_pca56
__attribute__
((weak));
22
extern
struct
op_axp_model
op_model_ev6
__attribute__
((weak));
23
extern
struct
op_axp_model
op_model_ev67
__attribute__
((weak));
24
25
static
struct
op_axp_model
*model;
26
27
extern
void
(*
perf_irq
)(
unsigned
long
,
struct
pt_regs
*);
28
static
void
(*save_perf_irq)(
unsigned
long
,
struct
pt_regs
*);
29
30
static
struct
op_counter_config
ctr[20];
31
static
struct
op_system_config
sys
;
32
static
struct
op_register_config
reg
;
33
34
/* Called from do_entInt to handle the performance monitor interrupt. */
35
36
static
void
37
op_handle_interrupt(
unsigned
long
which,
struct
pt_regs
*
regs
)
38
{
39
model->
handle_interrupt
(which, regs, ctr);
40
41
/* If the user has selected an interrupt frequency that is
42
not exactly the width of the counter, write a new value
43
into the counter such that it'll overflow after N more
44
events. */
45
if
((
reg
.need_reset >> which) & 1)
46
model->
reset_ctr
(&
reg
, which);
47
}
48
49
static
int
50
op_axp_setup(
void
)
51
{
52
unsigned
long
i
,
e
;
53
54
/* Install our interrupt handler into the existing hook. */
55
save_perf_irq =
perf_irq
;
56
perf_irq
= op_handle_interrupt;
57
58
/* Compute the mask of enabled counters. */
59
for
(i = e = 0; i < model->
num_counters
; ++
i
)
60
if
(ctr[i].
enabled
)
61
e |= 1 <<
i
;
62
reg
.enable =
e
;
63
64
/* Pre-compute the values to stuff in the hardware registers. */
65
model->
reg_setup
(&
reg
, ctr, &
sys
);
66
67
/* Configure the registers on all cpus. */
68
(
void
)
smp_call_function
(model->
cpu_setup
, &
reg
, 1);
69
model->
cpu_setup
(&
reg
);
70
return
0;
71
}
72
73
static
void
74
op_axp_shutdown(
void
)
75
{
76
/* Remove our interrupt handler. We may be removing this module. */
77
perf_irq
= save_perf_irq;
78
}
79
80
static
void
81
op_axp_cpu_start(
void
*
dummy
)
82
{
83
wrperfmon(1,
reg
.enable);
84
}
85
86
static
int
87
op_axp_start(
void
)
88
{
89
(
void
)
smp_call_function
(op_axp_cpu_start,
NULL
, 1);
90
op_axp_cpu_start(
NULL
);
91
return
0;
92
}
93
94
static
inline
void
95
op_axp_cpu_stop(
void
*
dummy
)
96
{
97
/* Disable performance monitoring for all counters. */
98
wrperfmon(0, -1);
99
}
100
101
static
void
102
op_axp_stop(
void
)
103
{
104
(
void
)
smp_call_function
(op_axp_cpu_stop,
NULL
, 1);
105
op_axp_cpu_stop(
NULL
);
106
}
107
108
static
int
109
op_axp_create_files(
struct
super_block
*
sb
,
struct
dentry
*root)
110
{
111
int
i
;
112
113
for
(i = 0; i < model->
num_counters
; ++
i
) {
114
struct
dentry
*
dir
;
115
char
buf
[4];
116
117
snprintf
(buf,
sizeof
buf,
"%d"
, i);
118
dir =
oprofilefs_mkdir
(sb, root, buf);
119
120
oprofilefs_create_ulong
(sb, dir,
"enabled"
, &ctr[i].enabled);
121
oprofilefs_create_ulong
(sb, dir,
"event"
, &ctr[i].
event
);
122
oprofilefs_create_ulong
(sb, dir,
"count"
, &ctr[i].
count
);
123
/* Dummies. */
124
oprofilefs_create_ulong
(sb, dir,
"kernel"
, &ctr[i].kernel);
125
oprofilefs_create_ulong
(sb, dir,
"user"
, &ctr[i].
user
);
126
oprofilefs_create_ulong
(sb, dir,
"unit_mask"
, &ctr[i].unit_mask);
127
}
128
129
if
(model->
can_set_proc_mode
) {
130
oprofilefs_create_ulong
(sb, root,
"enable_pal"
,
131
&
sys
.enable_pal);
132
oprofilefs_create_ulong
(sb, root,
"enable_kernel"
,
133
&
sys
.enable_kernel);
134
oprofilefs_create_ulong
(sb, root,
"enable_user"
,
135
&
sys
.enable_user);
136
}
137
138
return
0;
139
}
140
141
int
__init
142
oprofile_arch_init
(
struct
oprofile_operations
*ops)
143
{
144
struct
op_axp_model
*lmodel =
NULL
;
145
146
switch
(implver()) {
147
case
IMPLVER_EV4
:
148
lmodel = &
op_model_ev4
;
149
break
;
150
case
IMPLVER_EV5
:
151
/* 21164PC has a slightly different set of events.
152
Recognize the chip by the presence of the MAX insns. */
153
if
(!
amask
(
AMASK_MAX
))
154
lmodel = &
op_model_pca56
;
155
else
156
lmodel = &
op_model_ev5
;
157
break
;
158
case
IMPLVER_EV6
:
159
/* 21264A supports ProfileMe.
160
Recognize the chip by the presence of the CIX insns. */
161
if
(!
amask
(
AMASK_CIX
))
162
lmodel = &
op_model_ev67
;
163
else
164
lmodel = &
op_model_ev6
;
165
break
;
166
}
167
168
if
(!lmodel)
169
return
-
ENODEV
;
170
model = lmodel;
171
172
ops->
create_files
= op_axp_create_files;
173
ops->
setup
= op_axp_setup;
174
ops->
shutdown
= op_axp_shutdown;
175
ops->
start
= op_axp_start;
176
ops->
stop
= op_axp_stop;
177
ops->
cpu_type
= lmodel->
cpu_type
;
178
179
printk
(
KERN_INFO
"oprofile: using %s performance monitoring.\n"
,
180
lmodel->
cpu_type
);
181
182
return
0;
183
}
184
185
186
void
187
oprofile_arch_exit
(
void
)
188
{
189
}
Generated on Thu Jan 10 2013 12:54:26 for Linux Kernel by
1.8.2