/* Storage for platform version */ int pvr;
u64 platform_extended_mask;
/* Mask and Shift for Event code fields */ int ev_mask_pmcxsel, ev_shift_pmcxsel; //pmcxsel field int ev_mask_marked, ev_shift_marked; //marked filed int ev_mask_comb, ev_shift_comb; //combine field int ev_mask_unit, ev_shift_unit; //unit field int ev_mask_pmc, ev_shift_pmc; //pmc field int ev_mask_cache, ev_shift_cache; //Cache sel field int ev_mask_sample, ev_shift_sample; //Random sampling field int ev_mask_thd_sel, ev_shift_thd_sel; //thresh_sel field int ev_mask_thd_start, ev_shift_thd_start; //thresh_start field int ev_mask_thd_stop, ev_shift_thd_stop; //thresh_stop field int ev_mask_thd_cmp, ev_shift_thd_cmp; //thresh cmp field int ev_mask_sm, ev_shift_sm; //SDAR mode field int ev_mask_rsq, ev_shift_rsq; //radix scope qual field int ev_mask_l2l3, ev_shift_l2l3; //l2l3 sel field int ev_mask_mmcr3_src, ev_shift_mmcr3_src; //mmcr3 field
/* Return the extended regs mask value */
u64 perf_get_platform_reg_mask(void)
{ if (have_hwcap2(PPC_FEATURE2_ARCH_3_1)) return PERF_POWER10_MASK; if (have_hwcap2(PPC_FEATURE2_ARCH_3_00)) return PERF_POWER9_MASK;
return -1;
}
int check_extended_regs_support(void)
{ int fd; struct event event;
int platform_check_for_tests(void)
{
pvr = PVR_VER(mfspr(SPRN_PVR));
/* * Check for supported platforms * for sampling test
*/ switch (pvr) { case POWER11: case POWER10: case POWER9: break; default: goto out;
}
/* * Check PMU driver registered by looking for * PPC_FEATURE2_EBB bit in AT_HWCAP2
*/ if (!have_hwcap2(PPC_FEATURE2_EBB) || !have_hwcap2(PPC_FEATURE2_ARCH_3_00)) goto out;
return 0;
out:
printf("%s: Tests unsupported for this platform\n", __func__); return -1;
}
int check_pvr_for_sampling_tests(void)
{
SKIP_IF(platform_check_for_tests());
platform_extended_mask = perf_get_platform_reg_mask(); /* check if platform supports extended regs */ if (check_extended_regs_support()) goto out;
/* * Post process the mmap buffer. * - If sample_count != NULL then return count of total * number of samples present in the mmap buffer. * - If sample_count == NULL then return the address * of first sample from the mmap buffer
*/ void *__event_read_samples(void *sample_buff, size_t *size, u64 *sample_count)
{
size_t page_size = sysconf(_SC_PAGESIZE); struct perf_event_header *header = sample_buff + page_size; struct perf_event_mmap_page *metadata_page = sample_buff; unsignedlong data_head, data_tail;
/* Check for sample_count */ if (sample_count)
*sample_count = 0;
while (1) { /* * Reads the mmap data buffer by moving * the data_tail to know the last read data. * data_head points to head in data buffer. * refer "struct perf_event_mmap_page" in * "include/uapi/linux/perf_event.h".
*/ if (data_head - data_tail < sizeof(header)) return NULL;
int get_thresh_cmp_val(struct event event)
{ int exp = 0;
u64 result = 0;
u64 value;
if (!have_hwcap2(PPC_FEATURE2_ARCH_3_1)) return EV_CODE_EXTRACT(event.attr.config, thd_cmp);
value = EV_CODE_EXTRACT(event.attr.config1, thd_cmp);
if (!value) return value;
/* * Incase of P10, thresh_cmp value is not part of raw event code * and provided via attr.config1 parameter. To program threshold in MMCRA, * take a 18 bit number N and shift right 2 places and increment * the exponent E by 1 until the upper 10 bits of N are zero. * Write E to the threshold exponent and write the lower 8 bits of N * to the threshold mantissa. * The max threshold that can be written is 261120.
*/ if (value > 261120)
value = 261120; while ((64 - __builtin_clzl(value)) > 8) {
exp++;
value >>= 2;
}
/* * Note that it is invalid to write a mantissa with the * upper 2 bits of mantissa being zero, unless the * exponent is also zero.
*/ if (!(value & 0xC0) && exp)
result = -1; else
result = (exp << 8) | value; return result;
}
/* * Utility function to check for generic compat PMU * by comparing base_platform value from auxv and real * PVR value. * auxv_base_platform() func gives information of "base platform" * corresponding to PVR value. Incase, if the distro doesn't * support platform PVR (missing cputable support), base platform * in auxv will have a default value other than the real PVR's. * In this case, ISAv3 PMU (generic compat PMU) will be registered * in the system. auxv_generic_compat_pmu() makes use of the base * platform value from auxv to do this check.
*/ staticbool auxv_generic_compat_pmu(void)
{ int base_pvr = 0;
/* * Check for generic compat PMU. * First check for presence of pmu_name from * "/sys/bus/event_source/devices/cpu/caps". * If doesn't exist, fallback to using value * auxv.
*/ bool check_for_generic_compat_pmu(void)
{ char pmu_name[256];
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.