x86[_64]: Add support for CPUID sub-leaves

Some CPUID leaves may contain one or more sub-leaves accessed by setting
ECX to an appropriate value.
This commit is contained in:
Pawel Dziepak
2013-10-01 20:31:18 +02:00
parent c48c3f88a9
commit 4110b730db
10 changed files with 24 additions and 20 deletions
@@ -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);
+2 -2
View File
@@ -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
@@ -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
+1 -1
View File
@@ -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) {
+1 -1
View File
@@ -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");
+2 -2
View File
@@ -581,7 +581,7 @@ smp_add_safemode_menus(Menu *menu)
item->SetHelpText("Disables using the local APIC, also disables SMP.");
cpuid_info info;
if (get_current_cpuid(&info, 1) == B_OK
if (get_current_cpuid(&info, 1, 0) == B_OK
&& (info.regs.ecx & IA32_FEATURE_EXT_X2APIC) != 0) {
#if 0
menu->AddItem(item = new(nothrow) MenuItem("Disable X2APIC"));
@@ -617,7 +617,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) {
+3 -1
View File
@@ -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)
+3 -1
View File
@@ -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)
+9 -9
View File
@@ -522,7 +522,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
@@ -530,7 +530,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;
@@ -561,27 +561,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;
@@ -604,19 +604,19 @@ 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;
}
@@ -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;
}