xref: /illumos-gate/usr/src/test/util-tests/tests/smbios/smbios_test_proc.c (revision b1529121add3ff25fc7b58196363a5439c0f6b67)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2024 Oxide Computer Company
14  */
15 
16 /*
17  * SMBIOS processor tests. We build three main processors:
18  *
19  *   1. An early SMBIOS one based on 2.5 that has the initial core count and
20  *     related. A modern client should see the current values.
21  *   2. One based on SMBIOS 3.6 that has different values for the processor
22  *     counts to verify we use the newer fields both for cores counts and also
23  *     the processor family. Most of those were 3.x based. We use 3.6 so we can
24  *     get the newer threads enabled field. A pre-3.x client should not see the
25  *     same core values as something 3.0+.
26  *   3. One based on SMBIOS 3.8 that has the a socket type string listed.
27  */
28 
29 #include <stdlib.h>
30 #include "smbios_test.h"
31 
32 /*
33  * Older revisions lengths per the SMBIOS spec.
34  */
35 #define	SMBIOS_PROC_LEN_25	0x28
36 #define	SMBIOS_PROC_LEN_36	0x33
37 
38 static const char *smbios_proc_sock = "Gideon";
39 static const char *smbios_proc_mfg = "Harrow";
40 static const char *smbios_proc_vers = "Nona";
41 static const char *smbios_proc_serial = "Alecto";
42 static const char *smbios_proc_asset = "Matthias";
43 static const char *smbios_proc_pn = "Ortus";
44 static const char *smbios_proc_st = "Soul";
45 static const uint64_t smbios_proc_cpuid = 0x09099090;
46 
47 /*
48  * Construct a processor that we'll use throughout our tests. This fills in most
49  * of the fields. Some bits may override it and others will only copy a smaller
50  * length.
51  */
52 static void
53 smbios_test_proc_fill(smb_processor_t *proc)
54 {
55 	proc->smbpr_hdr.smbh_type = SMB_TYPE_PROCESSOR;
56 	proc->smbpr_hdr.smbh_len = sizeof (smb_processor_t);
57 	proc->smbpr_socket = 1;
58 	proc->smbpr_type = SMB_PRT_CENTRAL;
59 	proc->smbpr_family = SMB_PRF_HOBBIT;
60 	proc->smbpr_manufacturer = 2;
61 	proc->smbpr_cpuid = htole64(smbios_proc_cpuid);
62 	proc->smbpr_version = 3;
63 	proc->smbpr_voltage = 0x8b;
64 	proc->smbpr_clkspeed = htole16(0x1234);
65 	proc->smbpr_maxspeed = htole16(0x5678);
66 	proc->smbpr_curspeed = htole16(0x3210);
67 	proc->smbpr_status = SMB_PRS_ENABLED | 0x40;
68 	proc->smbpr_upgrade = SMB_PRU_SP3;
69 	proc->smbpr_l1cache = htole16(0x11ca);
70 	proc->smbpr_l2cache = htole16(0x12ca);
71 	proc->smbpr_l3cache = htole16(0x13ca);
72 	proc->smbpr_serial = 4;
73 	proc->smbpr_asset = 5;
74 	proc->smbpr_part = 6;
75 	proc->smbpr_corecount = 0x77;
76 	proc->smbpr_coresenabled = 0x3;
77 	proc->smbpr_threadcount = 0x19;
78 	proc->smbpr_cflags = htole16(SMB_PRC_64BIT | SMB_PRC_NX);
79 	proc->smbpr_family2 = htole16(0);
80 	proc->smbpr_corecount2 = htole16(0);
81 	proc->smbpr_coresenabled2 = htole16(0);
82 	proc->smbpr_threadcount2 = htole16(0);
83 	proc->smbpr_threaden = htole16(11);
84 }
85 
86 boolean_t
87 smbios_test_proc_mktable_25(smbios_test_table_t *table)
88 {
89 	smb_processor_t proc;
90 
91 	smbios_test_proc_fill(&proc);
92 	proc.smbpr_hdr.smbh_len = SMBIOS_PROC_LEN_25;
93 	(void) smbios_test_table_append(table, &proc, SMBIOS_PROC_LEN_25);
94 	smbios_test_table_append_string(table, smbios_proc_sock);
95 	smbios_test_table_append_string(table, smbios_proc_mfg);
96 	smbios_test_table_append_string(table, smbios_proc_vers);
97 	smbios_test_table_append_string(table, smbios_proc_serial);
98 	smbios_test_table_append_string(table, smbios_proc_asset);
99 	smbios_test_table_append_string(table, smbios_proc_pn);
100 	smbios_test_table_str_fini(table);
101 	smbios_test_table_append_eot(table);
102 
103 	return (B_TRUE);
104 }
105 
106 /*
107  * This is a 3.0 based table. The biggest difference here is that this table
108  * fills in the values that allows us to use family 2, core count 2, etc.
109  * fields.
110  */
111 boolean_t
112 smbios_test_proc_mktable_36(smbios_test_table_t *table)
113 {
114 	smb_processor_t proc;
115 
116 	smbios_test_proc_fill(&proc);
117 	proc.smbpr_hdr.smbh_len = sizeof (smb_processor_t);
118 	proc.smbpr_family = 0xfe;
119 	proc.smbpr_family2 = htole16(SMB_PRF_RV64);
120 	proc.smbpr_corecount = 0xff;
121 	proc.smbpr_corecount2 = htole16(0x171);
122 	proc.smbpr_coresenabled = 0xff;
123 	proc.smbpr_coresenabled2 = htole16(0x717);
124 	proc.smbpr_threadcount = 0xff;
125 	proc.smbpr_threadcount2 = htole16(0x5445);
126 	proc.smbpr_threaden = htole16(0x2232);
127 	(void) smbios_test_table_append(table, &proc, SMBIOS_PROC_LEN_36);
128 	smbios_test_table_append_string(table, smbios_proc_sock);
129 	smbios_test_table_append_string(table, smbios_proc_mfg);
130 	smbios_test_table_append_string(table, smbios_proc_vers);
131 	smbios_test_table_append_string(table, smbios_proc_serial);
132 	smbios_test_table_append_string(table, smbios_proc_asset);
133 	smbios_test_table_append_string(table, smbios_proc_pn);
134 	smbios_test_table_str_fini(table);
135 	smbios_test_table_append_eot(table);
136 
137 	return (B_TRUE);
138 }
139 
140 /*
141  * This is basically the 3.6 table, but we also fill in the socket type string.
142  */
143 boolean_t
144 smbios_test_proc_mktable_38(smbios_test_table_t *table)
145 {
146 	smb_processor_t proc;
147 
148 	smbios_test_proc_fill(&proc);
149 	proc.smbpr_hdr.smbh_len = sizeof (smb_processor_t);
150 	proc.smbpr_family = 0xfe;
151 	proc.smbpr_family2 = htole16(SMB_PRF_RV64);
152 	proc.smbpr_corecount = 0xff;
153 	proc.smbpr_corecount2 = htole16(0x171);
154 	proc.smbpr_coresenabled = 0xff;
155 	proc.smbpr_coresenabled2 = htole16(0x717);
156 	proc.smbpr_threadcount = 0xff;
157 	proc.smbpr_threadcount2 = htole16(0x5445);
158 	proc.smbpr_threaden = htole16(0x2232);
159 	proc.smbpr_socktype = 7;
160 	(void) smbios_test_table_append(table, &proc, sizeof (smb_processor_t));
161 	smbios_test_table_append_string(table, smbios_proc_sock);
162 	smbios_test_table_append_string(table, smbios_proc_mfg);
163 	smbios_test_table_append_string(table, smbios_proc_vers);
164 	smbios_test_table_append_string(table, smbios_proc_serial);
165 	smbios_test_table_append_string(table, smbios_proc_asset);
166 	smbios_test_table_append_string(table, smbios_proc_pn);
167 	smbios_test_table_append_string(table, smbios_proc_st);
168 	smbios_test_table_str_fini(table);
169 	smbios_test_table_append_eot(table);
170 
171 	return (B_TRUE);
172 }
173 
174 /*
175  * Verify common fields that'll be true across all tests. Verifying core,
176  * thread, and related is left to higher level logic as those are changed up
177  * between tests to cover the extensions.
178  */
179 static boolean_t
180 smbios_test_proc_verify_common(smbios_hdl_t *hdl, smbios_struct_t *sp,
181     smbios_processor_t *proc)
182 {
183 	boolean_t ret = B_TRUE;
184 	smbios_info_t info;
185 
186 	if (proc->smbp_cpuid != smbios_proc_cpuid) {
187 		warnx("processor state mismatch, found unexpected cpuid: 0x%"
188 		    PRIx64, proc->smbp_cpuid);
189 		ret = B_FALSE;
190 	}
191 
192 	if (SMB_PRV_LEGACY(proc->smbp_voltage)) {
193 		warnx("processor state mismatch, found legacy foltage: 0x%x",
194 		    proc->smbp_voltage);
195 		ret = B_FALSE;
196 	}
197 
198 	if (SMB_PRV_VOLTAGE(proc->smbp_voltage) != 0xb) {
199 		warnx("processor state mismatch, found legacy foltage: 0x%x",
200 		    SMB_PRV_VOLTAGE(proc->smbp_voltage));
201 		ret = B_FALSE;
202 	}
203 
204 	if (proc->smbp_status != (SMB_PRS_ENABLED | 0x40)) {
205 		warnx("processor state mismatch, found unexpected processor "
206 		    "status: 0x%x", proc->smbp_status);
207 		ret = B_FALSE;
208 	}
209 
210 	if (proc->smbp_upgrade != SMB_PRU_SP3) {
211 		warnx("processor state mismatch, found unexpected processor "
212 		    "socket: 0x%x", proc->smbp_upgrade);
213 		ret = B_FALSE;
214 	}
215 
216 	if (proc->smbp_clkspeed != 0x1234) {
217 		warnx("processor state mismatch, found unexpected clock speed: "
218 		    "0x%x", proc->smbp_clkspeed);
219 		ret = B_FALSE;
220 	}
221 
222 	if (proc->smbp_maxspeed != 0x5678) {
223 		warnx("processor state mismatch, found unexpected max speed: "
224 		    "0x%x", proc->smbp_maxspeed);
225 		ret = B_FALSE;
226 	}
227 
228 	if (proc->smbp_curspeed != 0x3210) {
229 		warnx("processor state mismatch, found unexpected current "
230 		    "speed: 0x%x", proc->smbp_curspeed);
231 		ret = B_FALSE;
232 	}
233 
234 
235 	if (proc->smbp_l1cache != 0x11ca) {
236 		warnx("processor state mismatch, found unexpected l1 cache id: "
237 		    "0x%" _PRIxID, proc->smbp_l1cache);
238 		ret = B_FALSE;
239 	}
240 
241 
242 	if (proc->smbp_l2cache != 0x12ca) {
243 		warnx("processor state mismatch, found unexpected l2 cache id: "
244 		    "0x%" _PRIxID, proc->smbp_l2cache);
245 		ret = B_FALSE;
246 	}
247 
248 	if (proc->smbp_l3cache != 0x13ca) {
249 		warnx("processor state mismatch, found unexpected l3 cache id: "
250 		    "0x%" _PRIxID, proc->smbp_l3cache);
251 		ret = B_FALSE;
252 	}
253 
254 	if (proc->smbp_cflags != (SMB_PRC_64BIT | SMB_PRC_NX)) {
255 		warnx("processor state mismatch, found unexpected "
256 		    "characteristic flags: 0x%x", proc->smbp_cflags);
257 		ret = B_FALSE;
258 	}
259 
260 	if (smbios_info_common(hdl, sp->smbstr_id, &info) != 0) {
261 		warnx("failed to get common chassis info: %s",
262 		    smbios_errmsg(smbios_errno(hdl)));
263 		return (B_FALSE);
264 	}
265 
266 	if (strcmp(info.smbi_manufacturer, smbios_proc_mfg) != 0) {
267 		warnx("processor state mismatch, found unexpected mfg: %s",
268 		    info.smbi_manufacturer);
269 		ret = B_FALSE;
270 	}
271 
272 
273 	if (strcmp(info.smbi_version, smbios_proc_vers) != 0) {
274 		warnx("processor state mismatch, found unexpected vers: %s",
275 		    info.smbi_version);
276 		ret = B_FALSE;
277 	}
278 
279 	if (strcmp(info.smbi_serial, smbios_proc_serial) != 0) {
280 		warnx("processor state mismatch, found unexpected serial: %s",
281 		    info.smbi_serial);
282 		ret = B_FALSE;
283 	}
284 
285 	if (strcmp(info.smbi_asset, smbios_proc_asset) != 0) {
286 		warnx("processor state mismatch, found unexpected asset: %s",
287 		    info.smbi_asset);
288 		ret = B_FALSE;
289 	}
290 
291 	if (strcmp(info.smbi_location, smbios_proc_sock) != 0) {
292 		warnx("processor state mismatch, found unexpected sock: %s",
293 		    info.smbi_location);
294 		ret = B_FALSE;
295 	}
296 
297 	if (strcmp(info.smbi_part, smbios_proc_pn) != 0) {
298 		warnx("processor state mismatch, found unexpected pn: %s",
299 		    info.smbi_part);
300 		ret = B_FALSE;
301 	}
302 
303 	return (ret);
304 }
305 
306 boolean_t
307 smbios_test_proc_verify_25(smbios_hdl_t *hdl)
308 {
309 	boolean_t ret = B_TRUE;
310 	smbios_struct_t sp;
311 	smbios_processor_t proc;
312 
313 	if (smbios_lookup_type(hdl, SMB_TYPE_PROCESSOR, &sp) == -1) {
314 		warnx("failed to lookup SMBIOS processor: %s",
315 		    smbios_errmsg(smbios_errno(hdl)));
316 		return (B_FALSE);
317 	}
318 
319 	if (smbios_info_processor(hdl, sp.smbstr_id, &proc) == -1) {
320 		warnx("failed to get processor: %s",
321 		    smbios_errmsg(smbios_errno(hdl)));
322 		return (B_FALSE);
323 	}
324 
325 	if (!smbios_test_proc_verify_common(hdl, &sp, &proc)) {
326 		ret = B_FALSE;
327 	}
328 
329 	if (proc.smbp_family != SMB_PRF_HOBBIT) {
330 		warnx("processor state mismatch, found unexpected family: 0x%x",
331 		    proc.smbp_family);
332 		ret = B_FALSE;
333 	}
334 
335 	if (proc.smbp_corecount != 0x77) {
336 		warnx("processor state mismatch, found unexpected core count: "
337 		    "0x%x",  proc.smbp_corecount);
338 		ret = B_FALSE;
339 	}
340 
341 	if (proc.smbp_coresenabled != 0x3) {
342 		warnx("processor state mismatch, found unexpected cores "
343 		    "enabled count: 0x%x",  proc.smbp_coresenabled);
344 		ret = B_FALSE;
345 	}
346 
347 	if (proc.smbp_threadcount != 0x19) {
348 		warnx("processor state mismatch, found unexpected thread "
349 		    "count: 0x%x",  proc.smbp_threadcount);
350 		ret = B_FALSE;
351 	}
352 
353 	return (ret);
354 }
355 
356 /*
357  * This verifies that the 3.6 based table with a 3.0+ client always sees the
358  * values from the uint16_t extension values.
359  */
360 boolean_t
361 smbios_test_proc_verify_36(smbios_hdl_t *hdl)
362 {
363 	boolean_t ret = B_TRUE;
364 	smbios_struct_t sp;
365 	smbios_processor_t proc;
366 
367 	if (smbios_lookup_type(hdl, SMB_TYPE_PROCESSOR, &sp) == -1) {
368 		warnx("failed to lookup SMBIOS processor: %s",
369 		    smbios_errmsg(smbios_errno(hdl)));
370 		return (B_FALSE);
371 	}
372 
373 	if (smbios_info_processor(hdl, sp.smbstr_id, &proc) == -1) {
374 		warnx("failed to get processor: %s",
375 		    smbios_errmsg(smbios_errno(hdl)));
376 		return (B_FALSE);
377 	}
378 
379 	if (!smbios_test_proc_verify_common(hdl, &sp, &proc)) {
380 		ret = B_FALSE;
381 	}
382 
383 	if (proc.smbp_family != SMB_PRF_RV64) {
384 		warnx("processor state mismatch, found unexpected family: 0x%x",
385 		    proc.smbp_family);
386 		ret = B_FALSE;
387 	}
388 
389 	if (proc.smbp_corecount != 0x171) {
390 		warnx("processor state mismatch, found unexpected core count: "
391 		    "0x%x",  proc.smbp_corecount);
392 		ret = B_FALSE;
393 	}
394 
395 	if (proc.smbp_coresenabled != 0x717) {
396 		warnx("processor state mismatch, found unexpected cores "
397 		    "enabled count: 0x%x",  proc.smbp_coresenabled);
398 		ret = B_FALSE;
399 	}
400 
401 	if (proc.smbp_threadcount != 0x5445) {
402 		warnx("processor state mismatch, found unexpected thread "
403 		    "count: 0x%x",  proc.smbp_threadcount);
404 		ret = B_FALSE;
405 	}
406 
407 	if (proc.smbp_threadsenabled != 0x2232) {
408 		warnx("processor state mismatch, found unexpected thread "
409 		    "enabled coun: 0x%x",  proc.smbp_threadsenabled);
410 		ret = B_FALSE;
411 	}
412 
413 	return (ret);
414 }
415 
416 /*
417  * This verifies that when a 2.5 based client uses a 3.x based table, we don't
418  * know about the second flags and instead seed data just based off of the
419  * original field with reserved and all.
420  */
421 boolean_t
422 smbios_test_proc_verify_36_25(smbios_hdl_t *hdl)
423 {
424 	boolean_t ret = B_TRUE;
425 	smbios_struct_t sp;
426 	smbios_processor_t proc;
427 
428 	if (smbios_lookup_type(hdl, SMB_TYPE_PROCESSOR, &sp) == -1) {
429 		warnx("failed to lookup SMBIOS processor: %s",
430 		    smbios_errmsg(smbios_errno(hdl)));
431 		return (B_FALSE);
432 	}
433 
434 	if (smbios_info_processor(hdl, sp.smbstr_id, &proc) == -1) {
435 		warnx("failed to get processor: %s",
436 		    smbios_errmsg(smbios_errno(hdl)));
437 		return (B_FALSE);
438 	}
439 
440 	if (!smbios_test_proc_verify_common(hdl, &sp, &proc)) {
441 		ret = B_FALSE;
442 	}
443 
444 	if (proc.smbp_family != 0xfe) {
445 		warnx("processor state mismatch, found unexpected family: 0x%x",
446 		    proc.smbp_family);
447 		ret = B_FALSE;
448 	}
449 
450 	if (proc.smbp_corecount != 0xff) {
451 		warnx("processor state mismatch, found unexpected core count: "
452 		    "0x%x",  proc.smbp_corecount);
453 		ret = B_FALSE;
454 	}
455 
456 	if (proc.smbp_coresenabled != 0xff) {
457 		warnx("processor state mismatch, found unexpected cores "
458 		    "enabled count: 0x%x",  proc.smbp_coresenabled);
459 		ret = B_FALSE;
460 	}
461 
462 	if (proc.smbp_threadcount != 0xff) {
463 		warnx("processor state mismatch, found unexpected thread "
464 		    "count: 0x%x",  proc.smbp_threadcount);
465 		ret = B_FALSE;
466 	}
467 
468 	return (ret);
469 }
470 
471 
472 boolean_t
473 smbios_test_proc_verify_38(smbios_hdl_t *hdl)
474 {
475 	boolean_t ret = B_TRUE;
476 	smbios_struct_t sp;
477 	smbios_processor_t proc;
478 
479 	if (smbios_lookup_type(hdl, SMB_TYPE_PROCESSOR, &sp) == -1) {
480 		warnx("failed to lookup SMBIOS processor: %s",
481 		    smbios_errmsg(smbios_errno(hdl)));
482 		return (B_FALSE);
483 	}
484 
485 	if (smbios_info_processor(hdl, sp.smbstr_id, &proc) == -1) {
486 		warnx("failed to get processor: %s",
487 		    smbios_errmsg(smbios_errno(hdl)));
488 		return (B_FALSE);
489 	}
490 
491 	if (!smbios_test_proc_verify_36(hdl)) {
492 		ret = B_FALSE;
493 	}
494 
495 	if (proc.smbp_socktype == NULL) {
496 		warnx("processor state mismatch: found NULL socket type");
497 		ret = B_FALSE;
498 	} else if (strcmp(proc.smbp_socktype, smbios_proc_st) != 0) {
499 		warnx("processor state mismatch: found unexpected socket type: "
500 		    "%s", proc.smbp_socktype);
501 		ret = B_FALSE;
502 	}
503 
504 	return (ret);
505 }
506