diff options
-rw-r--r-- | arch/powerpc/kernel/perf_counter.c | 28 | ||||
-rw-r--r-- | arch/powerpc/kernel/power5+-pmu.c | 103 | ||||
-rw-r--r-- | arch/powerpc/kernel/power5-pmu.c | 96 | ||||
-rw-r--r-- | arch/powerpc/kernel/power6-pmu.c | 126 | ||||
-rw-r--r-- | arch/powerpc/kernel/ppc970-pmu.c | 72 |
5 files changed, 413 insertions, 12 deletions
diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 0e5651385ddc..0697ade84dd3 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c | |||
@@ -307,6 +307,15 @@ u64 hw_perf_save_disable(void) | |||
307 | } | 307 | } |
308 | 308 | ||
309 | /* | 309 | /* |
310 | * Disable instruction sampling if it was enabled | ||
311 | */ | ||
312 | if (cpuhw->mmcr[2] & MMCRA_SAMPLE_ENABLE) { | ||
313 | mtspr(SPRN_MMCRA, | ||
314 | cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE); | ||
315 | mb(); | ||
316 | } | ||
317 | |||
318 | /* | ||
310 | * Set the 'freeze counters' bit. | 319 | * Set the 'freeze counters' bit. |
311 | * The barrier is to make sure the mtspr has been | 320 | * The barrier is to make sure the mtspr has been |
312 | * executed and the PMU has frozen the counters | 321 | * executed and the PMU has frozen the counters |
@@ -347,12 +356,11 @@ void hw_perf_restore(u64 disable) | |||
347 | * (possibly updated for removal of counters). | 356 | * (possibly updated for removal of counters). |
348 | */ | 357 | */ |
349 | if (!cpuhw->n_added) { | 358 | if (!cpuhw->n_added) { |
350 | mtspr(SPRN_MMCRA, cpuhw->mmcr[2]); | 359 | mtspr(SPRN_MMCRA, cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE); |
351 | mtspr(SPRN_MMCR1, cpuhw->mmcr[1]); | 360 | mtspr(SPRN_MMCR1, cpuhw->mmcr[1]); |
352 | mtspr(SPRN_MMCR0, cpuhw->mmcr[0]); | ||
353 | if (cpuhw->n_counters == 0) | 361 | if (cpuhw->n_counters == 0) |
354 | get_lppaca()->pmcregs_in_use = 0; | 362 | get_lppaca()->pmcregs_in_use = 0; |
355 | goto out; | 363 | goto out_enable; |
356 | } | 364 | } |
357 | 365 | ||
358 | /* | 366 | /* |
@@ -385,7 +393,7 @@ void hw_perf_restore(u64 disable) | |||
385 | * Then unfreeze the counters. | 393 | * Then unfreeze the counters. |
386 | */ | 394 | */ |
387 | get_lppaca()->pmcregs_in_use = 1; | 395 | get_lppaca()->pmcregs_in_use = 1; |
388 | mtspr(SPRN_MMCRA, cpuhw->mmcr[2]); | 396 | mtspr(SPRN_MMCRA, cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE); |
389 | mtspr(SPRN_MMCR1, cpuhw->mmcr[1]); | 397 | mtspr(SPRN_MMCR1, cpuhw->mmcr[1]); |
390 | mtspr(SPRN_MMCR0, (cpuhw->mmcr[0] & ~(MMCR0_PMC1CE | MMCR0_PMCjCE)) | 398 | mtspr(SPRN_MMCR0, (cpuhw->mmcr[0] & ~(MMCR0_PMC1CE | MMCR0_PMCjCE)) |
391 | | MMCR0_FC); | 399 | | MMCR0_FC); |
@@ -421,10 +429,20 @@ void hw_perf_restore(u64 disable) | |||
421 | write_pmc(counter->hw.idx, val); | 429 | write_pmc(counter->hw.idx, val); |
422 | perf_counter_update_userpage(counter); | 430 | perf_counter_update_userpage(counter); |
423 | } | 431 | } |
424 | mb(); | ||
425 | cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE; | 432 | cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE; |
433 | |||
434 | out_enable: | ||
435 | mb(); | ||
426 | mtspr(SPRN_MMCR0, cpuhw->mmcr[0]); | 436 | mtspr(SPRN_MMCR0, cpuhw->mmcr[0]); |
427 | 437 | ||
438 | /* | ||
439 | * Enable instruction sampling if necessary | ||
440 | */ | ||
441 | if (cpuhw->mmcr[2] & MMCRA_SAMPLE_ENABLE) { | ||
442 | mb(); | ||
443 | mtspr(SPRN_MMCRA, cpuhw->mmcr[2]); | ||
444 | } | ||
445 | |||
428 | out: | 446 | out: |
429 | local_irq_restore(flags); | 447 | local_irq_restore(flags); |
430 | } | 448 | } |
diff --git a/arch/powerpc/kernel/power5+-pmu.c b/arch/powerpc/kernel/power5+-pmu.c index cec21ea65b0e..1222c8ea3c26 100644 --- a/arch/powerpc/kernel/power5+-pmu.c +++ b/arch/powerpc/kernel/power5+-pmu.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Performance counter support for POWER5 (not POWER5++) processors. | 2 | * Performance counter support for POWER5+/++ (not POWER5) processors. |
3 | * | 3 | * |
4 | * Copyright 2009 Paul Mackerras, IBM Corporation. | 4 | * Copyright 2009 Paul Mackerras, IBM Corporation. |
5 | * | 5 | * |
@@ -281,10 +281,107 @@ static int power5p_get_alternatives(unsigned int event, unsigned int alt[]) | |||
281 | return nalt; | 281 | return nalt; |
282 | } | 282 | } |
283 | 283 | ||
284 | /* | ||
285 | * Map of which direct events on which PMCs are marked instruction events. | ||
286 | * Indexed by PMCSEL value, bit i (LE) set if PMC i is a marked event. | ||
287 | * Bit 0 is set if it is marked for all PMCs. | ||
288 | * The 0x80 bit indicates a byte decode PMCSEL value. | ||
289 | */ | ||
290 | static unsigned char direct_event_is_marked[0x28] = { | ||
291 | 0, /* 00 */ | ||
292 | 0x1f, /* 01 PM_IOPS_CMPL */ | ||
293 | 0x2, /* 02 PM_MRK_GRP_DISP */ | ||
294 | 0xe, /* 03 PM_MRK_ST_CMPL, PM_MRK_ST_GPS, PM_MRK_ST_CMPL_INT */ | ||
295 | 0, /* 04 */ | ||
296 | 0x1c, /* 05 PM_MRK_BRU_FIN, PM_MRK_INST_FIN, PM_MRK_CRU_FIN */ | ||
297 | 0x80, /* 06 */ | ||
298 | 0x80, /* 07 */ | ||
299 | 0, 0, 0,/* 08 - 0a */ | ||
300 | 0x18, /* 0b PM_THRESH_TIMEO, PM_MRK_GRP_TIMEO */ | ||
301 | 0, /* 0c */ | ||
302 | 0x80, /* 0d */ | ||
303 | 0x80, /* 0e */ | ||
304 | 0, /* 0f */ | ||
305 | 0, /* 10 */ | ||
306 | 0x14, /* 11 PM_MRK_GRP_BR_REDIR, PM_MRK_GRP_IC_MISS */ | ||
307 | 0, /* 12 */ | ||
308 | 0x10, /* 13 PM_MRK_GRP_CMPL */ | ||
309 | 0x1f, /* 14 PM_GRP_MRK, PM_MRK_{FXU,FPU,LSU}_FIN */ | ||
310 | 0x2, /* 15 PM_MRK_GRP_ISSUED */ | ||
311 | 0x80, /* 16 */ | ||
312 | 0x80, /* 17 */ | ||
313 | 0, 0, 0, 0, 0, | ||
314 | 0x80, /* 1d */ | ||
315 | 0x80, /* 1e */ | ||
316 | 0, /* 1f */ | ||
317 | 0x80, /* 20 */ | ||
318 | 0x80, /* 21 */ | ||
319 | 0x80, /* 22 */ | ||
320 | 0x80, /* 23 */ | ||
321 | 0x80, /* 24 */ | ||
322 | 0x80, /* 25 */ | ||
323 | 0x80, /* 26 */ | ||
324 | 0x80, /* 27 */ | ||
325 | }; | ||
326 | |||
327 | /* | ||
328 | * Returns 1 if event counts things relating to marked instructions | ||
329 | * and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not. | ||
330 | */ | ||
331 | static int power5p_marked_instr_event(unsigned int event) | ||
332 | { | ||
333 | int pmc, psel; | ||
334 | int bit, byte, unit; | ||
335 | u32 mask; | ||
336 | |||
337 | pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; | ||
338 | psel = event & PM_PMCSEL_MSK; | ||
339 | if (pmc >= 5) | ||
340 | return 0; | ||
341 | |||
342 | bit = -1; | ||
343 | if (psel < sizeof(direct_event_is_marked)) { | ||
344 | if (direct_event_is_marked[psel] & (1 << pmc)) | ||
345 | return 1; | ||
346 | if (direct_event_is_marked[psel] & 0x80) | ||
347 | bit = 4; | ||
348 | else if (psel == 0x08) | ||
349 | bit = pmc - 1; | ||
350 | else if (psel == 0x10) | ||
351 | bit = 4 - pmc; | ||
352 | else if (psel == 0x1b && (pmc == 1 || pmc == 3)) | ||
353 | bit = 4; | ||
354 | } else if ((psel & 0x48) == 0x40) { | ||
355 | bit = psel & 7; | ||
356 | } else if (psel == 0x28) { | ||
357 | bit = pmc - 1; | ||
358 | } else if (pmc == 3 && (psel == 0x2e || psel == 0x2f)) { | ||
359 | bit = 4; | ||
360 | } | ||
361 | |||
362 | if (!(event & PM_BUSEVENT_MSK) || bit == -1) | ||
363 | return 0; | ||
364 | |||
365 | byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; | ||
366 | unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK; | ||
367 | if (unit == PM_LSU0) { | ||
368 | /* byte 1 bits 0-7, byte 2 bits 0,2-4,6 */ | ||
369 | mask = 0x5dff00; | ||
370 | } else if (unit == PM_LSU1 && byte >= 4) { | ||
371 | byte -= 4; | ||
372 | /* byte 5 bits 6-7, byte 6 bits 0,4, byte 7 bits 0-4,6 */ | ||
373 | mask = 0x5f11c000; | ||
374 | } else | ||
375 | return 0; | ||
376 | |||
377 | return (mask >> (byte * 8 + bit)) & 1; | ||
378 | } | ||
379 | |||
284 | static int power5p_compute_mmcr(unsigned int event[], int n_ev, | 380 | static int power5p_compute_mmcr(unsigned int event[], int n_ev, |
285 | unsigned int hwc[], u64 mmcr[]) | 381 | unsigned int hwc[], u64 mmcr[]) |
286 | { | 382 | { |
287 | u64 mmcr1 = 0; | 383 | u64 mmcr1 = 0; |
384 | u64 mmcra = 0; | ||
288 | unsigned int pmc, unit, byte, psel; | 385 | unsigned int pmc, unit, byte, psel; |
289 | unsigned int ttm; | 386 | unsigned int ttm; |
290 | int i, isbus, bit, grsel; | 387 | int i, isbus, bit, grsel; |
@@ -404,6 +501,8 @@ static int power5p_compute_mmcr(unsigned int event[], int n_ev, | |||
404 | grsel = (event[i] >> PM_GRS_SH) & PM_GRS_MSK; | 501 | grsel = (event[i] >> PM_GRS_SH) & PM_GRS_MSK; |
405 | mmcr1 |= (u64)grsel << grsel_shift[bit]; | 502 | mmcr1 |= (u64)grsel << grsel_shift[bit]; |
406 | } | 503 | } |
504 | if (power5p_marked_instr_event(event[i])) | ||
505 | mmcra |= MMCRA_SAMPLE_ENABLE; | ||
407 | if ((psel & 0x58) == 0x40 && (byte & 1) != ((pmc >> 1) & 1)) | 506 | if ((psel & 0x58) == 0x40 && (byte & 1) != ((pmc >> 1) & 1)) |
408 | /* select alternate byte lane */ | 507 | /* select alternate byte lane */ |
409 | psel |= 0x10; | 508 | psel |= 0x10; |
@@ -419,7 +518,7 @@ static int power5p_compute_mmcr(unsigned int event[], int n_ev, | |||
419 | if (pmc_inuse & 0x3e) | 518 | if (pmc_inuse & 0x3e) |
420 | mmcr[0] |= MMCR0_PMCjCE; | 519 | mmcr[0] |= MMCR0_PMCjCE; |
421 | mmcr[1] = mmcr1; | 520 | mmcr[1] = mmcr1; |
422 | mmcr[2] = 0; | 521 | mmcr[2] = mmcra; |
423 | return 0; | 522 | return 0; |
424 | } | 523 | } |
425 | 524 | ||
diff --git a/arch/powerpc/kernel/power5-pmu.c b/arch/powerpc/kernel/power5-pmu.c index 379ed1087cca..116c4bb1809e 100644 --- a/arch/powerpc/kernel/power5-pmu.c +++ b/arch/powerpc/kernel/power5-pmu.c | |||
@@ -290,10 +290,102 @@ static int power5_get_alternatives(unsigned int event, unsigned int alt[]) | |||
290 | return nalt; | 290 | return nalt; |
291 | } | 291 | } |
292 | 292 | ||
293 | /* | ||
294 | * Map of which direct events on which PMCs are marked instruction events. | ||
295 | * Indexed by PMCSEL value, bit i (LE) set if PMC i is a marked event. | ||
296 | * Bit 0 is set if it is marked for all PMCs. | ||
297 | * The 0x80 bit indicates a byte decode PMCSEL value. | ||
298 | */ | ||
299 | static unsigned char direct_event_is_marked[0x28] = { | ||
300 | 0, /* 00 */ | ||
301 | 0x1f, /* 01 PM_IOPS_CMPL */ | ||
302 | 0x2, /* 02 PM_MRK_GRP_DISP */ | ||
303 | 0xe, /* 03 PM_MRK_ST_CMPL, PM_MRK_ST_GPS, PM_MRK_ST_CMPL_INT */ | ||
304 | 0, /* 04 */ | ||
305 | 0x1c, /* 05 PM_MRK_BRU_FIN, PM_MRK_INST_FIN, PM_MRK_CRU_FIN */ | ||
306 | 0x80, /* 06 */ | ||
307 | 0x80, /* 07 */ | ||
308 | 0, 0, 0,/* 08 - 0a */ | ||
309 | 0x18, /* 0b PM_THRESH_TIMEO, PM_MRK_GRP_TIMEO */ | ||
310 | 0, /* 0c */ | ||
311 | 0x80, /* 0d */ | ||
312 | 0x80, /* 0e */ | ||
313 | 0, /* 0f */ | ||
314 | 0, /* 10 */ | ||
315 | 0x14, /* 11 PM_MRK_GRP_BR_REDIR, PM_MRK_GRP_IC_MISS */ | ||
316 | 0, /* 12 */ | ||
317 | 0x10, /* 13 PM_MRK_GRP_CMPL */ | ||
318 | 0x1f, /* 14 PM_GRP_MRK, PM_MRK_{FXU,FPU,LSU}_FIN */ | ||
319 | 0x2, /* 15 PM_MRK_GRP_ISSUED */ | ||
320 | 0x80, /* 16 */ | ||
321 | 0x80, /* 17 */ | ||
322 | 0, 0, 0, 0, 0, | ||
323 | 0x80, /* 1d */ | ||
324 | 0x80, /* 1e */ | ||
325 | 0, /* 1f */ | ||
326 | 0x80, /* 20 */ | ||
327 | 0x80, /* 21 */ | ||
328 | 0x80, /* 22 */ | ||
329 | 0x80, /* 23 */ | ||
330 | 0x80, /* 24 */ | ||
331 | 0x80, /* 25 */ | ||
332 | 0x80, /* 26 */ | ||
333 | 0x80, /* 27 */ | ||
334 | }; | ||
335 | |||
336 | /* | ||
337 | * Returns 1 if event counts things relating to marked instructions | ||
338 | * and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not. | ||
339 | */ | ||
340 | static int power5_marked_instr_event(unsigned int event) | ||
341 | { | ||
342 | int pmc, psel; | ||
343 | int bit, byte, unit; | ||
344 | u32 mask; | ||
345 | |||
346 | pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; | ||
347 | psel = event & PM_PMCSEL_MSK; | ||
348 | if (pmc >= 5) | ||
349 | return 0; | ||
350 | |||
351 | bit = -1; | ||
352 | if (psel < sizeof(direct_event_is_marked)) { | ||
353 | if (direct_event_is_marked[psel] & (1 << pmc)) | ||
354 | return 1; | ||
355 | if (direct_event_is_marked[psel] & 0x80) | ||
356 | bit = 4; | ||
357 | else if (psel == 0x08) | ||
358 | bit = pmc - 1; | ||
359 | else if (psel == 0x10) | ||
360 | bit = 4 - pmc; | ||
361 | else if (psel == 0x1b && (pmc == 1 || pmc == 3)) | ||
362 | bit = 4; | ||
363 | } else if ((psel & 0x58) == 0x40) | ||
364 | bit = psel & 7; | ||
365 | |||
366 | if (!(event & PM_BUSEVENT_MSK)) | ||
367 | return 0; | ||
368 | |||
369 | byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; | ||
370 | unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK; | ||
371 | if (unit == PM_LSU0) { | ||
372 | /* byte 1 bits 0-7, byte 2 bits 0,2-4,6 */ | ||
373 | mask = 0x5dff00; | ||
374 | } else if (unit == PM_LSU1 && byte >= 4) { | ||
375 | byte -= 4; | ||
376 | /* byte 4 bits 1,3,5,7, byte 5 bits 6-7, byte 7 bits 0-4,6 */ | ||
377 | mask = 0x5f00c0aa; | ||
378 | } else | ||
379 | return 0; | ||
380 | |||
381 | return (mask >> (byte * 8 + bit)) & 1; | ||
382 | } | ||
383 | |||
293 | static int power5_compute_mmcr(unsigned int event[], int n_ev, | 384 | static int power5_compute_mmcr(unsigned int event[], int n_ev, |
294 | unsigned int hwc[], u64 mmcr[]) | 385 | unsigned int hwc[], u64 mmcr[]) |
295 | { | 386 | { |
296 | u64 mmcr1 = 0; | 387 | u64 mmcr1 = 0; |
388 | u64 mmcra = 0; | ||
297 | unsigned int pmc, unit, byte, psel; | 389 | unsigned int pmc, unit, byte, psel; |
298 | unsigned int ttm, grp; | 390 | unsigned int ttm, grp; |
299 | int i, isbus, bit, grsel; | 391 | int i, isbus, bit, grsel; |
@@ -430,6 +522,8 @@ static int power5_compute_mmcr(unsigned int event[], int n_ev, | |||
430 | grsel = (event[i] >> PM_GRS_SH) & PM_GRS_MSK; | 522 | grsel = (event[i] >> PM_GRS_SH) & PM_GRS_MSK; |
431 | mmcr1 |= (u64)grsel << grsel_shift[bit]; | 523 | mmcr1 |= (u64)grsel << grsel_shift[bit]; |
432 | } | 524 | } |
525 | if (power5_marked_instr_event(event[i])) | ||
526 | mmcra |= MMCRA_SAMPLE_ENABLE; | ||
433 | if (pmc <= 3) | 527 | if (pmc <= 3) |
434 | mmcr1 |= psel << MMCR1_PMCSEL_SH(pmc); | 528 | mmcr1 |= psel << MMCR1_PMCSEL_SH(pmc); |
435 | hwc[i] = pmc; | 529 | hwc[i] = pmc; |
@@ -442,7 +536,7 @@ static int power5_compute_mmcr(unsigned int event[], int n_ev, | |||
442 | if (pmc_inuse & 0x3e) | 536 | if (pmc_inuse & 0x3e) |
443 | mmcr[0] |= MMCR0_PMCjCE; | 537 | mmcr[0] |= MMCR0_PMCjCE; |
444 | mmcr[1] = mmcr1; | 538 | mmcr[1] = mmcr1; |
445 | mmcr[2] = 0; | 539 | mmcr[2] = mmcra; |
446 | return 0; | 540 | return 0; |
447 | } | 541 | } |
448 | 542 | ||
diff --git a/arch/powerpc/kernel/power6-pmu.c b/arch/powerpc/kernel/power6-pmu.c index b1f61f3c97bb..fce1fc290a1d 100644 --- a/arch/powerpc/kernel/power6-pmu.c +++ b/arch/powerpc/kernel/power6-pmu.c | |||
@@ -49,12 +49,134 @@ | |||
49 | #define MMCR1_PMCSEL_MSK 0xff | 49 | #define MMCR1_PMCSEL_MSK 0xff |
50 | 50 | ||
51 | /* | 51 | /* |
52 | * Map of which direct events on which PMCs are marked instruction events. | ||
53 | * Indexed by PMCSEL value >> 1. | ||
54 | * Bottom 4 bits are a map of which PMCs are interesting, | ||
55 | * top 4 bits say what sort of event: | ||
56 | * 0 = direct marked event, | ||
57 | * 1 = byte decode event, | ||
58 | * 4 = add/and event (PMC1 -> bits 0 & 4), | ||
59 | * 5 = add/and event (PMC1 -> bits 1 & 5), | ||
60 | * 6 = add/and event (PMC1 -> bits 2 & 6), | ||
61 | * 7 = add/and event (PMC1 -> bits 3 & 7). | ||
62 | */ | ||
63 | static unsigned char direct_event_is_marked[0x60 >> 1] = { | ||
64 | 0, /* 00 */ | ||
65 | 0, /* 02 */ | ||
66 | 0, /* 04 */ | ||
67 | 0x07, /* 06 PM_MRK_ST_CMPL, PM_MRK_ST_GPS, PM_MRK_ST_CMPL_INT */ | ||
68 | 0x04, /* 08 PM_MRK_DFU_FIN */ | ||
69 | 0x06, /* 0a PM_MRK_IFU_FIN, PM_MRK_INST_FIN */ | ||
70 | 0, /* 0c */ | ||
71 | 0, /* 0e */ | ||
72 | 0x02, /* 10 PM_MRK_INST_DISP */ | ||
73 | 0x08, /* 12 PM_MRK_LSU_DERAT_MISS */ | ||
74 | 0, /* 14 */ | ||
75 | 0, /* 16 */ | ||
76 | 0x0c, /* 18 PM_THRESH_TIMEO, PM_MRK_INST_FIN */ | ||
77 | 0x0f, /* 1a PM_MRK_INST_DISP, PM_MRK_{FXU,FPU,LSU}_FIN */ | ||
78 | 0x01, /* 1c PM_MRK_INST_ISSUED */ | ||
79 | 0, /* 1e */ | ||
80 | 0, /* 20 */ | ||
81 | 0, /* 22 */ | ||
82 | 0, /* 24 */ | ||
83 | 0, /* 26 */ | ||
84 | 0x15, /* 28 PM_MRK_DATA_FROM_L2MISS, PM_MRK_DATA_FROM_L3MISS */ | ||
85 | 0, /* 2a */ | ||
86 | 0, /* 2c */ | ||
87 | 0, /* 2e */ | ||
88 | 0x4f, /* 30 */ | ||
89 | 0x7f, /* 32 */ | ||
90 | 0x4f, /* 34 */ | ||
91 | 0x5f, /* 36 */ | ||
92 | 0x6f, /* 38 */ | ||
93 | 0x4f, /* 3a */ | ||
94 | 0, /* 3c */ | ||
95 | 0x08, /* 3e PM_MRK_INST_TIMEO */ | ||
96 | 0x1f, /* 40 */ | ||
97 | 0x1f, /* 42 */ | ||
98 | 0x1f, /* 44 */ | ||
99 | 0x1f, /* 46 */ | ||
100 | 0x1f, /* 48 */ | ||
101 | 0x1f, /* 4a */ | ||
102 | 0x1f, /* 4c */ | ||
103 | 0x1f, /* 4e */ | ||
104 | 0, /* 50 */ | ||
105 | 0x05, /* 52 PM_MRK_BR_TAKEN, PM_MRK_BR_MPRED */ | ||
106 | 0x1c, /* 54 PM_MRK_PTEG_FROM_L3MISS, PM_MRK_PTEG_FROM_L2MISS */ | ||
107 | 0x02, /* 56 PM_MRK_LD_MISS_L1 */ | ||
108 | 0, /* 58 */ | ||
109 | 0, /* 5a */ | ||
110 | 0, /* 5c */ | ||
111 | 0, /* 5e */ | ||
112 | }; | ||
113 | |||
114 | /* | ||
115 | * Masks showing for each unit which bits are marked events. | ||
116 | * These masks are in LE order, i.e. 0x00000001 is byte 0, bit 0. | ||
117 | */ | ||
118 | static u32 marked_bus_events[16] = { | ||
119 | 0x01000000, /* direct events set 1: byte 3 bit 0 */ | ||
120 | 0x00010000, /* direct events set 2: byte 2 bit 0 */ | ||
121 | 0, 0, 0, 0, /* IDU, IFU, nest: nothing */ | ||
122 | 0x00000088, /* VMX set 1: byte 0 bits 3, 7 */ | ||
123 | 0x000000c0, /* VMX set 2: byte 0 bits 4-7 */ | ||
124 | 0x04010000, /* LSU set 1: byte 2 bit 0, byte 3 bit 2 */ | ||
125 | 0xff010000u, /* LSU set 2: byte 2 bit 0, all of byte 3 */ | ||
126 | 0, /* LSU set 3 */ | ||
127 | 0x00000010, /* VMX set 3: byte 0 bit 4 */ | ||
128 | 0, /* BFP set 1 */ | ||
129 | 0x00000022, /* BFP set 2: byte 0 bits 1, 5 */ | ||
130 | 0, 0 | ||
131 | }; | ||
132 | |||
133 | /* | ||
134 | * Returns 1 if event counts things relating to marked instructions | ||
135 | * and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not. | ||
136 | */ | ||
137 | static int power6_marked_instr_event(unsigned int event) | ||
138 | { | ||
139 | int pmc, psel, ptype; | ||
140 | int bit, byte, unit; | ||
141 | u32 mask; | ||
142 | |||
143 | pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; | ||
144 | psel = (event & PM_PMCSEL_MSK) >> 1; /* drop edge/level bit */ | ||
145 | if (pmc >= 5) | ||
146 | return 0; | ||
147 | |||
148 | bit = -1; | ||
149 | if (psel < sizeof(direct_event_is_marked)) { | ||
150 | ptype = direct_event_is_marked[psel]; | ||
151 | if (pmc == 0 || !(ptype & (1 << (pmc - 1)))) | ||
152 | return 0; | ||
153 | ptype >>= 4; | ||
154 | if (ptype == 0) | ||
155 | return 1; | ||
156 | if (ptype == 1) | ||
157 | bit = 0; | ||
158 | else | ||
159 | bit = ptype ^ (pmc - 1); | ||
160 | } else if ((psel & 0x48) == 0x40) | ||
161 | bit = psel & 7; | ||
162 | |||
163 | if (!(event & PM_BUSEVENT_MSK) || bit == -1) | ||
164 | return 0; | ||
165 | |||
166 | byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; | ||
167 | unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK; | ||
168 | mask = marked_bus_events[unit]; | ||
169 | return (mask >> (byte * 8 + bit)) & 1; | ||
170 | } | ||
171 | |||
172 | /* | ||
52 | * Assign PMC numbers and compute MMCR1 value for a set of events | 173 | * Assign PMC numbers and compute MMCR1 value for a set of events |
53 | */ | 174 | */ |
54 | static int p6_compute_mmcr(unsigned int event[], int n_ev, | 175 | static int p6_compute_mmcr(unsigned int event[], int n_ev, |
55 | unsigned int hwc[], u64 mmcr[]) | 176 | unsigned int hwc[], u64 mmcr[]) |
56 | { | 177 | { |
57 | u64 mmcr1 = 0; | 178 | u64 mmcr1 = 0; |
179 | u64 mmcra = 0; | ||
58 | int i; | 180 | int i; |
59 | unsigned int pmc, ev, b, u, s, psel; | 181 | unsigned int pmc, ev, b, u, s, psel; |
60 | unsigned int ttmset = 0; | 182 | unsigned int ttmset = 0; |
@@ -116,6 +238,8 @@ static int p6_compute_mmcr(unsigned int event[], int n_ev, | |||
116 | if (ev & PM_LLAV) | 238 | if (ev & PM_LLAV) |
117 | mmcr1 |= MMCR1_PMC1_LLA_VALUE >> pmc; | 239 | mmcr1 |= MMCR1_PMC1_LLA_VALUE >> pmc; |
118 | } | 240 | } |
241 | if (power6_marked_instr_event(event[i])) | ||
242 | mmcra |= MMCRA_SAMPLE_ENABLE; | ||
119 | mmcr1 |= (u64)psel << MMCR1_PMCSEL_SH(pmc); | 243 | mmcr1 |= (u64)psel << MMCR1_PMCSEL_SH(pmc); |
120 | } | 244 | } |
121 | mmcr[0] = 0; | 245 | mmcr[0] = 0; |
@@ -124,7 +248,7 @@ static int p6_compute_mmcr(unsigned int event[], int n_ev, | |||
124 | if (pmc_inuse & 0xe) | 248 | if (pmc_inuse & 0xe) |
125 | mmcr[0] |= MMCR0_PMCjCE; | 249 | mmcr[0] |= MMCR0_PMCjCE; |
126 | mmcr[1] = mmcr1; | 250 | mmcr[1] = mmcr1; |
127 | mmcr[2] = 0; | 251 | mmcr[2] = mmcra; |
128 | return 0; | 252 | return 0; |
129 | } | 253 | } |
130 | 254 | ||
diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c index c3256580be1a..aed8ccd7c077 100644 --- a/arch/powerpc/kernel/ppc970-pmu.c +++ b/arch/powerpc/kernel/ppc970-pmu.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #define PM_PMC_MSK 0xf | 19 | #define PM_PMC_MSK 0xf |
20 | #define PM_UNIT_SH 8 /* TTMMUX number and setting - unit select */ | 20 | #define PM_UNIT_SH 8 /* TTMMUX number and setting - unit select */ |
21 | #define PM_UNIT_MSK 0xf | 21 | #define PM_UNIT_MSK 0xf |
22 | #define PM_SPCSEL_SH 6 | ||
23 | #define PM_SPCSEL_MSK 3 | ||
22 | #define PM_BYTE_SH 4 /* Byte number of event bus to use */ | 24 | #define PM_BYTE_SH 4 /* Byte number of event bus to use */ |
23 | #define PM_BYTE_MSK 3 | 25 | #define PM_BYTE_MSK 3 |
24 | #define PM_PMCSEL_MSK 0xf | 26 | #define PM_PMCSEL_MSK 0xf |
@@ -88,8 +90,11 @@ static short mmcr1_adder_bits[8] = { | |||
88 | * Layout of constraint bits: | 90 | * Layout of constraint bits: |
89 | * 6666555555555544444444443333333333222222222211111111110000000000 | 91 | * 6666555555555544444444443333333333222222222211111111110000000000 |
90 | * 3210987654321098765432109876543210987654321098765432109876543210 | 92 | * 3210987654321098765432109876543210987654321098765432109876543210 |
91 | * <><>[ >[ >[ >< >< >< >< ><><><><><><><><> | 93 | * <><><>[ >[ >[ >< >< >< >< ><><><><><><><><> |
92 | * T0T1 UC PS1 PS2 B0 B1 B2 B3 P1P2P3P4P5P6P7P8 | 94 | * SPT0T1 UC PS1 PS2 B0 B1 B2 B3 P1P2P3P4P5P6P7P8 |
95 | * | ||
96 | * SP - SPCSEL constraint | ||
97 | * 48-49: SPCSEL value 0x3_0000_0000_0000 | ||
93 | * | 98 | * |
94 | * T0 - TTM0 constraint | 99 | * T0 - TTM0 constraint |
95 | * 46-47: TTM0SEL value (0=FPU, 2=IFU, 3=VPU) 0xC000_0000_0000 | 100 | * 46-47: TTM0SEL value (0=FPU, 2=IFU, 3=VPU) 0xC000_0000_0000 |
@@ -126,6 +131,57 @@ static short mmcr1_adder_bits[8] = { | |||
126 | * 0-13: Count of events needing PMC2..PMC8 | 131 | * 0-13: Count of events needing PMC2..PMC8 |
127 | */ | 132 | */ |
128 | 133 | ||
134 | static unsigned char direct_marked_event[8] = { | ||
135 | (1<<2) | (1<<3), /* PMC1: PM_MRK_GRP_DISP, PM_MRK_ST_CMPL */ | ||
136 | (1<<3) | (1<<5), /* PMC2: PM_THRESH_TIMEO, PM_MRK_BRU_FIN */ | ||
137 | (1<<3) | (1<<5), /* PMC3: PM_MRK_ST_CMPL_INT, PM_MRK_VMX_FIN */ | ||
138 | (1<<4) | (1<<5), /* PMC4: PM_MRK_GRP_CMPL, PM_MRK_CRU_FIN */ | ||
139 | (1<<4) | (1<<5), /* PMC5: PM_GRP_MRK, PM_MRK_GRP_TIMEO */ | ||
140 | (1<<3) | (1<<4) | (1<<5), | ||
141 | /* PMC6: PM_MRK_ST_STS, PM_MRK_FXU_FIN, PM_MRK_GRP_ISSUED */ | ||
142 | (1<<4) | (1<<5), /* PMC7: PM_MRK_FPU_FIN, PM_MRK_INST_FIN */ | ||
143 | (1<<4) /* PMC8: PM_MRK_LSU_FIN */ | ||
144 | }; | ||
145 | |||
146 | /* | ||
147 | * Returns 1 if event counts things relating to marked instructions | ||
148 | * and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not. | ||
149 | */ | ||
150 | static int p970_marked_instr_event(unsigned int event) | ||
151 | { | ||
152 | int pmc, psel, unit, byte, bit; | ||
153 | unsigned int mask; | ||
154 | |||
155 | pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; | ||
156 | psel = event & PM_PMCSEL_MSK; | ||
157 | if (pmc) { | ||
158 | if (direct_marked_event[pmc - 1] & (1 << psel)) | ||
159 | return 1; | ||
160 | if (psel == 0) /* add events */ | ||
161 | bit = (pmc <= 4)? pmc - 1: 8 - pmc; | ||
162 | else if (psel == 7 || psel == 13) /* decode events */ | ||
163 | bit = 4; | ||
164 | else | ||
165 | return 0; | ||
166 | } else | ||
167 | bit = psel; | ||
168 | |||
169 | byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; | ||
170 | unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK; | ||
171 | mask = 0; | ||
172 | switch (unit) { | ||
173 | case PM_VPU: | ||
174 | mask = 0x4c; /* byte 0 bits 2,3,6 */ | ||
175 | case PM_LSU0: | ||
176 | /* byte 2 bits 0,2,3,4,6; all of byte 1 */ | ||
177 | mask = 0x085dff00; | ||
178 | case PM_LSU1L: | ||
179 | mask = 0x50 << 24; /* byte 3 bits 4,6 */ | ||
180 | break; | ||
181 | } | ||
182 | return (mask >> (byte * 8 + bit)) & 1; | ||
183 | } | ||
184 | |||
129 | /* Masks and values for using events from the various units */ | 185 | /* Masks and values for using events from the various units */ |
130 | static u64 unit_cons[PM_LASTUNIT+1][2] = { | 186 | static u64 unit_cons[PM_LASTUNIT+1][2] = { |
131 | [PM_FPU] = { 0xc80000000000ull, 0x040000000000ull }, | 187 | [PM_FPU] = { 0xc80000000000ull, 0x040000000000ull }, |
@@ -138,7 +194,7 @@ static u64 unit_cons[PM_LASTUNIT+1][2] = { | |||
138 | 194 | ||
139 | static int p970_get_constraint(unsigned int event, u64 *maskp, u64 *valp) | 195 | static int p970_get_constraint(unsigned int event, u64 *maskp, u64 *valp) |
140 | { | 196 | { |
141 | int pmc, byte, unit, sh; | 197 | int pmc, byte, unit, sh, spcsel; |
142 | u64 mask = 0, value = 0; | 198 | u64 mask = 0, value = 0; |
143 | int grp = -1; | 199 | int grp = -1; |
144 | 200 | ||
@@ -177,6 +233,11 @@ static int p970_get_constraint(unsigned int event, u64 *maskp, u64 *valp) | |||
177 | mask |= 0x800000000ull; | 233 | mask |= 0x800000000ull; |
178 | value |= 0x100000000ull; | 234 | value |= 0x100000000ull; |
179 | } | 235 | } |
236 | spcsel = (event >> PM_SPCSEL_SH) & PM_SPCSEL_MSK; | ||
237 | if (spcsel) { | ||
238 | mask |= 3ull << 48; | ||
239 | value |= (u64)spcsel << 48; | ||
240 | } | ||
180 | *maskp = mask; | 241 | *maskp = mask; |
181 | *valp = value; | 242 | *valp = value; |
182 | return 0; | 243 | return 0; |
@@ -209,6 +270,7 @@ static int p970_compute_mmcr(unsigned int event[], int n_ev, | |||
209 | unsigned char ttmuse[2]; | 270 | unsigned char ttmuse[2]; |
210 | unsigned char pmcsel[8]; | 271 | unsigned char pmcsel[8]; |
211 | int i; | 272 | int i; |
273 | int spcsel; | ||
212 | 274 | ||
213 | if (n_ev > 8) | 275 | if (n_ev > 8) |
214 | return -1; | 276 | return -1; |
@@ -316,6 +378,10 @@ static int p970_compute_mmcr(unsigned int event[], int n_ev, | |||
316 | } | 378 | } |
317 | pmcsel[pmc] = psel; | 379 | pmcsel[pmc] = psel; |
318 | hwc[i] = pmc; | 380 | hwc[i] = pmc; |
381 | spcsel = (event[i] >> PM_SPCSEL_SH) & PM_SPCSEL_MSK; | ||
382 | mmcr1 |= spcsel; | ||
383 | if (p970_marked_instr_event(event[i])) | ||
384 | mmcra |= MMCRA_SAMPLE_ENABLE; | ||
319 | } | 385 | } |
320 | for (pmc = 0; pmc < 2; ++pmc) | 386 | for (pmc = 0; pmc < 2; ++pmc) |
321 | mmcr0 |= pmcsel[pmc] << (MMCR0_PMC1SEL_SH - 7 * pmc); | 387 | mmcr0 |= pmcsel[pmc] << (MMCR0_PMC1SEL_SH - 7 * pmc); |