char model[CPU_MODEL_SIZE];
uint8_t model_id;
uint8_t stepping;
+ uint8_t num_cores;
s_cpu_flags flags;
} s_cpu;
#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;
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,
(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;
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;
+ }
+
}
/*
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)
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));