4 * Licensed under the terms of the GNU GPL License version 2.
6 * Intel multicore/multithread determination.
12 #include "../x86info.h"
16 * fls - find last (most-significant) bit set
17 * @x: the word to search
19 * This is defined the same way as ffs.
20 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
29 if (!(x & 0xffff0000u)) {
33 if (!(x & 0xff000000u)) {
37 if (!(x & 0xf0000000u)) {
41 if (!(x & 0xc0000000u)) {
45 if (!(x & 0x80000000u)) {
52 static int get_count_order(unsigned int count)
56 order = fls(count) - 1;
57 if (count & (count - 1))
62 static int intel_num_cpu_cores(struct cpudata *cpu)
64 unsigned int eax, ebx, ecx, edx;
66 if (cpu->cpuid_level < 4)
69 /* Intel has a non-standard dependency on %ecx for this CPUID level. */
70 cpuid_count(cpu->number, 4, 0, &eax, &ebx, &ecx, &edx);
72 return (eax >> 26) + 1;
77 static int phys_pkg_id(int cpuid_apic, int index_msb)
79 return cpuid_apic >> index_msb;
82 void get_intel_topology(struct cpudata *cpu)
84 unsigned int eax, ebx, ecx, edx;
85 unsigned int index_msb, core_bits;
87 if (!(cpu->flags_edx & X86_FEATURE_HT))
90 if (cpu_has(cpu, X86_FEATURE_CMP_LEGACY))
93 if (cpu_has(cpu, X86_FEATURE_XTOPOLOGY))
98 cpuid(cpu->number, 1, &eax, &ebx, &ecx, &edx);
99 cpu->num_siblings = (ebx & 0xff0000) >> 16;
101 if (cpu->num_siblings == 1) {
103 printf("Hyper-Threading is disabled\n");
107 if (cpu->num_siblings <= 1)
110 index_msb = get_count_order(cpu->num_siblings);
111 cpu->initial_apicid = (cpuid_ebx(cpu->number, 1) >> 24) & 0xFF;
112 cpu->phys_proc_id = phys_pkg_id(cpu->initial_apicid, index_msb);
114 cpu->x86_max_cores = intel_num_cpu_cores(cpu);
115 cpu->num_siblings = cpu->num_siblings / cpu->x86_max_cores;
117 index_msb = get_count_order(cpu->num_siblings);
119 core_bits = get_count_order(cpu->x86_max_cores);
121 cpu->cpu_core_id = phys_pkg_id(cpu->apicid, index_msb) &
122 ((1 << core_bits) - 1);
125 if ((cpu->x86_max_cores * cpu->num_siblings) > 1) {
126 printf("%s:\n", __func__);
127 printf("\tSiblings: %d\n", cpu->num_siblings);
128 printf("\tPhysical Processor ID: %d\n", cpu->phys_proc_id);
129 printf("\tProcessor Core ID: %d\n", cpu->cpu_core_id);