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.c103
1 files changed, 101 insertions, 2 deletions
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 */
290static 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 */
331static 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
284static int power5p_compute_mmcr(unsigned int event[], int n_ev, 380static 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