added 1 changeset to branch 'refs/remotes/pdziepak-github/lock_elision' old head: 00587fccdd0901f20c02e88fe23b4cd53a7eb49c new head: a1eeb52fc85c2ff85b79b92f0809dc643c8917eb overview: https://github.com/pdziepak/Haiku/compare/00587fc...a1eeb52 ---------------------------------------------------------------------------- a1eeb52: x86: Support sub-leaves of CPUID eax = 7 CPUID leaf 7 may contain many sub-leaves which are chosen by register ecx. Even though, currently, there is no CPU with more than one sub-leave we have to set ecx to the valid value. [ Pawel Dziepak <pdziepak@xxxxxxxxxxx> ] ---------------------------------------------------------------------------- Commit: a1eeb52fc85c2ff85b79b92f0809dc643c8917eb Author: Pawel Dziepak <pdziepak@xxxxxxxxxxx> Date: Tue Aug 13 20:39:17 2013 UTC ---------------------------------------------------------------------------- 11 files changed, 32 insertions(+), 24 deletions(-) headers/private/kernel/arch/x86/arch_cpu.h | 2 +- .../private/kernel/arch/x86/arch_system_info.h | 2 +- src/add-ons/kernel/cpu/x86/generic_x86.cpp | 4 +-- .../drivers/power/x86_cpuidle/intel_cpuidle.cpp | 2 +- src/system/boot/platform/bios_ia32/cpu.cpp | 2 +- src/system/boot/platform/bios_ia32/long.cpp | 2 +- src/system/boot/platform/bios_ia32/smp.cpp | 2 +- src/system/kernel/arch/x86/32/cpuid.S | 4 ++- src/system/kernel/arch/x86/64/cpuid.S | 4 ++- src/system/kernel/arch/x86/arch_cpu.cpp | 30 +++++++++++--------- src/system/kernel/arch/x86/arch_system_info.cpp | 2 +- ---------------------------------------------------------------------------- diff --git a/headers/private/kernel/arch/x86/arch_cpu.h b/headers/private/kernel/arch/x86/arch_cpu.h index cf35b5e..9511c3a 100644 --- a/headers/private/kernel/arch/x86/arch_cpu.h +++ b/headers/private/kernel/arch/x86/arch_cpu.h @@ -241,7 +241,7 @@ enum x86_feature_type { FEATURE_EXT_AMD, // cpuid eax=0x80000001, edx register (AMD) FEATURE_6_EAX, // cpuid eax=6, eax registers FEATURE_6_ECX, // cpuid eax=6, ecx registers - FEATURE_7_EBX, // cpuid eax=7, ebx registers + FEATURE_7_0_EBX, // cpuid eax=7 ecx=0, ebx register FEATURE_NUM }; diff --git a/headers/private/kernel/arch/x86/arch_system_info.h b/headers/private/kernel/arch/x86/arch_system_info.h index b8a7383..0f92e37 100644 --- a/headers/private/kernel/arch/x86/arch_system_info.h +++ b/headers/private/kernel/arch/x86/arch_system_info.h @@ -12,7 +12,7 @@ extern "C" { #endif -status_t get_current_cpuid(cpuid_info* info, uint32 eax); +status_t get_current_cpuid(cpuid_info* info, uint32 eax, uint32 ecx); uint32 get_eflags(void); void set_eflags(uint32 value); diff --git a/src/add-ons/kernel/cpu/x86/generic_x86.cpp b/src/add-ons/kernel/cpu/x86/generic_x86.cpp index b394ff9..94e6a1b 100644 --- a/src/add-ons/kernel/cpu/x86/generic_x86.cpp +++ b/src/add-ons/kernel/cpu/x86/generic_x86.cpp @@ -208,9 +208,9 @@ generic_mtrr_compute_physical_mask(void) uint32 bits = 36; cpuid_info cpuInfo; - if (get_current_cpuid(&cpuInfo, 0x80000000) == B_OK + if (get_current_cpuid(&cpuInfo, 0x80000000, 0) == B_OK && (cpuInfo.eax_0.max_eax & 0xff) >= 8) { - get_current_cpuid(&cpuInfo, 0x80000008); + get_current_cpuid(&cpuInfo, 0x80000008, 0); bits = cpuInfo.regs.eax & 0xff; // Obviously, the bits are not always reported correctly diff --git a/src/add-ons/kernel/drivers/power/x86_cpuidle/intel_cpuidle.cpp b/src/add-ons/kernel/drivers/power/x86_cpuidle/intel_cpuidle.cpp index 7f6fbd6..cbbd1bc 100644 --- a/src/add-ons/kernel/drivers/power/x86_cpuidle/intel_cpuidle.cpp +++ b/src/add-ons/kernel/drivers/power/x86_cpuidle/intel_cpuidle.cpp @@ -91,7 +91,7 @@ intel_cpuidle_init(void) return B_ERROR; cpuid_info cpuid; - get_current_cpuid(&cpuid, 5); + get_current_cpuid(&cpuid, 5, 0); /* ecx[0] monitor/mwait extension supported * ecx[1] support for treating interrupts as break-events for mwait * edx number of sub-states diff --git a/src/system/boot/platform/bios_ia32/cpu.cpp b/src/system/boot/platform/bios_ia32/cpu.cpp index e9d405b..cc70cba 100644 --- a/src/system/boot/platform/bios_ia32/cpu.cpp +++ b/src/system/boot/platform/bios_ia32/cpu.cpp @@ -327,7 +327,7 @@ check_cpu_features() } cpuid_info info; - if (get_current_cpuid(&info, 1) != B_OK) + if (get_current_cpuid(&info, 1, 0) != B_OK) return B_ERROR; if ((info.eax_1.features & RDTSC_FEATURE) == 0) { diff --git a/src/system/boot/platform/bios_ia32/long.cpp b/src/system/boot/platform/bios_ia32/long.cpp index d632efc..3db5220 100644 --- a/src/system/boot/platform/bios_ia32/long.cpp +++ b/src/system/boot/platform/bios_ia32/long.cpp @@ -330,7 +330,7 @@ long_start_kernel() { // Check whether long mode is supported. cpuid_info info; - get_current_cpuid(&info, 0x80000001); + get_current_cpuid(&info, 0x80000001, 0); if ((info.regs.edx & (1 << 29)) == 0) panic("64-bit kernel requires a 64-bit CPU"); diff --git a/src/system/boot/platform/bios_ia32/smp.cpp b/src/system/boot/platform/bios_ia32/smp.cpp index e3abb4f..edaf487 100644 --- a/src/system/boot/platform/bios_ia32/smp.cpp +++ b/src/system/boot/platform/bios_ia32/smp.cpp @@ -601,7 +601,7 @@ smp_init(void) #endif cpuid_info info; - if (get_current_cpuid(&info, 1) != B_OK) + if (get_current_cpuid(&info, 1, 0) != B_OK) return; if ((info.eax_1.features & IA32_FEATURE_APIC) == 0) { diff --git a/src/system/kernel/arch/x86/32/cpuid.S b/src/system/kernel/arch/x86/32/cpuid.S index 5eb2573..eb44b1b 100644 --- a/src/system/kernel/arch/x86/32/cpuid.S +++ b/src/system/kernel/arch/x86/32/cpuid.S @@ -11,12 +11,14 @@ .text -/* void get_current_cpuid(cpuid_info *info, uint32 eaxRegister) */ +/* void get_current_cpuid(cpuid_info *info, uint32 eaxRegister, + uint32 ecxRegister) */ FUNCTION(get_current_cpuid): pushl %ebx pushl %edi movl 12(%esp),%edi /* first arg points to the cpuid_info structure */ movl 16(%esp),%eax /* second arg sets up eax */ + movl 20(%esp),%ecx /* third arg sets up ecx */ cpuid movl %eax,0(%edi) /* copy the regs into the cpuid_info structure */ movl %ebx,4(%edi) diff --git a/src/system/kernel/arch/x86/64/cpuid.S b/src/system/kernel/arch/x86/64/cpuid.S index 8e6b07c..1085359 100644 --- a/src/system/kernel/arch/x86/64/cpuid.S +++ b/src/system/kernel/arch/x86/64/cpuid.S @@ -10,10 +10,12 @@ .text -/* status_t get_current_cpuid(cpuid_info* info, uint32 eaxRegister) */ +/* status_t get_current_cpuid(cpuid_info* info, uint32 eaxRegister, + uint32 ecxRegister) */ FUNCTION(get_current_cpuid): push %rbx movl %esi, %eax + movl %edx, %ecx cpuid movl %eax, 0(%rdi) movl %ebx, 4(%rdi) diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index 157baf3..cea8400 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -500,9 +500,9 @@ dump_feature_string(int currentCPU, cpu_ent* cpu) strlcat(features, "aperfmperf ", sizeof(features)); if (cpu->arch.feature[FEATURE_6_ECX] & IA32_FEATURE_EPB) strlcat(features, "epb ", sizeof(features)); - if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_HLE) + if (cpu->arch.feature[FEATURE_7_0_EBX] & IA32_FEATURE_HLE) strlcat(features, "hle ", sizeof(features)); - if (cpu->arch.feature[FEATURE_7_EBX] & IA32_FEATURE_RTM) + if (cpu->arch.feature[FEATURE_7_0_EBX] & IA32_FEATURE_RTM) strlcat(features, "rtm ", sizeof(features)); dprintf("CPU %d: features: %s\n", currentCPU, features); @@ -526,7 +526,7 @@ detect_cpu(int currentCPU) cpu->arch.model_name[0] = 0; // print some fun data - get_current_cpuid(&cpuid, 0); + get_current_cpuid(&cpuid, 0, 0); uint32 maxBasicLeaf = cpuid.eax_0.max_eax; // build the vendor string @@ -534,7 +534,7 @@ detect_cpu(int currentCPU) memcpy(vendorString, cpuid.eax_0.vendor_id, sizeof(cpuid.eax_0.vendor_id)); // get the family, model, stepping - get_current_cpuid(&cpuid, 1); + get_current_cpuid(&cpuid, 1, 0); cpu->arch.type = cpuid.eax_1.type; cpu->arch.family = cpuid.eax_1.family; cpu->arch.extended_family = cpuid.eax_1.extended_family; @@ -565,27 +565,27 @@ detect_cpu(int currentCPU) } // see if we can get the model name - get_current_cpuid(&cpuid, 0x80000000); + get_current_cpuid(&cpuid, 0x80000000, 0); uint32 maxExtendedLeaf = cpuid.eax_0.max_eax; if (maxExtendedLeaf >= 0x80000004) { // build the model string (need to swap ecx/edx data before copying) unsigned int temp; memset(cpu->arch.model_name, 0, sizeof(cpu->arch.model_name)); - get_current_cpuid(&cpuid, 0x80000002); + get_current_cpuid(&cpuid, 0x80000002, 0); temp = cpuid.regs.edx; cpuid.regs.edx = cpuid.regs.ecx; cpuid.regs.ecx = temp; memcpy(cpu->arch.model_name, cpuid.as_chars, sizeof(cpuid.as_chars)); - get_current_cpuid(&cpuid, 0x80000003); + get_current_cpuid(&cpuid, 0x80000003, 0); temp = cpuid.regs.edx; cpuid.regs.edx = cpuid.regs.ecx; cpuid.regs.ecx = temp; memcpy(cpu->arch.model_name + 16, cpuid.as_chars, sizeof(cpuid.as_chars)); - get_current_cpuid(&cpuid, 0x80000004); + get_current_cpuid(&cpuid, 0x80000004, 0); temp = cpuid.regs.edx; cpuid.regs.edx = cpuid.regs.ecx; cpuid.regs.ecx = temp; @@ -608,26 +608,30 @@ detect_cpu(int currentCPU) } // load feature bits - get_current_cpuid(&cpuid, 1); + get_current_cpuid(&cpuid, 1, 0); cpu->arch.feature[FEATURE_COMMON] = cpuid.eax_1.features; // edx cpu->arch.feature[FEATURE_EXT] = cpuid.eax_1.extended_features; // ecx if (maxExtendedLeaf >= 0x80000001) { - get_current_cpuid(&cpuid, 0x80000001); + get_current_cpuid(&cpuid, 0x80000001, 0); cpu->arch.feature[FEATURE_EXT_AMD] = cpuid.regs.edx; // edx if (cpu->arch.vendor != VENDOR_AMD) cpu->arch.feature[FEATURE_EXT_AMD] &= IA32_FEATURES_INTEL_EXT; } if (maxBasicLeaf >= 6) { - get_current_cpuid(&cpuid, 6); + get_current_cpuid(&cpuid, 6, 0); cpu->arch.feature[FEATURE_6_EAX] = cpuid.regs.eax; cpu->arch.feature[FEATURE_6_ECX] = cpuid.regs.ecx; } if (maxBasicLeaf >= 7) { - get_current_cpuid(&cpuid, 7); - cpu->arch.feature[FEATURE_7_EBX] = cpuid.regs.ebx; + get_current_cpuid(&cpuid, 7, 0); + + // EAX contains maximum ECX input value (i.e. sub-leaf number). + // Currently (August 2013) only sub-leaf 0 is present. + + cpu->arch.feature[FEATURE_7_0_EBX] = cpuid.regs.ebx; } #if DUMP_FEATURE_STRING diff --git a/src/system/kernel/arch/x86/arch_system_info.cpp b/src/system/kernel/arch/x86/arch_system_info.cpp index a1423ff..280ca0e 100644 --- a/src/system/kernel/arch/x86/arch_system_info.cpp +++ b/src/system/kernel/arch/x86/arch_system_info.cpp @@ -29,7 +29,7 @@ get_cpuid_for(cpuid_info *info, uint32 currentCPU, uint32 eaxRegister, if (currentCPU != forCPU) return false; - get_current_cpuid(info, eaxRegister); + get_current_cpuid(info, eaxRegister, 0); return true; }