summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErwan Velu <erwan.velu@free.fr>2009-11-27 15:44:33 +0100
committerErwan Velu <erwan.velu@free.fr>2009-12-04 10:11:14 +0100
commit8ae29a14d58100f21c8c6611190f15a46680f318 (patch)
tree8c4f6451f251c08d8989d9d954a9b8f3a48be8b8
parenteaba6a11bfa443f2cd792b3fb719f03ff5c8bb1c (diff)
downloadsyslinux-8ae29a14d58100f21c8c6611190f15a46680f318.tar.gz
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.h3
-rw-r--r--com32/gpllib/cpuid.c25
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));