aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/power5-pmu.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2009-04-08 06:30:18 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-08 06:39:28 -0400
commitf708223d49ac39f5af1643985056206c98033f5b (patch)
tree67e317f49e49845183dd5e74f01a0ac14e5088b2 /arch/powerpc/kernel/power5-pmu.c
parentdc66270b51a62b1a6888d5309229e638a305c47b (diff)
perf_counter: powerpc: set sample enable bit for marked instruction events
Impact: enable access to hardware feature POWER processors have the ability to "mark" a subset of the instructions and provide more detailed information on what happens to the marked instructions as they flow through the pipeline. This marking is enabled by the "sample enable" bit in MMCRA, and there are synchronization requirements around setting and clearing the bit. This adds logic to the processor-specific back-ends so that they know which events relate to marked instructions and set the sampling enable bit if any event that we want to put on the PMU is a marked instruction event. It also adds logic to the generic powerpc code to do the necessary synchronization if that bit is set. Signed-off-by: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> LKML-Reference: <18908.31930.1024.228867@cargo.ozlabs.ibm.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/powerpc/kernel/power5-pmu.c')
-rw-r--r--arch/powerpc/kernel/power5-pmu.c96
1 files changed, 95 insertions, 1 deletions
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 */
299static 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 */
340static 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
293static int power5_compute_mmcr(unsigned int event[], int n_ev, 384static 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