1*679a141eSToomas Soome /*
2*679a141eSToomas Soome  * This file and its contents are supplied under the terms of the
3*679a141eSToomas Soome  * Common Development and Distribution License ("CDDL"), version 1.0.
4*679a141eSToomas Soome  * You may only use this file in accordance with the terms of version
5*679a141eSToomas Soome  * 1.0 of the CDDL.
6*679a141eSToomas Soome  *
7*679a141eSToomas Soome  * A full copy of the text of the CDDL should have accompanied this
8*679a141eSToomas Soome  * source.  A copy of the CDDL is also available via the Internet at
9*679a141eSToomas Soome  * http://www.illumos.org/license/CDDL.
10*679a141eSToomas Soome  */
11*679a141eSToomas Soome 
12*679a141eSToomas Soome /*
13*679a141eSToomas Soome  * Copyright 2023 Oxide Computer Company
14*679a141eSToomas Soome  */
15*679a141eSToomas Soome 
16*679a141eSToomas Soome /*
17*679a141eSToomas Soome  * Tests for the old Sun OEM SMBIOS Type 145, memory device extended
18*679a141eSToomas Soome  * information.
19*679a141eSToomas Soome  */
20*679a141eSToomas Soome 
21*679a141eSToomas Soome #include "smbios_test.h"
22*679a141eSToomas Soome 
23*679a141eSToomas Soome /*
24*679a141eSToomas Soome  * Please keep the ncs value the same as the mktable_cs() array size.
25*679a141eSToomas Soome  */
26*679a141eSToomas Soome static const uint8_t smbios_extmemdevice_ncs = 23;
27*679a141eSToomas Soome static const uint16_t smbios_extmemdevice_mdev = 6;
28*679a141eSToomas Soome static const uint8_t smbios_extmemdevice_dchan = 7;
29*679a141eSToomas Soome 
30*679a141eSToomas Soome static void
smbios_test_extmem_mktable_common(smb_memdevice_ext_t * ext)31*679a141eSToomas Soome smbios_test_extmem_mktable_common(smb_memdevice_ext_t *ext)
32*679a141eSToomas Soome {
33*679a141eSToomas Soome 	ext->smbmdeve_hdr.smbh_type = SUN_OEM_EXT_MEMDEVICE;
34*679a141eSToomas Soome 	ext->smbmdeve_hdr.smbh_len = sizeof (*ext);
35*679a141eSToomas Soome 	ext->smbmdeve_mdev = htole16(smbios_extmemdevice_mdev);
36*679a141eSToomas Soome 	ext->smbmdeve_dchan = smbios_extmemdevice_dchan;
37*679a141eSToomas Soome 	ext->smbmdeve_ncs = 0;
38*679a141eSToomas Soome }
39*679a141eSToomas Soome 
40*679a141eSToomas Soome boolean_t
smbios_test_extmem_mktable_invlen_cs(smbios_test_table_t * table)41*679a141eSToomas Soome smbios_test_extmem_mktable_invlen_cs(smbios_test_table_t *table)
42*679a141eSToomas Soome {
43*679a141eSToomas Soome 	smb_memdevice_ext_t ext;
44*679a141eSToomas Soome 
45*679a141eSToomas Soome 	smbios_test_extmem_mktable_common(&ext);
46*679a141eSToomas Soome 	ext.smbmdeve_ncs = smbios_extmemdevice_ncs;
47*679a141eSToomas Soome 	(void) smbios_test_table_append(table, &ext, sizeof (ext));
48*679a141eSToomas Soome 	smbios_test_table_append_eot(table);
49*679a141eSToomas Soome 
50*679a141eSToomas Soome 	return (B_TRUE);
51*679a141eSToomas Soome }
52*679a141eSToomas Soome 
53*679a141eSToomas Soome boolean_t
smbios_test_extmem_mktable_nocs(smbios_test_table_t * table)54*679a141eSToomas Soome smbios_test_extmem_mktable_nocs(smbios_test_table_t *table)
55*679a141eSToomas Soome {
56*679a141eSToomas Soome 	smb_memdevice_ext_t ext;
57*679a141eSToomas Soome 
58*679a141eSToomas Soome 	smbios_test_extmem_mktable_common(&ext);
59*679a141eSToomas Soome 	(void) smbios_test_table_append(table, &ext, sizeof (ext));
60*679a141eSToomas Soome 	smbios_test_table_append_eot(table);
61*679a141eSToomas Soome 
62*679a141eSToomas Soome 	return (B_TRUE);
63*679a141eSToomas Soome }
64*679a141eSToomas Soome 
65*679a141eSToomas Soome boolean_t
smbios_test_extmem_mktable_cs(smbios_test_table_t * table)66*679a141eSToomas Soome smbios_test_extmem_mktable_cs(smbios_test_table_t *table)
67*679a141eSToomas Soome {
68*679a141eSToomas Soome 	smb_memdevice_ext_t ext;
69*679a141eSToomas Soome 	uint8_t cs[23];
70*679a141eSToomas Soome 
71*679a141eSToomas Soome 	for (uint8_t i = 0; i < ARRAY_SIZE(cs); i++) {
72*679a141eSToomas Soome 		cs[i] = i;
73*679a141eSToomas Soome 	}
74*679a141eSToomas Soome 
75*679a141eSToomas Soome 	smbios_test_extmem_mktable_common(&ext);
76*679a141eSToomas Soome 	ext.smbmdeve_ncs = smbios_extmemdevice_ncs;
77*679a141eSToomas Soome 	ext.smbmdeve_hdr.smbh_len += sizeof (cs);
78*679a141eSToomas Soome 	(void) smbios_test_table_append(table, &ext, sizeof (ext));
79*679a141eSToomas Soome 	smbios_test_table_append_raw(table, &cs, sizeof (cs));
80*679a141eSToomas Soome 	smbios_test_table_append_eot(table);
81*679a141eSToomas Soome 
82*679a141eSToomas Soome 	return (B_TRUE);
83*679a141eSToomas Soome }
84*679a141eSToomas Soome 
85*679a141eSToomas Soome static boolean_t
smbios_test_extmem_verify_common(const smbios_memdevice_ext_t * ext,uint_t ncs)86*679a141eSToomas Soome smbios_test_extmem_verify_common(const smbios_memdevice_ext_t *ext, uint_t ncs)
87*679a141eSToomas Soome {
88*679a141eSToomas Soome 	boolean_t ret = B_TRUE;
89*679a141eSToomas Soome 
90*679a141eSToomas Soome 	if (ext->smbmdeve_md != smbios_extmemdevice_mdev) {
91*679a141eSToomas Soome 		warnx("memory device mismatch, found 0x%x, expected 0x%x",
92*679a141eSToomas Soome 		    ext->smbmdeve_md, smbios_extmemdevice_mdev);
93*679a141eSToomas Soome 		ret = B_FALSE;
94*679a141eSToomas Soome 
95*679a141eSToomas Soome 	}
96*679a141eSToomas Soome 
97*679a141eSToomas Soome 	if (ext->smbmdeve_drch != smbios_extmemdevice_dchan) {
98*679a141eSToomas Soome 		warnx("dram channel mismatch, found 0x%x, expected 0x%x",
99*679a141eSToomas Soome 		    ext->smbmdeve_drch, smbios_extmemdevice_dchan);
100*679a141eSToomas Soome 		ret = B_FALSE;
101*679a141eSToomas Soome 
102*679a141eSToomas Soome 	}
103*679a141eSToomas Soome 
104*679a141eSToomas Soome 	if (ext->smbmdeve_ncs != ncs) {
105*679a141eSToomas Soome 		warnx("cs count mismatch, found 0x%x, expected 0x%x",
106*679a141eSToomas Soome 		    ext->smbmdeve_ncs, ncs);
107*679a141eSToomas Soome 		ret = B_FALSE;
108*679a141eSToomas Soome 	}
109*679a141eSToomas Soome 
110*679a141eSToomas Soome 	return (ret);
111*679a141eSToomas Soome }
112*679a141eSToomas Soome 
113*679a141eSToomas Soome boolean_t
smbios_test_extmem_verify_invlen_cs(smbios_hdl_t * hdl)114*679a141eSToomas Soome smbios_test_extmem_verify_invlen_cs(smbios_hdl_t *hdl)
115*679a141eSToomas Soome {
116*679a141eSToomas Soome 	smbios_struct_t sp;
117*679a141eSToomas Soome 	smbios_memdevice_ext_t ext;
118*679a141eSToomas Soome 	boolean_t ret = B_TRUE;
119*679a141eSToomas Soome 	uint_t ncs;
120*679a141eSToomas Soome 	uint8_t *cs;
121*679a141eSToomas Soome 
122*679a141eSToomas Soome 	if (smbios_lookup_type(hdl, SUN_OEM_EXT_MEMDEVICE, &sp) == -1) {
123*679a141eSToomas Soome 		warnx("failed to lookup SMBIOS extended memory device: %s",
124*679a141eSToomas Soome 		    smbios_errmsg(smbios_errno(hdl)));
125*679a141eSToomas Soome 	}
126*679a141eSToomas Soome 
127*679a141eSToomas Soome 	if (smbios_info_extmemdevice(hdl, sp.smbstr_id, &ext) == -1) {
128*679a141eSToomas Soome 		warnx("failed to get extended memory device: %s",
129*679a141eSToomas Soome 		    smbios_errmsg(smbios_errno(hdl)));
130*679a141eSToomas Soome 		return (B_FALSE);
131*679a141eSToomas Soome 	}
132*679a141eSToomas Soome 
133*679a141eSToomas Soome 	if (!smbios_test_extmem_verify_common(&ext, smbios_extmemdevice_ncs)) {
134*679a141eSToomas Soome 		ret = B_FALSE;
135*679a141eSToomas Soome 	}
136*679a141eSToomas Soome 
137*679a141eSToomas Soome 	if (smbios_info_extmemdevice_cs(hdl, sp.smbstr_id, &ncs, &cs) == 0) {
138*679a141eSToomas Soome 		warnx("getting cs succeeded when it should have failed");
139*679a141eSToomas Soome 		smbios_info_extmemdevice_cs_free(hdl, ncs, cs);
140*679a141eSToomas Soome 		return (B_FALSE);
141*679a141eSToomas Soome 	}
142*679a141eSToomas Soome 
143*679a141eSToomas Soome 	if (smbios_errno(hdl) != ESMB_SHORT) {
144*679a141eSToomas Soome 		warnx("encountered wrong error for cs info, expected: 0x%x, "
145*679a141eSToomas Soome 		    "found: 0x%x", ESMB_SHORT, smbios_errno(hdl));
146*679a141eSToomas Soome 		ret = B_FALSE;
147*679a141eSToomas Soome 	}
148*679a141eSToomas Soome 
149*679a141eSToomas Soome 	return (ret);
150*679a141eSToomas Soome }
151*679a141eSToomas Soome 
152*679a141eSToomas Soome boolean_t
smbios_test_extmem_verify_nocs(smbios_hdl_t * hdl)153*679a141eSToomas Soome smbios_test_extmem_verify_nocs(smbios_hdl_t *hdl)
154*679a141eSToomas Soome {
155*679a141eSToomas Soome 	smbios_struct_t sp;
156*679a141eSToomas Soome 	smbios_memdevice_ext_t ext;
157*679a141eSToomas Soome 	boolean_t ret = B_TRUE;
158*679a141eSToomas Soome 	uint_t ncs;
159*679a141eSToomas Soome 	uint8_t *cs;
160*679a141eSToomas Soome 
161*679a141eSToomas Soome 	if (smbios_lookup_type(hdl, SUN_OEM_EXT_MEMDEVICE, &sp) == -1) {
162*679a141eSToomas Soome 		warnx("failed to lookup SMBIOS extended memory device: %s",
163*679a141eSToomas Soome 		    smbios_errmsg(smbios_errno(hdl)));
164*679a141eSToomas Soome 	}
165*679a141eSToomas Soome 
166*679a141eSToomas Soome 	if (smbios_info_extmemdevice(hdl, sp.smbstr_id, &ext) == -1) {
167*679a141eSToomas Soome 		warnx("failed to get extended memory device: %s",
168*679a141eSToomas Soome 		    smbios_errmsg(smbios_errno(hdl)));
169*679a141eSToomas Soome 		return (B_FALSE);
170*679a141eSToomas Soome 	}
171*679a141eSToomas Soome 
172*679a141eSToomas Soome 	if (!smbios_test_extmem_verify_common(&ext, 0)) {
173*679a141eSToomas Soome 		ret = B_FALSE;
174*679a141eSToomas Soome 	}
175*679a141eSToomas Soome 
176*679a141eSToomas Soome 	if (smbios_info_extmemdevice_cs(hdl, sp.smbstr_id, &ncs, &cs) == -1) {
177*679a141eSToomas Soome 		warnx("failed to get extended memory device cs: %s",
178*679a141eSToomas Soome 		    smbios_errmsg(smbios_errno(hdl)));
179*679a141eSToomas Soome 		return (B_FALSE);
180*679a141eSToomas Soome 	}
181*679a141eSToomas Soome 
182*679a141eSToomas Soome 	if (ncs != 0 || cs != NULL) {
183*679a141eSToomas Soome 		warnx("non-cs case turned up 0x%x cs entries with address %p",
184*679a141eSToomas Soome 		    ncs, cs);
185*679a141eSToomas Soome 		ret = B_FALSE;
186*679a141eSToomas Soome 	}
187*679a141eSToomas Soome 
188*679a141eSToomas Soome 	return (ret);
189*679a141eSToomas Soome }
190*679a141eSToomas Soome 
191*679a141eSToomas Soome boolean_t
smbios_test_extmem_verify_cs(smbios_hdl_t * hdl)192*679a141eSToomas Soome smbios_test_extmem_verify_cs(smbios_hdl_t *hdl)
193*679a141eSToomas Soome {
194*679a141eSToomas Soome 	smbios_struct_t sp;
195*679a141eSToomas Soome 	smbios_memdevice_ext_t ext;
196*679a141eSToomas Soome 	boolean_t ret = B_TRUE;
197*679a141eSToomas Soome 	uint_t ncs;
198*679a141eSToomas Soome 	uint8_t *cs;
199*679a141eSToomas Soome 
200*679a141eSToomas Soome 	if (smbios_lookup_type(hdl, SUN_OEM_EXT_MEMDEVICE, &sp) == -1) {
201*679a141eSToomas Soome 		warnx("failed to lookup SMBIOS extended memory device: %s",
202*679a141eSToomas Soome 		    smbios_errmsg(smbios_errno(hdl)));
203*679a141eSToomas Soome 	}
204*679a141eSToomas Soome 
205*679a141eSToomas Soome 	if (smbios_info_extmemdevice(hdl, sp.smbstr_id, &ext) == -1) {
206*679a141eSToomas Soome 		warnx("failed to get extended memory device: %s",
207*679a141eSToomas Soome 		    smbios_errmsg(smbios_errno(hdl)));
208*679a141eSToomas Soome 		return (B_FALSE);
209*679a141eSToomas Soome 	}
210*679a141eSToomas Soome 
211*679a141eSToomas Soome 	if (!smbios_test_extmem_verify_common(&ext, smbios_extmemdevice_ncs)) {
212*679a141eSToomas Soome 		ret = B_FALSE;
213*679a141eSToomas Soome 	}
214*679a141eSToomas Soome 
215*679a141eSToomas Soome 	if (smbios_info_extmemdevice_cs(hdl, sp.smbstr_id, &ncs, &cs) == -1) {
216*679a141eSToomas Soome 		warnx("failed to get extended memory device cs: %s",
217*679a141eSToomas Soome 		    smbios_errmsg(smbios_errno(hdl)));
218*679a141eSToomas Soome 		return (B_FALSE);
219*679a141eSToomas Soome 	}
220*679a141eSToomas Soome 
221*679a141eSToomas Soome 	if (ncs != smbios_extmemdevice_ncs) {
222*679a141eSToomas Soome 		warnx("smbios_info_extmemdevice_cs returned wrong number of "
223*679a141eSToomas Soome 		    "cs, expected 0x%x, found 0x%x", smbios_extmemdevice_ncs,
224*679a141eSToomas Soome 		    ncs);
225*679a141eSToomas Soome 		ret = B_FALSE;
226*679a141eSToomas Soome 	}
227*679a141eSToomas Soome 
228*679a141eSToomas Soome 	if (cs == NULL) {
229*679a141eSToomas Soome 		warnx("somehow got NULL pointer for valid cs case");
230*679a141eSToomas Soome 		ret = B_FALSE;
231*679a141eSToomas Soome 	}
232*679a141eSToomas Soome 
233*679a141eSToomas Soome 	for (uint_t i = 0; i < ncs; i++) {
234*679a141eSToomas Soome 		if (cs[i] != i) {
235*679a141eSToomas Soome 			warnx("cs %u has wrong value 0x%x, expected 0x%x", i,
236*679a141eSToomas Soome 			    cs[i], i);
237*679a141eSToomas Soome 			ret = B_FALSE;
238*679a141eSToomas Soome 		}
239*679a141eSToomas Soome 	}
240*679a141eSToomas Soome 
241*679a141eSToomas Soome 	smbios_info_extmemdevice_cs_free(hdl, ncs, cs);
242*679a141eSToomas Soome 	return (ret);
243*679a141eSToomas Soome }
244