diff options
author | Erwan Velu <erwan.velu@free.fr> | 2009-11-27 15:44:33 +0100 |
---|---|---|
committer | Erwan Velu <erwan.velu@free.fr> | 2009-12-04 10:11:14 +0100 |
commit | 8ae29a14d58100f21c8c6611190f15a46680f318 (patch) | |
tree | 8c4f6451f251c08d8989d9d954a9b8f3a48be8b8 | |
parent | eaba6a11bfa443f2cd792b3fb719f03ff5c8bb1c (diff) | |
download | syslinux.git-8ae29a14d58100f21c8c6611190f15a46680f318.tar.gz syslinux.git-8ae29a14d58100f21c8c6611190f15a46680f318.tar.xz syslinux.git-8ae29a14d58100f21c8c6611190f15a46680f318.zip |
cpuid: Adding cpu core detection
Impact: we are now able to detect the number of cpu cores
We can detect the number of cores using cpuid(4) or cpuid_ecx(0x80000008)
-rw-r--r-- | com32/gplinclude/cpuid.h | 3 | ||||
-rw-r--r-- | com32/gpllib/cpuid.c | 25 |
2 files changed, 25 insertions, 3 deletions
diff --git a/com32/gplinclude/cpuid.h b/com32/gplinclude/cpuid.h index 9f463aed..677f3f9f 100644 --- a/com32/gplinclude/cpuid.h +++ b/com32/gplinclude/cpuid.h @@ -127,6 +127,7 @@ typedef struct { char model[CPU_MODEL_SIZE]; uint8_t model_id; uint8_t stepping; + uint8_t num_cores; s_cpu_flags flags; } s_cpu; @@ -206,7 +207,7 @@ struct cpuinfo_x86 { #ifdef CONFIG_SMP cpumask_t llc_shared_map; /* cpus sharing the last level cache */ #endif - unsigned char x86_max_cores; /* cpuid returned max cores value */ + unsigned char x86_num_cores; /* cpuid returned the number of cores */ unsigned char booted_cores; /* number of cores as seen by OS */ unsigned char apicid; unsigned char x86_clflush_size; diff --git a/com32/gpllib/cpuid.c b/com32/gpllib/cpuid.c index b24de0a7..b2451403 100644 --- a/com32/gpllib/cpuid.c +++ b/com32/gpllib/cpuid.c @@ -136,7 +136,7 @@ int get_model_name(struct cpuinfo_x86 *c) void generic_identify(struct cpuinfo_x86 *c) { uint32_t tfms, xlvl; - unsigned int ebx; + uint32_t eax, ebx, ecx, edx; /* Get vendor name */ cpuid(0x00000000, @@ -146,6 +146,7 @@ void generic_identify(struct cpuinfo_x86 *c) (uint32_t *) & c->x86_vendor_id[4]); get_cpu_vendor(c); + /* Intel-defined flags: level 0x00000001 */ if (c->cpuid_level >= 0x00000001) { uint32_t capability, excap; @@ -176,6 +177,25 @@ void generic_identify(struct cpuinfo_x86 *c) if (xlvl >= 0x80000004) get_model_name(c); /* Default name */ } + + /* Detecting the number of cores */ + switch (c->x86_vendor) { + case X86_VENDOR_AMD: + if (xlvl >= 0x80000008) { + c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; + if (c->x86_num_cores & (c->x86_num_cores - 1)) + c->x86_num_cores = 1; + } + break; + case X86_VENDOR_INTEL: + cpuid(0x4, &eax, &ebx, &ecx, &edx); + c->x86_num_cores = ((eax & 0xfc000000) >> 26) + 1; + break; + default: + c->x86_num_cores = 1; + break; + } + } /* @@ -359,6 +379,7 @@ void set_generic_info(struct cpuinfo_x86 *c, s_cpu * cpu) strncpy(cpu->vendor, cpu_devs[c->x86_vendor]->c_vendor, sizeof(cpu->vendor)); strncpy(cpu->model, c->x86_model_id, sizeof(cpu->model)); + cpu->num_cores = c->x86_num_cores; } void detect_cpu(s_cpu * cpu) @@ -369,7 +390,7 @@ void detect_cpu(s_cpu * cpu) c.x86_vendor = X86_VENDOR_UNKNOWN; c.cpuid_level = -1; /* CPUID not detected */ c.x86_model = c.x86_mask = 0; /* So far unknown... */ - c.x86_max_cores = 1; + c.x86_num_cores = 1; memset(&c.x86_capability, 0, sizeof(c.x86_capability)); memset(&c.x86_vendor_id, 0, sizeof(c.x86_vendor_id)); memset(&c.x86_model_id, 0, sizeof(c.x86_model_id)); |