forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-11 297b60346df8beafee954a0fd7c2d64f33f3b9bc
kernel/arch/x86/kernel/cpu/topology.c
....@@ -7,50 +7,85 @@
77
88 #include <linux/cpu.h>
99 #include <asm/apic.h>
10
-#include <asm/pat.h>
10
+#include <asm/memtype.h>
1111 #include <asm/processor.h>
12
+
13
+#include "cpu.h"
1214
1315 /* leaf 0xb SMT level */
1416 #define SMT_LEVEL 0
1517
16
-/* leaf 0xb sub-leaf types */
18
+/* extended topology sub-leaf types */
1719 #define INVALID_TYPE 0
1820 #define SMT_TYPE 1
1921 #define CORE_TYPE 2
22
+#define DIE_TYPE 5
2023
2124 #define LEAFB_SUBTYPE(ecx) (((ecx) >> 8) & 0xff)
2225 #define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f)
2326 #define LEVEL_MAX_SIBLINGS(ebx) ((ebx) & 0xffff)
2427
28
+unsigned int __max_die_per_package __read_mostly = 1;
29
+EXPORT_SYMBOL(__max_die_per_package);
30
+
31
+#ifdef CONFIG_SMP
32
+/*
33
+ * Check if given CPUID extended toplogy "leaf" is implemented
34
+ */
35
+static int check_extended_topology_leaf(int leaf)
36
+{
37
+ unsigned int eax, ebx, ecx, edx;
38
+
39
+ cpuid_count(leaf, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
40
+
41
+ if (ebx == 0 || (LEAFB_SUBTYPE(ecx) != SMT_TYPE))
42
+ return -1;
43
+
44
+ return 0;
45
+}
46
+/*
47
+ * Return best CPUID Extended Toplogy Leaf supported
48
+ */
49
+static int detect_extended_topology_leaf(struct cpuinfo_x86 *c)
50
+{
51
+ if (c->cpuid_level >= 0x1f) {
52
+ if (check_extended_topology_leaf(0x1f) == 0)
53
+ return 0x1f;
54
+ }
55
+
56
+ if (c->cpuid_level >= 0xb) {
57
+ if (check_extended_topology_leaf(0xb) == 0)
58
+ return 0xb;
59
+ }
60
+
61
+ return -1;
62
+}
63
+#endif
64
+
2565 int detect_extended_topology_early(struct cpuinfo_x86 *c)
2666 {
2767 #ifdef CONFIG_SMP
2868 unsigned int eax, ebx, ecx, edx;
69
+ int leaf;
2970
30
- if (c->cpuid_level < 0xb)
31
- return -1;
32
-
33
- cpuid_count(0xb, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
34
-
35
- /*
36
- * check if the cpuid leaf 0xb is actually implemented.
37
- */
38
- if (ebx == 0 || (LEAFB_SUBTYPE(ecx) != SMT_TYPE))
71
+ leaf = detect_extended_topology_leaf(c);
72
+ if (leaf < 0)
3973 return -1;
4074
4175 set_cpu_cap(c, X86_FEATURE_XTOPOLOGY);
4276
77
+ cpuid_count(leaf, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
4378 /*
4479 * initial apic id, which also represents 32-bit extended x2apic id.
4580 */
4681 c->initial_apicid = edx;
47
- smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
82
+ smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx));
4883 #endif
4984 return 0;
5085 }
5186
5287 /*
53
- * Check for extended topology enumeration cpuid leaf 0xb and if it
88
+ * Check for extended topology enumeration cpuid leaf, and if it
5489 * exists, use it for populating initial_apicid and cpu topology
5590 * detection.
5691 */
....@@ -58,22 +93,31 @@
5893 {
5994 #ifdef CONFIG_SMP
6095 unsigned int eax, ebx, ecx, edx, sub_index;
61
- unsigned int ht_mask_width, core_plus_mask_width;
96
+ unsigned int ht_mask_width, core_plus_mask_width, die_plus_mask_width;
6297 unsigned int core_select_mask, core_level_siblings;
98
+ unsigned int die_select_mask, die_level_siblings;
99
+ unsigned int pkg_mask_width;
100
+ bool die_level_present = false;
101
+ int leaf;
63102
64
- if (detect_extended_topology_early(c) < 0)
103
+ leaf = detect_extended_topology_leaf(c);
104
+ if (leaf < 0)
65105 return -1;
66106
67107 /*
68108 * Populate HT related information from sub-leaf level 0.
69109 */
70
- cpuid_count(0xb, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
71
- core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
110
+ cpuid_count(leaf, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
111
+ c->initial_apicid = edx;
112
+ core_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
113
+ smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx));
72114 core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
115
+ die_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
116
+ pkg_mask_width = die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
73117
74118 sub_index = 1;
75
- do {
76
- cpuid_count(0xb, sub_index, &eax, &ebx, &ecx, &edx);
119
+ while (true) {
120
+ cpuid_count(leaf, sub_index, &eax, &ebx, &ecx, &edx);
77121
78122 /*
79123 * Check for the Core type in the implemented sub leaves.
....@@ -81,23 +125,44 @@
81125 if (LEAFB_SUBTYPE(ecx) == CORE_TYPE) {
82126 core_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
83127 core_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
84
- break;
128
+ die_level_siblings = core_level_siblings;
129
+ die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
130
+ }
131
+ if (LEAFB_SUBTYPE(ecx) == DIE_TYPE) {
132
+ die_level_present = true;
133
+ die_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
134
+ die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
85135 }
86136
137
+ if (LEAFB_SUBTYPE(ecx) != INVALID_TYPE)
138
+ pkg_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
139
+ else
140
+ break;
141
+
87142 sub_index++;
88
- } while (LEAFB_SUBTYPE(ecx) != INVALID_TYPE);
143
+ }
89144
90
- core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width;
145
+ core_select_mask = (~(-1 << pkg_mask_width)) >> ht_mask_width;
146
+ die_select_mask = (~(-1 << die_plus_mask_width)) >>
147
+ core_plus_mask_width;
91148
92
- c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, ht_mask_width)
93
- & core_select_mask;
94
- c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, core_plus_mask_width);
149
+ c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid,
150
+ ht_mask_width) & core_select_mask;
151
+
152
+ if (die_level_present) {
153
+ c->cpu_die_id = apic->phys_pkg_id(c->initial_apicid,
154
+ core_plus_mask_width) & die_select_mask;
155
+ }
156
+
157
+ c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid,
158
+ pkg_mask_width);
95159 /*
96160 * Reinit the apicid, now that we have extended initial_apicid.
97161 */
98162 c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
99163
100164 c->x86_max_cores = (core_level_siblings / smp_num_siblings);
165
+ __max_die_per_package = (die_level_siblings / core_level_siblings);
101166 #endif
102167 return 0;
103168 }