Page MenuHomeFreeBSD

D31109.diff
No OneTemporary

D31109.diff

diff --git a/lib/libpmc/libpmc_pmu_util.c b/lib/libpmc/libpmc_pmu_util.c
--- a/lib/libpmc/libpmc_pmu_util.c
+++ b/lib/libpmc/libpmc_pmu_util.c
@@ -142,6 +142,13 @@
return (name);
}
+#elif defined(__powerpc64__)
+
+static const char *
+pmu_alias_get(const char *name)
+{
+ return (name);
+}
#elif defined(__aarch64__)
@@ -571,6 +578,33 @@
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
--- a/sys/dev/hwpmc/hwpmc_power8.c
+++ b/sys/dev/hwpmc/hwpmc_power8.c
@@ -43,6 +43,12 @@
#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 @@
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 @@
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_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
--- a/sys/dev/hwpmc/hwpmc_powerpc.c
+++ b/sys/dev/hwpmc/hwpmc_powerpc.c
@@ -603,6 +603,9 @@
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
--- 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];
};

File Metadata

Mime Type
text/plain
Expires
Tue, Sep 24, 12:19 AM (21 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12608095
Default Alt Text
D31109.diff (4 KB)

Event Timeline