1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
6 #include <cpu/x86/name.h>
9 static int smbios_cpu_vendor(u8
*start
)
11 if (cpu_have_cpuid()) {
13 const struct cpuid_result res
= cpuid(0);
18 return smbios_add_string(start
, (const char *)tmp
);
20 return smbios_add_string(start
, "Unknown");
24 static int smbios_processor_name(u8
*start
)
27 const char *str
= "Unknown Processor Name";
28 if (cpu_have_cpuid()) {
30 struct cpuid_result res
;
31 if (cpu_cpuid_extended_level() >= 0x80000004) {
33 for (i
= 0; i
< 3; i
++) {
34 res
= cpuid(0x80000002 + i
);
41 str
= (const char *)tmp
;
44 return smbios_add_string(start
, str
);
47 static int get_socket_type(void)
49 if (CONFIG(CPU_INTEL_SLOT_1
))
50 return PROCESSOR_UPGRADE_SLOT_1
;
51 if (CONFIG(CPU_INTEL_SOCKET_MPGA604
))
52 return PROCESSOR_UPGRADE_SOCKET_MPGA604
;
53 if (CONFIG(CPU_INTEL_SOCKET_LGA775
))
54 return PROCESSOR_UPGRADE_SOCKET_LGA775
;
55 if (CONFIG(CPU_INTEL_SOCKET_LGA1700
))
56 return PROCESSOR_UPGRADE_SOCKET_LGA1700
;
57 if (CONFIG(CPU_INTEL_SOCKET_LGA4189
))
58 return PROCESSOR_UPGRADE_SOCKET_LGA4189
;
59 if (CONFIG(CPU_INTEL_SOCKET_LGA4677
))
60 return PROCESSOR_UPGRADE_SOCKET_LGA4677
;
61 if (CONFIG(CPU_INTEL_SOCKET_LGA3647_1
))
62 return PROCESSOR_UPGRADE_SOCKET_LGA3647_1
;
63 if (CONFIG(CPU_INTEL_SOCKET_OTHER
))
64 return PROCESSOR_UPGRADE_OTHER
;
66 return PROCESSOR_UPGRADE_UNKNOWN
;
69 unsigned int __weak
smbios_processor_family(struct cpuid_result res
)
71 return (res
.eax
> 0) ? SMBIOS_PROCESSOR_FAMILY_PENTIUM_PRO
: SMBIOS_PROCESSOR_FAMILY_INTEL486
;
74 static size_t get_number_of_caches(size_t max_logical_cpus_sharing_cache
)
76 size_t number_of_cpus_per_package
= 0;
77 size_t max_logical_cpus_per_package
= 0;
78 struct cpuid_result res
;
80 if (!cpu_have_cpuid())
85 max_logical_cpus_per_package
= (res
.ebx
>> 16) & 0xff;
87 /* Check if it's last level cache */
88 if (max_logical_cpus_sharing_cache
== max_logical_cpus_per_package
)
91 if (cpuid_get_max_func() >= 0xb) {
92 res
= cpuid_ext(0xb, 1);
93 number_of_cpus_per_package
= res
.ebx
& 0xff;
95 number_of_cpus_per_package
= max_logical_cpus_per_package
;
98 return number_of_cpus_per_package
/ max_logical_cpus_sharing_cache
;
101 #define MAX_CPUS_ENABLED (CONFIG_MAX_CPUS > 0xff ? 0xff : CONFIG_MAX_CPUS)
103 int smbios_write_type4(unsigned long *current
, int handle
)
105 unsigned int cpu_voltage
;
106 struct cpuid_result res
;
107 uint16_t characteristics
= 0;
108 static unsigned int cnt
= 0;
111 /* Provide sane defaults even for CPU without CPUID */
112 res
.eax
= res
.edx
= 0;
115 if (cpu_have_cpuid())
118 struct smbios_type4
*t
= smbios_carve_table(*current
, SMBIOS_PROCESSOR_INFORMATION
,
121 snprintf(buf
, sizeof(buf
), "CPU%d", cnt
++);
122 t
->socket_designation
= smbios_add_string(t
->eos
, buf
);
124 t
->processor_id
[0] = res
.eax
;
125 t
->processor_id
[1] = res
.edx
;
126 t
->processor_manufacturer
= smbios_cpu_vendor(t
->eos
);
127 t
->processor_version
= smbios_processor_name(t
->eos
);
128 t
->processor_family
= smbios_processor_family(res
);
129 t
->processor_type
= SMBIOS_PROCESSOR_TYPE_CENTRAL
;
131 * If CPUID leaf 11 is available, calculate "core count" by dividing
132 * SMT_ID (logical processors in a core) by Core_ID (number of cores).
133 * This seems to be the way to arrive to a number of cores mentioned on
136 if (cpu_have_cpuid() && cpuid_get_max_func() >= 0xb) {
137 uint32_t leaf_b_cores
= 0, leaf_b_threads
= 0;
138 res
= cpuid_ext(0xb, 1);
139 leaf_b_cores
= res
.ebx
;
140 res
= cpuid_ext(0xb, 0);
141 leaf_b_threads
= res
.ebx
;
142 /* if hyperthreading is not available, pretend this is 1 */
143 if (leaf_b_threads
== 0)
146 t
->core_count2
= leaf_b_cores
/ leaf_b_threads
;
147 t
->core_count
= t
->core_count2
> 0xff ? 0xff : t
->core_count2
;
148 t
->thread_count2
= leaf_b_cores
;
149 t
->thread_count
= t
->thread_count2
> 0xff ? 0xff : t
->thread_count2
;
151 t
->core_count
= (res
.ebx
>> 16) & 0xff;
152 t
->core_count2
= t
->core_count
;
153 t
->thread_count2
= t
->core_count2
;
154 t
->thread_count
= t
->thread_count2
;
156 /* Assume we enable all the cores always, capped only by MAX_CPUS */
157 t
->core_enabled
= MIN(t
->core_count
, MAX_CPUS_ENABLED
);
158 t
->core_enabled2
= MIN(t
->core_count2
, CONFIG_MAX_CPUS
);
159 t
->l1_cache_handle
= 0xffff;
160 t
->l2_cache_handle
= 0xffff;
161 t
->l3_cache_handle
= 0xffff;
162 t
->serial_number
= smbios_add_string(t
->eos
, smbios_processor_serial_number());
163 t
->status
= SMBIOS_PROCESSOR_STATUS_CPU_ENABLED
| SMBIOS_PROCESSOR_STATUS_POPULATED
;
164 t
->processor_upgrade
= get_socket_type();
165 if (cpu_have_cpuid() && cpuid_get_max_func() >= 0x16) {
166 t
->current_speed
= cpuid_eax(0x16); /* base frequency */
167 t
->external_clock
= cpuid_ecx(0x16);
169 t
->current_speed
= smbios_cpu_get_current_speed_mhz();
170 t
->external_clock
= smbios_processor_external_clock();
173 /* This field identifies a capability for the system, not the processor itself. */
174 t
->max_speed
= smbios_cpu_get_max_speed_mhz();
176 if (cpu_have_cpuid()) {
179 if ((res
.ecx
) & BIT(5))
180 characteristics
|= BIT(6); /* BIT6: Enhanced Virtualization */
182 if ((res
.edx
) & BIT(28))
183 characteristics
|= BIT(4); /* BIT4: Hardware Thread */
185 if (cpu_cpuid_extended_level() >= 0x80000001) {
186 res
= cpuid(0x80000001);
188 if ((res
.edx
) & BIT(20))
189 characteristics
|= BIT(5); /* BIT5: Execute Protection */
192 t
->processor_characteristics
= characteristics
| smbios_processor_characteristics();
193 cpu_voltage
= smbios_cpu_get_voltage();
195 t
->voltage
= 0x80 | cpu_voltage
;
197 const int len
= smbios_full_table_len(&t
->header
, t
->eos
);
203 * Parse the "Deterministic Cache Parameters" as provided by Intel in
204 * leaf 4 or AMD in extended leaf 0x8000001d.
206 * @param current Pointer to memory address to write the tables to
207 * @param handle Pointer to handle for the tables
208 * @param max_struct_size Pointer to maximum struct size
209 * @param type4 Pointer to SMBIOS type 4 structure
211 int smbios_write_type7_cache_parameters(unsigned long *current
,
213 int *max_struct_size
,
214 struct smbios_type4
*type4
)
216 unsigned int cnt
= CACHE_L1D
;
219 if (!cpu_have_cpuid())
222 enum cpu_type dcache_cpuid
= cpu_check_deterministic_cache_cpuid_supported();
223 if (dcache_cpuid
== CPUID_TYPE_INVALID
|| dcache_cpuid
== CPUID_COMMAND_UNSUPPORTED
) {
224 printk(BIOS_DEBUG
, "SMBIOS: Unknown CPU or CPU doesn't support Deterministic "
225 "Cache CPUID leaf\n");
230 enum smbios_cache_associativity associativity
;
231 enum smbios_cache_type type
;
232 struct cpu_cache_info info
;
233 if (!fill_cpu_cache_info(cnt
++, &info
))
236 const u8 cache_type
= info
.type
;
237 const u8 level
= info
.level
;
238 const size_t assoc
= info
.num_ways
;
239 const size_t cache_share
= info
.num_cores_shared
;
240 const size_t cache_size
= info
.size
* get_number_of_caches(cache_share
);
243 /* No more caches in the system */
246 switch (cache_type
) {
248 type
= SMBIOS_CACHE_TYPE_DATA
;
251 type
= SMBIOS_CACHE_TYPE_INSTRUCTION
;
254 type
= SMBIOS_CACHE_TYPE_UNIFIED
;
257 type
= SMBIOS_CACHE_TYPE_UNKNOWN
;
261 if (info
.fully_associative
)
262 associativity
= SMBIOS_CACHE_ASSOCIATIVITY_FULL
;
264 associativity
= smbios_cache_associativity(assoc
);
266 const int h
= (*handle
)++;
268 update_max(len
, *max_struct_size
, smbios_write_type7(current
, h
,
269 level
, smbios_cache_sram_type(), associativity
,
270 type
, cache_size
, cache_size
));
275 type4
->l1_cache_handle
= h
;
278 type4
->l2_cache_handle
= h
;
281 type4
->l3_cache_handle
= h
;