forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 072de836f53be56a70cecf70b43ae43b7ce17376
kernel/arch/x86/kernel/cpu/topology.c
....@@ -7,39 +7,74 @@
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 */
....@@ -50,7 +85,7 @@
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,30 @@
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);
110
+ cpuid_count(leaf, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
111
+ c->initial_apicid = edx;
71112 core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
72113 core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
114
+ die_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
115
+ pkg_mask_width = die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
73116
74117 sub_index = 1;
75
- do {
76
- cpuid_count(0xb, sub_index, &eax, &ebx, &ecx, &edx);
118
+ while (true) {
119
+ cpuid_count(leaf, sub_index, &eax, &ebx, &ecx, &edx);
77120
78121 /*
79122 * Check for the Core type in the implemented sub leaves.
....@@ -81,23 +124,44 @@
81124 if (LEAFB_SUBTYPE(ecx) == CORE_TYPE) {
82125 core_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
83126 core_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
84
- break;
127
+ die_level_siblings = core_level_siblings;
128
+ die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
129
+ }
130
+ if (LEAFB_SUBTYPE(ecx) == DIE_TYPE) {
131
+ die_level_present = true;
132
+ die_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
133
+ die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
85134 }
86135
136
+ if (LEAFB_SUBTYPE(ecx) != INVALID_TYPE)
137
+ pkg_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
138
+ else
139
+ break;
140
+
87141 sub_index++;
88
- } while (LEAFB_SUBTYPE(ecx) != INVALID_TYPE);
142
+ }
89143
90
- core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width;
144
+ core_select_mask = (~(-1 << pkg_mask_width)) >> ht_mask_width;
145
+ die_select_mask = (~(-1 << die_plus_mask_width)) >>
146
+ core_plus_mask_width;
91147
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);
148
+ c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid,
149
+ ht_mask_width) & core_select_mask;
150
+
151
+ if (die_level_present) {
152
+ c->cpu_die_id = apic->phys_pkg_id(c->initial_apicid,
153
+ core_plus_mask_width) & die_select_mask;
154
+ }
155
+
156
+ c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid,
157
+ pkg_mask_width);
95158 /*
96159 * Reinit the apicid, now that we have extended initial_apicid.
97160 */
98161 c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
99162
100163 c->x86_max_cores = (core_level_siblings / smp_num_siblings);
164
+ __max_die_per_package = (die_level_siblings / core_level_siblings);
101165 #endif
102166 return 0;
103167 }