aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/power6-pmu.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-20 14:29:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-20 14:29:32 -0400
commit12e24f34cb0d55efd08c18b2112507d4bf498008 (patch)
tree83b07be17b8ef45f42360a3b9159b3aaae3fbad4 /arch/powerpc/kernel/power6-pmu.c
parent1eb51c33b21ffa3fceb634d1d6bcd6488c79bc26 (diff)
parenteadc84cc01e04f9f74ec2de0c9355be035c7b396 (diff)
Merge branch 'perfcounters-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perfcounters-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (49 commits) perfcounter: Handle some IO return values perf_counter: Push perf_sample_data through the swcounter code perf_counter tools: Define and use our own u64, s64 etc. definitions perf_counter: Close race in perf_lock_task_context() perf_counter, x86: Improve interactions with fast-gup perf_counter: Simplify and fix task migration counting perf_counter tools: Add a data file header perf_counter: Update userspace callchain sampling uses perf_counter: Make callchain samples extensible perf report: Filter to parent set by default perf_counter tools: Handle lost events perf_counter: Add event overlow handling fs: Provide empty .set_page_dirty() aop for anon inodes perf_counter: tools: Makefile tweaks for 64-bit powerpc perf_counter: powerpc: Add processor back-end for MPC7450 family perf_counter: powerpc: Make powerpc perf_counter code safe for 32-bit kernels perf_counter: powerpc: Change how processor-specific back-ends get selected perf_counter: powerpc: Use unsigned long for register and constraint values perf_counter: powerpc: Enable use of software counters on 32-bit powerpc perf_counter tools: Add and use isprint() ...
Diffstat (limited to 'arch/powerpc/kernel/power6-pmu.c')
-rw-r--r--arch/powerpc/kernel/power6-pmu.c72
1 files changed, 43 insertions, 29 deletions
diff --git a/arch/powerpc/kernel/power6-pmu.c b/arch/powerpc/kernel/power6-pmu.c
index 46f74bebcfd9..09ae5bf5bda7 100644
--- a/arch/powerpc/kernel/power6-pmu.c
+++ b/arch/powerpc/kernel/power6-pmu.c
@@ -10,7 +10,9 @@
10 */ 10 */
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/perf_counter.h> 12#include <linux/perf_counter.h>
13#include <linux/string.h>
13#include <asm/reg.h> 14#include <asm/reg.h>
15#include <asm/cputable.h>
14 16
15/* 17/*
16 * Bits in event code for POWER6 18 * Bits in event code for POWER6
@@ -41,9 +43,9 @@
41#define MMCR1_NESTSEL_SH 45 43#define MMCR1_NESTSEL_SH 45
42#define MMCR1_NESTSEL_MSK 0x7 44#define MMCR1_NESTSEL_MSK 0x7
43#define MMCR1_NESTSEL(m) (((m) >> MMCR1_NESTSEL_SH) & MMCR1_NESTSEL_MSK) 45#define MMCR1_NESTSEL(m) (((m) >> MMCR1_NESTSEL_SH) & MMCR1_NESTSEL_MSK)
44#define MMCR1_PMC1_LLA ((u64)1 << 44) 46#define MMCR1_PMC1_LLA (1ul << 44)
45#define MMCR1_PMC1_LLA_VALUE ((u64)1 << 39) 47#define MMCR1_PMC1_LLA_VALUE (1ul << 39)
46#define MMCR1_PMC1_ADDR_SEL ((u64)1 << 35) 48#define MMCR1_PMC1_ADDR_SEL (1ul << 35)
47#define MMCR1_PMC1SEL_SH 24 49#define MMCR1_PMC1SEL_SH 24
48#define MMCR1_PMCSEL_SH(n) (MMCR1_PMC1SEL_SH - (n) * 8) 50#define MMCR1_PMCSEL_SH(n) (MMCR1_PMC1SEL_SH - (n) * 8)
49#define MMCR1_PMCSEL_MSK 0xff 51#define MMCR1_PMCSEL_MSK 0xff
@@ -173,10 +175,10 @@ static int power6_marked_instr_event(u64 event)
173 * Assign PMC numbers and compute MMCR1 value for a set of events 175 * Assign PMC numbers and compute MMCR1 value for a set of events
174 */ 176 */
175static int p6_compute_mmcr(u64 event[], int n_ev, 177static int p6_compute_mmcr(u64 event[], int n_ev,
176 unsigned int hwc[], u64 mmcr[]) 178 unsigned int hwc[], unsigned long mmcr[])
177{ 179{
178 u64 mmcr1 = 0; 180 unsigned long mmcr1 = 0;
179 u64 mmcra = 0; 181 unsigned long mmcra = 0;
180 int i; 182 int i;
181 unsigned int pmc, ev, b, u, s, psel; 183 unsigned int pmc, ev, b, u, s, psel;
182 unsigned int ttmset = 0; 184 unsigned int ttmset = 0;
@@ -215,7 +217,7 @@ static int p6_compute_mmcr(u64 event[], int n_ev,
215 /* check for conflict on this byte of event bus */ 217 /* check for conflict on this byte of event bus */
216 if ((ttmset & (1 << b)) && MMCR1_TTMSEL(mmcr1, b) != u) 218 if ((ttmset & (1 << b)) && MMCR1_TTMSEL(mmcr1, b) != u)
217 return -1; 219 return -1;
218 mmcr1 |= (u64)u << MMCR1_TTMSEL_SH(b); 220 mmcr1 |= (unsigned long)u << MMCR1_TTMSEL_SH(b);
219 ttmset |= 1 << b; 221 ttmset |= 1 << b;
220 if (u == 5) { 222 if (u == 5) {
221 /* Nest events have a further mux */ 223 /* Nest events have a further mux */
@@ -224,7 +226,7 @@ static int p6_compute_mmcr(u64 event[], int n_ev,
224 MMCR1_NESTSEL(mmcr1) != s) 226 MMCR1_NESTSEL(mmcr1) != s)
225 return -1; 227 return -1;
226 ttmset |= 0x10; 228 ttmset |= 0x10;
227 mmcr1 |= (u64)s << MMCR1_NESTSEL_SH; 229 mmcr1 |= (unsigned long)s << MMCR1_NESTSEL_SH;
228 } 230 }
229 if (0x30 <= psel && psel <= 0x3d) { 231 if (0x30 <= psel && psel <= 0x3d) {
230 /* these need the PMCx_ADDR_SEL bits */ 232 /* these need the PMCx_ADDR_SEL bits */
@@ -243,7 +245,7 @@ static int p6_compute_mmcr(u64 event[], int n_ev,
243 if (power6_marked_instr_event(event[i])) 245 if (power6_marked_instr_event(event[i]))
244 mmcra |= MMCRA_SAMPLE_ENABLE; 246 mmcra |= MMCRA_SAMPLE_ENABLE;
245 if (pmc < 4) 247 if (pmc < 4)
246 mmcr1 |= (u64)psel << MMCR1_PMCSEL_SH(pmc); 248 mmcr1 |= (unsigned long)psel << MMCR1_PMCSEL_SH(pmc);
247 } 249 }
248 mmcr[0] = 0; 250 mmcr[0] = 0;
249 if (pmc_inuse & 1) 251 if (pmc_inuse & 1)
@@ -265,10 +267,11 @@ static int p6_compute_mmcr(u64 event[], int n_ev,
265 * 20-23, 24-27, 28-31 ditto for bytes 1, 2, 3 267 * 20-23, 24-27, 28-31 ditto for bytes 1, 2, 3
266 * 32-34 select field: nest (subunit) event selector 268 * 32-34 select field: nest (subunit) event selector
267 */ 269 */
268static int p6_get_constraint(u64 event, u64 *maskp, u64 *valp) 270static int p6_get_constraint(u64 event, unsigned long *maskp,
271 unsigned long *valp)
269{ 272{
270 int pmc, byte, sh, subunit; 273 int pmc, byte, sh, subunit;
271 u64 mask = 0, value = 0; 274 unsigned long mask = 0, value = 0;
272 275
273 pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; 276 pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
274 if (pmc) { 277 if (pmc) {
@@ -282,11 +285,11 @@ static int p6_get_constraint(u64 event, u64 *maskp, u64 *valp)
282 byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; 285 byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
283 sh = byte * 4 + (16 - PM_UNIT_SH); 286 sh = byte * 4 + (16 - PM_UNIT_SH);
284 mask |= PM_UNIT_MSKS << sh; 287 mask |= PM_UNIT_MSKS << sh;
285 value |= (u64)(event & PM_UNIT_MSKS) << sh; 288 value |= (unsigned long)(event & PM_UNIT_MSKS) << sh;
286 if ((event & PM_UNIT_MSKS) == (5 << PM_UNIT_SH)) { 289 if ((event & PM_UNIT_MSKS) == (5 << PM_UNIT_SH)) {
287 subunit = (event >> PM_SUBUNIT_SH) & PM_SUBUNIT_MSK; 290 subunit = (event >> PM_SUBUNIT_SH) & PM_SUBUNIT_MSK;
288 mask |= (u64)PM_SUBUNIT_MSK << 32; 291 mask |= (unsigned long)PM_SUBUNIT_MSK << 32;
289 value |= (u64)subunit << 32; 292 value |= (unsigned long)subunit << 32;
290 } 293 }
291 } 294 }
292 if (pmc <= 4) { 295 if (pmc <= 4) {
@@ -458,7 +461,7 @@ static int p6_get_alternatives(u64 event, unsigned int flags, u64 alt[])
458 return nalt; 461 return nalt;
459} 462}
460 463
461static void p6_disable_pmc(unsigned int pmc, u64 mmcr[]) 464static void p6_disable_pmc(unsigned int pmc, unsigned long mmcr[])
462{ 465{
463 /* Set PMCxSEL to 0 to disable PMCx */ 466 /* Set PMCxSEL to 0 to disable PMCx */
464 if (pmc <= 3) 467 if (pmc <= 3)
@@ -515,18 +518,29 @@ static int power6_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
515 }, 518 },
516}; 519};
517 520
518struct power_pmu power6_pmu = { 521static struct power_pmu power6_pmu = {
519 .n_counter = 6, 522 .name = "POWER6",
520 .max_alternatives = MAX_ALT, 523 .n_counter = 6,
521 .add_fields = 0x1555, 524 .max_alternatives = MAX_ALT,
522 .test_adder = 0x3000, 525 .add_fields = 0x1555,
523 .compute_mmcr = p6_compute_mmcr, 526 .test_adder = 0x3000,
524 .get_constraint = p6_get_constraint, 527 .compute_mmcr = p6_compute_mmcr,
525 .get_alternatives = p6_get_alternatives, 528 .get_constraint = p6_get_constraint,
526 .disable_pmc = p6_disable_pmc, 529 .get_alternatives = p6_get_alternatives,
527 .limited_pmc_event = p6_limited_pmc_event, 530 .disable_pmc = p6_disable_pmc,
528 .flags = PPMU_LIMITED_PMC5_6 | PPMU_ALT_SIPR, 531 .limited_pmc_event = p6_limited_pmc_event,
529 .n_generic = ARRAY_SIZE(power6_generic_events), 532 .flags = PPMU_LIMITED_PMC5_6 | PPMU_ALT_SIPR,
530 .generic_events = power6_generic_events, 533 .n_generic = ARRAY_SIZE(power6_generic_events),
531 .cache_events = &power6_cache_events, 534 .generic_events = power6_generic_events,
535 .cache_events = &power6_cache_events,
532}; 536};
537
538static int init_power6_pmu(void)
539{
540 if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power6"))
541 return -ENODEV;
542
543 return register_power_pmu(&power6_pmu);
544}
545
546arch_initcall(init_power6_pmu);