Date: Mon, 26 Jul 2021 13:30:40 GMT From: Leandro Lupori <luporl@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: b48a2770d48b - main - powerpc64: add Power8 and Power9 PMCs Message-ID: <202107261330.16QDUeMP087746@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by luporl: URL: https://cgit.FreeBSD.org/src/commit/?id=b48a2770d48b9f9aa61788704897e9a2e9e10c09 commit b48a2770d48b9f9aa61788704897e9a2e9e10c09 Author: Leandro Lupori <luporl@FreeBSD.org> AuthorDate: 2021-07-23 18:09:09 +0000 Commit: Leandro Lupori <luporl@FreeBSD.org> CommitDate: 2021-07-26 13:27:23 +0000 powerpc64: add Power8 and Power9 PMCs Add support to allocate Power8 and 9 PMCs. Submitted by: Leonardo Bianconi <leonardo.bianconi@eldorado.org.br> Reviewed by: mhorne Sponsored by: Instituto de Pesquisas Eldorado (eldorado.org.br) Differential Revision: https://reviews.freebsd.org/D31109 --- lib/libpmc/libpmc_pmu_util.c | 34 ++++++++++++++++++++++++ sys/dev/hwpmc/hwpmc_power8.c | 59 +++++++++++++++++++++++++++++++++++++++--- sys/dev/hwpmc/hwpmc_powerpc.c | 3 +++ sys/powerpc/include/pmc_mdep.h | 1 + 4 files changed, 93 insertions(+), 4 deletions(-) diff --git a/lib/libpmc/libpmc_pmu_util.c b/lib/libpmc/libpmc_pmu_util.c index e6f74e6abe81..edd99357678e 100644 --- a/lib/libpmc/libpmc_pmu_util.c +++ b/lib/libpmc/libpmc_pmu_util.c @@ -142,6 +142,13 @@ pmu_alias_get(const char *name) return (name); } +#elif defined(__powerpc64__) + +static const char * +pmu_alias_get(const char *name) +{ + return (name); +} #elif defined(__aarch64__) @@ -571,6 +578,33 @@ pmc_pmu_pmcallocate(const char *event_name, struct pmc_op_pmcallocate *pm) return (pmc_pmu_amd_pmcallocate(event_name, pm, &ped)); } +#elif defined(__powerpc64__) + +int +pmc_pmu_pmcallocate(const char *event_name, struct pmc_op_pmcallocate *pm) +{ + const struct pmu_event *pe; + struct pmu_event_desc ped; + int idx = -1; + + bzero(&pm->pm_md, sizeof(pm->pm_md)); + pm->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE); + event_name = pmu_alias_get(event_name); + + if ((pe = pmu_event_get(NULL, event_name, &idx)) == NULL) + return (ENOENT); + if (pe->event == NULL) + return (ENOENT); + if (pmu_parse_event(&ped, pe->event)) + return (ENOENT); + + assert(ped.ped_event >= 0); + pm->pm_ev = idx; + pm->pm_md.pm_event = ped.ped_event; + pm->pm_class = PMC_CLASS_POWER8; + return (0); +} + #elif defined(__aarch64__) int diff --git a/sys/dev/hwpmc/hwpmc_power8.c b/sys/dev/hwpmc/hwpmc_power8.c index 7cc2ac8295f6..ce063a57a10e 100644 --- a/sys/dev/hwpmc/hwpmc_power8.c +++ b/sys/dev/hwpmc/hwpmc_power8.c @@ -43,6 +43,12 @@ __FBSDID("$FreeBSD$"); #define POWER8_MAX_PMCS 6 +#define PM_EVENT_CODE(pe) (pe & 0xffff) +#define PM_EVENT_COUNTER(pe) ((pe >> 16) & 0xffff) + +#define PM_CYC 0x1e +#define PM_INST_CMPL 0x02 + static struct pmc_ppc_event power8_event_codes[] = { {PMC_EV_POWER8_INSTR_COMPLETED, .pe_flags = PMC_FLAG_PMC5, @@ -275,6 +281,54 @@ power8_resume_pmc(bool ie) mtspr(SPR_MMCR0, mmcr0); } +static int +power8_allocate_pmc(int cpu, int ri, struct pmc *pm, + const struct pmc_op_pmcallocate *a) +{ + uint32_t caps, config, counter, pe; + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); + KASSERT(ri >= 0 && ri < ppc_max_pmcs, + ("[powerpc,%d] illegal row index %d", __LINE__, ri)); + + pe = a->pm_md.pm_event; + counter = PM_EVENT_COUNTER(pe); + config = PM_EVENT_CODE(pe); + + /* + * PMC5 and PMC6 are not programmable and always count instructions + * completed and cycles, respectively. + * + * When counter is 0 any of the 4 programmable PMCs may be used for + * the specified event, otherwise it must match ri + 1. + */ + if (counter == 0 && config == PM_INST_CMPL) + counter = 5; + else if (counter == 0 && config == PM_CYC) + counter = 6; + else if (counter > 4) + return (EINVAL); + + if (counter != 0 && counter != ri + 1) + return (EINVAL); + + caps = a->pm_caps; + + if (caps & PMC_CAP_SYSTEM) + config |= POWERPC_PMC_KERNEL_ENABLE; + if (caps & PMC_CAP_USER) + config |= POWERPC_PMC_USER_ENABLE; + if ((caps & (PMC_CAP_USER | PMC_CAP_SYSTEM)) == 0) + config |= POWERPC_PMC_ENABLE; + + pm->pm_md.pm_powerpc.pm_powerpc_evsel = config; + + PMCDBG3(MDP,ALL,1,"powerpc-allocate cpu=%d ri=%d -> config=0x%x", + cpu, ri, config); + return (0); +} + int pmc_power8_initialize(struct pmc_mdep *pmc_mdep) { @@ -291,7 +345,7 @@ pmc_power8_initialize(struct pmc_mdep *pmc_mdep) pcd->pcd_pcpu_init = power8_pcpu_init; pcd->pcd_pcpu_fini = power8_pcpu_fini; - pcd->pcd_allocate_pmc = powerpc_allocate_pmc; + pcd->pcd_allocate_pmc = power8_allocate_pmc; pcd->pcd_release_pmc = powerpc_release_pmc; pcd->pcd_start_pmc = powerpc_start_pmc; pcd->pcd_stop_pmc = powerpc_stop_pmc; @@ -304,10 +358,7 @@ pmc_power8_initialize(struct pmc_mdep *pmc_mdep) pmc_mdep->pmd_npmc += POWER8_MAX_PMCS; pmc_mdep->pmd_intr = powerpc_pmc_intr; - ppc_event_codes = power8_event_codes; ppc_event_codes_size = power8_event_codes_size; - ppc_event_first = PMC_EV_POWER8_FIRST; - ppc_event_last = PMC_EV_POWER8_LAST; ppc_max_pmcs = POWER8_MAX_PMCS; powerpc_set_pmc = power8_set_pmc; diff --git a/sys/dev/hwpmc/hwpmc_powerpc.c b/sys/dev/hwpmc/hwpmc_powerpc.c index e97211f0d9a6..3a2115ece3cb 100644 --- a/sys/dev/hwpmc/hwpmc_powerpc.c +++ b/sys/dev/hwpmc/hwpmc_powerpc.c @@ -603,6 +603,9 @@ pmc_md_initialize() pmc_mdep = NULL; } + /* Set the value for kern.hwpmc.cpuid */ + snprintf(pmc_cpuid, sizeof(pmc_cpuid), "%08lx", mfpvr()); + return (pmc_mdep); } diff --git a/sys/powerpc/include/pmc_mdep.h b/sys/powerpc/include/pmc_mdep.h index 0a1609196ef9..3d31ff7b99cd 100644 --- a/sys/powerpc/include/pmc_mdep.h +++ b/sys/powerpc/include/pmc_mdep.h @@ -10,6 +10,7 @@ #define PMC_MDEP_CLASS_INDEX_POWERPC 1 union pmc_md_op_pmcallocate { + uint32_t pm_event; uint64_t __pad[4]; };
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202107261330.16QDUeMP087746>