[haiku-commits] BRANCH pdziepak-github.lock_elision [a1eeb52] src/system/kernel/arch/x86 src/system/boot/platform/bios_ia32 headers/private/kernel/arch/x86 src/system/kernel/arch/x86/32 src/add-ons/kernel/cpu/x86

  • From: pdziepak-github.lock_elision <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 14 Aug 2013 00:15:35 +0200 (CEST)

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


Other related posts:

  • » [haiku-commits] BRANCH pdziepak-github.lock_elision [a1eeb52] src/system/kernel/arch/x86 src/system/boot/platform/bios_ia32 headers/private/kernel/arch/x86 src/system/kernel/arch/x86/32 src/add-ons/kernel/cpu/x86 - pdziepak-github . lock_elision