from .spr import mtspr, mfspr from artiq.language.core import kernel _MAX_SPRS_PER_GRP_BITS = 11 _SPRGROUP_PC = 7 << _MAX_SPRS_PER_GRP_BITS _SPR_PCMR_CP = 0x00000001 # Counter present _SPR_PCMR_CISM = 0x00000004 # Count in supervisor mode _SPR_PCMR_CIUM = 0x00000008 # Count in user mode _SPR_PCMR_LA = 0x00000010 # Load access event _SPR_PCMR_SA = 0x00000020 # Store access event _SPR_PCMR_IF = 0x00000040 # Instruction fetch event _SPR_PCMR_DCM = 0x00000080 # Data cache miss event _SPR_PCMR_ICM = 0x00000100 # Insn cache miss event _SPR_PCMR_IFS = 0x00000200 # Insn fetch stall event _SPR_PCMR_LSUS = 0x00000400 # LSU stall event _SPR_PCMR_BS = 0x00000800 # Branch stall event _SPR_PCMR_DTLBM = 0x00001000 # DTLB miss event _SPR_PCMR_ITLBM = 0x00002000 # ITLB miss event _SPR_PCMR_DDS = 0x00004000 # Data dependency stall event _SPR_PCMR_WPE = 0x03ff8000 # Watchpoint events @kernel(flags={"nowrite", "nounwind"}) def _PCCR(n): return _SPRGROUP_PC + n @kernel(flags={"nowrite", "nounwind"}) def _PCMR(n): return _SPRGROUP_PC + 8 + n class CorePCU: """Core device performance counter unit (PCU) access""" def __init__(self, dmgr, core_device="core"): self.core = dmgr.get(core_device) @kernel def start(self): """ Configure and clear the kernel CPU performance counters. The eight counters are configures to count the folloging events: * Load or store * Instruction fetch * Data cache miss * Instruction cache miss * Instruction fetch stall * Load-store-unit stall * Branch stall * Data dependency stall """ for i in range(8): if not mfspr(_PCMR(i)) & _SPR_PCMR_CP: raise ValueError("counter not present") mtspr(_PCMR(i), 0) mtspr(_PCCR(i), 0) mtspr(_PCMR(0), _SPR_PCMR_CISM | _SPR_PCMR_LA | _SPR_PCMR_SA) mtspr(_PCMR(1), _SPR_PCMR_CISM | _SPR_PCMR_IF) mtspr(_PCMR(2), _SPR_PCMR_CISM | _SPR_PCMR_DCM) mtspr(_PCMR(3), _SPR_PCMR_CISM | _SPR_PCMR_ICM) mtspr(_PCMR(4), _SPR_PCMR_CISM | _SPR_PCMR_IFS) mtspr(_PCMR(5), _SPR_PCMR_CISM | _SPR_PCMR_LSUS) mtspr(_PCMR(6), _SPR_PCMR_CISM | _SPR_PCMR_BS) mtspr(_PCMR(7), _SPR_PCMR_CISM | _SPR_PCMR_DDS) @kernel def get(self, r): """ Read the performance counters and store the counts in the array provided. :param list[int] r: array to store the counter values """ for i in range(8): r[i] = mfspr(_PCCR(i))