// SPDX-License-Identifier: GPL-2.0-or-later /* * Performance counter support for PPC970-family processors. * * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
*/ #include <linux/string.h> #include <linux/perf_event.h> #include <asm/reg.h> #include <asm/cputable.h>
#include"internal.h"
/* * Bits in event code for PPC970
*/ #define PM_PMC_SH 12 /* PMC number (1-based) for direct events */ #define PM_PMC_MSK 0xf #define PM_UNIT_SH 8 /* TTMMUX number and setting - unit select */ #define PM_UNIT_MSK 0xf #define PM_SPCSEL_SH 6 #define PM_SPCSEL_MSK 3 #define PM_BYTE_SH 4 /* Byte number of event bus to use */ #define PM_BYTE_MSK 3 #define PM_PMCSEL_MSK 0xf
/* * Returns 1 if event counts things relating to marked instructions * and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not.
*/ staticint p970_marked_instr_event(u64 event)
{ int pmc, psel, unit, byte, bit; unsignedint mask;
/* First pass to count resource use */
pmc_grp_use[0] = pmc_grp_use[1] = 0;
memset(busbyte, 0, sizeof(busbyte));
memset(unituse, 0, sizeof(unituse)); for (i = 0; i < n_ev; ++i) {
pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK; if (pmc) { if (pmc_inuse & (1 << (pmc - 1))) return -1;
pmc_inuse |= 1 << (pmc - 1); /* count 1/2/5/6 vs 3/4/7/8 use */
++pmc_grp_use[((pmc - 1) >> 1) & 1];
}
unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK;
byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK; if (unit) { if (unit > PM_LASTUNIT) return -1; if (!pmc)
++pmc_grp_use[byte & 1]; if (busbyte[byte] && busbyte[byte] != unit) return -1;
busbyte[byte] = unit;
unituse[unit] = 1;
}
} if (pmc_grp_use[0] > 4 || pmc_grp_use[1] > 4) return -1;
/* * Assign resources and set multiplexer selects. * * PM_ISU can go either on TTM0 or TTM1, but that's the only * choice we have to deal with.
*/ if (unituse[PM_ISU] &
(unituse[PM_FPU] | unituse[PM_IFU] | unituse[PM_VPU]))
unitmap[PM_ISU] = 2 | 4; /* move ISU to TTM1 */ /* Set TTM[01]SEL fields. */
ttmuse[0] = ttmuse[1] = 0; for (i = PM_FPU; i <= PM_STS; ++i) { if (!unituse[i]) continue;
ttm = unitmap[i];
++ttmuse[(ttm >> 2) & 1];
mmcr1 |= (unsignedlong)(ttm & ~4) << MMCR1_TTM1SEL_SH;
} /* Check only one unit per TTMx */ if (ttmuse[0] > 1 || ttmuse[1] > 1) return -1;
/* Set byte lane select fields and TTM3SEL. */ for (byte = 0; byte < 4; ++byte) {
unit = busbyte[byte]; if (!unit) continue; if (unit <= PM_STS)
ttm = (unitmap[unit] >> 2) & 1; elseif (unit == PM_LSU0)
ttm = 2; else {
ttm = 3; if (unit == PM_LSU1L && byte >= 2)
mmcr1 |= 1ull << (MMCR1_TTM3SEL_SH + 3 - byte);
}
mmcr1 |= (unsignedlong)ttm
<< (MMCR1_TD_CP_DBG0SEL_SH - 2 * byte);
}
/* Second pass: assign PMCs, set PMCxSEL and PMCx_ADDER_SEL fields */
memset(pmcsel, 0x8, sizeof(pmcsel)); /* 8 means don't count */ for (i = 0; i < n_ev; ++i) {
pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK;
byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK;
psel = event[i] & PM_PMCSEL_MSK; if (!pmc) { /* Bus event or any-PMC direct event */ if (unit)
psel |= 0x10 | ((byte & 2) << 2); else
psel |= 8; for (pmc = 0; pmc < 8; ++pmc) { if (pmc_inuse & (1 << pmc)) continue;
grp = (pmc >> 1) & 1; if (unit) { if (grp == (byte & 1)) break;
} elseif (pmc_grp_use[grp] < 4) {
++pmc_grp_use[grp]; break;
}
}
pmc_inuse |= 1 << pmc;
} else { /* Direct event */
--pmc; if (psel == 0 && (byte & 2)) /* add events on higher-numbered bus */
mmcr1 |= 1ull << mmcr1_adder_bits[pmc];
}
pmcsel[pmc] = psel;
hwc[i] = pmc;
spcsel = (event[i] >> PM_SPCSEL_SH) & PM_SPCSEL_MSK;
mmcr1 |= spcsel; if (p970_marked_instr_event(event[i]))
mmcra |= MMCRA_SAMPLE_ENABLE;
} for (pmc = 0; pmc < 2; ++pmc)
mmcr0 |= pmcsel[pmc] << (MMCR0_PMC1SEL_SH - 7 * pmc); for (; pmc < 8; ++pmc)
mmcr1 |= (unsignedlong)pmcsel[pmc]
<< (MMCR1_PMC3SEL_SH - 5 * (pmc - 2)); if (pmc_inuse & 1)
mmcr0 |= MMCR0_PMC1CE; if (pmc_inuse & 0xfe)
mmcr0 |= MMCR0_PMCjCE;
mmcra |= 0x2000; /* mark only one IOP per PPC instruction */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.