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 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 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 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 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 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 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 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 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