diff options
Diffstat (limited to 'arch/powerpc/kernel/power4-pmu.c')
-rw-r--r-- | arch/powerpc/kernel/power4-pmu.c | 90 |
1 files changed, 54 insertions, 36 deletions
diff --git a/arch/powerpc/kernel/power4-pmu.c b/arch/powerpc/kernel/power4-pmu.c index 07bd308a5fa7..3c90a3d9173e 100644 --- a/arch/powerpc/kernel/power4-pmu.c +++ b/arch/powerpc/kernel/power4-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 POWER4 | 18 | * Bits in event code for POWER4 |
@@ -179,22 +181,22 @@ static short mmcr1_adder_bits[8] = { | |||
179 | */ | 181 | */ |
180 | 182 | ||
181 | static struct unitinfo { | 183 | static struct unitinfo { |
182 | u64 value, mask; | 184 | unsigned long value, mask; |
183 | int unit; | 185 | int unit; |
184 | int lowerbit; | 186 | int lowerbit; |
185 | } p4_unitinfo[16] = { | 187 | } p4_unitinfo[16] = { |
186 | [PM_FPU] = { 0x44000000000000ull, 0x88000000000000ull, PM_FPU, 0 }, | 188 | [PM_FPU] = { 0x44000000000000ul, 0x88000000000000ul, PM_FPU, 0 }, |
187 | [PM_ISU1] = { 0x20080000000000ull, 0x88000000000000ull, PM_ISU1, 0 }, | 189 | [PM_ISU1] = { 0x20080000000000ul, 0x88000000000000ul, PM_ISU1, 0 }, |
188 | [PM_ISU1_ALT] = | 190 | [PM_ISU1_ALT] = |
189 | { 0x20080000000000ull, 0x88000000000000ull, PM_ISU1, 0 }, | 191 | { 0x20080000000000ul, 0x88000000000000ul, PM_ISU1, 0 }, |
190 | [PM_IFU] = { 0x02200000000000ull, 0x08820000000000ull, PM_IFU, 41 }, | 192 | [PM_IFU] = { 0x02200000000000ul, 0x08820000000000ul, PM_IFU, 41 }, |
191 | [PM_IFU_ALT] = | 193 | [PM_IFU_ALT] = |
192 | { 0x02200000000000ull, 0x08820000000000ull, PM_IFU, 41 }, | 194 | { 0x02200000000000ul, 0x08820000000000ul, PM_IFU, 41 }, |
193 | [PM_IDU0] = { 0x10100000000000ull, 0x80840000000000ull, PM_IDU0, 1 }, | 195 | [PM_IDU0] = { 0x10100000000000ul, 0x80840000000000ul, PM_IDU0, 1 }, |
194 | [PM_ISU2] = { 0x10140000000000ull, 0x80840000000000ull, PM_ISU2, 0 }, | 196 | [PM_ISU2] = { 0x10140000000000ul, 0x80840000000000ul, PM_ISU2, 0 }, |
195 | [PM_LSU0] = { 0x01400000000000ull, 0x08800000000000ull, PM_LSU0, 0 }, | 197 | [PM_LSU0] = { 0x01400000000000ul, 0x08800000000000ul, PM_LSU0, 0 }, |
196 | [PM_LSU1] = { 0x00000000000000ull, 0x00010000000000ull, PM_LSU1, 40 }, | 198 | [PM_LSU1] = { 0x00000000000000ul, 0x00010000000000ul, PM_LSU1, 40 }, |
197 | [PM_GPS] = { 0x00000000000000ull, 0x00000000000000ull, PM_GPS, 0 } | 199 | [PM_GPS] = { 0x00000000000000ul, 0x00000000000000ul, PM_GPS, 0 } |
198 | }; | 200 | }; |
199 | 201 | ||
200 | static unsigned char direct_marked_event[8] = { | 202 | static unsigned char direct_marked_event[8] = { |
@@ -249,10 +251,11 @@ static int p4_marked_instr_event(u64 event) | |||
249 | return (mask >> (byte * 8 + bit)) & 1; | 251 | return (mask >> (byte * 8 + bit)) & 1; |
250 | } | 252 | } |
251 | 253 | ||
252 | static int p4_get_constraint(u64 event, u64 *maskp, u64 *valp) | 254 | static int p4_get_constraint(u64 event, unsigned long *maskp, |
255 | unsigned long *valp) | ||
253 | { | 256 | { |
254 | int pmc, byte, unit, lower, sh; | 257 | int pmc, byte, unit, lower, sh; |
255 | u64 mask = 0, value = 0; | 258 | unsigned long mask = 0, value = 0; |
256 | int grp = -1; | 259 | int grp = -1; |
257 | 260 | ||
258 | pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; | 261 | pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; |
@@ -282,14 +285,14 @@ static int p4_get_constraint(u64 event, u64 *maskp, u64 *valp) | |||
282 | value |= p4_unitinfo[unit].value; | 285 | value |= p4_unitinfo[unit].value; |
283 | sh = p4_unitinfo[unit].lowerbit; | 286 | sh = p4_unitinfo[unit].lowerbit; |
284 | if (sh > 1) | 287 | if (sh > 1) |
285 | value |= (u64)lower << sh; | 288 | value |= (unsigned long)lower << sh; |
286 | else if (lower != sh) | 289 | else if (lower != sh) |
287 | return -1; | 290 | return -1; |
288 | unit = p4_unitinfo[unit].unit; | 291 | unit = p4_unitinfo[unit].unit; |
289 | 292 | ||
290 | /* Set byte lane select field */ | 293 | /* Set byte lane select field */ |
291 | mask |= 0xfULL << (28 - 4 * byte); | 294 | mask |= 0xfULL << (28 - 4 * byte); |
292 | value |= (u64)unit << (28 - 4 * byte); | 295 | value |= (unsigned long)unit << (28 - 4 * byte); |
293 | } | 296 | } |
294 | if (grp == 0) { | 297 | if (grp == 0) { |
295 | /* increment PMC1/2/5/6 field */ | 298 | /* increment PMC1/2/5/6 field */ |
@@ -353,9 +356,9 @@ static int p4_get_alternatives(u64 event, unsigned int flags, u64 alt[]) | |||
353 | } | 356 | } |
354 | 357 | ||
355 | static int p4_compute_mmcr(u64 event[], int n_ev, | 358 | static int p4_compute_mmcr(u64 event[], int n_ev, |
356 | unsigned int hwc[], u64 mmcr[]) | 359 | unsigned int hwc[], unsigned long mmcr[]) |
357 | { | 360 | { |
358 | u64 mmcr0 = 0, mmcr1 = 0, mmcra = 0; | 361 | unsigned long mmcr0 = 0, mmcr1 = 0, mmcra = 0; |
359 | unsigned int pmc, unit, byte, psel, lower; | 362 | unsigned int pmc, unit, byte, psel, lower; |
360 | unsigned int ttm, grp; | 363 | unsigned int ttm, grp; |
361 | unsigned int pmc_inuse = 0; | 364 | unsigned int pmc_inuse = 0; |
@@ -429,9 +432,11 @@ static int p4_compute_mmcr(u64 event[], int n_ev, | |||
429 | return -1; | 432 | return -1; |
430 | 433 | ||
431 | /* Set TTMxSEL fields. Note, units 1-3 => TTM0SEL codes 0-2 */ | 434 | /* Set TTMxSEL fields. Note, units 1-3 => TTM0SEL codes 0-2 */ |
432 | mmcr1 |= (u64)(unituse[3] * 2 + unituse[2]) << MMCR1_TTM0SEL_SH; | 435 | mmcr1 |= (unsigned long)(unituse[3] * 2 + unituse[2]) |
433 | mmcr1 |= (u64)(unituse[7] * 3 + unituse[6] * 2) << MMCR1_TTM1SEL_SH; | 436 | << MMCR1_TTM0SEL_SH; |
434 | mmcr1 |= (u64)unituse[9] << MMCR1_TTM2SEL_SH; | 437 | mmcr1 |= (unsigned long)(unituse[7] * 3 + unituse[6] * 2) |
438 | << MMCR1_TTM1SEL_SH; | ||
439 | mmcr1 |= (unsigned long)unituse[9] << MMCR1_TTM2SEL_SH; | ||
435 | 440 | ||
436 | /* Set TTCxSEL fields. */ | 441 | /* Set TTCxSEL fields. */ |
437 | if (unitlower & 0xe) | 442 | if (unitlower & 0xe) |
@@ -456,7 +461,8 @@ static int p4_compute_mmcr(u64 event[], int n_ev, | |||
456 | ttm = unit - 1; /* 2->1, 3->2 */ | 461 | ttm = unit - 1; /* 2->1, 3->2 */ |
457 | else | 462 | else |
458 | ttm = unit >> 2; | 463 | ttm = unit >> 2; |
459 | mmcr1 |= (u64)ttm << (MMCR1_TD_CP_DBG0SEL_SH - 2*byte); | 464 | mmcr1 |= (unsigned long)ttm |
465 | << (MMCR1_TD_CP_DBG0SEL_SH - 2 * byte); | ||
460 | } | 466 | } |
461 | } | 467 | } |
462 | 468 | ||
@@ -519,7 +525,7 @@ static int p4_compute_mmcr(u64 event[], int n_ev, | |||
519 | return 0; | 525 | return 0; |
520 | } | 526 | } |
521 | 527 | ||
522 | static void p4_disable_pmc(unsigned int pmc, u64 mmcr[]) | 528 | static void p4_disable_pmc(unsigned int pmc, unsigned long mmcr[]) |
523 | { | 529 | { |
524 | /* | 530 | /* |
525 | * Setting the PMCxSEL field to 0 disables PMC x. | 531 | * Setting the PMCxSEL field to 0 disables PMC x. |
@@ -583,16 +589,28 @@ static int power4_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | |||
583 | }, | 589 | }, |
584 | }; | 590 | }; |
585 | 591 | ||
586 | struct power_pmu power4_pmu = { | 592 | static struct power_pmu power4_pmu = { |
587 | .n_counter = 8, | 593 | .name = "POWER4/4+", |
588 | .max_alternatives = 5, | 594 | .n_counter = 8, |
589 | .add_fields = 0x0000001100005555ull, | 595 | .max_alternatives = 5, |
590 | .test_adder = 0x0011083300000000ull, | 596 | .add_fields = 0x0000001100005555ul, |
591 | .compute_mmcr = p4_compute_mmcr, | 597 | .test_adder = 0x0011083300000000ul, |
592 | .get_constraint = p4_get_constraint, | 598 | .compute_mmcr = p4_compute_mmcr, |
593 | .get_alternatives = p4_get_alternatives, | 599 | .get_constraint = p4_get_constraint, |
594 | .disable_pmc = p4_disable_pmc, | 600 | .get_alternatives = p4_get_alternatives, |
595 | .n_generic = ARRAY_SIZE(p4_generic_events), | 601 | .disable_pmc = p4_disable_pmc, |
596 | .generic_events = p4_generic_events, | 602 | .n_generic = ARRAY_SIZE(p4_generic_events), |
597 | .cache_events = &power4_cache_events, | 603 | .generic_events = p4_generic_events, |
604 | .cache_events = &power4_cache_events, | ||
598 | }; | 605 | }; |
606 | |||
607 | static int init_power4_pmu(void) | ||
608 | { | ||
609 | if (!cur_cpu_spec->oprofile_cpu_type || | ||
610 | strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power4")) | ||
611 | return -ENODEV; | ||
612 | |||
613 | return register_power_pmu(&power4_pmu); | ||
614 | } | ||
615 | |||
616 | arch_initcall(init_power4_pmu); | ||