11 #include <linux/string.h>
12 #include <linux/perf_event.h>
14 #include <asm/cputable.h>
20 #define PM_PMC_MSK 0xf
22 #define PM_UNIT_MSK 0xf
23 #define PM_SPCSEL_SH 6
24 #define PM_SPCSEL_MSK 3
27 #define PM_PMCSEL_MSK 0xf
45 #define MMCR0_PMC1SEL_SH 8
46 #define MMCR0_PMC2SEL_SH 1
47 #define MMCR_PMCSEL_MSK 0x1f
52 #define MMCR1_TTM0SEL_SH 62
53 #define MMCR1_TTM1SEL_SH 59
54 #define MMCR1_TTM3SEL_SH 53
55 #define MMCR1_TTMSEL_MSK 3
56 #define MMCR1_TD_CP_DBG0SEL_SH 50
57 #define MMCR1_TD_CP_DBG1SEL_SH 48
58 #define MMCR1_TD_CP_DBG2SEL_SH 46
59 #define MMCR1_TD_CP_DBG3SEL_SH 44
60 #define MMCR1_PMC1_ADDER_SEL_SH 39
61 #define MMCR1_PMC2_ADDER_SEL_SH 38
62 #define MMCR1_PMC6_ADDER_SEL_SH 37
63 #define MMCR1_PMC5_ADDER_SEL_SH 36
64 #define MMCR1_PMC8_ADDER_SEL_SH 35
65 #define MMCR1_PMC7_ADDER_SEL_SH 34
66 #define MMCR1_PMC3_ADDER_SEL_SH 33
67 #define MMCR1_PMC4_ADDER_SEL_SH 32
68 #define MMCR1_PMC3SEL_SH 27
69 #define MMCR1_PMC4SEL_SH 22
70 #define MMCR1_PMC5SEL_SH 17
71 #define MMCR1_PMC6SEL_SH 12
72 #define MMCR1_PMC7SEL_SH 7
73 #define MMCR1_PMC8SEL_SH 2
75 static short mmcr1_adder_bits[8] = {
131 static unsigned char direct_marked_event[8] = {
137 (1<<3) | (1<<4) | (1<<5),
147 static int p970_marked_instr_event(
u64 event)
155 if (direct_marked_event[pmc - 1] & (1 << psel))
158 bit = (pmc <= 4)? pmc - 1: 8 - pmc;
159 else if (psel == 7 || psel == 13)
181 return (mask >> (byte * 8 + bit)) & 1;
185 static unsigned long unit_cons[
PM_LASTUNIT+1][2] = {
186 [
PM_FPU] = { 0xc80000000000ull, 0x040000000000ull },
187 [
PM_VPU] = { 0xc80000000000ull, 0xc40000000000ull },
188 [
PM_ISU] = { 0x080000000000ull, 0x020000000000ull },
189 [
PM_IFU] = { 0xc80000000000ull, 0x840000000000ull },
190 [
PM_IDU] = { 0x380000000000ull, 0x010000000000ull },
191 [
PM_STS] = { 0x380000000000ull, 0x310000000000ull },
194 static int p970_get_constraint(
u64 event,
unsigned long *maskp,
198 unsigned long mask = 0,
value = 0;
208 grp = ((pmc - 1) >> 1) & 1;
214 mask |= unit_cons[
unit][0];
224 mask |= 0xfULL << (28 - 4 *
byte);
225 value |= (
unsigned long)unit << (28 - 4 * byte);
229 mask |= 0x8000000000ull;
230 value |= 0x1000000000ull;
231 }
else if (grp == 1) {
233 mask |= 0x800000000ull;
234 value |= 0x100000000ull;
246 static int p970_get_alternatives(
u64 event,
unsigned int flags,
u64 alt[])
251 if (event == 0x2002 || event == 0x3002) {
252 alt[1] =
event ^ 0x1000;
259 static int p970_compute_mmcr(
u64 event[],
int n_ev,
260 unsigned int hwc[],
unsigned long mmcr[])
262 unsigned long mmcr0 = 0, mmcr1 = 0, mmcra = 0;
264 unsigned int ttm, grp;
265 unsigned int pmc_inuse = 0;
266 unsigned int pmc_grp_use[2];
267 unsigned char busbyte[4];
268 unsigned char unituse[16];
269 unsigned char unitmap[] = { 0, 0<<3, 3<<3, 1<<3, 2<<3, 0|4, 3|4 };
270 unsigned char ttmuse[2];
271 unsigned char pmcsel[8];
279 pmc_grp_use[0] = pmc_grp_use[1] = 0;
280 memset(busbyte, 0,
sizeof(busbyte));
281 memset(unituse, 0,
sizeof(unituse));
282 for (i = 0; i < n_ev; ++
i) {
285 if (pmc_inuse & (1 << (pmc - 1)))
287 pmc_inuse |= 1 << (pmc - 1);
289 ++pmc_grp_use[((pmc - 1) >> 1) & 1];
297 ++pmc_grp_use[byte & 1];
298 if (busbyte[byte] && busbyte[byte] != unit)
304 if (pmc_grp_use[0] > 4 || pmc_grp_use[1] > 4)
317 ttmuse[0] = ttmuse[1] = 0;
322 ++ttmuse[(ttm >> 2) & 1];
326 if (ttmuse[0] > 1 || ttmuse[1] > 1)
330 for (byte = 0; byte < 4; ++
byte) {
331 unit = busbyte[
byte];
335 ttm = (unitmap[
unit] >> 2) & 1;
343 mmcr1 |= (
unsigned long)ttm
348 memset(pmcsel, 0x8,
sizeof(pmcsel));
349 for (i = 0; i < n_ev; ++
i) {
357 psel |= 0x10 | ((byte & 2) << 2);
360 for (pmc = 0; pmc < 8; ++pmc) {
361 if (pmc_inuse & (1 << pmc))
363 grp = (pmc >> 1) & 1;
365 if (grp == (byte & 1))
367 }
else if (pmc_grp_use[grp] < 4) {
372 pmc_inuse |= 1 << pmc;
376 if (psel == 0 && (byte & 2))
378 mmcr1 |= 1ull << mmcr1_adder_bits[pmc];
384 if (p970_marked_instr_event(event[i]))
385 mmcra |= MMCRA_SAMPLE_ENABLE;
387 for (pmc = 0; pmc < 2; ++pmc)
389 for (; pmc < 8; ++pmc)
390 mmcr1 |= (
unsigned long)pmcsel[pmc]
393 mmcr0 |= MMCR0_PMC1CE;
394 if (pmc_inuse & 0xfe)
395 mmcr0 |= MMCR0_PMCjCE;
406 static void p970_disable_pmc(
unsigned int pmc,
unsigned long mmcr[])
420 mmcr[
i] = (mmcr[
i] & ~(0x1f
UL << shift)) | (0x08
UL << shift);
423 static int ppc970_generic_events[] = {
432 #define C(x) PERF_COUNT_HW_CACHE_##x
439 static int ppc970_cache_events[
C(
MAX)][
C(
OP_MAX)][
C(RESULT_MAX)] = {
443 [
C(OP_PREFETCH)] = { 0x731, 0 },
448 [
C(OP_PREFETCH)] = { 0, 0 },
453 [
C(OP_PREFETCH)] = { 0x733, 0 },
458 [
C(OP_PREFETCH)] = { -1, -1 },
463 [
C(OP_PREFETCH)] = { -1, -1 },
468 [
C(OP_PREFETCH)] = { -1, -1 },
473 [
C(OP_PREFETCH)] = { -1, -1 },
478 .name =
"PPC970/FX/MP",
480 .max_alternatives = 2,
481 .add_fields = 0x001100005555ull,
482 .test_adder = 0x013300000000ull,
483 .compute_mmcr = p970_compute_mmcr,
484 .get_constraint = p970_get_constraint,
485 .get_alternatives = p970_get_alternatives,
486 .disable_pmc = p970_disable_pmc,
487 .n_generic =
ARRAY_SIZE(ppc970_generic_events),
488 .generic_events = ppc970_generic_events,
489 .cache_events = &ppc970_cache_events,
493 static int __init init_ppc970_pmu(
void)