[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,
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;

View File

@@ -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;

View File

@@ -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"

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_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"

View File

@@ -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),

View File

@@ -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,

View File

@@ -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,

View File

@@ -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 {

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)
{ /* 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)

View File

@@ -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"