[aarch64] Provide the state of WFI/WFE Low Power Methods

This commit is contained in:
CyrIng
2025-06-20 22:48:45 +02:00
parent 40a47f225a
commit 743135c206
10 changed files with 74 additions and 66 deletions

View File

@@ -259,7 +259,8 @@ typedef union
RES0 : 4-1, RES0 : 4-1,
WFI_RET_CTRL : 7-4, WFI_RET_CTRL : 7-4,
WFE_RET_CTRL : 10-7, WFE_RET_CTRL : 10-7,
RES1 : 32-10, SIMD_RET_CTRL : 13-10,
RES1 : 32-13,
RES2 : 64-32; RES2 : 64-32;
}; };
} CPUPWRCTLR; } CPUPWRCTLR;

View File

@@ -171,14 +171,12 @@ typedef struct
{ {
struct { struct {
unsigned long long unsigned long long
CfgLock : 1-0, /* Core */ WFI : 1-0, /* Thread */
IORedir : 2-1, /* Core */ WFE : 2-1, /* Thread */
SCTLRX : 3-2, /* Thread */ SCTLRX : 3-2, /* Thread */
Unused : 32-3, Unused : 32-3,
Revision: 64-32; Revision: 64-32;
}; };
unsigned short int CStateLimit;
unsigned short int CStateBaseAddr; /* Any I/O BAR */
} Query; } Query;
CACHE_TOPOLOGY T; CACHE_TOPOLOGY T;

View File

@@ -1033,8 +1033,9 @@
#define RSC_PERF_MON_CPC_CODE_EN "Continuous Performance Control" #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_CST_CODE_EN "ACPI Processor C-States"
#define RSC_PERF_MON_HWP_CODE_EN "Hardware-Controlled Performance 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_LOW_PWR_CODE_EN "Low Power Methods"
#define RSC_PERF_MON_CSTATE_BAR_CODE_EN "C-States Base Address" #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_MONITOR_MWAIT_CODE_EN "MONITOR/MWAIT"
#define RSC_PERF_MON_MWAIT_IDX_CSTATE_CODE_EN "State index" #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_CPC_CODE "_CPC"
#define RSC_PERF_LABEL_CST_CODE "_CST" #define RSC_PERF_LABEL_CST_CODE "_CST"
#define RSC_PERF_LABEL_HWP_CODE "HWP" #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 \ #define RSC_PERF_LABEL_MWAIT_IDX_CODE \
"#0 #1 #2 #3 #4 #5 #6 #7" "#0 #1 #2 #3 #4 #5 #6 #7"

View File

@@ -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_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_CST_CODE_FR RSC_PERF_MON_CST_CODE_EN
#define RSC_PERF_MON_HWP_CODE_FR "Hardware-Controlled Performance States" #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_LOW_PWR_CODE_FR "M""\xa9""thodes de Basse Consommation"
#define RSC_PERF_MON_CSTATE_BAR_CODE_FR "Adresse Base C-States" #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_MONITOR_MWAIT_CODE_FR "MONITOR/MWAIT"
#define RSC_PERF_MON_MWAIT_IDX_CSTATE_CODE_FR "State index" #define RSC_PERF_MON_MWAIT_IDX_CSTATE_CODE_FR "State index"

View File

