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