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:
committed by
waddlesplash
parent
af5f256338
commit
6c380f3c8e
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user