kernel/x86: add definitions for cpuid leaves

remove feature_5_ecx

Change-Id: I247a37c875e5dd04f2239fdceeef67e402b1245d
Reviewed-on: https://review.haiku-os.org/c/haiku/+/8880
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
Jérôme Duval
2025-02-04 17:22:34 +00:00
committed by waddlesplash
parent af5f256338
commit 6c380f3c8e
3 changed files with 30 additions and 25 deletions
+6 -5
View File
@@ -188,6 +188,12 @@
#define IA32_MSR_PAT_TYPE_WRITE_BACK 0x6ULL
#define IA32_MSR_PAT_TYPE_UNCACHED 0x7ULL
// cpuid leaves
#define IA32_CPUID_LEAF_MWAIT 0x5
#define IA32_CPUID_LEAF_XSTATE 0xd
#define IA32_CPUID_LEAF_TSC 0x15
#define IA32_CPUID_LEAF_FREQUENCY 0x16
// x86 features from cpuid eax 1, edx register
// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-5)
#define IA32_FEATURE_FPU (1 << 0) // x87 fpu
@@ -282,10 +288,6 @@
| IA32_FEATURE_AMD_EXT_RDTSCP \
| IA32_FEATURE_AMD_EXT_LONG)
// x86 defined features from cpuid eax 5, ecx register
#define IA32_FEATURE_POWER_MWAIT (1 << 0)
#define IA32_FEATURE_INTERRUPT_MWAIT (1 << 1)
// x86 defined features from cpuid eax 6, eax register
// reference https://software.intel.com/content/dam/develop/public/us/en/documents/253666-sdm-vol-2a.pdf (Table 3-8)
#define IA32_FEATURE_DTS (1 << 0) // Digital Thermal Sensor
@@ -514,7 +516,6 @@ enum x86_feature_type {
FEATURE_EXT, // cpuid eax=1, ecx register
FEATURE_EXT_AMD_ECX, // cpuid eax=0x80000001, ecx register (AMD)
FEATURE_EXT_AMD, // cpuid eax=0x80000001, edx register (AMD)
FEATURE_5_ECX, // cpuid eax=5, ecx register
FEATURE_6_EAX, // cpuid eax=6, eax registers
FEATURE_6_ECX, // cpuid eax=6, ecx registers
FEATURE_7_EBX, // cpuid eax=7, ebx registers
@@ -23,6 +23,10 @@
#define CPUIDLE_CSTATE_MAX 8
#define CPUID_MWAIT_ECX_EXTENSIONS 0x1
#define CPUID_MWAIT_ECX_INTERRUPTS_BREAK 0x2
#define CPUID_MWAIT_ECX_SUPPORT (CPUID_MWAIT_ECX_EXTENSIONS | CPUID_MWAIT_ECX_INTERRUPTS_BREAK)
#define MWAIT_INTERRUPTS_BREAK (1 << 0)
#define X86_CSTATES_MODULE_NAME CPUIDLE_MODULES_PREFIX "/x86_cstates/v1"
@@ -126,10 +130,6 @@ init_cstates()
{
if (!x86_check_feature(IA32_FEATURE_EXT_MONITOR, FEATURE_EXT))
return B_ERROR;
if (!x86_check_feature(IA32_FEATURE_POWER_MWAIT, FEATURE_5_ECX))
return B_ERROR;
if (!x86_check_feature(IA32_FEATURE_INTERRUPT_MWAIT, FEATURE_5_ECX))
return B_ERROR;
// we need invariant TSC
if (!x86_check_feature(IA32_FEATURE_INVARIANT_TSC, FEATURE_EXT_7_EDX))
@@ -139,17 +139,26 @@ init_cstates()
cpuid_info cpuid;
get_current_cpuid(&cpuid, 0, 0);
uint32 maxBasicLeaf = cpuid.eax_0.max_eax;
if (maxBasicLeaf < 5)
if (maxBasicLeaf < IA32_CPUID_LEAF_MWAIT)
return B_ERROR;
get_current_cpuid(&cpuid, 5, 0);
if ((cpuid.regs.eax & 0xffff) < sizeof(int32))
get_current_cpuid(&cpuid, IA32_CPUID_LEAF_MWAIT, 0);
uint32 minMonitorLineSize = cpuid.regs.eax & 0xffff;
//uint32 maxMonitorLineSize = cpuid.regs.ebx & 0xffff;
uint32 mwaitSubStates = cpuid.regs.edx;
if (minMonitorLineSize < sizeof(int32))
return B_ERROR;
if (mwaitSubStates == 0)
return B_ERROR;
// check Enumeration of Monitor-Mwait extensions 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)
return B_ERROR;
char cStates[64];
unsigned int offset = 0;
for (int32 i = 1; i < CPUIDLE_CSTATE_MAX; i++) {
int32 subStates = (cpuid.regs.edx >> (i * 4)) & 0xf;
int32 subStates = (mwaitSubStates >> (i * 4)) & 0xf;
// no sub-states means the state is not available
if (subStates == 0)
continue;
+7 -12
View File
@@ -1445,11 +1445,6 @@ detect_cpu(int currentCPU, bool full = true)
cpu->arch.feature[FEATURE_EXT_AMD] &= IA32_FEATURES_INTEL_EXT;
}
if (maxBasicLeaf >= 5) {
get_current_cpuid(&cpuid, 5, 0);
cpu->arch.feature[FEATURE_5_ECX] = cpuid.regs.ecx;
}
if (maxBasicLeaf >= 6) {
get_current_cpuid(&cpuid, 6, 0);
cpu->arch.feature[FEATURE_6_EAX] = cpuid.regs.eax;
@@ -1627,23 +1622,23 @@ init_tsc_with_cpuid(kernel_args* args, uint32* conversionFactor)
cpuid_info cpuid;
get_current_cpuid(&cpuid, 0, 0);
uint32 maxBasicLeaf = cpuid.eax_0.max_eax;
if (maxBasicLeaf < 0x15)
if (maxBasicLeaf < IA32_CPUID_LEAF_TSC)
return;
get_current_cpuid(&cpuid, 0x15, 0);
get_current_cpuid(&cpuid, IA32_CPUID_LEAF_TSC, 0);
if (cpuid.regs.eax == 0 || cpuid.regs.ebx == 0)
return;
uint32 khz = cpuid.regs.ecx / 1000;
uint32 denominator = cpuid.regs.eax;
uint32 numerator = cpuid.regs.ebx;
if (khz == 0 && model == 0x5f) {
// CPUID 0x16 isn't supported, hardcoding
// CPUID_LEAF_FREQUENCY isn't supported, hardcoding
khz = 25000;
}
if (khz == 0 && maxBasicLeaf >= 0x16) {
if (khz == 0 && maxBasicLeaf >= IA32_CPUID_LEAF_FREQUENCY) {
// for these CPUs the base frequency is also the tsc frequency
get_current_cpuid(&cpuid, 0x16, 0);
get_current_cpuid(&cpuid, IA32_CPUID_LEAF_FREQUENCY, 0);
khz = cpuid.regs.eax * 1000 * denominator / numerator;
}
if (khz == 0)
@@ -1908,10 +1903,10 @@ arch_cpu_init_post_vm(kernel_args* args)
call_all_cpus_sync(&enable_osxsave, NULL);
gXsaveMask = IA32_XCR0_X87 | IA32_XCR0_SSE;
cpuid_info cpuid;
get_current_cpuid(&cpuid, 0xd, 0);
get_current_cpuid(&cpuid, IA32_CPUID_LEAF_XSTATE, 0);
gXsaveMask |= (cpuid.regs.eax & IA32_XCR0_AVX);
call_all_cpus_sync(&enable_xsavemask, NULL);
get_current_cpuid(&cpuid, 0xd, 0);
get_current_cpuid(&cpuid, IA32_CPUID_LEAF_XSTATE, 0);
gFPUSaveLength = cpuid.regs.ebx;
if (gFPUSaveLength > sizeof(((struct arch_thread *)0)->fpu_state))
gFPUSaveLength = 832;