From 743135c20695a8683a033c6671cdae69ed33d4e3 Mon Sep 17 00:00:00 2001 From: CyrIng Date: Fri, 20 Jun 2025 22:48:45 +0200 Subject: [PATCH] [aarch64] Provide the state of WFI/WFE Low Power Methods --- aarch64/arm_reg.h | 3 +- aarch64/corefreq-api.h | 6 ++-- aarch64/corefreq-cli-rsc-en.h | 8 ++++-- aarch64/corefreq-cli-rsc-fr.h | 5 ++-- aarch64/corefreq-cli-rsc.c | 8 ++++-- aarch64/corefreq-cli-rsc.h | 8 ++++-- aarch64/corefreq-cli.c | 53 ++++++++++++++++++++--------------- aarch64/corefreq.h | 6 ++-- aarch64/corefreqd.c | 22 +++++++-------- aarch64/corefreqk.c | 21 ++++++-------- 10 files changed, 74 insertions(+), 66 deletions(-) diff --git a/aarch64/arm_reg.h b/aarch64/arm_reg.h index 5a72083..dfdd685 100644 --- a/aarch64/arm_reg.h +++ b/aarch64/arm_reg.h @@ -259,7 +259,8 @@ typedef union RES0 : 4-1, WFI_RET_CTRL : 7-4, WFE_RET_CTRL : 10-7, - RES1 : 32-10, + SIMD_RET_CTRL : 13-10, + RES1 : 32-13, RES2 : 64-32; }; } CPUPWRCTLR; diff --git a/aarch64/corefreq-api.h b/aarch64/corefreq-api.h index 8b1608b..cab3ab5 100644 --- a/aarch64/corefreq-api.h +++ b/aarch64/corefreq-api.h @@ -171,14 +171,12 @@ typedef struct { struct { unsigned long long - CfgLock : 1-0, /* Core */ - IORedir : 2-1, /* Core */ + WFI : 1-0, /* Thread */ + WFE : 2-1, /* Thread */ SCTLRX : 3-2, /* Thread */ Unused : 32-3, Revision: 64-32; }; - unsigned short int CStateLimit; - unsigned short int CStateBaseAddr; /* Any I/O BAR */ } Query; CACHE_TOPOLOGY T; diff --git a/aarch64/corefreq-cli-rsc-en.h b/aarch64/corefreq-cli-rsc-en.h index c34a825..93d5109 100644 --- a/aarch64/corefreq-cli-rsc-en.h +++ b/aarch64/corefreq-cli-rsc-en.h @@ -1033,8 +1033,9 @@ #define RSC_PERF_MON_CPC_CODE_EN "Continuous Performance Control" #define RSC_PERF_MON_CST_CODE_EN "ACPI Processor C-States" #define RSC_PERF_MON_HWP_CODE_EN "Hardware-Controlled Performance States" -#define RSC_PERF_MON_CORE_CSTATE_CODE_EN "Core C-States" -#define RSC_PERF_MON_CSTATE_BAR_CODE_EN "C-States Base Address" +#define RSC_PERF_MON_LOW_PWR_CODE_EN "Low Power Methods" +#define RSC_PERF_MON_WFI_CODE_EN "Wait for Interrupt" +#define RSC_PERF_MON_WFE_CODE_EN "Wait for Event" #define RSC_PERF_MON_MONITOR_MWAIT_CODE_EN "MONITOR/MWAIT" #define RSC_PERF_MON_MWAIT_IDX_CSTATE_CODE_EN "State index" @@ -1921,7 +1922,8 @@ #define RSC_PERF_LABEL_CPC_CODE "_CPC" #define RSC_PERF_LABEL_CST_CODE "_CST" #define RSC_PERF_LABEL_HWP_CODE "HWP" -#define RSC_PERF_LABEL_CST_BAR_CODE "BAR" +#define RSC_PERF_LABEL_WFI_CODE "WFI" +#define RSC_PERF_LABEL_WFE_CODE "WFE" #define RSC_PERF_LABEL_MWAIT_IDX_CODE \ "#0 #1 #2 #3 #4 #5 #6 #7" diff --git a/aarch64/corefreq-cli-rsc-fr.h b/aarch64/corefreq-cli-rsc-fr.h index f4883c8..211ceac 100644 --- a/aarch64/corefreq-cli-rsc-fr.h +++ b/aarch64/corefreq-cli-rsc-fr.h @@ -735,8 +735,9 @@ do echo -en "$h$l\t""\xc3""\x$h$l""\t"; done; done;echo #define RSC_PERF_MON_CPC_CODE_FR RSC_PERF_MON_CPC_CODE_EN #define RSC_PERF_MON_CST_CODE_FR RSC_PERF_MON_CST_CODE_EN #define RSC_PERF_MON_HWP_CODE_FR "Hardware-Controlled Performance States" -#define RSC_PERF_MON_CORE_CSTATE_CODE_FR "Core C-States" -#define RSC_PERF_MON_CSTATE_BAR_CODE_FR "Adresse Base C-States" +#define RSC_PERF_MON_LOW_PWR_CODE_FR "M""\xa9""thodes de Basse Consommation" +#define RSC_PERF_MON_WFI_CODE_FR "Attente d'Interruption" +#define RSC_PERF_MON_WFE_CODE_FR "Attente d'""\x89""v""\xa9""nement" #define RSC_PERF_MON_MONITOR_MWAIT_CODE_FR "MONITOR/MWAIT" #define RSC_PERF_MON_MWAIT_IDX_CSTATE_CODE_FR "State index" diff --git a/aarch64/corefreq-cli-rsc.c b/aarch64/corefreq-cli-rsc.c index 462f02b..39cbe2d 100644 --- a/aarch64/corefreq-cli-rsc.c +++ b/aarch64/corefreq-cli-rsc.c @@ -1042,8 +1042,9 @@ RESOURCE_ST Resource[] = { LDT(RSC_PERF_MON_CPC), LDT(RSC_PERF_MON_CST), LDT(RSC_PERF_MON_HWP), - LDT(RSC_PERF_MON_CORE_CSTATE), - LDT(RSC_PERF_MON_CSTATE_BAR), + LDT(RSC_PERF_MON_LOW_PWR), + LDT(RSC_PERF_MON_WFI), + LDT(RSC_PERF_MON_WFE), LDT(RSC_PERF_MON_MONITOR_MWAIT), LDT(RSC_PERF_MON_MWAIT_IDX_CSTATE), LDT(RSC_PERF_MON_MWAIT_SUB_CSTATE), @@ -1060,7 +1061,8 @@ RESOURCE_ST Resource[] = { LDQ(RSC_PERF_LABEL_CPC), LDQ(RSC_PERF_LABEL_CST), LDQ(RSC_PERF_LABEL_HWP), - LDQ(RSC_PERF_LABEL_CST_BAR), + LDQ(RSC_PERF_LABEL_WFI), + LDQ(RSC_PERF_LABEL_WFE), LDQ(RSC_PERF_LABEL_MWAIT_IDX), LDQ(RSC_PERF_ENCODING_C0), LDQ(RSC_PERF_ENCODING_C1), diff --git a/aarch64/corefreq-cli-rsc.h b/aarch64/corefreq-cli-rsc.h index 7e5bcc2..0d58349 100644 --- a/aarch64/corefreq-cli-rsc.h +++ b/aarch64/corefreq-cli-rsc.h @@ -865,8 +865,9 @@ enum { RSC_PERF_MON_CPC, RSC_PERF_MON_CST, RSC_PERF_MON_HWP, - RSC_PERF_MON_CORE_CSTATE, - RSC_PERF_MON_CSTATE_BAR, + RSC_PERF_MON_LOW_PWR, + RSC_PERF_MON_WFI, + RSC_PERF_MON_WFE, RSC_PERF_MON_MONITOR_MWAIT, RSC_PERF_MON_MWAIT_IDX_CSTATE, RSC_PERF_MON_MWAIT_SUB_CSTATE, @@ -883,7 +884,8 @@ enum { RSC_PERF_LABEL_CPC, RSC_PERF_LABEL_CST, RSC_PERF_LABEL_HWP, - RSC_PERF_LABEL_CST_BAR, + RSC_PERF_LABEL_WFI, + RSC_PERF_LABEL_WFE, RSC_PERF_LABEL_MWAIT_IDX, RSC_PERF_ENCODING_C0, RSC_PERF_ENCODING_C1, diff --git a/aarch64/corefreq-cli.c b/aarch64/corefreq-cli.c index 694d116..88307d6 100644 --- a/aarch64/corefreq-cli.c +++ b/aarch64/corefreq-cli.c @@ -3249,10 +3249,11 @@ REASON_CODE SysInfoTech(Window *win, }, { NULL, - RO(Shm)->Cpu[RO(Shm)->Proc.Service.Core].Query.CStateBaseAddr != 0, - 2, "%s%.*sCCx [%3s]", - RSC(PERF_MON_CORE_CSTATE).CODE(), NULL, - width - 14 - RSZ(PERF_MON_CORE_CSTATE), + RO(Shm)->Cpu[RO(Shm)->Proc.Service.Core].Query.WFI + | RO(Shm)->Cpu[RO(Shm)->Proc.Service.Core].Query.WFE, + 2, "%s%.*sWFx [%3s]", + RSC(PERF_MON_LOW_PWR).CODE(), NULL, + width - 14 - RSZ(PERF_MON_LOW_PWR), NULL, SCANKEY_NULL, NULL @@ -3533,7 +3534,6 @@ REASON_CODE SysInfoPerfMon( Window *win, RSC(SYSINFO_PERFMON_COND3).ATTR(), RSC(SYSINFO_PERFMON_COND4).ATTR() }; - unsigned int bix; /* Section Mark */ if (RO(Shm)->Proc.PM_version > 0) { @@ -3580,18 +3580,25 @@ REASON_CODE SysInfoPerfMon( Window *win, } /* Section Mark */ PUT( SCANKEY_NULL, attrib[0], width, 2, - "%s", RSC(PERF_MON_CORE_CSTATE).CODE() ); + "%s", RSC(PERF_MON_LOW_PWR).CODE() ); PUT( SCANKEY_NULL, - attrib[ !RO(Shm)->Cpu[ - RO(Shm)->Proc.Service.Core - ].Query.CStateBaseAddr ? 0 : 3 ], + attrib[RO(Shm)->Cpu[RO(Shm)->Proc.Service.Core].Query.WFI ?3:2], width, 3, - "%s%.*s%s [ 0x%-4X]", RSC(PERF_MON_CSTATE_BAR).CODE(), - width - (OutFunc == NULL ? 21 : 19) - - RSZ(PERF_MON_CSTATE_BAR), hSpace, - RSC(PERF_LABEL_CST_BAR).CODE(), - RO(Shm)->Cpu[RO(Shm)->Proc.Service.Core].Query.CStateBaseAddr ); + "%s%.*s%s [%7s]", RSC(PERF_MON_WFI).CODE(), + width - (OutFunc == NULL ? 21 : 19) - RSZ(PERF_MON_WFI), hSpace, + RSC(PERF_LABEL_WFI).CODE(), + RO(Shm)->Cpu[RO(Shm)->Proc.Service.Core].Query.WFI ? + RSC(ENABLE).CODE() : RSC(PRESENT).CODE() ); + + PUT( SCANKEY_NULL, + attrib[RO(Shm)->Cpu[RO(Shm)->Proc.Service.Core].Query.WFE ?3:2], + width, 3, + "%s%.*s%s [%7s]", RSC(PERF_MON_WFE).CODE(), + width - (OutFunc == NULL ? 21 : 19) - RSZ(PERF_MON_WFE), hSpace, + RSC(PERF_LABEL_WFE).CODE(), + RO(Shm)->Cpu[RO(Shm)->Proc.Service.Core].Query.WFE ? + RSC(ENABLE).CODE() : RSC(PRESENT).CODE() ); /* Section Mark */ if (RO(Shm)->Proc.Features.ACPI_CST_CAP) { PUT( SCANKEY_NULL, attrib[RO(Shm)->Proc.Features.ACPI_CST ? 3 : 0], @@ -3627,17 +3634,19 @@ REASON_CODE SysInfoPerfMon( Window *win, RO(Shm)->Proc.Features.MWait.SubCstate_MWAIT6, RO(Shm)->Proc.Features.MWait.SubCstate_MWAIT7 ); /* Section Mark */ - bix = RO(Shm)->Proc.Features.PerfMon.CoreCycles == 1 ? 2 : 0; - - PUT( SCANKEY_NULL, attrib[bix], width, 2, + PUT( SCANKEY_NULL, + attrib[RO(Shm)->Proc.Features.PerfMon.CoreCycles ? 2 : 0], + width, 2, "%s%.*s[%7s]", RSC(PERF_MON_CORE_CYCLE).CODE(), - width - 12 - RSZ(PERF_MON_CORE_CYCLE), hSpace, POWERED(bix) ); + width - 12 - RSZ(PERF_MON_CORE_CYCLE), hSpace, + POWERED(RO(Shm)->Proc.Features.PerfMon.CoreCycles) ); - bix = RO(Shm)->Proc.Features.PerfMon.InstrRetired == 1 ? 2 : 0; - - PUT( SCANKEY_NULL, attrib[bix], width, 2, + PUT( SCANKEY_NULL, + attrib[RO(Shm)->Proc.Features.PerfMon.InstrRetired ? 2 : 0], + width, 2, "%s%.*s[%7s]", RSC(PERF_MON_INST_RET).CODE(), - width - 12 - RSZ(PERF_MON_INST_RET), hSpace, POWERED(bix) ); + width - 12 - RSZ(PERF_MON_INST_RET), hSpace, + POWERED(RO(Shm)->Proc.Features.PerfMon.InstrRetired) ); /* Section Mark */ PUT( SCANKEY_NULL, attrib[RO(Shm)->Proc.Features.ACPI_PCT_CAP ? 3:0], width, 2, diff --git a/aarch64/corefreq.h b/aarch64/corefreq.h index 002f0e4..300d33b 100644 --- a/aarch64/corefreq.h +++ b/aarch64/corefreq.h @@ -36,13 +36,11 @@ typedef struct unsigned int Revision; struct { - unsigned short int CfgLock : 1-0, - IORedir : 2-1, + unsigned short int WFI : 1-0, + WFE : 2-1, SCTLRX : 3-2, Unused : 16-3; }; - unsigned short int CStateLimit; - unsigned short int CStateBaseAddr; /* Any I/O BAR */ } Query; struct { diff --git a/aarch64/corefreqd.c b/aarch64/corefreqd.c index 3321603..062875c 100644 --- a/aarch64/corefreqd.c +++ b/aarch64/corefreqd.c @@ -832,16 +832,16 @@ void Topology(RO(SHM_STRUCT) *RO(Shm), RO(PROC) *RO(Proc), RO(CORE) **RO(Core), } void CStates(RO(SHM_STRUCT) *RO(Shm), RO(CORE) **RO(Core), unsigned int cpu) -{ /* Copy the C-State Configuration Control */ - RO(Shm)->Cpu[cpu].Query.CfgLock = RO(Core, AT(cpu))->Query.CfgLock; +{ + /* Guess C-States capability from HCR_EL2.TWI or HCR_EL2.TWE */ + if (BITEXTRZ(RO(Core, AT(cpu))->SystemRegister.FLAGS, FLAG_EL, 2) >= 2) + { + RO(Shm)->Cpu[cpu].Query.WFI = \ + !BITEXTRZ(RO(Core, AT(cpu))->SystemRegister.HCR, HYPCR_TWI, 1); - RO(Shm)->Cpu[cpu].Query.CStateLimit = \ - RO(Core, AT(cpu))->Query.CStateLimit; - /* Copy the Max C-State Inclusion */ - RO(Shm)->Cpu[cpu].Query.IORedir = RO(Core, AT(cpu))->Query.IORedir; - /* Copy any architectural C-States I/O Base Address */ - RO(Shm)->Cpu[cpu].Query.CStateBaseAddr = \ - RO(Core, AT(cpu))->Query.CStateBaseAddr; + RO(Shm)->Cpu[cpu].Query.WFE = \ + !BITEXTRZ(RO(Core, AT(cpu))->SystemRegister.HCR, HYPCR_TWE, 1); + } } void PowerThermal( RO(SHM_STRUCT) *RO(Shm), RO(PROC) *RO(Proc), @@ -1200,11 +1200,11 @@ void PerCore_Update( RO(SHM_STRUCT) *RO(Shm), RO(PROC) *RO(Proc), Topology(RO(Shm), RO(Proc), RO(Core), cpu); - CStates(RO(Shm), RO(Core), cpu); - PowerThermal(RO(Shm), RO(Proc), RO(Core), cpu); SystemRegisters(RO(Shm), RO(Core), cpu); + + CStates(RO(Shm), RO(Core), cpu); } #define SysOnce(drv) ioctl(drv, COREFREQ_IOCTL_SYSONCE) diff --git a/aarch64/corefreqk.c b/aarch64/corefreqk.c index 1e73ef1..2707ea8 100644 --- a/aarch64/corefreqk.c +++ b/aarch64/corefreqk.c @@ -1324,14 +1324,14 @@ static void Query_Features(void *pArg) if (BITEXTRZ(FLAGS, FLAG_EL, 2) >= 2) { - volatile unsigned long long HCR; - __asm__ __volatile__( - "mrs %[hcr] , hcr_el2""\n\t" - "isb" - : [hcr] "=r" (HCR) - : - : "cc", "memory" - ); + volatile unsigned long long HCR; + __asm__ __volatile__( + "mrs %[hcr] , hcr_el2""\n\t" + "isb" + : [hcr] "=r" (HCR) + : + : "cc", "memory" + ); if ((iArg->Features->FGT== 0) && (BITEXTRZ(HCR, HYPCR_TID3, 1) == 0)) { volatile AA64DFR1 dfr1; @@ -3254,7 +3254,6 @@ static void PerCore_Reset(CORE_RO *Core) static void PerCore_GenericMachine(void *arg) { - volatile CPUPWRCTLR cpuPwrCtl; volatile PMUSERENR pmuser; volatile PMCNTENSET enset; volatile PMCNTENCLR enclr; @@ -3268,10 +3267,6 @@ static void PerCore_GenericMachine(void *arg) Core->Boost[BOOST(MAX)].Q < PUBLIC(RO(Proc))->Features.Factory.Ratio ? Hybrid_Secondary : Hybrid_Primary; } - if (Experimental && (PUBLIC(RO(Proc))->HypervisorID == BARE_METAL)) { - cpuPwrCtl.value = SysRegRead(CPUPWRCTLR_EL1); - Core->Query.CStateBaseAddr = cpuPwrCtl.WFI_RET_CTRL; - } if (PUBLIC(RO(Proc))->Features.PerfMon.Version > 0) { __asm__ __volatile__( "mrs %[pmuser], pmuserenr_el0" "\n\t"