xref: /illumos-gate/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c (revision a92282e44f968185a6bba094d1e5fece2da819cf)
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 (c) 2018, Joyent, Inc.
14  * Copyright 2020 Oxide Computer Company
15  */
16 
17 /*
18  * Basic testing of the SMBIOS 3.2 Slot extensions.
19  */
20 
21 #include "smbios_test.h"
22 
23 static const char *smbios_test_name = "The One Slot";
24 static uint8_t smbios_slot_bus = 0x42;
25 static uint8_t smbios_slot_df = 0x23;
26 static uint8_t smbios_slot_info = 0x65;
27 static uint16_t smbios_slot_pitch = 0x12af;
28 
29 static void
30 smbios_test_slot_fill(smb_slot_t *slot)
31 {
32 	bzero(slot, sizeof (smb_slot_t));
33 	slot->smbsl_hdr.smbh_type = SMB_TYPE_SLOT;
34 	slot->smbsl_hdr.smbh_len = sizeof (smb_slot_t);
35 	slot->smbsl_name = 1;
36 	slot->smbsl_type = SMB_SLT_PCIE3G16;
37 	slot->smbsl_width = SMB_SLW_16X;
38 	slot->smbsl_length = SMB_SLL_SHORT;
39 	slot->smbsl_id = htole16(1);
40 	slot->smbsl_ch1 = SMB_SLCH1_33V;
41 	slot->smbsl_ch2 = SMB_SLCH2_PME;
42 	slot->smbsl_sg = htole16(1);
43 	slot->smbsl_bus = smbios_slot_bus;
44 	slot->smbsl_df = smbios_slot_df;
45 	slot->smbsl_dbw = SMB_SLW_16X;
46 }
47 
48 boolean_t
49 smbios_test_slot_mktable(smbios_test_table_t *table)
50 {
51 	smb_slot_t slot;
52 	smb_slot_peer_t peers[2];
53 	const uint8_t endstring = 0;
54 
55 	smbios_test_slot_fill(&slot);
56 
57 	slot.smbsl_hdr.smbh_len += sizeof (peers);
58 	slot.smbsl_npeers = 2;
59 
60 	peers[0].smbspb_group_no = htole16(1);
61 	peers[0].smbspb_bus = 0x42;
62 	peers[0].smbspb_df = 0x42;
63 	peers[0].smbspb_width = SMB_SLW_8X;
64 
65 	peers[1].smbspb_group_no = htole16(1);
66 	peers[1].smbspb_bus = 0x23;
67 	peers[1].smbspb_df = 0x31;
68 	peers[1].smbspb_width = SMB_SLW_8X;
69 
70 	(void) smbios_test_table_append(table, &slot, sizeof (slot));
71 	(void) smbios_test_table_append_raw(table, peers, sizeof (peers));
72 	(void) smbios_test_table_append_string(table, smbios_test_name);
73 	(void) smbios_test_table_append_raw(table, &endstring,
74 	    sizeof (endstring));
75 
76 	smbios_test_table_append_eot(table);
77 
78 	return (B_TRUE);
79 }
80 
81 /*
82  * 3.4 introduced additional data after peers. This verison constructs a variant
83  * with no peers.
84  */
85 boolean_t
86 smbios_test_slot_mktable_34_nopeers(smbios_test_table_t *table)
87 {
88 	smb_slot_t slot;
89 	smb_slot_cont_t cont;
90 	const uint8_t endstring = 0;
91 
92 	smbios_test_slot_fill(&slot);
93 	slot.smbsl_hdr.smbh_len = SMB_SLOT_CONT_START + sizeof (cont);
94 
95 	cont.smbsl_info = smbios_slot_info;
96 	cont.smbsl_pwidth = SMB_SLW_32X;
97 	cont.smbsl_pitch = htole16(smbios_slot_pitch);
98 
99 	(void) smbios_test_table_append(table, &slot, sizeof (slot));
100 	/*
101 	 * Append a raw zero to fill in the gaps that the peers would have had
102 	 * so the cont structure starts at the right offset.
103 	 */
104 	(void) smbios_test_table_append_raw(table, &endstring,
105 	    sizeof (endstring));
106 	(void) smbios_test_table_append_raw(table, &cont, sizeof (cont));
107 	(void) smbios_test_table_append_string(table, smbios_test_name);
108 	(void) smbios_test_table_append_raw(table, &endstring,
109 	    sizeof (endstring));
110 	smbios_test_table_append_eot(table);
111 	return (B_TRUE);
112 }
113 
114 boolean_t
115 smbios_test_slot_mktable_34_peers(smbios_test_table_t *table)
116 {
117 	smb_slot_t slot;
118 	smb_slot_cont_t cont;
119 	smb_slot_peer_t peers[1];
120 	const uint8_t endstring = 0;
121 
122 	smbios_test_slot_fill(&slot);
123 	slot.smbsl_npeers = 1;
124 	slot.smbsl_hdr.smbh_len = SMB_SLOT_CONT_START + 5 * slot.smbsl_npeers +
125 	    sizeof (cont);
126 
127 	peers[0].smbspb_group_no = htole16(1);
128 	peers[0].smbspb_bus = 0x42;
129 	peers[0].smbspb_df = 0x9a;
130 	peers[0].smbspb_width = SMB_SLW_8X;
131 
132 	cont.smbsl_info = smbios_slot_info;
133 	cont.smbsl_pwidth = SMB_SLW_32X;
134 	cont.smbsl_pitch = htole16(smbios_slot_pitch);
135 
136 	(void) smbios_test_table_append(table, &slot, sizeof (slot));
137 	(void) smbios_test_table_append_raw(table, peers, sizeof (peers));
138 	(void) smbios_test_table_append_raw(table, &endstring,
139 	    sizeof (endstring));
140 	(void) smbios_test_table_append_raw(table, &cont, sizeof (cont));
141 	(void) smbios_test_table_append_string(table, smbios_test_name);
142 	(void) smbios_test_table_append_raw(table, &endstring,
143 	    sizeof (endstring));
144 	smbios_test_table_append_eot(table);
145 	return (B_TRUE);
146 }
147 
148 
149 static boolean_t
150 smbios_test_slot_common(smbios_slot_t *slot)
151 {
152 	uint_t errs = 0;
153 
154 	if (strcmp(slot->smbl_name, smbios_test_name) != 0) {
155 		warnx("slot name mismatch, expected %s, found %s",
156 		    smbios_test_name, slot->smbl_name);
157 		errs++;
158 	}
159 
160 	if (slot->smbl_type != SMB_SLT_PCIE3G16) {
161 		warnx("incorrect slot type, found %u", slot->smbl_type);
162 		errs++;
163 	}
164 
165 	if (slot->smbl_width != SMB_SLW_16X) {
166 		warnx("incorrect slot width, found %u", slot->smbl_width);
167 		errs++;
168 	}
169 
170 	if (slot->smbl_length != SMB_SLL_SHORT) {
171 		warnx("incorrect slot length, found %u", slot->smbl_length);
172 		errs++;
173 	}
174 
175 	if (slot->smbl_dbw != SMB_SLW_16X) {
176 		warnx("incorrect slot data bus width, found %u",
177 		    slot->smbl_dbw);
178 		errs++;
179 	}
180 
181 	if (slot->smbl_bus != smbios_slot_bus) {
182 		warnx("incorrect slot bus id, found 0x%x\n", slot->smbl_bus);
183 	}
184 
185 	if (slot->smbl_df != smbios_slot_df) {
186 		warnx("incorrect slot df id, found 0x%x\n", slot->smbl_df);
187 	}
188 
189 	if (errs > 0) {
190 		return (B_FALSE);
191 	}
192 
193 	return (B_TRUE);
194 }
195 
196 boolean_t
197 smbios_test_slot_verify(smbios_hdl_t *hdl)
198 {
199 	smbios_struct_t sp;
200 	smbios_slot_t slot;
201 	uint_t npeers;
202 	smbios_slot_peer_t *peers;
203 	uint_t errs = 0;
204 
205 	if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) {
206 		warnx("failed to lookup SMBIOS slot: %s",
207 		    smbios_errmsg(smbios_errno(hdl)));
208 		return (B_FALSE);
209 	}
210 
211 	if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) {
212 		warnx("failed to get SMBIOS slot info: %s",
213 		    smbios_errmsg(smbios_errno(hdl)));
214 		return (B_FALSE);
215 	}
216 
217 	if (!smbios_test_slot_common(&slot)) {
218 		errs++;
219 	}
220 
221 	if (slot.smbl_npeers != 2) {
222 		warnx("incorrect number of slot peers, found %u",
223 		    slot.smbl_npeers);
224 		errs++;
225 	}
226 
227 	if (smbios_info_slot_peers(hdl, sp.smbstr_id, &npeers, &peers) != 0) {
228 		warnx("failed to get SMBIOS peer info: %s",
229 		    smbios_errmsg(smbios_errno(hdl)));
230 		return (B_FALSE);
231 	}
232 
233 	if (npeers != 2) {
234 		warnx("got wrong number of slot peers: %u", npeers);
235 		return (B_FALSE);
236 	}
237 
238 	if (peers[0].smblp_group != 1) {
239 		warnx("incorrect group for peer 0: %u", peers[0].smblp_group);
240 		errs++;
241 	}
242 
243 	if (peers[0].smblp_data_width != SMB_SLW_8X) {
244 		warnx("incorrect data width for peer 0: %u",
245 		    peers[0].smblp_data_width);
246 		errs++;
247 	}
248 
249 	if (peers[0].smblp_device != (0x42 >> 3)) {
250 		warnx("incorrect PCI device for peer 0: %u",
251 		    peers[0].smblp_device);
252 		errs++;
253 	}
254 
255 	if (peers[0].smblp_function != (0x42 & 0x7)) {
256 		warnx("incorrect PCI function for peer 0: %u",
257 		    peers[0].smblp_function);
258 		errs++;
259 	}
260 
261 	if (peers[1].smblp_group != 1) {
262 		warnx("incorrect group for peer 1: %u", peers[1].smblp_group);
263 		errs++;
264 	}
265 
266 	if (peers[1].smblp_device != (0x31 >> 3)) {
267 		warnx("incorrect PCI device for peer 1: %u",
268 		    peers[1].smblp_device);
269 		errs++;
270 	}
271 
272 	if (peers[1].smblp_function != (0x31 & 0x7)) {
273 		warnx("incorrect PCI function for peer 1: %u",
274 		    peers[1].smblp_function);
275 		errs++;
276 	}
277 
278 	if (peers[1].smblp_data_width != SMB_SLW_8X) {
279 		warnx("incorrect data width for peer 1: %u",
280 		    peers[1].smblp_data_width);
281 		errs++;
282 	}
283 
284 	smbios_info_slot_peers_free(hdl, npeers, peers);
285 
286 	if (slot.smbl_info != 0) {
287 		warnx("found wrong slot info: 0x%x", slot.smbl_info);
288 		errs++;
289 	}
290 
291 	if (slot.smbl_pwidth != 0) {
292 		warnx("found wrong slot physical width: 0x%x",
293 		    slot.smbl_pwidth);
294 		errs++;
295 	}
296 
297 	if (slot.smbl_pitch != 0) {
298 		warnx("found wrong slot pitch: 0x%x", slot.smbl_pitch);
299 		errs++;
300 	}
301 
302 	if (errs > 0) {
303 		return (B_FALSE);
304 	}
305 
306 	return (B_TRUE);
307 }
308 
309 boolean_t
310 smbios_test_slot_verify_34_nopeers(smbios_hdl_t *hdl)
311 {
312 	smbios_struct_t sp;
313 	smbios_slot_t slot;
314 	uint_t npeers;
315 	smbios_slot_peer_t *peers;
316 	uint_t errs = 0;
317 
318 	if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) {
319 		warnx("failed to lookup SMBIOS slot: %s",
320 		    smbios_errmsg(smbios_errno(hdl)));
321 		return (B_FALSE);
322 	}
323 
324 	if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) {
325 		warnx("failed to get SMBIOS slot info: %s",
326 		    smbios_errmsg(smbios_errno(hdl)));
327 		return (B_FALSE);
328 	}
329 
330 	if (!smbios_test_slot_common(&slot)) {
331 		errs++;
332 	}
333 
334 	if (slot.smbl_npeers != 0) {
335 		warnx("incorrect number of slot peers, found %u",
336 		    slot.smbl_npeers);
337 		errs++;
338 	}
339 
340 	if (smbios_info_slot_peers(hdl, sp.smbstr_id, &npeers, &peers) != 0) {
341 		warnx("failed to get SMBIOS peer info: %s",
342 		    smbios_errmsg(smbios_errno(hdl)));
343 		return (B_FALSE);
344 	}
345 
346 	if (npeers != 0) {
347 		warnx("got wrong number of slot peers: %u", npeers);
348 		errs++;
349 	}
350 
351 	if (peers != NULL) {
352 		warnx("expected NULL peers pointer, but found %p", peers);
353 		errs++;
354 	}
355 
356 	smbios_info_slot_peers_free(hdl, npeers, peers);
357 
358 	if (slot.smbl_info != smbios_slot_info) {
359 		warnx("found wrong slot info: 0x%x, expected 0x%x",
360 		    slot.smbl_info, smbios_slot_info);
361 		errs++;
362 	}
363 
364 	if (slot.smbl_pwidth != SMB_SLW_32X) {
365 		warnx("found wrong slot physical width: 0x%x, expected 0x%x",
366 		    slot.smbl_pwidth, SMB_SLW_32X);
367 		errs++;
368 	}
369 
370 	if (slot.smbl_pitch != smbios_slot_pitch) {
371 		warnx("found wrong slot pitch: 0x%x, expected 0x%x",
372 		    slot.smbl_pitch, smbios_slot_pitch);
373 		errs++;
374 	}
375 
376 	if (errs > 0) {
377 		return (B_FALSE);
378 	}
379 
380 	return (B_TRUE);
381 }
382 
383 boolean_t
384 smbios_test_slot_verify_34_peers(smbios_hdl_t *hdl)
385 {
386 	smbios_struct_t sp;
387 	smbios_slot_t slot;
388 	uint_t npeers;
389 	smbios_slot_peer_t *peers;
390 	uint_t errs = 0;
391 
392 	if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) {
393 		warnx("failed to lookup SMBIOS slot: %s",
394 		    smbios_errmsg(smbios_errno(hdl)));
395 		return (B_FALSE);
396 	}
397 
398 	if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) {
399 		warnx("failed to get SMBIOS slot info: %s",
400 		    smbios_errmsg(smbios_errno(hdl)));
401 		return (B_FALSE);
402 	}
403 
404 	if (!smbios_test_slot_common(&slot)) {
405 		errs++;
406 	}
407 
408 	if (slot.smbl_npeers != 1) {
409 		warnx("incorrect number of slot peers, found %u",
410 		    slot.smbl_npeers);
411 		errs++;
412 	}
413 
414 	if (smbios_info_slot_peers(hdl, sp.smbstr_id, &npeers, &peers) != 0) {
415 		warnx("failed to get SMBIOS peer info: %s",
416 		    smbios_errmsg(smbios_errno(hdl)));
417 		return (B_FALSE);
418 	}
419 
420 	if (npeers != 1) {
421 		warnx("got wrong number of slot peers: %u", npeers);
422 		errs++;
423 	}
424 
425 	if (peers[0].smblp_group != 1) {
426 		warnx("incorrect group for peer 0: %u", peers[0].smblp_group);
427 		errs++;
428 	}
429 
430 	if (peers[0].smblp_data_width != SMB_SLW_8X) {
431 		warnx("incorrect data width for peer 0: %u",
432 		    peers[0].smblp_data_width);
433 		errs++;
434 	}
435 
436 	if (peers[0].smblp_bus != 0x42) {
437 		warnx("incorrect PCI bus for peer 0: %u",
438 		    peers[0].smblp_bus);
439 		errs++;
440 	}
441 
442 	if (peers[0].smblp_device != (0x9a >> 3)) {
443 		warnx("incorrect PCI device for peer 0: %u",
444 		    peers[0].smblp_device);
445 		errs++;
446 	}
447 
448 	if (peers[0].smblp_function != (0x9a & 0x7)) {
449 		warnx("incorrect PCI function for peer 0: %u",
450 		    peers[0].smblp_function);
451 		errs++;
452 	}
453 
454 	smbios_info_slot_peers_free(hdl, npeers, peers);
455 
456 	if (slot.smbl_info != smbios_slot_info) {
457 		warnx("found wrong slot info: 0x%x, expected 0x%x",
458 		    slot.smbl_info, smbios_slot_info);
459 		errs++;
460 	}
461 
462 	if (slot.smbl_pwidth != SMB_SLW_32X) {
463 		warnx("found wrong slot physical width: 0x%x, expected 0x%x",
464 		    slot.smbl_pwidth, SMB_SLW_32X);
465 		errs++;
466 	}
467 
468 	if (slot.smbl_pitch != smbios_slot_pitch) {
469 		warnx("found wrong slot pitch: 0x%x, expected 0x%x",
470 		    slot.smbl_pitch, smbios_slot_pitch);
471 		errs++;
472 	}
473 
474 	if (errs > 0) {
475 		return (B_FALSE);
476 	}
477 
478 	return (B_TRUE);
479 }
480