@@ -1042,8 +1042,9 @@ RESOURCE_ST Resource[] = {
LDT(RSC_PERF_MON_CPC), LDT(RSC_PERF_MON_CPC),
LDT(RSC_PERF_MON_CST), LDT(RSC_PERF_MON_CST),
LDT(RSC_PERF_MON_HWP), LDT(RSC_PERF_MON_HWP),
LDT(RSC_PERF_MON_CORE_CSTATE), LDT(RSC_PERF_MON_LOW_PWR),
LDT(RSC_PERF_MON_CSTATE_BAR), LDT(RSC_PERF_MON_WFI),
LDT(RSC_PERF_MON_WFE),
LDT(RSC_PERF_MON_MONITOR_MWAIT), LDT(RSC_PERF_MON_MONITOR_MWAIT),
LDT(RSC_PERF_MON_MWAIT_IDX_CSTATE), LDT(RSC_PERF_MON_MWAIT_IDX_CSTATE),
LDT(RSC_PERF_MON_MWAIT_SUB_CSTATE), LDT(RSC_PERF_MON_MWAIT_SUB_CSTATE),
@@ -1060,7 +1061,8 @@ RESOURCE_ST Resource[] = {
LDQ(RSC_PERF_LABEL_CPC), LDQ(RSC_PERF_LABEL_CPC),
LDQ(RSC_PERF_LABEL_CST), LDQ(RSC_PERF_LABEL_CST),
LDQ(RSC_PERF_LABEL_HWP), 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_LABEL_MWAIT_IDX),
LDQ(RSC_PERF_ENCODING_C0), LDQ(RSC_PERF_ENCODING_C0),
LDQ(RSC_PERF_ENCODING_C1), LDQ(RSC_PERF_ENCODING_C1),

View File

@@ -865,8 +865,9 @@ enum {
RSC_PERF_MON_CPC, RSC_PERF_MON_CPC,
RSC_PERF_MON_CST, RSC_PERF_MON_CST,
RSC_PERF_MON_HWP, RSC_PERF_MON_HWP,
RSC_PERF_MON_CORE_CSTATE, RSC_PERF_MON_LOW_PWR,
RSC_PERF_MON_CSTATE_BAR, RSC_PERF_MON_WFI,
RSC_PERF_MON_WFE,
RSC_PERF_MON_MONITOR_MWAIT, RSC_PERF_MON_MONITOR_MWAIT,
RSC_PERF_MON_MWAIT_IDX_CSTATE, RSC_PERF_MON_MWAIT_IDX_CSTATE,
RSC_PERF_MON_MWAIT_SUB_CSTATE, RSC_PERF_MON_MWAIT_SUB_CSTATE,
@@ -883,7 +884,8 @@ enum {
RSC_PERF_LABEL_CPC, RSC_PERF_LABEL_CPC,
RSC_PERF_LABEL_CST, RSC_PERF_LABEL_CST,
RSC_PERF_LABEL_HWP, RSC_PERF_LABEL_HWP,
RSC_PERF_LABEL_CST_BAR, RSC_PERF_LABEL_WFI,
RSC_PERF_LABEL_WFE,
RSC_PERF_LABEL_MWAIT_IDX, RSC_PERF_LABEL_MWAIT_IDX,
RSC_PERF_ENCODING_C0, RSC_PERF_ENCODING_C0,
RSC_PERF_ENCODING_C1, RSC_PERF_ENCODING_C1,

View File

@@ -3249,10 +3249,11 @@ REASON_CODE SysInfoTech(Window *win,
}, },
{ {
NULL, NULL,
RO(Shm)->Cpu[RO(Shm)->Proc.Service.Core].Query.CStateBaseAddr != 0, RO(Shm)->Cpu[RO(Shm)->Proc.Service.Core].Query.WFI
2, "%s%.*sCCx [%3s]", | RO(Shm)->Cpu[RO(Shm)->Proc.Service.Core].Query.WFE,
RSC(PERF_MON_CORE_CSTATE).CODE(), NULL, 2, "%s%.*sWFx [%3s]",
width - 14 - RSZ(PERF_MON_CORE_CSTATE), RSC(PERF_MON_LOW_PWR).CODE(), NULL,
width - 14 - RSZ(PERF_MON_LOW_PWR),
NULL, NULL,
SCANKEY_NULL, SCANKEY_NULL,
NULL NULL
@@ -3533,7 +3534,6 @@ REASON_CODE SysInfoPerfMon( Window *win,
RSC(SYSINFO_PERFMON_COND3).ATTR(), RSC(SYSINFO_PERFMON_COND3).ATTR(),
RSC(SYSINFO_PERFMON_COND4).ATTR() RSC(SYSINFO_PERFMON_COND4).ATTR()
}; };
unsigned int bix;
/* Section Mark */ /* Section Mark */
if (RO(Shm)->Proc.PM_version > 0) if (RO(Shm)->Proc.PM_version > 0)
{ {
@@ -3580,18 +3580,25 @@ REASON_CODE SysInfoPerfMon( Window *win,
} }
/* Section Mark */ /* Section Mark */
PUT( SCANKEY_NULL, attrib[0], width, 2, PUT( SCANKEY_NULL, attrib[0], width, 2,
"%s", RSC(PERF_MON_CORE_CSTATE).CODE() ); "%s", RSC(PERF_MON_LOW_PWR).CODE() );
PUT( SCANKEY_NULL, PUT( SCANKEY_NULL,
attrib[ !RO(Shm)->Cpu[ attrib[RO(Shm)->Cpu[RO(Shm)->Proc.Service.Core].Query.WFI ?3:2],
RO(Shm)->Proc.Service.Core
].Query.CStateBaseAddr ? 0 : 3 ],
width, 3, width, 3,
"%s%.*s%s [ 0x%-4X]", RSC(PERF_MON_CSTATE_BAR).CODE(), "%s%.*s%s [%7s]", RSC(PERF_MON_WFI).CODE(),
width - (OutFunc == NULL ? 21 : 19) width - (OutFunc == NULL ? 21 : 19) - RSZ(PERF_MON_WFI), hSpace,
- RSZ(PERF_MON_CSTATE_BAR), hSpace, RSC(PERF_LABEL_WFI).CODE(),
RSC(PERF_LABEL_CST_BAR).CODE(), RO(Shm)->Cpu[RO(Shm)->Proc.Service.Core].Query.WFI ?
RO(Shm)->Cpu[RO(Shm)->Proc.Service.Core].Query.CStateBaseAddr ); 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 */ /* Section Mark */
if (RO(Shm)->Proc.Features.ACPI_CST_CAP) { if (RO(Shm)->Proc.Features.ACPI_CST_CAP) {
PUT( SCANKEY_NULL, attrib[RO(Shm)->Proc.Features.ACPI_CST ? 3 : 0], 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_MWAIT6,
RO(Shm)->Proc.Features.MWait.SubCstate_MWAIT7 ); RO(Shm)->Proc.Features.MWait.SubCstate_MWAIT7 );
/* Section Mark */ /* Section Mark */
bix = RO(Shm)->Proc.Features.PerfMon.CoreCycles == 1 ? 2 : 0; PUT( SCANKEY_NULL,
attrib[RO(Shm)->Proc.Features.PerfMon.CoreCycles ? 2 : 0],
PUT( SCANKEY_NULL, attrib[bix], width, 2, width, 2,
"%s%.*s[%7s]", RSC(PERF_MON_CORE_CYCLE).CODE(), "%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[RO(Shm)->Proc.Features.PerfMon.InstrRetired ? 2 : 0],
PUT( SCANKEY_NULL, attrib[bix], width, 2, width, 2,
"%s%.*s[%7s]", RSC(PERF_MON_INST_RET).CODE(), "%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 */ /* Section Mark */
PUT( SCANKEY_NULL, attrib[RO(Shm)->Proc.Features.ACPI_PCT_CAP ? 3:0], PUT( SCANKEY_NULL, attrib[RO(Shm)->Proc.Features.ACPI_PCT_CAP ? 3:0],
width, 2, width, 2,

View File

@@ -36,13 +36,11 @@ typedef struct
unsigned int Revision; unsigned int Revision;
struct { struct {
unsigned short int CfgLock : 1-0, unsigned short int WFI : 1-0,
IORedir : 2-1, WFE : 2-1,
SCTLRX : 3-2, SCTLRX : 3-2,
Unused : 16-3; Unused : 16-3;
}; };
unsigned short int CStateLimit;
unsigned short int CStateBaseAddr; /* Any I/O BAR */
} Query; } Query;
struct { struct {

View File

@@ -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) 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(Shm)->Cpu[cpu].Query.WFE = \
RO(Core, AT(cpu))->Query.CStateLimit; !BITEXTRZ(RO(Core, AT(cpu))->SystemRegister.HCR, HYPCR_TWE, 1);
/* 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;
} }
void PowerThermal( RO(SHM_STRUCT) *RO(Shm), RO(PROC) *RO(Proc), 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); Topology(RO(Shm), RO(Proc), RO(Core), cpu);
CStates(RO(Shm), RO(Core), cpu);
PowerThermal(RO(Shm), RO(Proc), RO(Core), cpu); PowerThermal(RO(Shm), RO(Proc), RO(Core), cpu);
SystemRegisters(RO(Shm), RO(Core), cpu); SystemRegisters(RO(Shm), RO(Core), cpu);
CStates(RO(Shm), RO(Core), cpu);
} }
#define SysOnce(drv) ioctl(drv, COREFREQ_IOCTL_SYSONCE) #define SysOnce(drv) ioctl(drv, COREFREQ_IOCTL_SYSONCE)

View File

@@ -1324,14 +1324,14 @@ static void Query_Features(void *pArg)
if (BITEXTRZ(FLAGS, FLAG_EL, 2) >= 2) if (BITEXTRZ(FLAGS, FLAG_EL, 2) >= 2)
{ {
volatile unsigned long long HCR; volatile unsigned long long HCR;
__asm__ __volatile__( __asm__ __volatile__(
"mrs %[hcr] , hcr_el2""\n\t" "mrs %[hcr] , hcr_el2""\n\t"
"isb" "isb"
: [hcr] "=r" (HCR) : [hcr] "=r" (HCR)
: :
: "cc", "memory" : "cc", "memory"
); );
if ((iArg->Features->FGT== 0) && (BITEXTRZ(HCR, HYPCR_TID3, 1) == 0)) if ((iArg->Features->FGT== 0) && (BITEXTRZ(HCR, HYPCR_TID3, 1) == 0))
{ {
volatile AA64DFR1 dfr1; volatile AA64DFR1 dfr1;
@@ -3254,7 +3254,6 @@ static void PerCore_Reset(CORE_RO *Core)
static void PerCore_GenericMachine(void *arg) static void PerCore_GenericMachine(void *arg)
{ {
volatile CPUPWRCTLR cpuPwrCtl;
volatile PMUSERENR pmuser; volatile PMUSERENR pmuser;
volatile PMCNTENSET enset; volatile PMCNTENSET enset;
volatile PMCNTENCLR enclr; volatile PMCNTENCLR enclr;
@@ -3268,10 +3267,6 @@ static void PerCore_GenericMachine(void *arg)
Core->Boost[BOOST(MAX)].Q < PUBLIC(RO(Proc))->Features.Factory.Ratio ? Core->Boost[BOOST(MAX)].Q < PUBLIC(RO(Proc))->Features.Factory.Ratio ?
Hybrid_Secondary : Hybrid_Primary; 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) { if (PUBLIC(RO(Proc))->Features.PerfMon.Version > 0) {
__asm__ __volatile__( __asm__ __volatile__(
"mrs %[pmuser], pmuserenr_el0" "\n\t" "mrs %[pmuser], pmuserenr_el0" "\n\t"