Skip to content

Commit

Permalink
[AArch64] Allow user access to PMU counters
Browse files Browse the repository at this point in the history
  • Loading branch information
cyring committed May 11, 2024
1 parent 78e2f0a commit a78e0ae
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 33 deletions.
13 changes: 4 additions & 9 deletions aarch64/bitasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ typedef unsigned int Bit32;
#define LOCKLESS LOCK_LESS
#define BUS_LOCK FULL_LOCK

#define BARRIER(pfx) \
#define BARRIER(_option) \
__asm__ volatile \
( \
"dsb" "\n\t" \
"dsb " #_option "\n\t" \
"isb" \
: \
: \
Expand Down Expand Up @@ -98,13 +98,8 @@ __asm__ volatile \
"mrs " #_reg ", cntvct_el0" "\n\t"

#define ASM_CODE_RDPMC(_ctr, _reg) \
"# Read PMC counter." "\n\t" \
/*TODO "movq $" #_ctr ", %%rcx" "\n\t" \
"rdpmc" "\n\t" \
"shlq $32 , %%rdx" "\n\t" \
"orq %%rdx , %%rax" "\n\t" */ \
"# Save counter value." "\n\t" \
/*TODO "movq %%rax , %%" #_reg "\n\t" */
"# Read PMU counter." "\n\t" \
"mrs " #_reg ", " #_ctr "\n\t" \

#define ASM_RDPMC(_ctr, _reg) ASM_CODE_RDPMC(_ctr, _reg)

Expand Down
7 changes: 2 additions & 5 deletions aarch64/corefreqd.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,12 +473,9 @@ static void *Child_Thread(void *arg)
RW(SHM_STRUCT) *RW(Shm) = Arg->Ref->RW(Shm);
CPU_STRUCT *Cpu = &RO(Shm)->Cpu[cpu];

CALL_FUNC MatrixCallFunc[2] = {
CALL_FUNC CallSliceFunc = (CALL_FUNC[2]){
CallWith_RDTSC_No_RDPMC, CallWith_RDTSC_RDPMC
};
const int withRDPMC = ((RO(Shm)->Proc.PM_version >= 1));

CALL_FUNC CallSliceFunc = MatrixCallFunc[withRDPMC];
}[ RO(Shm)->Proc.Features.PerfMon.FixCtrs == 2 ];

pthread_t tid = pthread_self();
cpu_set_t cpuset;
Expand Down
43 changes: 27 additions & 16 deletions aarch64/corefreqk.c
Original file line number Diff line number Diff line change
Expand Up @@ -581,10 +581,13 @@ static void Query_Features(void *pArg)
iArg->Features->Inv_TSC = \
iArg->Features->RDTSCP = cntpct.PhysicalCount != 0;

iArg->Features->PerfMon.FixCtrs = 1; /* Fixed Cycle Counter */
iArg->Features->PerfMon.FixCtrs = 0;
iArg->Features->PerfMon.MonCtrs = pmcr.NumEvtCtrs;
iArg->Features->PerfMon.Version = dfr0.PMUVer;

if (iArg->Features->PerfMon.Version > 0) {
iArg->Features->PerfMon.FixCtrs++; /* Fixed Cycle Counter */
iArg->Features->PerfMon.FixCtrs++; /* Instruction Counter */
}
/*TODO(Memory-mapped PMU register at offset 0xe00): pmcfgr */
iArg->Features->PerfMon.MonWidth = \
iArg->Features->PerfMon.FixWidth = 0b111111 == 0b111111 ? 64 : 0;
Expand Down Expand Up @@ -2510,6 +2513,7 @@ static void PerCore_Reset(CORE_RO *Core)
{
BITCLR_CC(LOCKLESS, PUBLIC(RO(Proc))->HWP_Mask , Core->Bind);
BITCLR_CC(LOCKLESS, PUBLIC(RO(Proc))->CR_Mask , Core->Bind);
BITCLR_CC(LOCKLESS, PUBLIC(RO(Proc))->SPEC_CTRL_Mask, Core->Bind);

BITCLR_CC(LOCKLESS, PUBLIC(RW(Proc))->HWP , Core->Bind);
BITCLR_CC(LOCKLESS, PUBLIC(RW(Proc))->CSV2_1 , Core->Bind);
Expand All @@ -2527,6 +2531,7 @@ static void PerCore_Reset(CORE_RO *Core)
static void PerCore_GenericMachine(void *arg)
{
volatile CPUPWRCTLR cpuPwrCtl;
volatile PMUSERENR pmuser;
volatile REVIDR revid;
CORE_RO *Core = (CORE_RO *) arg;

Expand All @@ -2541,19 +2546,17 @@ static void PerCore_GenericMachine(void *arg)
cpuPwrCtl.value = SysRegRead(CPUPWRCTLR_EL1);
Core->Query.CStateBaseAddr = cpuPwrCtl.WFI_RET_CTRL;
}
if (Core->Bind == PUBLIC(RO(Proc))->Service.Core) {
volatile PMUSERENR pmuser;

__asm__ __volatile__(
"mrs %[pmuser], pmuserenr_el0" "\n\t"
"isb"
: [pmuser] "=r" (pmuser)
:
: "memory"
);

if (Core->Bind == PUBLIC(RO(Proc))->Service.Core) {
PUBLIC(RO(Proc))->Features.PerfMon.CoreCycles = pmuser.CR;
PUBLIC(RO(Proc))->Features.PerfMon.InstrRetired = pmuser.IR;

}
__asm__ __volatile__(
"mrs %[revid], revidr_el1" "\n\t"
Expand Down Expand Up @@ -2834,6 +2837,12 @@ static void Generic_Core_Counters_Set(union SAVE_AREA_CORE *Save, CORE_RO *Core)
"orr x12 , x12, %[ENSET]" "\n\t"
"msr pmcntenset_el0, x12" "\n\t"

"# Enable User-space access to counters""\n\t"
"mrs x12 , pmuserenr_el0" "\n\t"
"str x12 , %[PMUSER]" "\n\t"
"orr x12 , x12, %[ENUSR]" "\n\t"
"msr pmuserenr_el0, %12" "\n\t"

"# Enable all PMU counters" "\n\t"
"mrs x12 , pmcr_el0" "\n\t"
"str x12 , %[PMCR]" "\n\t"
Expand All @@ -2846,11 +2855,13 @@ static void Generic_Core_Counters_Set(union SAVE_AREA_CORE *Save, CORE_RO *Core)
[PMTYPE2] "+m" (Save->PMTYPE[1]),
[PMTYPE1] "+m" (Save->PMTYPE[0]),
[PMCCFILTR] "+m" (Save->PMCCFILTR),
[PMCNTEN] "+m" (Save->PMCNTEN)
[PMCNTEN] "+m" (Save->PMCNTEN),
[PMUSER] "+m" (Save->PMUSER)
: [EVENT3] "r" (0x0008),
[EVENT2] "r" (0x0011),
[FILTR1] "r" (0x0),
[ENSET] "r" (0b10000000000000000000000000001100),
[ENUSR] "r" (0b0000101),
[CTRL] "i" (0b0000000010000111)
: "memory", "%x12"
);
Expand All @@ -2861,14 +2872,13 @@ static void Generic_Core_Counters_Clear(union SAVE_AREA_CORE *Save,
{
__asm__ __volatile__(
"# Restore PMU configuration registers" "\n\t"
"ldr x12 , %[PMCR]" "\n\t"
"msr pmcr_el0, x12" "\n\t"
"msr pmcr_el0, %[PMCR]" "\n\t"

"ldr x12 , %[PMCNTEN]" "\n\t"
"msr pmcntenset_el0, x12" "\n\t"
"msr pmuserenr_el0, %[PMUSER]" "\n\t"

"msr pmcntenset_el0, %[PMCNTEN]" "\n\t"

"ldr x12 , %[PMCCFILTR]" "\n\t"
"msr pmccfiltr_el0, x12" "\n\t"
"msr pmccfiltr_el0, %[PMCCFILTR]" "\n\t"

"ldr x12 , %[PMSELR]" "\n\t"
"orr x12 , x12, #0b11111" "\n\t"
Expand All @@ -2893,13 +2903,14 @@ static void Generic_Core_Counters_Clear(union SAVE_AREA_CORE *Save,

"isb"
:
: [PMCR] "m" (Save->PMCR),
: [PMCR] "r" (Save->PMCR),
[PMSELR] "m" (Save->PMSELR),
[PMTYPE3] "m" (Save->PMTYPE[2]),
[PMTYPE2] "m" (Save->PMTYPE[1]),
[PMTYPE1] "m" (Save->PMTYPE[0]),
[PMCCFILTR] "m" (Save->PMCCFILTR),
[PMCNTEN] "m" (Save->PMCNTEN)
[PMCCFILTR] "r" (Save->PMCCFILTR),
[PMCNTEN] "r" (Save->PMCNTEN),
[PMUSER] "r" (Save->PMUSER)
: "memory", "%x12"
);
}
Expand Down
1 change: 1 addition & 0 deletions aarch64/corefreqk.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ typedef struct
PMXEVTYPER PMTYPE[3];
PMCCFILTR PMCCFILTR;
PMCNTENSET PMCNTEN;
PMUSERENR PMUSER;
};
} SaveArea;
#ifdef CONFIG_CPU_FREQ
Expand Down
12 changes: 9 additions & 3 deletions aarch64/corefreqm.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,19 @@ void CallWith_RDTSC_RDPMC( RO(SHM_STRUCT) *RO(Shm),
{
struct SLICE_STRUCT *pSlice = &RO(Shm)->Cpu[cpu].Slice;

RDTSC_PMCx1(pSlice->Counter[0].TSC,0x40000000,pSlice->Counter[0].INST);
RDTSC_PMCx1( pSlice->Counter[0].TSC,
pmevcntr3_el0,
pSlice->Counter[0].INST );

RDTSC_PMCx1(pSlice->Counter[1].TSC,0x40000000,pSlice->Counter[1].INST);
RDTSC_PMCx1( pSlice->Counter[1].TSC,
pmevcntr3_el0,
pSlice->Counter[1].INST );

SliceFunc(RO(Shm), RW(Shm), cpu, arg);

RDTSC_PMCx1(pSlice->Counter[2].TSC,0x40000000,pSlice->Counter[2].INST);
RDTSC_PMCx1( pSlice->Counter[2].TSC,
pmevcntr3_el0,
pSlice->Counter[2].INST );

if (BITVAL(RW(Shm)->Proc.Sync, BURN)) {
DeltaTSC(pSlice);
Expand Down

0 comments on commit a78e0ae

Please sign in to comment.