aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
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
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')
-rw-r--r--arch/powerpc/kernel/perf_counter.c28
-rw-r--r--arch/powerpc/kernel/power5+-pmu.c103
-rw-r--r--arch/powerpc/kernel/power5-pmu.c96
-rw-r--r--arch/powerpc/kernel/power6-pmu.c126
-rw-r--r--arch/powerpc/kernel/ppc970-pmu.c72
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 */
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
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
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 */
63static 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 */
118static 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 */
137static 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 */
54static int p6_compute_mmcr(unsigned int event[], int n_ev, 175static 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
134static 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 */
150static 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 */
130static u64 unit_cons[PM_LASTUNIT+1][2] = { 186static 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
139static int p970_get_constraint(unsigned int event, u64 *maskp, u64 *valp) 195static 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);