x86_cstates: Log errors indicating why C-states can't be used.
As long as we have MWAIT and invariant TSC, anyway. Also add a check for VENDOR_INTEL for the C5/C6 state disabling.
This commit is contained in:
@@ -139,25 +139,34 @@ init_cstates()
|
|||||||
cpuid_info cpuid;
|
cpuid_info cpuid;
|
||||||
get_current_cpuid(&cpuid, 0, 0);
|
get_current_cpuid(&cpuid, 0, 0);
|
||||||
uint32 maxBasicLeaf = cpuid.eax_0.max_eax;
|
uint32 maxBasicLeaf = cpuid.eax_0.max_eax;
|
||||||
if (maxBasicLeaf < IA32_CPUID_LEAF_MWAIT)
|
if (maxBasicLeaf < IA32_CPUID_LEAF_MWAIT) {
|
||||||
|
dprintf("can't use x86 C-States: no CPUID leaf for MWAIT\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
get_current_cpuid(&cpuid, IA32_CPUID_LEAF_MWAIT, 0);
|
get_current_cpuid(&cpuid, IA32_CPUID_LEAF_MWAIT, 0);
|
||||||
uint32 minMonitorLineSize = cpuid.regs.eax & 0xffff;
|
uint32 minMonitorLineSize = cpuid.regs.eax & 0xffff;
|
||||||
//uint32 maxMonitorLineSize = cpuid.regs.ebx & 0xffff;
|
//uint32 maxMonitorLineSize = cpuid.regs.ebx & 0xffff;
|
||||||
uint32 mwaitSubStates = cpuid.regs.edx;
|
uint32 mwaitSubStates = cpuid.regs.edx;
|
||||||
if (minMonitorLineSize < sizeof(int32))
|
if (minMonitorLineSize < sizeof(int32)) {
|
||||||
|
dprintf("can't use x86 C-States: line size too small\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
if (mwaitSubStates == 0)
|
}
|
||||||
|
if (mwaitSubStates == 0) {
|
||||||
|
dprintf("can't use x86 C-States: no MWAIT sub-states\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// check Enumeration of Monitor-Mwait extensions is supported
|
// check Enumeration of Monitor-Mwait extensions is supported
|
||||||
// and check treating interrupts as break-events even when interrupts disabled is supported
|
// and check treating interrupts as break-events even when interrupts disabled is supported
|
||||||
if ((cpuid.regs.ecx & CPUID_MWAIT_ECX_SUPPORT) != CPUID_MWAIT_ECX_SUPPORT)
|
if ((cpuid.regs.ecx & CPUID_MWAIT_ECX_SUPPORT) != CPUID_MWAIT_ECX_SUPPORT) {
|
||||||
|
dprintf("can't use x86 C-States: extensions missing\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
cpu_ent* cpu = &gCPU[0];
|
cpu_ent* cpu = &gCPU[0];
|
||||||
uint8 model = cpu->arch.model + (cpu->arch.extended_model << 4);
|
uint8 model = cpu->arch.model + (cpu->arch.extended_model << 4);
|
||||||
if (cpu->arch.family == 6) {
|
if (cpu->arch.vendor == VENDOR_INTEL && cpu->arch.family == 6) {
|
||||||
// disable C5 and C6 states on Skylake (same as Linux)
|
// disable C5 and C6 states on Skylake (same as Linux)
|
||||||
if (model == 0x5e && (mwaitSubStates & (0xf << 28)) != 0)
|
if (model == 0x5e && (mwaitSubStates & (0xf << 28)) != 0)
|
||||||
mwaitSubStates &= 0xf00fffff;
|
mwaitSubStates &= 0xf00fffff;
|
||||||
@@ -181,8 +190,10 @@ init_cstates()
|
|||||||
sCStateCount++;
|
sCStateCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sCStateCount == 0)
|
if (sCStateCount == 0) {
|
||||||
|
dprintf("can't use x86 C-States: none found\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
sIdleTime = new(std::nothrow) bigtime_t[smp_get_num_cpus()];
|
sIdleTime = new(std::nothrow) bigtime_t[smp_get_num_cpus()];
|
||||||
if (sIdleTime == NULL)
|
if (sIdleTime == NULL)
|
||||||
@@ -191,7 +202,7 @@ init_cstates()
|
|||||||
|
|
||||||
cstates_set_scheduler_mode(SCHEDULER_MODE_LOW_LATENCY);
|
cstates_set_scheduler_mode(SCHEDULER_MODE_LOW_LATENCY);
|
||||||
|
|
||||||
dprintf("using Intel C-States: C0%s\n", cStates);
|
dprintf("using x86 C-States: C0%s\n", cStates);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,4 +251,3 @@ module_info* modules[] = {
|
|||||||
(module_info*)&sX86CStates,
|
(module_info*)&sX86CStates,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user