diff options
author | Robert Richter <robert.richter@amd.com> | 2010-02-26 04:54:56 -0500 |
---|---|---|
committer | Robert Richter <robert.richter@amd.com> | 2010-05-04 05:35:28 -0400 |
commit | da759fe5be24ec3b236a76c007b460cf6caf2009 (patch) | |
tree | 881639946d460a9fc5d9528793bd10e703f826a4 /arch/x86/oprofile | |
parent | 8617f98c001d00b176422d707e6a67b88bcd7e0d (diff) |
oprofile/x86: move IBS code
Moving code to make future changes easier. This groups all IBS code
together.
Signed-off-by: Robert Richter <robert.richter@amd.com>
Diffstat (limited to 'arch/x86/oprofile')
-rw-r--r-- | arch/x86/oprofile/op_model_amd.c | 220 |
1 files changed, 110 insertions, 110 deletions
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 536d0b0b39a5..e159254fb7cd 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c | |||
@@ -102,116 +102,6 @@ static u32 get_ibs_caps(void) | |||
102 | return ibs_caps; | 102 | return ibs_caps; |
103 | } | 103 | } |
104 | 104 | ||
105 | #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX | ||
106 | |||
107 | static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, | ||
108 | struct op_msrs const * const msrs) | ||
109 | { | ||
110 | u64 val; | ||
111 | int i; | ||
112 | |||
113 | /* enable active counters */ | ||
114 | for (i = 0; i < NUM_COUNTERS; ++i) { | ||
115 | int virt = op_x86_phys_to_virt(i); | ||
116 | if (!reset_value[virt]) | ||
117 | continue; | ||
118 | rdmsrl(msrs->controls[i].addr, val); | ||
119 | val &= model->reserved; | ||
120 | val |= op_x86_get_ctrl(model, &counter_config[virt]); | ||
121 | wrmsrl(msrs->controls[i].addr, val); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | #endif | ||
126 | |||
127 | /* functions for op_amd_spec */ | ||
128 | |||
129 | static void op_amd_shutdown(struct op_msrs const * const msrs) | ||
130 | { | ||
131 | int i; | ||
132 | |||
133 | for (i = 0; i < NUM_COUNTERS; ++i) { | ||
134 | if (!msrs->counters[i].addr) | ||
135 | continue; | ||
136 | release_perfctr_nmi(MSR_K7_PERFCTR0 + i); | ||
137 | release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); | ||
138 | } | ||
139 | } | ||
140 | |||
141 | static int op_amd_fill_in_addresses(struct op_msrs * const msrs) | ||
142 | { | ||
143 | int i; | ||
144 | |||
145 | for (i = 0; i < NUM_COUNTERS; i++) { | ||
146 | if (!reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) | ||
147 | goto fail; | ||
148 | if (!reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) { | ||
149 | release_perfctr_nmi(MSR_K7_PERFCTR0 + i); | ||
150 | goto fail; | ||
151 | } | ||
152 | /* both registers must be reserved */ | ||
153 | msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; | ||
154 | msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; | ||
155 | continue; | ||
156 | fail: | ||
157 | if (!counter_config[i].enabled) | ||
158 | continue; | ||
159 | op_x86_warn_reserved(i); | ||
160 | op_amd_shutdown(msrs); | ||
161 | return -EBUSY; | ||
162 | } | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, | ||
168 | struct op_msrs const * const msrs) | ||
169 | { | ||
170 | u64 val; | ||
171 | int i; | ||
172 | |||
173 | /* setup reset_value */ | ||
174 | for (i = 0; i < NUM_VIRT_COUNTERS; ++i) { | ||
175 | if (counter_config[i].enabled | ||
176 | && msrs->counters[op_x86_virt_to_phys(i)].addr) | ||
177 | reset_value[i] = counter_config[i].count; | ||
178 | else | ||
179 | reset_value[i] = 0; | ||
180 | } | ||
181 | |||
182 | /* clear all counters */ | ||
183 | for (i = 0; i < NUM_COUNTERS; ++i) { | ||
184 | if (!msrs->controls[i].addr) | ||
185 | continue; | ||
186 | rdmsrl(msrs->controls[i].addr, val); | ||
187 | if (val & ARCH_PERFMON_EVENTSEL_ENABLE) | ||
188 | op_x86_warn_in_use(i); | ||
189 | val &= model->reserved; | ||
190 | wrmsrl(msrs->controls[i].addr, val); | ||
191 | /* | ||
192 | * avoid a false detection of ctr overflows in NMI | ||
193 | * handler | ||
194 | */ | ||
195 | wrmsrl(msrs->counters[i].addr, -1LL); | ||
196 | } | ||
197 | |||
198 | /* enable active counters */ | ||
199 | for (i = 0; i < NUM_COUNTERS; ++i) { | ||
200 | int virt = op_x86_phys_to_virt(i); | ||
201 | if (!reset_value[virt]) | ||
202 | continue; | ||
203 | |||
204 | /* setup counter registers */ | ||
205 | wrmsrl(msrs->counters[i].addr, -(u64)reset_value[virt]); | ||
206 | |||
207 | /* setup control registers */ | ||
208 | rdmsrl(msrs->controls[i].addr, val); | ||
209 | val &= model->reserved; | ||
210 | val |= op_x86_get_ctrl(model, &counter_config[virt]); | ||
211 | wrmsrl(msrs->controls[i].addr, val); | ||
212 | } | ||
213 | } | ||
214 | |||
215 | /* | 105 | /* |
216 | * 16-bit Linear Feedback Shift Register (LFSR) | 106 | * 16-bit Linear Feedback Shift Register (LFSR) |
217 | * | 107 | * |
@@ -376,6 +266,116 @@ static void op_amd_stop_ibs(void) | |||
376 | wrmsrl(MSR_AMD64_IBSOPCTL, 0); | 266 | wrmsrl(MSR_AMD64_IBSOPCTL, 0); |
377 | } | 267 | } |
378 | 268 | ||
269 | #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX | ||
270 | |||
271 | static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, | ||
272 | struct op_msrs const * const msrs) | ||
273 | { | ||
274 | u64 val; | ||
275 | int i; | ||
276 | |||
277 | /* enable active counters */ | ||
278 | for (i = 0; i < NUM_COUNTERS; ++i) { | ||
279 | int virt = op_x86_phys_to_virt(i); | ||
280 | if (!reset_value[virt]) | ||
281 | continue; | ||
282 | rdmsrl(msrs->controls[i].addr, val); | ||
283 | val &= model->reserved; | ||
284 | val |= op_x86_get_ctrl(model, &counter_config[virt]); | ||
285 | wrmsrl(msrs->controls[i].addr, val); | ||
286 | } | ||
287 | } | ||
288 | |||
289 | #endif | ||
290 | |||
291 | /* functions for op_amd_spec */ | ||
292 | |||
293 | static void op_amd_shutdown(struct op_msrs const * const msrs) | ||
294 | { | ||
295 | int i; | ||
296 | |||
297 | for (i = 0; i < NUM_COUNTERS; ++i) { | ||
298 | if (!msrs->counters[i].addr) | ||
299 | continue; | ||
300 | release_perfctr_nmi(MSR_K7_PERFCTR0 + i); | ||
301 | release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); | ||
302 | } | ||
303 | } | ||
304 | |||
305 | static int op_amd_fill_in_addresses(struct op_msrs * const msrs) | ||
306 | { | ||
307 | int i; | ||
308 | |||
309 | for (i = 0; i < NUM_COUNTERS; i++) { | ||
310 | if (!reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) | ||
311 | goto fail; | ||
312 | if (!reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) { | ||
313 | release_perfctr_nmi(MSR_K7_PERFCTR0 + i); | ||
314 | goto fail; | ||
315 | } | ||
316 | /* both registers must be reserved */ | ||
317 | msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; | ||
318 | msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; | ||
319 | continue; | ||
320 | fail: | ||
321 | if (!counter_config[i].enabled) | ||
322 | continue; | ||
323 | op_x86_warn_reserved(i); | ||
324 | op_amd_shutdown(msrs); | ||
325 | return -EBUSY; | ||
326 | } | ||
327 | |||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, | ||
332 | struct op_msrs const * const msrs) | ||
333 | { | ||
334 | u64 val; | ||
335 | int i; | ||
336 | |||
337 | /* setup reset_value */ | ||
338 | for (i = 0; i < NUM_VIRT_COUNTERS; ++i) { | ||
339 | if (counter_config[i].enabled | ||
340 | && msrs->counters[op_x86_virt_to_phys(i)].addr) | ||
341 | reset_value[i] = counter_config[i].count; | ||
342 | else | ||
343 | reset_value[i] = 0; | ||
344 | } | ||
345 | |||
346 | /* clear all counters */ | ||
347 | for (i = 0; i < NUM_COUNTERS; ++i) { | ||
348 | if (!msrs->controls[i].addr) | ||
349 | continue; | ||
350 | rdmsrl(msrs->controls[i].addr, val); | ||
351 | if (val & ARCH_PERFMON_EVENTSEL_ENABLE) | ||
352 | op_x86_warn_in_use(i); | ||
353 | val &= model->reserved; | ||
354 | wrmsrl(msrs->controls[i].addr, val); | ||
355 | /* | ||
356 | * avoid a false detection of ctr overflows in NMI | ||
357 | * handler | ||
358 | */ | ||
359 | wrmsrl(msrs->counters[i].addr, -1LL); | ||
360 | } | ||
361 | |||
362 | /* enable active counters */ | ||
363 | for (i = 0; i < NUM_COUNTERS; ++i) { | ||
364 | int virt = op_x86_phys_to_virt(i); | ||
365 | if (!reset_value[virt]) | ||
366 | continue; | ||
367 | |||
368 | /* setup counter registers */ | ||
369 | wrmsrl(msrs->counters[i].addr, -(u64)reset_value[virt]); | ||
370 | |||
371 | /* setup control registers */ | ||
372 | rdmsrl(msrs->controls[i].addr, val); | ||
373 | val &= model->reserved; | ||
374 | val |= op_x86_get_ctrl(model, &counter_config[virt]); | ||
375 | wrmsrl(msrs->controls[i].addr, val); | ||
376 | } | ||
377 | } | ||
378 | |||
379 | static int op_amd_check_ctrs(struct pt_regs * const regs, | 379 | static int op_amd_check_ctrs(struct pt_regs * const regs, |
380 | struct op_msrs const * const msrs) | 380 | struct op_msrs const * const msrs) |
381 | { | 381 | { |