1 /*
2 * Licensed under the terms of the GNU GPL License version 2.
3 *
4 * Intel multicore/multithread determination.
5 */
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <strings.h>
10 #include <x86info.h>
11 #include "intel.h"
12
13 /**
14 * tp_fls - find last (most-significant) bit set
15 * @x: the word to search
16 *
17 * This is defined the same way as ffs.
18 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
19 */
20
tp_fls(int x)21 static int tp_fls(int x)
22 {
23 return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
24 }
25
get_count_order(unsigned int count)26 static int get_count_order(unsigned int count)
27 {
28 int order;
29
30 order = tp_fls(count) - 1;
31 if (count & (count - 1))
32 order++;
33 return order;
34 }
35
intel_num_cpu_cores(struct cpudata * cpu)36 static int intel_num_cpu_cores(struct cpudata *cpu)
37 {
38 unsigned int eax, ebx, ecx, edx;
39
40 if (cpu->cpuid_level < 4)
41 return 1;
42
43 /* intel.has a non-standard dependency on %ecx for this CPUID level. */
44 cpuid_count(cpu->number, 4, 0, &eax, &ebx, &ecx, &edx);
45 if (eax & 0x1f)
46 return (eax >> 26) + 1;
47 else
48 return 1;
49 }
50
phys_pkg_id(int cpuid_apic,int index_msb)51 static int phys_pkg_id(int cpuid_apic, int index_msb)
52 {
53 return cpuid_apic >> index_msb;
54 }
55
get_intel_topology(struct cpudata * cpu)56 void get_intel_topology(struct cpudata *cpu)
57 {
58 unsigned int eax, ebx, ecx, edx;
59 unsigned int index_msb, core_bits;
60
61 if (!(cpu->flags_edx & X86_FEATURE_HT))
62 return;
63 /*
64 if (cpu_has(cpu, X86_FEATURE_CMP_LEGACY))
65 goto out;
66
67 if (cpu_has(cpu, X86_FEATURE_XTOPOLOGY))
68 return;
69 */
70
71
72 cpuid(cpu->number, 1, &eax, &ebx, &ecx, &edx);
73 cpu->num_siblings = (ebx & 0xff0000) >> 16;
74
75 if (cpu->num_siblings == 1) {
76 if (debug)
77 printf("Hyper-Threading is disabled\n");
78 goto out;
79 }
80
81 if (cpu->num_siblings <= 1)
82 goto out;
83
84 index_msb = get_count_order(cpu->num_siblings);
85 cpu->initial_apicid = (cpuid_ebx(cpu->number, 1) >> 24) & 0xFF;
86 cpu->phys_proc_id = phys_pkg_id(cpu->initial_apicid, index_msb);
87
88 cpu->x86_max_cores = intel_num_cpu_cores(cpu);
89 cpu->num_siblings = cpu->num_siblings / cpu->x86_max_cores;
90
91 index_msb = get_count_order(cpu->num_siblings);
92
93 core_bits = get_count_order(cpu->x86_max_cores);
94
95 cpu->cpu_core_id = phys_pkg_id(cpu->apicid, index_msb) &
96 ((1 << core_bits) - 1);
97
98 if (debug == 1) {
99 if ((cpu->x86_max_cores * cpu->num_siblings) > 1) {
100 printf("%s:\n", __func__);
101 printf("\tSiblings: %d\n", cpu->num_siblings);
102 printf("\tPhysical Processor ID: %d\n", cpu->phys_proc_id);
103 printf("\tProcessor Core ID: %d\n", cpu->cpu_core_id);
104 }
105 }
106 out:
107 return;
108 }
109