/** *get_pmu_feat-ReturnsID_DFR0_EL1.PerfMonBits * *Return:ID_DFR0_EL1.PerfMonBits
*/ static uint64_t get_pmu_feat(void) {
uint64_t id_dfr0_el1 = ARM64_READ_SYSREG(ID_DFR0_EL1);
id_dfr0_el1 = id_dfr0_el1 >> 24; /* Shift PerfMon field down to bit 0 */
id_dfr0_el1 &= 0x7; /* Mask to leave just the PerfMon bits */ return id_dfr0_el1;
}
/** *get_pmn-Returnsthenumberofprogrammablecounters * *Return:Thenumberofavailableprogrammablecounters
*/ static uint64_t get_pmn(void) {
uint64_t pmcr_el0 = ARM64_READ_SYSREG(PMCR_EL0);
pmcr_el0 = pmcr_el0 >> 11; /* Shift N field down to bit 0 */
pmcr_el0 &= 0x1F; /* Mask to leave just the 5 N bits */ return pmcr_el0;
}
/** *reset_ccnt-ResetstheCCNT
*/ staticvoid reset_ccnt(void) {
uint64_t reg = ARM64_READ_SYSREG(PMCR_EL0);
reg = set_bit(reg, PMCR_EL0_C_BIT);
ARM64_WRITE_SYSREG(PMCR_EL0, reg);
} /** *get_event_code_string-GetthecodenameforagivenPMUevent * *@event:currentstatesofthepmucounters * *Return:TheCodeoftheeventasaString
*/ staticconstchar* get_event_code_string(int event) { switch (event) { case PMU_EV_SW_INCR: return"SW_INCR"; case PMU_EV_L1I_CACHE_REFILL: return"L1I_CACHE_REFILL"; case PMU_EV_L1I_TLB_REFILL: return"L1I_TLB_REFILL"; case PMU_EV_L1D_CACHE_REFILL: return"L1D_CACHE_REFILL"; case PMU_EV_L1D_CACHE: return"L1D_CACHE"; case PMU_EV_L1D_TLB_REFILL: return"L1D_TLB_REFILL"; case PMU_EV_LD_RETIRED: return"LD_RETIRED"; case PMU_EV_ST_RETIRED: return"ST_RETIRED"; case PMU_EV_INST_RETIRED: return"INST_RETIRED"; case PMU_EV_EXC_TAKEN: return"EXC_TAKEN"; case PMU_EV_EXC_RETURN: return"EXC_RETURN"; case PMU_EV_CID_WRITE_RETIRED: return"CID_WRITE_RETIRED"; case PMU_EV_PC_WRITE_RETIRED: return"PC_WRITE_RETIRED"; case PMU_EV_BR_IMMED_RETIRED: return"BR_IMMED_RETIRED"; case PMU_EV_UNALIGNED_LDST_RETIRED: return"UNALIGNED_LDST_RETIRED"; case PMU_EV_BR_MIS_PRED: return"BR_MIS_PRED"; case PMU_EV_CPU_CYCLES: return"CPU_CYCLES"; case PMU_EV_BR_PRED: return"BR_PRED"; case PMU_EV_MEM_ACCESS: return"MEM_ACCESS"; case PMU_EV_L1I_CACHE: return"L1I_CACHE"; case PMU_EV_L1D_CACHE_WB: return"L1D_CACHE_WB"; case PMU_EV_L2D_CACHE: return"L2D_CACHE"; case PMU_EV_L2D_CACHE_REFILL: return"L2D_CACHE_REFILL"; case PMU_EV_L2D_CACHE_WB: return"L2D_CACHE_WB"; case PMU_EV_BUS_ACCESS: return"BUS_ACCESS"; case PMU_EV_MEMORY_ERROR: return"MEMORY_ERROR"; case PMU_EV_BUS_CYCLES: return"BUS_CYCLES"; case PMU_EV_CHAIN: return"CHAIN"; case PMU_EV_BUS_ACCESS_LD: return"BUS_ACCESS_LD"; case PMU_EV_BUS_ACCESS_ST: return"BUS_ACCESS_ST"; case PMU_EV_BR_INDIRECT_SPEC: return"BR_INDIRECT_SPEC"; case PMU_EV_EXC_IRQ: return"EXC_IRQ"; case PMU_EV_EXC_FIQ: return"EXC_FIQ"; case -1: return"CCNT"; default: return"UNKNOWN_EVENT";
}
}
if (nb_counters < state->evt_cnt) {
fprintf(stderr, "ERROR: There are only %" PRIu64 " Programmable Counters, yet you are trying to record %" PRIu64 " events.\n",
nb_counters, state->evt_cnt);
return;
}
enable_pmu(); // Enable the PMU
reset_ccnt(); // Reset the CCNT (cycle counter)
reset_pmn(); // Reset the configurable counters
write_flags((1 << 31) | 0xf); // Reset overflow flags
for (size_t i = 0; i < state->evt_cnt; i++) {
pmn_config(i, state->evts[i] | RECORD_ALL);
set_pmu_filters(i, 0U | RECORD_ALL);
}
ccnt_divider(0); // Enable divide by 64
enable_ccnt(); // Enable CCNT
for (size_t i = 0; i < state->evt_cnt; i++)
enable_pmn(i);
}
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.