summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/smbios/smbios.c147
-rw-r--r--usr/src/common/smbios/mktables.sh13
-rw-r--r--usr/src/common/smbios/smb_info.c332
-rw-r--r--usr/src/common/smbios/smb_open.c2
-rw-r--r--usr/src/lib/libsmbios/common/mapfile-vers17
-rw-r--r--usr/src/test/util-tests/tests/smbios/Makefile16
-rw-r--r--usr/src/test/util-tests/tests/smbios/smbios.c257
-rw-r--r--usr/src/test/util-tests/tests/smbios/smbios_test.h41
-rw-r--r--usr/src/test/util-tests/tests/smbios/smbios_test_chassis.c556
-rw-r--r--usr/src/test/util-tests/tests/smbios/smbios_test_errors.c61
-rw-r--r--usr/src/test/util-tests/tests/smbios/smbios_test_fwinfo.c429
-rw-r--r--usr/src/test/util-tests/tests/smbios/smbios_test_pinfo.c5
-rw-r--r--usr/src/test/util-tests/tests/smbios/smbios_test_slot.c222
-rw-r--r--usr/src/test/util-tests/tests/smbios/smbios_test_strings.c157
-rw-r--r--usr/src/test/util-tests/tests/smbios/smbios_test_strprop.c255
-rw-r--r--usr/src/uts/common/sys/smbios.h153
-rw-r--r--usr/src/uts/common/sys/smbios_impl.h78
17 files changed, 2592 insertions, 149 deletions
diff --git a/usr/src/cmd/smbios/smbios.c b/usr/src/cmd/smbios/smbios.c
index e4cf35c189..859d8d71c7 100644
--- a/usr/src/cmd/smbios/smbios.c
+++ b/usr/src/cmd/smbios/smbios.c
@@ -480,7 +480,8 @@ static void
print_chassis(smbios_hdl_t *shp, id_t id, FILE *fp)
{
smbios_chassis_t c;
- int elem_cnt;
+ smbios_chassis_entry_t *elts;
+ uint_t nelts, i;
(void) smbios_info_chassis(shp, id, &c);
@@ -504,35 +505,38 @@ print_chassis(smbios_hdl_t *shp, id_t id, FILE *fp)
oprintf(fp, " Chassis Height: %uu\n", c.smbc_uheight);
oprintf(fp, " Power Cords: %u\n", c.smbc_cords);
- elem_cnt = c.smbc_elems;
- oprintf(fp, " Element Records: %u\n", elem_cnt);
+ oprintf(fp, " Element Records: %u\n", c.smbc_elems);
- if (elem_cnt > 0) {
- id_t *elems;
- uint8_t type;
- int i, n, cnt;
+ if (c.smbc_elems == 0) {
+ return;
+ }
- elems = alloca(c.smbc_elems * sizeof (id_t));
- cnt = smbios_info_contains(shp, id, elem_cnt, elems);
- if (cnt > SMB_CONT_MAX)
- return;
- n = MIN(elem_cnt, cnt);
+ if (smbios_info_chassis_elts(shp, id, &nelts, &elts) != 0) {
+ smbios_warn(shp, "failed to read chassis elements");
+ return;
+ }
- oprintf(fp, "\n");
- for (i = 0; i < n; i++) {
- type = (uint8_t)elems[i];
- if (type & 0x80) {
- /* SMBIOS structrure Type */
- desc_printf(smbios_type_name(type & 0x7f), fp,
- " Contained SMBIOS structure Type: %u",
- type & 0x80);
- } else {
- /* SMBIOS Base Board Type */
- desc_printf(smbios_bboard_type_desc(type), fp,
- " Contained SMBIOS Base Board Type: 0x%x",
- type);
- }
+ oprintf(fp, "\n");
+
+ for (i = 0; i < nelts; i++) {
+ switch (elts[i].smbce_type) {
+ case SMB_CELT_BBOARD:
+ desc_printf(smbios_bboard_type_desc(elts[i].smbce_elt),
+ fp, " Contained SMBIOS Base Board Type: 0x%x",
+ elts[i].smbce_elt);
+ break;
+ case SMB_CELT_SMBIOS:
+ desc_printf(smbios_type_name(elts[i].smbce_elt), fp,
+ " Contained SMBIOS structure Type: %u",
+ elts[i].smbce_elt);
+ break;
+ default:
+ oprintf(fp, " Unknown contained Type: %u/%u\n",
+ elts[i].smbce_type, elts[i].smbce_elt);
+ break;
}
+ oprintf(fp, " Minimum number: %u\n", elts[i].smbce_min);
+ oprintf(fp, " Maximum number: %u\n", elts[i].smbce_max);
}
}
@@ -782,6 +786,19 @@ print_slot(smbios_hdl_t *shp, id_t id, FILE *fp)
oprintf(fp, " Slot Pitch: %u.%u mm\n", s.smbl_pitch / 100,
s.smbl_pitch % 100);
}
+
+ /*
+ * The slot height was introduced in SMBIOS 3.5. However, a value of
+ * zero here does not mean that it is unknown, but rather that the
+ * concept is not applicable. Therefore we cannot use a standard check
+ * against zero for this and instead use the version.
+ */
+ if (smbios_vergteq(&v, 3, 5)) {
+ desc_printf(smbios_slot_height_desc(s.smbl_height), fp,
+ " Height: 0x%x", s.smbl_height);
+ } else {
+ oprintf(fp, " Height: unknown\n");
+ }
}
static void
@@ -798,7 +815,7 @@ print_obdevs_ext(smbios_hdl_t *shp, id_t id, FILE *fp)
* are the actual device type.
*/
enabled = oe.smboe_dtype >> 7;
- type = smbios_onboard_type_desc(oe.smboe_dtype & 0x7f);
+ type = smbios_onboard_ext_type_desc(oe.smboe_dtype & 0x7f);
str_print(fp, " Reference Designator", oe.smboe_name);
oprintf(fp, " Device Enabled: %s\n", enabled == B_TRUE ? "true" :
@@ -1685,6 +1702,74 @@ print_extmemdevice(smbios_hdl_t *shp, id_t id, FILE *fp)
}
}
+static void
+print_strprop_info(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_strprop_t prop;
+
+ if (smbios_info_strprop(shp, id, &prop) != 0) {
+ smbios_warn(shp, "failed to read string property information");
+ return;
+ }
+
+ desc_printf(smbios_strprop_id_desc(prop.smbsp_prop_id), fp,
+ " Property ID: %u", prop.smbsp_prop_id);
+ if (prop.smbsp_prop_val != NULL) {
+ str_print(fp, " Property Value", prop.smbsp_prop_val);
+ }
+ id_printf(fp, " Parent Handle: ", prop.smbsp_parent);
+}
+
+static void
+print_fwinfo(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_fwinfo_t fw;
+ smbios_fwinfo_comp_t *comps;
+ uint_t ncomps, i;
+
+ if (smbios_info_fwinfo(shp, id, &fw) != 0) {
+ smbios_warn(shp, "failed to read firmware inventory");
+ return;
+ }
+
+ str_print(fp, " Component Name", fw.smbfw_name);
+ str_print(fp, " ID", fw.smbfw_id);
+ str_print(fp, " Release Date", fw.smbfw_reldate);
+ str_print(fp, " Lowest Supported Version", fw.smbfw_lsv);
+ desc_printf(smbios_fwinfo_vers_desc(fw.smbfw_vers_fmt), fp,
+ " Version Format: %u", fw.smbfw_vers_fmt);
+ desc_printf(smbios_fwinfo_id_desc(fw.smbfw_id_fmt), fp,
+ " ID Format: %u", fw.smbfw_id_fmt);
+ if (fw.smbfw_imgsz != UINT64_MAX) {
+ oprintf(fp, " Image Size: %" PRIu64 "\n", fw.smbfw_imgsz);
+ } else {
+ oprintf(fp, " Image Size: unknown\n");
+ }
+
+ flag_printf(fp, "Characteristics", fw.smbfw_chars,
+ sizeof (fw.smbfw_chars) * NBBY, smbios_fwinfo_ch_name,
+ smbios_fwinfo_ch_desc);
+
+ desc_printf(smbios_fwinfo_state_desc(fw.smbfw_state), fp, " State: %u",
+ fw.smbfw_state);
+ oprintf(fp, " Number of Associated Components: %u\n",
+ fw.smbfw_ncomps);
+
+ if (fw.smbfw_ncomps == 0)
+ return;
+
+ if (smbios_info_fwinfo_comps(shp, id, &ncomps, &comps) == -1) {
+ smbios_warn(shp, "failed to read firmware inventory "
+ "components");
+ return;
+ }
+
+ oprintf(fp, "\n Component Handles:\n");
+ for (i = 0; i < ncomps; i++) {
+ oprintf(fp, " %ld\n", comps[i]);
+ }
+}
+
static int
print_struct(smbios_hdl_t *shp, const smbios_struct_t *sp, void *fp)
{
@@ -1841,6 +1926,14 @@ print_struct(smbios_hdl_t *shp, const smbios_struct_t *sp, void *fp)
oprintf(fp, "\n");
print_processor_info(shp, sp->smbstr_id, fp);
break;
+ case SMB_TYPE_STRPROP:
+ oprintf(fp, "\n");
+ print_strprop_info(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_FWINFO:
+ oprintf(fp, "\n");
+ print_fwinfo(shp, sp->smbstr_id, fp);
+ break;
case SUN_OEM_EXT_PROCESSOR:
oprintf(fp, "\n");
print_extprocessor(shp, sp->smbstr_id, fp);
diff --git a/usr/src/common/smbios/mktables.sh b/usr/src/common/smbios/mktables.sh
index 95bd9d6f8b..7256eedfb8 100644
--- a/usr/src/common/smbios/mktables.sh
+++ b/usr/src/common/smbios/mktables.sh
@@ -23,6 +23,7 @@
#
# Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
# Copyright (c) 2018, Joyent, Inc.
+# Copyright 2021 Oxide Computer Company
# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -47,6 +48,7 @@ SMB_BIOSXB2_ smbios_bios_xb2_name uint_t
SMB_CAT_ smbios_cache_ctype_name uint_t
SMB_CAF_ smbios_cache_flag_name uint_t
SMB_EVFL_ smbios_evlog_flag_name uint_t
+SMB_FWC_ smbios_fwinfo_ch_name uint_t
SMB_IPMI_F_ smbios_ipmi_flag_name uint_t
SMB_POWERSUP_F_ smbios_powersup_flag_name uint_t
SMB_MOMC_ smbios_memdevice_op_capab_name uint_t
@@ -81,6 +83,10 @@ SMB_COOLDEV_T_ smbios_cooldev_type_desc uint_t
SMB_EVFL_ smbios_evlog_flag_desc uint_t
SMB_EVHF_ smbios_evlog_format_desc uint_t
SMB_EVM_ smbios_evlog_method_desc uint_t
+SMB_FWC_ smbios_fwinfo_ch_desc uint_t
+SMB_FWI_ smbios_fwinfo_id_desc uint_t
+SMB_FWS_ smbios_fwinfo_state_desc uint_t
+SMB_FWV_ smbios_fwinfo_vers_desc uint_t
SMB_HWSEC_PS_ smbios_hwsec_desc uint_t
SMB_IPMI_F_ smbios_ipmi_flag_desc uint_t
SMB_IPMI_T_ smbios_ipmi_type_desc uint_t
@@ -100,6 +106,7 @@ SMB_MDR_ smbios_memdevice_rank_desc uint_t
SMB_MTECH_ smbios_memdevice_memtech_desc uint_t
SMB_MOMC_ smbios_memdevice_op_capab_desc uint_t
SMB_OBT_ smbios_onboard_type_desc uint_t
+SMB_OBET_ smbios_onboard_ext_type_desc uint_t
SMB_PDI_ smbios_pointdev_iface_desc uint_t
SMB_PDT_ smbios_pointdev_type_desc uint_t
SMB_POC_ smbios_port_conn_desc uint_t
@@ -115,10 +122,12 @@ SMB_RV_PRIV_ smbios_riscv_priv_desc uint_t
SMB_RV_WIDTH_ smbios_riscv_width_desc uint_t
SMB_SLCH1_ smbios_slot_ch1_desc uint_t
SMB_SLCH2_ smbios_slot_ch2_desc uint_t
+SMB_SLHT_ smbios_slot_height_desc uint_t
SMB_SLL_ smbios_slot_length_desc uint_t
SMB_SLT_ smbios_slot_type_desc uint_t
SMB_SLU_ smbios_slot_usage_desc uint_t
SMB_SLW_ smbios_slot_width_desc uint_t
+SMB_STRP_ smbios_strprop_id_desc uint_t
SMB_TPROBE_L_ smbios_tprobe_loc_desc uint_t
SMB_TPROBE_S_ smbios_tprobe_status_desc uint_t
SMB_TYPE_ smbios_type_desc uint_t
@@ -143,7 +152,7 @@ echo "\
echo "$name_funcs" | while read p name type; do
[ -z "$p" ] && continue
- pattern="^#define[ ]\($p[A-Za-z0-9_]*\)[ ]*[A-Z0-9]*.*$"
+ pattern="^#define[ ]\(${p}[A-Za-z0-9_]*\)[ ]*[A-Z0-9]*.*\$"
replace=' case \1: return ("\1");'
echo "\nconst char *\n$name($type x)\n{\n\tswitch (x) {"
@@ -162,7 +171,7 @@ done
#
echo "$desc_funcs" | while read p name type; do
[ -z "$p" ] && continue
- pattern="^#define[ ]\($p[A-Za-z0-9_]*\)[ ]*.*/\\* \(.*\) \\*/$"
+ pattern="^#define[ ]\(${p}[A-Za-z0-9_]*\)[ ]*.*/\\* \(.*\) \\*/\$"
replace=' case \1: return (\2);'
echo "\nconst char *\n$name($type x)\n{\n\tswitch (x) {"
diff --git a/usr/src/common/smbios/smb_info.c b/usr/src/common/smbios/smb_info.c
index 9aba4deba8..09d7d5374a 100644
--- a/usr/src/common/smbios/smb_info.c
+++ b/usr/src/common/smbios/smb_info.c
@@ -22,7 +22,7 @@
/*
* Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
* Copyright 2019 Joyent, Inc.
- * Copyright 2020 Oxide Computer Company
+ * Copyright 2021 Oxide Computer Company
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -78,6 +78,8 @@
#include <string.h>
#endif
+#define SMB_CONT_WORD 2 /* contained elements are word size */
+
/*
* A large number of SMBIOS structures contain a set of common strings used to
* describe a h/w component's serial number, manufacturer, etc. These fields
@@ -130,9 +132,9 @@ static const struct smb_infospec {
offsetof(smb_chassis_t, smbch_asset),
0,
0,
- offsetof(smb_chassis_t, smbch_cn),
- SMB_CONT_BYTE,
- offsetof(smb_chassis_t, smbch_cv) },
+ 0,
+ 0,
+ 0 },
{ SMB_TYPE_PROCESSOR,
offsetof(smb_processor_t, smbpr_manufacturer),
0,
@@ -216,6 +218,18 @@ static const struct smb_infospec {
0,
0
},
+ { SMB_TYPE_FWINFO,
+ offsetof(smb_fwinfo_t, smbfwii_mfg),
+ 0,
+ offsetof(smb_fwinfo_t, smbfwii_vers),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ },
{ SMB_TYPE_EOT }
};
@@ -363,9 +377,7 @@ smbios_info_contains(smbios_hdl_t *shp, id_t id, uint_t idc, id_t *idv)
n = MIN(cnt, idc);
for (i = 0; i < n; i++) {
if (size == SMB_CONT_WORD)
- idv[i] = *((uint8_t *)(uintptr_t)cp + (i * 2));
- else if (size == SMB_CONT_BYTE)
- idv[i] = *((uint8_t *)(uintptr_t)cp + (i * 3));
+ idv[i] = *((uint16_t *)(uintptr_t)cp + (i * 2));
else
return (smb_set_errno(shp, ESMB_INVAL));
}
@@ -516,43 +528,156 @@ int
smbios_info_chassis(smbios_hdl_t *shp, id_t id, smbios_chassis_t *chp)
{
const smb_struct_t *stp = smb_lookup_id(shp, id);
- /* Length is measurable by one byte, so it'll be no more than 255. */
- uint8_t buf[256];
- smb_chassis_t *ch = (smb_chassis_t *)&buf[0];
+ smb_chassis_t ch;
- if (stp == NULL)
+ if (stp == NULL) {
return (-1); /* errno is set for us */
+ }
- if (stp->smbst_hdr->smbh_type != SMB_TYPE_CHASSIS)
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_CHASSIS) {
return (smb_set_errno(shp, ESMB_TYPE));
+ }
- smb_info_bcopy(stp->smbst_hdr, ch, sizeof (buf));
+ if (stp->smbst_hdr->smbh_len < sizeof (ch)) {
+ return (smb_set_errno(shp, ESMB_SHORT));
+ }
+
+ smb_info_bcopy(stp->smbst_hdr, &ch, sizeof (ch));
bzero(chp, sizeof (smb_base_chassis_t));
- if (smb_libgteq(shp, SMB_VERSION_27)) {
- bzero(chp->smbc_sku, sizeof (chp->smbc_sku));
+
+ /*
+ * See the comments for the smb_chassis_pre35_t in sys/smbios_impl.h for
+ * an explanation as to why this is here. The use of smb_strptr with
+ * index 0 below ensures that we initialize this to an empty string.
+ */
+ if (smb_libgteq(shp, SMB_VERSION_35)) {
+ chp->smbc_sku = smb_strptr(stp, 0);
+ } else if (smb_libgteq(shp, SMB_VERSION_27)) {
+ smb_chassis_pre35_t *p35 = (smb_chassis_pre35_t *)chp;
+ bzero(p35->smbc_sku, sizeof (p35->smbc_sku));
}
- chp->smbc_oemdata = ch->smbch_oemdata;
- chp->smbc_lock = (ch->smbch_type & SMB_CHT_LOCK) != 0;
- chp->smbc_type = ch->smbch_type & ~SMB_CHT_LOCK;
- chp->smbc_bustate = ch->smbch_bustate;
- chp->smbc_psstate = ch->smbch_psstate;
- chp->smbc_thstate = ch->smbch_thstate;
- chp->smbc_security = ch->smbch_security;
- chp->smbc_uheight = ch->smbch_uheight;
- chp->smbc_cords = ch->smbch_cords;
- chp->smbc_elems = ch->smbch_cn;
- chp->smbc_elemlen = ch->smbch_cm;
+ chp->smbc_oemdata = ch.smbch_oemdata;
+ chp->smbc_lock = (ch.smbch_type & SMB_CHT_LOCK) != 0;
+ chp->smbc_type = ch.smbch_type & ~SMB_CHT_LOCK;
+ chp->smbc_bustate = ch.smbch_bustate;
+ chp->smbc_psstate = ch.smbch_psstate;
+ chp->smbc_thstate = ch.smbch_thstate;
+ chp->smbc_security = ch.smbch_security;
+ chp->smbc_uheight = ch.smbch_uheight;
+ chp->smbc_cords = ch.smbch_cords;
+ chp->smbc_elems = ch.smbch_cn;
+ chp->smbc_elemlen = ch.smbch_cm;
+
+ /*
+ * If the table is older than version 2.7 which added support for the
+ * chassis SKU, there's no reason to proceed.
+ */
+ if (!smb_gteq(shp, SMB_VERSION_27)) {
+ return (0);
+ }
if (smb_libgteq(shp, SMB_VERSION_27)) {
- (void) strlcpy(chp->smbc_sku, SMB_CH_SKU(ch),
- sizeof (chp->smbc_sku));
+ uint8_t strno;
+ const char *str;
+ off_t off = sizeof (ch) + ch.smbch_cn * ch.smbch_cm;
+ if (stp->smbst_hdr->smbh_len < off + 1) {
+ return (smb_set_errno(shp, ESMB_SHORT));
+ }
+ smb_info_bcopy_offset(stp->smbst_hdr, &strno, sizeof (strno),
+ off);
+ str = smb_strptr(stp, strno);
+ if (smb_libgteq(shp, SMB_VERSION_35)) {
+ chp->smbc_sku = str;
+ } else {
+ smb_chassis_pre35_t *p35 = (smb_chassis_pre35_t *)chp;
+ (void) strlcpy(p35->smbc_sku, str,
+ sizeof (p35->smbc_sku));
+ }
}
return (0);
}
int
+smbios_info_chassis_elts(smbios_hdl_t *shp, id_t id, uint_t *nentsp,
+ smbios_chassis_entry_t **entsp)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ smbios_chassis_entry_t *entry;
+ smb_chassis_t ch;
+ size_t entlen;
+ uint_t i;
+
+ if (stp == NULL) {
+ return (-1); /* errno is set for us */
+ }
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_CHASSIS) {
+ return (smb_set_errno(shp, ESMB_TYPE));
+ }
+
+ if (stp->smbst_hdr->smbh_len < sizeof (ch)) {
+ return (smb_set_errno(shp, ESMB_SHORT));
+ }
+
+ smb_info_bcopy(stp->smbst_hdr, &ch, sizeof (ch));
+ if (ch.smbch_cm != sizeof (smb_chassis_entry_t)) {
+ return (smb_set_errno(shp, ESMB_CORRUPT));
+ }
+
+ if (ch.smbch_cn == 0) {
+ *nentsp = 0;
+ *entsp = NULL;
+ return (0);
+ }
+
+ entlen = ch.smbch_cm * ch.smbch_cn;
+ if (stp->smbst_hdr->smbh_len < sizeof (ch) + entlen) {
+ return (smb_set_errno(shp, ESMB_SHORT));
+ }
+
+ if ((entry = smb_alloc(entlen)) == NULL) {
+ return (smb_set_errno(shp, ESMB_NOMEM));
+ }
+
+ for (i = 0; i < ch.smbch_cn; i++) {
+ smb_chassis_entry_t e;
+ size_t off = sizeof (ch) + i * sizeof (e);
+
+ smb_info_bcopy_offset(stp->smbst_hdr, &e, sizeof (e), off);
+ /*
+ * The top bit is used to indicate what type of record this is,
+ * while the lower 7-bits indicate the actual type.
+ */
+ entry[i].smbce_type = e.smbce_type & 0x80 ?
+ SMB_CELT_SMBIOS : SMB_CELT_BBOARD;
+ entry[i].smbce_elt = e.smbce_type & 0x7f;
+ entry[i].smbce_min = e.smbce_min;
+ entry[i].smbce_max = e.smbce_max;
+ }
+
+ *entsp = entry;
+ *nentsp = ch.smbch_cn;
+
+ return (0);
+}
+
+void
+smbios_info_chassis_elts_free(smbios_hdl_t *shp, uint_t nents,
+ smbios_chassis_entry_t *ent)
+{
+ size_t sz = nents * sizeof (smbios_chassis_entry_t);
+
+ if (nents == 0) {
+ ASSERT3P(ent, ==, NULL);
+ return;
+ }
+
+ smb_free(ent, sz);
+}
+
+int
smbios_info_processor(smbios_hdl_t *shp, id_t id, smbios_processor_t *pp)
{
const smb_struct_t *stp = smb_lookup_id(shp, id);
@@ -733,6 +858,10 @@ smbios_info_slot(smbios_hdl_t *shp, id_t id, smbios_slot_t *sp)
sp->smbl_pwidth = cont.smbsl_pwidth;
sp->smbl_pitch = cont.smbsl_pitch;
+ if (smb_libgteq(shp, SMB_VERSION_35)) {
+ sp->smbl_height = cont.smbsl_height;
+ }
+
return (0);
}
@@ -1671,6 +1800,10 @@ smbios_info_processor_riscv(smbios_hdl_t *shp, id_t id,
const smb_processor_info_t *proc;
const smb_processor_info_riscv_t *rv;
+ if (stp == NULL) {
+ return (-1); /* errno is set for us */
+ }
+
if (stp->smbst_hdr->smbh_type != SMB_TYPE_PROCESSOR_INFO) {
return (smb_set_errno(shp, ESMB_TYPE));
}
@@ -1730,6 +1863,10 @@ smbios_info_pointdev(smbios_hdl_t *shp, id_t id, smbios_pointdev_t *pd)
const smb_struct_t *stp = smb_lookup_id(shp, id);
smb_pointdev_t point;
+ if (stp == NULL) {
+ return (-1); /* errno is set for us */
+ }
+
if (stp->smbst_hdr->smbh_type != SMB_TYPE_POINTDEV) {
return (smb_set_errno(shp, ESMB_TYPE));
}
@@ -1754,6 +1891,10 @@ smbios_info_battery(smbios_hdl_t *shp, id_t id, smbios_battery_t *bp)
const smb_struct_t *stp = smb_lookup_id(shp, id);
smb_battery_t bat;
+ if (stp == NULL) {
+ return (-1); /* errno is set for us */
+ }
+
if (stp->smbst_hdr->smbh_type != SMB_TYPE_BATTERY) {
return (smb_set_errno(shp, ESMB_TYPE));
}
@@ -1800,3 +1941,138 @@ smbios_info_battery(smbios_hdl_t *shp, id_t id, smbios_battery_t *bp)
return (0);
}
+
+int
+smbios_info_strprop(smbios_hdl_t *shp, id_t id, smbios_strprop_t *str)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ smb_strprop_t prop;
+
+ if (stp == NULL) {
+ return (-1); /* errno is set for us */
+ }
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_STRPROP) {
+ return (smb_set_errno(shp, ESMB_TYPE));
+ }
+
+ if (stp->smbst_hdr->smbh_len < sizeof (prop)) {
+ return (smb_set_errno(shp, ESMB_SHORT));
+ }
+
+ if (stp->smbst_hdr->smbh_len > sizeof (prop)) {
+ return (smb_set_errno(shp, ESMB_CORRUPT));
+ }
+
+ bzero(str, sizeof (*str));
+ smb_info_bcopy(stp->smbst_hdr, &prop, sizeof (prop));
+
+ str->smbsp_parent = prop.smbstrp_phdl;
+ str->smbsp_prop_id = prop.smbstrp_prop_id;
+ str->smbsp_prop_val = smb_strptr(stp, prop.smbstrp_prop_val);
+
+ return (0);
+}
+
+int
+smbios_info_fwinfo(smbios_hdl_t *shp, id_t id, smbios_fwinfo_t *fwinfo)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ smb_fwinfo_t fw;
+
+ if (stp == NULL) {
+ return (-1); /* errno is set for us */
+ }
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_FWINFO) {
+ return (smb_set_errno(shp, ESMB_TYPE));
+ }
+
+ if (stp->smbst_hdr->smbh_len < sizeof (fw)) {
+ return (smb_set_errno(shp, ESMB_SHORT));
+ }
+
+ /*
+ * The verion and manufacturer are part of smbios_info_common().
+ */
+ bzero(fwinfo, sizeof (*fwinfo));
+ smb_info_bcopy(stp->smbst_hdr, &fw, sizeof (fw));
+ fwinfo->smbfw_name = smb_strptr(stp, fw.smbfwii_name);
+ fwinfo->smbfw_id = smb_strptr(stp, fw.smbfwii_id);
+ fwinfo->smbfw_reldate = smb_strptr(stp, fw.smbfwii_reldate);
+ fwinfo->smbfw_lsv = smb_strptr(stp, fw.smbfwii_lsv);
+ fwinfo->smbfw_imgsz = fw.smbfwii_imgsz;
+ fwinfo->smbfw_chars = fw.smbfwii_chars;
+ fwinfo->smbfw_state = fw.smbfwii_state;
+ fwinfo->smbfw_ncomps = fw.smbfwii_ncomps;
+ fwinfo->smbfw_vers_fmt = fw.smbfwii_vers_fmt;
+ fwinfo->smbfw_id_fmt = fw.smbfwii_id_fmt;
+
+ return (0);
+}
+
+int
+smbios_info_fwinfo_comps(smbios_hdl_t *shp, id_t id, uint_t *ncompsp,
+ smbios_fwinfo_comp_t **compsp)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ smbios_fwinfo_comp_t *comps;
+ smb_fwinfo_t fw;
+ size_t need;
+ uint_t i;
+
+ if (stp == NULL) {
+ return (-1); /* errno is set for us */
+ }
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_FWINFO) {
+ return (smb_set_errno(shp, ESMB_TYPE));
+ }
+
+ if (stp->smbst_hdr->smbh_len < sizeof (fw)) {
+ return (smb_set_errno(shp, ESMB_SHORT));
+ }
+
+ smb_info_bcopy(stp->smbst_hdr, &fw, sizeof (fw));
+ if (fw.smbfwii_ncomps == 0) {
+ *ncompsp = 0;
+ *compsp = NULL;
+ return (0);
+ }
+
+ need = fw.smbfwii_ncomps * sizeof (uint16_t) + sizeof (smb_fwinfo_t);
+ if (stp->smbst_hdr->smbh_len < need) {
+ return (smb_set_errno(shp, ESMB_SHORT));
+ }
+
+ comps = smb_alloc(fw.smbfwii_ncomps * sizeof (smbios_fwinfo_comp_t));
+ if (comps == NULL) {
+ return (smb_set_errno(shp, ESMB_NOMEM));
+ }
+
+ for (i = 0; i < fw.smbfwii_ncomps; i++) {
+ uint16_t id;
+ size_t off = sizeof (smb_fwinfo_t) + sizeof (uint16_t) * i;
+ smb_info_bcopy_offset(stp->smbst_hdr, &id, sizeof (id), off);
+ comps[i].smbfwe_id = id;
+ }
+
+ *ncompsp = fw.smbfwii_ncomps;
+ *compsp = comps;
+
+ return (0);
+}
+
+void
+smbios_info_fwinfo_comps_free(smbios_hdl_t *shp, uint_t ncomps,
+ smbios_fwinfo_comp_t *comps)
+{
+ size_t sz = ncomps * sizeof (smbios_fwinfo_comp_t);
+
+ if (ncomps == 0) {
+ ASSERT3P(comps, ==, NULL);
+ return;
+ }
+
+ smb_free(comps, sz);
+}
diff --git a/usr/src/common/smbios/smb_open.c b/usr/src/common/smbios/smb_open.c
index 6747c84499..454fb61b8b 100644
--- a/usr/src/common/smbios/smb_open.c
+++ b/usr/src/common/smbios/smb_open.c
@@ -22,6 +22,7 @@
/*
* Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
* Copyright 2018 Joyent, Inc.
+ * Copyright 2021 Oxide Computer Company
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -232,6 +233,7 @@ smbios_bufopen(const smbios_entry_t *ep, const void *buf, size_t len,
case SMB_VERSION_32:
case SMB_VERSION_33:
case SMB_VERSION_34:
+ case SMB_VERSION_35:
break;
default:
return (smb_open_error(shp, errp, ESMB_VERSION));
diff --git a/usr/src/lib/libsmbios/common/mapfile-vers b/usr/src/lib/libsmbios/common/mapfile-vers
index 70667deb49..49d8d04096 100644
--- a/usr/src/lib/libsmbios/common/mapfile-vers
+++ b/usr/src/lib/libsmbios/common/mapfile-vers
@@ -22,6 +22,7 @@
# Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
# Copyright (c) 2018, Joyent, Inc.
# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2021 Oxide Computer Company
#
#
@@ -80,6 +81,11 @@ SYMBOL_VERSION SUNWprivate_1.1 {
smbios_evlog_format_desc;
smbios_evlog_method_desc;
smbios_fdopen;
+ smbios_fwinfo_ch_name;
+ smbios_fwinfo_ch_desc;
+ smbios_fwinfo_id_desc;
+ smbios_fwinfo_state_desc;
+ smbios_fwinfo_vers_desc;
smbios_hwsec_desc;
smbios_info_battery;
smbios_info_bboard;
@@ -87,10 +93,15 @@ SYMBOL_VERSION SUNWprivate_1.1 {
smbios_info_boot;
smbios_info_cache;
smbios_info_chassis;
+ smbios_info_chassis_elts;
+ smbios_info_chassis_elts_free;
smbios_info_cooldev;
smbios_info_common;
smbios_info_contains;
smbios_info_eventlog;
+ smbios_info_fwinfo;
+ smbios_info_fwinfo_comps;
+ smbios_info_fwinfo_comps_free;
smbios_info_hwsec;
smbios_info_ipmi;
smbios_info_iprobe;
@@ -116,6 +127,7 @@ SYMBOL_VERSION SUNWprivate_1.1 {
smbios_info_slot_peers_free;
smbios_info_smbios;
smbios_info_smbios_version;
+ smbios_info_strprop;
smbios_info_strtab;
smbios_info_system;
smbios_info_pciexrc;
@@ -140,8 +152,9 @@ SYMBOL_VERSION SUNWprivate_1.1 {
smbios_memdevice_memtech_desc;
smbios_memdevice_type_desc;
smbios_memdevice_rank_desc;
- smbios_open;
+ smbios_onboard_ext_type_desc;
smbios_onboard_type_desc;
+ smbios_open;
smbios_pointdev_iface_desc;
smbios_pointdev_type_desc;
smbios_port_conn_desc;
@@ -168,10 +181,12 @@ SYMBOL_VERSION SUNWprivate_1.1 {
smbios_slot_ch1_name;
smbios_slot_ch2_desc;
smbios_slot_ch2_name;
+ smbios_slot_height_desc;
smbios_slot_length_desc;
smbios_slot_type_desc;
smbios_slot_usage_desc;
smbios_slot_width_desc;
+ smbios_strprop_id_desc;
smbios_system_wakeup_desc;
smbios_tprobe_loc_desc;
smbios_tprobe_status_desc;
diff --git a/usr/src/test/util-tests/tests/smbios/Makefile b/usr/src/test/util-tests/tests/smbios/Makefile
index e783a337dc..819ebe5be6 100644
--- a/usr/src/test/util-tests/tests/smbios/Makefile
+++ b/usr/src/test/util-tests/tests/smbios/Makefile
@@ -11,6 +11,7 @@
#
# Copyright (c) 2018, Joyent, Inc.
+# Copyright 2021 Oxide Computer Company
#
include $(SRC)/Makefile.master
@@ -19,10 +20,14 @@ ROOTOPTPKG = $(ROOT)/opt/util-tests
TESTDIR = $(ROOTOPTPKG)/tests/
OBJS = smbios.o \
+ smbios_test_chassis.o \
smbios_test_errors.o \
+ smbios_test_fwinfo.o \
smbios_test_memdevice.o \
smbios_test_pinfo.o \
- smbios_test_slot.o
+ smbios_test_slot.o \
+ smbios_test_strings.o \
+ smbios_test_strprop.o
PROGS = smbios
include $(SRC)/cmd/Makefile.cmd
@@ -30,6 +35,15 @@ include $(SRC)/test/Makefile.com
CMDS = $(PROGS:%=$(TESTDIR)/%)
$(CMDS) := FILEMODE = 0555
+CSTD = $(GNU_C99)
+
+#
+# Since this program uses quite a number of variables declared on the
+# stack that are then written to by libsmbios, we opt to pay the cost
+# of always have the stack protector on every function as an additional
+# means of checking ourselves.
+#
+STACKPROTECT = all
LDLIBS += -lsmbios -lumem
CFLAGS += -_gcc=-Wall -_gcc=-Wextra -_gcc=-Wno-unknown-pragmas
diff --git a/usr/src/test/util-tests/tests/smbios/smbios.c b/usr/src/test/util-tests/tests/smbios/smbios.c
index 429d4f81be..73958dda71 100644
--- a/usr/src/test/util-tests/tests/smbios/smbios.c
+++ b/usr/src/test/util-tests/tests/smbios/smbios.c
@@ -11,7 +11,7 @@
/*
* Copyright (c) 2018, Joyent, Inc.
- * Copyright 2020 Oxide Computer Company
+ * Copyright 2021 Oxide Computer Company
*/
/*
@@ -21,8 +21,15 @@
*/
#include <umem.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h>
#include "smbios_test.h"
+static int test_dirfd = -1;
+
const char *
_umem_debug_init(void)
{
@@ -112,6 +119,14 @@ smbios_test_table_append_string(smbios_test_table_t *table, const char *str)
(void) smbios_test_table_append_common(table, str, len);
}
+void
+smbios_test_table_str_fini(smbios_test_table_t *table)
+{
+ const uint8_t endstring = 0;
+
+ smbios_test_table_append_raw(table, &endstring, sizeof (endstring));
+}
+
uint16_t
smbios_test_table_append(smbios_test_table_t *table, const void *buf,
size_t len)
@@ -215,6 +230,34 @@ smbios_test_table_fini(smbios_test_table_t *table)
static const smbios_test_t smbios_tests[] = {
{
.st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = 0xffff,
+ .st_mktable = smbios_test_badvers_mktable,
+ .st_desc = "bad library version"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = 0,
+ .st_mktable = smbios_test_badvers_mktable,
+ .st_desc = "bad library version (zeros)"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_slot_mktable,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_verify_badids,
+ .st_desc = "smbios_info_* with bad id"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_slot_mktable,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_verify_strings,
+ .st_desc = "smbios string functions"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
.st_tvers = SMB_VERSION_32,
.st_libvers = SMB_VERSION,
.st_mktable = smbios_test_slot_mktable,
@@ -239,10 +282,20 @@ static const smbios_test_t smbios_tests[] = {
.st_desc = "slot 3.4 with peers"
}, {
.st_entry = SMBIOS_ENTRY_POINT_30,
- .st_tvers = SMB_VERSION,
- .st_libvers = 0xffff,
- .st_mktable = smbios_test_badvers_mktable,
- .st_desc = "bad library version"
+ .st_tvers = SMB_VERSION_35,
+ .st_libvers = SMB_VERSION_34,
+ .st_mktable = smbios_test_slot_mktable_35,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_slot_verify_34_overrun,
+ .st_desc = "slot 3.5 against 3.4 lib"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION_35,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_slot_mktable_35,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_slot_verify_35,
+ .st_desc = "slot 3.5"
}, {
.st_entry = SMBIOS_ENTRY_POINT_30,
.st_tvers = SMB_VERSION_32,
@@ -250,7 +303,7 @@ static const smbios_test_t smbios_tests[] = {
.st_mktable = smbios_test_memdevice_mktable_32,
.st_canopen = B_TRUE,
.st_verify = smbios_test_memdevice_verify_32,
- .st_desc = "memory device 3.2 / 3.2"
+ .st_desc = "memory device 3.2 % 3.2"
}, {
.st_entry = SMBIOS_ENTRY_POINT_30,
.st_tvers = SMB_VERSION_32,
@@ -258,7 +311,7 @@ static const smbios_test_t smbios_tests[] = {
.st_mktable = smbios_test_memdevice_mktable_32,
.st_canopen = B_TRUE,
.st_verify = smbios_test_memdevice_verify_32_33,
- .st_desc = "memory device 3.2 / 3.3"
+ .st_desc = "memory device 3.2 % 3.3"
}, {
.st_entry = SMBIOS_ENTRY_POINT_30,
.st_tvers = SMB_VERSION_33,
@@ -331,8 +384,143 @@ static const smbios_test_t smbios_tests[] = {
.st_canopen = B_TRUE,
.st_verify = smbios_test_pinfo_verify_badtype,
.st_desc = "processor additional information - bad type"
- },
-
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_strprop_mktable_invlen1,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_strprop_verify_invlen1,
+ .st_desc = "string property - bad table length 1"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_strprop_mktable_invlen2,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_strprop_verify_invlen2,
+ .st_desc = "string property - bad table length 2"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_memdevice_mktable_32,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_strprop_verify_badtype,
+ .st_desc = "string property - bad type"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_strprop_mktable_basic,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_strprop_verify_basic,
+ .st_desc = "string property - basic"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_strprop_mktable_badstr,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_strprop_verify_badstr,
+ .st_desc = "string property - bad string"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_fwinfo_mktable_invlen_base,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_fwinfo_verify_invlen_base,
+ .st_desc = "firmware inventory - bad base length"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_fwinfo_mktable_invlen_comps,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_fwinfo_verify_invlen_comps,
+ .st_desc = "firmware inventory - bad comp length"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_memdevice_mktable_32,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_fwinfo_verify_badtype,
+ .st_desc = "firmware inventory - bad type"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_fwinfo_mktable_nocomps,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_fwinfo_verify_nocomps,
+ .st_desc = "firmware inventory - no components"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_fwinfo_mktable_comps,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_fwinfo_verify_comps,
+ .st_desc = "firmware inventory - components"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION_24,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_chassis_mktable_invlen_base,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_chassis_verify_invlen,
+ .st_desc = "chassis - bad length (2.4 table)"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_chassis_mktable_invlen_base,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_chassis_verify_invlen,
+ .st_desc = "chassis - bad length (latest version)"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_chassis_mktable_base,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_chassis_verify_invlen,
+ .st_desc = "chassis - bad length, expect sku"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION_24,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_chassis_mktable_base,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_chassis_verify_base,
+ .st_desc = "chassis - basic 2.4 version"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_chassis_mktable_sku_nocomps,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_chassis_verify_sku_nocomps,
+ .st_desc = "chassis - sku, but no components"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION_24,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_chassis_mktable_comps,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_chassis_verify_comps,
+ .st_desc = "chassis - 2.4 version with comps"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_chassis_mktable_sku_nocomps,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_chassis_verify_sku_nocomps,
+ .st_desc = "chassis - sku + comps"
+ }
};
static boolean_t
@@ -374,6 +562,26 @@ smbios_test_run_one(const smbios_test_t *test)
ret = B_TRUE;
}
+ if (hdl != NULL && test_dirfd > -1) {
+ int fd;
+ char fname[PATH_MAX];
+
+ (void) snprintf(fname, sizeof (fname), "%s.smbios",
+ test->st_desc);
+ fd = openat(test_dirfd, fname, O_RDWR | O_CREAT, 0644);
+ if (fd < 0) {
+ warn("failed to dump test %s, failed to open output "
+ "file", test->st_desc);
+ } else {
+ if (smbios_write(hdl, fd) != 0) {
+ warnx("failed to dump test %s: %s",
+ test->st_desc,
+ smbios_errmsg(smbios_errno(hdl)));
+ } else {
+ (void) close(fd);
+ }
+ }
+ }
out:
if (hdl != NULL) {
smbios_close(hdl);
@@ -393,16 +601,39 @@ out:
}
int
-main(void)
+main(int argc, char *argv[])
{
- int err = 0;
+ int ret = 0, c;
size_t i;
+ const char *outdir = NULL;
+
+ while ((c = getopt(argc, argv, ":d:")) != -1) {
+ switch (c) {
+ case 'd':
+ outdir = optarg;
+ break;
+ case '?':
+ errx(EXIT_FAILURE, "unknown option: -%c", optopt);
+ case ':':
+ errx(EXIT_FAILURE, "-%c requires an operand", optopt);
+ }
+ }
+
+ if (outdir != NULL) {
+ if ((test_dirfd = open(outdir, O_RDONLY)) < 0) {
+ err(EXIT_FAILURE, "failed to open %s", outdir);
+ }
+ }
for (i = 0; i < ARRAY_SIZE(smbios_tests); i++) {
if (!smbios_test_run_one(&smbios_tests[i])) {
- err = 1;
+ ret = 1;
}
}
- return (err);
+ if (ret == 0) {
+ (void) printf("All tests passed successfully\n");
+ }
+
+ return (ret);
}
diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test.h b/usr/src/test/util-tests/tests/smbios/smbios_test.h
index c6490f1d13..341eb47255 100644
--- a/usr/src/test/util-tests/tests/smbios/smbios_test.h
+++ b/usr/src/test/util-tests/tests/smbios/smbios_test.h
@@ -11,7 +11,7 @@
/*
* Copyright 2019 Robert Mustacchi
- * Copyright 2020 Oxide Computer Company
+ * Copyright 2021 Oxide Computer Company
*/
#ifndef _SMBIOS_TEST_H
@@ -58,6 +58,7 @@ extern void smbios_test_table_append_raw(smbios_test_table_t *, const void *,
size_t);
extern void smbios_test_table_append_string(smbios_test_table_t *,
const char *);
+extern void smbios_test_table_str_fini(smbios_test_table_t *);
extern uint16_t smbios_test_table_append(smbios_test_table_t *, const void *,
size_t);
extern void smbios_test_table_append_eot(smbios_test_table_t *);
@@ -81,10 +82,15 @@ typedef struct smbios_test {
extern boolean_t smbios_test_slot_mktable(smbios_test_table_t *);
extern boolean_t smbios_test_slot_mktable_34_nopeers(smbios_test_table_t *);
extern boolean_t smbios_test_slot_mktable_34_peers(smbios_test_table_t *);
+extern boolean_t smbios_test_slot_mktable_35(smbios_test_table_t *);
extern boolean_t smbios_test_slot_verify(smbios_hdl_t *);
extern boolean_t smbios_test_slot_verify_34_nopeers(smbios_hdl_t *);
extern boolean_t smbios_test_slot_verify_34_peers(smbios_hdl_t *);
+extern boolean_t smbios_test_slot_verify_34_overrun(smbios_hdl_t *);
+extern boolean_t smbios_test_slot_verify_35(smbios_hdl_t *);
+
extern boolean_t smbios_test_badvers_mktable(smbios_test_table_t *);
+extern boolean_t smbios_test_verify_badids(smbios_hdl_t *);
extern boolean_t smbios_test_memdevice_mktable_32(smbios_test_table_t *);
extern boolean_t smbios_test_memdevice_mktable_33(smbios_test_table_t *);
@@ -108,6 +114,39 @@ extern boolean_t smbios_test_pinfo_verify_invlen3(smbios_hdl_t *);
extern boolean_t smbios_test_pinfo_verify_invlen4(smbios_hdl_t *);
extern boolean_t smbios_test_pinfo_verify_badtype(smbios_hdl_t *);
+extern boolean_t smbios_test_strprop_mktable_invlen1(smbios_test_table_t *);
+extern boolean_t smbios_test_strprop_mktable_invlen2(smbios_test_table_t *);
+extern boolean_t smbios_test_strprop_mktable_badstr(smbios_test_table_t *);
+extern boolean_t smbios_test_strprop_mktable_basic(smbios_test_table_t *);
+extern boolean_t smbios_test_strprop_verify_invlen1(smbios_hdl_t *);
+extern boolean_t smbios_test_strprop_verify_invlen2(smbios_hdl_t *);
+extern boolean_t smbios_test_strprop_verify_badstr(smbios_hdl_t *);
+extern boolean_t smbios_test_strprop_verify_badtype(smbios_hdl_t *);
+extern boolean_t smbios_test_strprop_verify_basic(smbios_hdl_t *);
+
+extern boolean_t smbios_test_fwinfo_mktable_invlen_base(smbios_test_table_t *);
+extern boolean_t smbios_test_fwinfo_mktable_invlen_comps(smbios_test_table_t *);
+extern boolean_t smbios_test_fwinfo_mktable_nocomps(smbios_test_table_t *);
+extern boolean_t smbios_test_fwinfo_mktable_comps(smbios_test_table_t *);
+extern boolean_t smbios_test_fwinfo_verify_invlen_base(smbios_hdl_t *);
+extern boolean_t smbios_test_fwinfo_verify_invlen_comps(smbios_hdl_t *);
+extern boolean_t smbios_test_fwinfo_verify_badtype(smbios_hdl_t *);
+extern boolean_t smbios_test_fwinfo_verify_nocomps(smbios_hdl_t *);
+extern boolean_t smbios_test_fwinfo_verify_comps(smbios_hdl_t *);
+
+extern boolean_t smbios_test_verify_strings(smbios_hdl_t *);
+
+extern boolean_t smbios_test_chassis_mktable_invlen_base(smbios_test_table_t *);
+extern boolean_t smbios_test_chassis_mktable_base(smbios_test_table_t *);
+extern boolean_t smbios_test_chassis_mktable_comps(smbios_test_table_t *);
+extern boolean_t smbios_test_chassis_mktable_sku(smbios_test_table_t *);
+extern boolean_t smbios_test_chassis_mktable_sku_nocomps(smbios_test_table_t *);
+extern boolean_t smbios_test_chassis_verify_invlen(smbios_hdl_t *);
+extern boolean_t smbios_test_chassis_verify_base(smbios_hdl_t *);
+extern boolean_t smbios_test_chassis_verify_comps(smbios_hdl_t *);
+extern boolean_t smbios_test_chassis_verify_sku_nocomps(smbios_hdl_t *);
+extern boolean_t smbios_test_chassis_verify_sku(smbios_hdl_t *);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test_chassis.c b/usr/src/test/util-tests/tests/smbios/smbios_test_chassis.c
new file mode 100644
index 0000000000..1d6ef45505
--- /dev/null
+++ b/usr/src/test/util-tests/tests/smbios/smbios_test_chassis.c
@@ -0,0 +1,556 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2021 Oxide Computer Company
+ */
+
+/*
+ * Tests for SMBIOS Type 3 - SMB_TYPE_CHASSIS.
+ */
+
+#include "smbios_test.h"
+
+static const char *smbios_chassis_mfg = "Shrina";
+static const char *smbios_chassis_vers = "7R";
+static const char *smbios_chassis_serial = "What's my number?";
+static const char *smbios_chassis_asset = "lost";
+static const char *smbios_chassis_sku = "Proud";
+static const uint32_t smbios_chassis_oem = 0x36105997;
+static const uint8_t smbios_chassis_uheight = 7;
+
+boolean_t
+smbios_test_chassis_mktable_invlen_base(smbios_test_table_t *table)
+{
+ smb_header_t hdr;
+
+ hdr.smbh_type = SMB_TYPE_CHASSIS;
+ hdr.smbh_len = sizeof (hdr);
+
+ (void) smbios_test_table_append(table, &hdr, sizeof (hdr));
+ smbios_test_table_append_eot(table);
+
+ return (B_TRUE);
+}
+
+static void
+smbios_test_chassis_mktable_fill_chassis(smb_chassis_t *ch)
+{
+ ch->smbch_hdr.smbh_type = SMB_TYPE_CHASSIS;
+ ch->smbch_hdr.smbh_len = sizeof (*ch);
+ ch->smbch_manufacturer = 1;
+ ch->smbch_type = SMB_CHT_LUNCHBOX;
+ ch->smbch_version = 2;
+ ch->smbch_serial = 3;
+ ch->smbch_asset = 4;
+ ch->smbch_bustate = SMB_CHST_SAFE;
+ ch->smbch_psstate = SMB_CHST_NONREC;
+ ch->smbch_thstate = SMB_CHST_WARNING;
+ ch->smbch_security = SMB_CHSC_NONE;
+ ch->smbch_oemdata = htole32(smbios_chassis_oem);
+ ch->smbch_uheight = smbios_chassis_uheight;
+ ch->smbch_cords = smbios_chassis_uheight - 1;
+ ch->smbch_cn = 0;
+ ch->smbch_cm = sizeof (smb_chassis_entry_t);
+}
+
+static void
+smbios_test_chassis_mktable_fill_entries(smb_chassis_entry_t *ents)
+{
+ ents[0].smbce_type = SMB_TYPE_COOLDEV | (1 << 7);
+ ents[0].smbce_min = 1;
+ ents[0].smbce_max = 42;
+ ents[1].smbce_type = SMB_BBT_IO;
+ ents[1].smbce_min = 5;
+ ents[1].smbce_max = 123;
+}
+
+static void
+smbios_test_chassis_mktable_append_strings(smbios_test_table_t *table)
+{
+ smbios_test_table_append_string(table, smbios_chassis_mfg);
+ smbios_test_table_append_string(table, smbios_chassis_vers);
+ smbios_test_table_append_string(table, smbios_chassis_serial);
+ smbios_test_table_append_string(table, smbios_chassis_asset);
+}
+
+/*
+ * This is an SMBIOS 2.4-esque table.
+ */
+boolean_t
+smbios_test_chassis_mktable_base(smbios_test_table_t *table)
+{
+ smb_chassis_t ch;
+
+ smbios_test_chassis_mktable_fill_chassis(&ch);
+ (void) smbios_test_table_append(table, &ch, sizeof (ch));
+ smbios_test_chassis_mktable_append_strings(table);
+ smbios_test_table_str_fini(table);
+ smbios_test_table_append_eot(table);
+
+ return (B_TRUE);
+}
+
+boolean_t
+smbios_test_chassis_mktable_comps(smbios_test_table_t *table)
+{
+ smb_chassis_t ch;
+ smb_chassis_entry_t ents[2];
+
+ smbios_test_chassis_mktable_fill_chassis(&ch);
+ smbios_test_chassis_mktable_fill_entries(ents);
+ ch.smbch_hdr.smbh_len += sizeof (ents);
+ ch.smbch_cn = 2;
+ (void) smbios_test_table_append(table, &ch, sizeof (ch));
+ smbios_test_table_append_raw(table, ents, sizeof (ents));
+ smbios_test_chassis_mktable_append_strings(table);
+ smbios_test_table_str_fini(table);
+ smbios_test_table_append_eot(table);
+
+ return (B_TRUE);
+}
+
+boolean_t
+smbios_test_chassis_mktable_sku_nocomps(smbios_test_table_t *table)
+{
+ smb_chassis_t ch;
+ const uint8_t sku_str = 5;
+
+ smbios_test_chassis_mktable_fill_chassis(&ch);
+ ch.smbch_hdr.smbh_len++;
+ (void) smbios_test_table_append(table, &ch, sizeof (ch));
+ smbios_test_table_append_raw(table, &sku_str, sizeof (sku_str));
+ smbios_test_chassis_mktable_append_strings(table);
+ smbios_test_table_append_string(table, smbios_chassis_sku);
+ smbios_test_table_str_fini(table);
+ smbios_test_table_append_eot(table);
+
+ return (B_TRUE);
+}
+
+boolean_t
+smbios_test_chassis_mktable_sku(smbios_test_table_t *table)
+{
+ smb_chassis_t ch;
+ const uint8_t sku_str = 5;
+ smb_chassis_entry_t ents[2];
+
+ ch.smbch_cn = 2;
+
+ smbios_test_chassis_mktable_fill_chassis(&ch);
+ smbios_test_chassis_mktable_fill_entries(ents);
+ ch.smbch_hdr.smbh_len += sizeof (ents) + 1;
+ (void) smbios_test_table_append(table, &ch, sizeof (ch));
+ smbios_test_table_append_raw(table, &sku_str, sizeof (sku_str));
+ smbios_test_chassis_mktable_append_strings(table);
+ smbios_test_table_append_string(table, smbios_chassis_sku);
+ smbios_test_table_str_fini(table);
+ smbios_test_table_append_eot(table);
+
+ return (B_TRUE);
+}
+
+boolean_t
+smbios_test_chassis_verify_invlen(smbios_hdl_t *hdl)
+{
+ smbios_struct_t sp;
+ smbios_chassis_t ch;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_CHASSIS, &sp) == -1) {
+ warnx("failed to lookup SMBIOS chassis: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_chassis(hdl, sp.smbstr_id, &ch) != -1) {
+ warnx("accidentally parsed invalid chassis as valid");
+ return (B_FALSE);
+ }
+
+ if (smbios_errno(hdl) != ESMB_SHORT) {
+ warnx("encountered wrong error for chassis, expected: "
+ "0x%x, found: 0x%x", ESMB_SHORT, smbios_errno(hdl));
+ return (B_FALSE);
+ }
+
+ return (B_TRUE);
+}
+
+static boolean_t
+smbios_test_chassis_verify_common(smbios_hdl_t *hdl, smbios_struct_t *sp,
+ smbios_chassis_t *ch)
+{
+ boolean_t ret = B_TRUE;
+ smbios_info_t info;
+
+ if (ch->smbc_oemdata != smbios_chassis_oem) {
+ warnx("chassis state mismatch, found unexpected oem data: 0x%x",
+ ch->smbc_oemdata);
+ ret = B_FALSE;
+ }
+
+ if (ch->smbc_lock != 0) {
+ warnx("chassis state mismatch, found unexpected lock: 0x%x",
+ ch->smbc_lock);
+ ret = B_FALSE;
+ }
+
+ if (ch->smbc_type != SMB_CHT_LUNCHBOX) {
+ warnx("chassis state mismatch, found unexpected type: 0x%x",
+ ch->smbc_type);
+ ret = B_FALSE;
+ }
+
+ if (ch->smbc_bustate != SMB_CHST_SAFE) {
+ warnx("chassis state mismatch, found unexpected boot state: "
+ "0x%x", ch->smbc_bustate);
+ ret = B_FALSE;
+ }
+
+ if (ch->smbc_psstate != SMB_CHST_NONREC) {
+ warnx("chassis state mismatch, found unexpected power state: "
+ "0x%x", ch->smbc_psstate);
+ ret = B_FALSE;
+ }
+
+ if (ch->smbc_thstate != SMB_CHST_WARNING) {
+ warnx("chassis state mismatch, found unexpected thermal state: "
+ "0x%x", ch->smbc_thstate);
+ ret = B_FALSE;
+ }
+
+ if (ch->smbc_security != SMB_CHSC_NONE) {
+ warnx("chassis state mismatch, found unexpected security "
+ "value: 0x%x", ch->smbc_security);
+ ret = B_FALSE;
+ }
+
+ if (ch->smbc_uheight != smbios_chassis_uheight) {
+ warnx("chassis state mismatch, found unexpected uheight value: "
+ "0x%x", ch->smbc_uheight);
+ ret = B_FALSE;
+ }
+
+ if (ch->smbc_cords != smbios_chassis_uheight - 1) {
+ warnx("chassis state mismatch, found unexpected cords value: "
+ "0x%x", ch->smbc_cords);
+ ret = B_FALSE;
+ }
+
+ if (ch->smbc_elemlen != sizeof (smb_chassis_entry_t)) {
+ warnx("chassis state mismatch, found unexpected elemlen value: "
+ "0x%x", ch->smbc_elemlen);
+ ret = B_FALSE;
+ }
+
+ if (smbios_info_common(hdl, sp->smbstr_id, &info) != 0) {
+ warnx("failed to get common chassis info: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (strcmp(info.smbi_manufacturer, smbios_chassis_mfg) != 0) {
+ warnx("chassis state mismatch, found unexpected mfg: "
+ "%s", info.smbi_manufacturer);
+ ret = B_FALSE;
+ }
+
+ if (strcmp(info.smbi_version, smbios_chassis_vers) != 0) {
+ warnx("chassis state mismatch, found unexpected version: %s",
+ info.smbi_version);
+ ret = B_FALSE;
+ }
+
+ if (strcmp(info.smbi_serial, smbios_chassis_serial) != 0) {
+ warnx("chassis state mismatch, found unexpected serial: %s",
+ info.smbi_serial);
+ ret = B_FALSE;
+ }
+
+ if (strcmp(info.smbi_asset, smbios_chassis_asset) != 0) {
+ warnx("chassis state mismatch, found unexpected asset: %s",
+ info.smbi_asset);
+ ret = B_FALSE;
+ }
+
+ return (ret);
+}
+
+boolean_t
+smbios_test_chassis_verify_base(smbios_hdl_t *hdl)
+{
+ boolean_t ret = B_TRUE;
+ smbios_struct_t sp;
+ smbios_chassis_t ch;
+ smbios_chassis_entry_t *elts;
+ uint_t nelts;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_CHASSIS, &sp) == -1) {
+ warnx("failed to lookup SMBIOS chassis: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_chassis(hdl, sp.smbstr_id, &ch) == -1) {
+ warnx("failed to get chassis: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (!smbios_test_chassis_verify_common(hdl, &sp, &ch)) {
+ ret = B_FALSE;
+ }
+
+ if (ch.smbc_elems != 0) {
+ warnx("chassis state mismatch, found unexpected number of "
+ "elements: 0x%x", ch.smbc_elems);
+ ret = B_FALSE;
+ }
+
+ if (strcmp(ch.smbc_sku, "") != 0) {
+ warnx("chassis state mismatch, found unexpected sku: %s",
+ ch.smbc_sku);
+ ret = B_FALSE;
+ }
+
+ if (smbios_info_chassis_elts(hdl, sp.smbstr_id, &nelts, &elts) != 0) {
+ warnx("failed to get chassis elements: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (nelts != 0) {
+ warnx("chassis state mismatch, smbios_info_chassis_elts() "
+ "returned a non-zero number of entries: %u", nelts);
+ ret = B_FALSE;
+ }
+
+ if (elts != NULL) {
+ warnx("chassis state mismatch, smbios_info_chassis_elts() "
+ "returned a non-NULL pointer: %p", elts);
+ ret = B_FALSE;
+ }
+
+ return (ret);
+}
+
+boolean_t
+smbios_test_chassis_verify_sku_nocomps(smbios_hdl_t *hdl)
+{
+ boolean_t ret = B_TRUE;
+ smbios_struct_t sp;
+ smbios_chassis_t ch;
+ smbios_chassis_entry_t *elts;
+ uint_t nelts;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_CHASSIS, &sp) == -1) {
+ warnx("failed to lookup SMBIOS chassis: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_chassis(hdl, sp.smbstr_id, &ch) == -1) {
+ warnx("failed to get chassis: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (!smbios_test_chassis_verify_common(hdl, &sp, &ch)) {
+ ret = B_FALSE;
+ }
+
+ if (ch.smbc_elems != 0) {
+ warnx("chassis state mismatch, found unexpected number of "
+ "elements: 0x%x", ch.smbc_elems);
+ ret = B_FALSE;
+ }
+
+ if (strcmp(ch.smbc_sku, smbios_chassis_sku) != 0) {
+ warnx("chassis state mismatch, found unexpected sku: %s",
+ ch.smbc_sku);
+ ret = B_FALSE;
+ }
+
+ if (smbios_info_chassis_elts(hdl, sp.smbstr_id, &nelts, &elts) != 0) {
+ warnx("failed to get chassis elements: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (nelts != 0) {
+ warnx("chassis state mismatch, smbios_info_chassis_elts() "
+ "returned a non-zero number of entries: %u", nelts);
+ ret = B_FALSE;
+ }
+
+ if (elts != NULL) {
+ warnx("chassis state mismatch, smbios_info_chassis_elts() "
+ "returned a non-NULL pointer: %p", elts);
+ ret = B_FALSE;
+ }
+
+
+ return (ret);
+}
+
+static boolean_t
+smbios_test_chassis_verify_common_comps(smbios_hdl_t *hdl, smbios_struct_t *sp)
+{
+ boolean_t ret = B_TRUE;
+ smbios_chassis_entry_t *elts;
+ uint_t nelts;
+
+ if (smbios_info_chassis_elts(hdl, sp->smbstr_id, &nelts, &elts) != 0) {
+ warnx("failed to get chassis elements: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (nelts != 2) {
+ warnx("chassis state mismatch, smbios_info_chassis_elts() "
+ "returned the wrong number of entries: %u", nelts);
+ return (B_FALSE);
+ }
+
+ if (elts[0].smbce_type != SMB_CELT_SMBIOS) {
+ warnx("chassis elts[0] type mismatch, found: %u",
+ elts[0].smbce_type);
+ ret = B_FALSE;
+ }
+
+ if (elts[0].smbce_elt != SMB_TYPE_COOLDEV) {
+ warnx("chassis elts[0] elt type mismatch, found: %u",
+ elts[0].smbce_elt);
+ ret = B_FALSE;
+ }
+
+ if (elts[0].smbce_min != 1) {
+ warnx("chassis elts[0] minimum number mismatch, found: %u",
+ elts[0].smbce_min);
+ ret = B_FALSE;
+ }
+
+ if (elts[0].smbce_max != 42) {
+ warnx("chassis elts[0] maximum number mismatch, found: %u",
+ elts[0].smbce_max);
+ ret = B_FALSE;
+ }
+
+ if (elts[1].smbce_type != SMB_CELT_BBOARD) {
+ warnx("chassis elts[1] type mismatch, found: %u",
+ elts[1].smbce_type);
+ ret = B_FALSE;
+ }
+
+ if (elts[1].smbce_elt != SMB_BBT_IO) {
+ warnx("chassis elts[1] elt type mismatch, found: %u",
+ elts[1].smbce_elt);
+ ret = B_FALSE;
+ }
+
+ if (elts[1].smbce_min != 5) {
+ warnx("chassis elts[1] minimum number mismatch, found: %u",
+ elts[1].smbce_min);
+ ret = B_FALSE;
+ }
+
+ if (elts[1].smbce_max != 123) {
+ warnx("chassis elts[1] maximum number mismatch, found: %u",
+ elts[1].smbce_max);
+ ret = B_FALSE;
+ }
+ return (ret);
+}
+
+boolean_t
+smbios_test_chassis_verify_comps(smbios_hdl_t *hdl)
+{
+ boolean_t ret = B_TRUE;
+ smbios_struct_t sp;
+ smbios_chassis_t ch;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_CHASSIS, &sp) == -1) {
+ warnx("failed to lookup SMBIOS chassis: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_chassis(hdl, sp.smbstr_id, &ch) == -1) {
+ warnx("failed to get chassis: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (!smbios_test_chassis_verify_common(hdl, &sp, &ch)) {
+ ret = B_FALSE;
+ }
+
+ if (ch.smbc_elems != 2) {
+ warnx("chassis state mismatch, found unexpected number of "
+ "elements: 0x%x", ch.smbc_elems);
+ ret = B_FALSE;
+ }
+
+ if (strcmp(ch.smbc_sku, "") != 0) {
+ warnx("chassis state mismatch, found unexpected sku: %s",
+ ch.smbc_sku);
+ ret = B_FALSE;
+ }
+
+ if (!smbios_test_chassis_verify_common_comps(hdl, &sp)) {
+ ret = B_FALSE;
+ }
+
+ return (ret);
+}
+
+
+boolean_t
+smbios_test_chassis_verify_sku(smbios_hdl_t *hdl)
+{
+ boolean_t ret = B_TRUE;
+ smbios_struct_t sp;
+ smbios_chassis_t ch;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_CHASSIS, &sp) == -1) {
+ warnx("failed to lookup SMBIOS chassis: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_chassis(hdl, sp.smbstr_id, &ch) == -1) {
+ warnx("failed to get chassis: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (!smbios_test_chassis_verify_common(hdl, &sp, &ch)) {
+ ret = B_FALSE;
+ }
+
+ if (ch.smbc_elems != 2) {
+ warnx("chassis state mismatch, found unexpected number of "
+ "elements: 0x%x", ch.smbc_elems);
+ ret = B_FALSE;
+ }
+
+ if (strcmp(ch.smbc_sku, smbios_chassis_sku) != 0) {
+ warnx("chassis state mismatch, found unexpected sku: %s",
+ ch.smbc_sku);
+ ret = B_FALSE;
+ }
+
+ if (!smbios_test_chassis_verify_common_comps(hdl, &sp)) {
+ ret = B_FALSE;
+ }
+
+ return (ret);
+}
diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test_errors.c b/usr/src/test/util-tests/tests/smbios/smbios_test_errors.c
index 0bca13c7bb..5211eebc74 100644
--- a/usr/src/test/util-tests/tests/smbios/smbios_test_errors.c
+++ b/usr/src/test/util-tests/tests/smbios/smbios_test_errors.c
@@ -11,6 +11,7 @@
/*
* Copyright 2019 Robert Mustacchi
+ * Copyright 2021 Oxide Computer Company
*/
/*
@@ -26,3 +27,63 @@ smbios_test_badvers_mktable(smbios_test_table_t *table)
smbios_test_table_append_eot(table);
return (B_TRUE);
}
+
+typedef int (*smbios_lookup_f)(smbios_hdl_t *, id_t, void *);
+typedef struct {
+ smbios_lookup_f sif_func;
+ const char *sif_name;
+} smbios_info_func_t;
+
+static smbios_info_func_t smbios_lookup_funcs[] = {
+ { (smbios_lookup_f)smbios_info_bboard, "bboard" },
+ { (smbios_lookup_f)smbios_info_chassis, "chassis" },
+ { (smbios_lookup_f)smbios_info_processor, "processor" },
+ { (smbios_lookup_f)smbios_info_extprocessor, "extprocessor" },
+ { (smbios_lookup_f)smbios_info_cache, "cache" },
+ { (smbios_lookup_f)smbios_info_pointdev, "pointdev" },
+ { (smbios_lookup_f)smbios_info_battery, "battery" },
+ { (smbios_lookup_f)smbios_info_port, "port" },
+ { (smbios_lookup_f)smbios_info_extport, "extport" },
+ { (smbios_lookup_f)smbios_info_slot, "slot" },
+ { (smbios_lookup_f)smbios_info_obdevs_ext, "obdevs_ext" },
+ { (smbios_lookup_f)smbios_info_memarray, "memarray" },
+ { (smbios_lookup_f)smbios_info_extmemarray, "extmemarray" },
+ { (smbios_lookup_f)smbios_info_memarrmap, "memarrmap" },
+ { (smbios_lookup_f)smbios_info_memdevice, "memdevice" },
+ { (smbios_lookup_f)smbios_info_extmemdevice, "extmemdevice" },
+ { (smbios_lookup_f)smbios_info_memdevmap, "memdevmap" },
+ { (smbios_lookup_f)smbios_info_vprobe, "vprobe" },
+ { (smbios_lookup_f)smbios_info_cooldev, "cooldev" },
+ { (smbios_lookup_f)smbios_info_tprobe, "tprobe" },
+ { (smbios_lookup_f)smbios_info_iprobe, "iprobe" },
+ { (smbios_lookup_f)smbios_info_powersup, "powersup" },
+ { (smbios_lookup_f)smbios_info_pciexrc, "pciexrc" },
+ { (smbios_lookup_f)smbios_info_processor_info, "processor_info" },
+ { (smbios_lookup_f)smbios_info_processor_riscv, "processor_riscv" },
+ { (smbios_lookup_f)smbios_info_strprop, "strprop" },
+ { (smbios_lookup_f)smbios_info_fwinfo, "fwinfo" }
+};
+
+/*
+ * Go through and verify that if we give an explicit lookup a bad id, it
+ * properly detects that and errors. We simply use SMB_ID_NOTSUP, which should
+ * always trigger the internal lookup to fail. In addition, we always pass NULL
+ * for the actual data pointer to make sure that if we get further, we'll crash
+ * on writing to a NULL pointer.
+ */
+boolean_t
+smbios_test_verify_badids(smbios_hdl_t *hdl)
+{
+ boolean_t ret = B_TRUE;
+
+ for (size_t i = 0; i < ARRAY_SIZE(smbios_lookup_funcs); i++) {
+ if (smbios_lookup_funcs[i].sif_func(hdl, SMB_ID_NOTSUP, NULL) !=
+ -1) {
+ warnx("smbios_info_%s somehow didn't fail?!",
+ smbios_lookup_funcs[i].sif_name);
+ ret = B_FALSE;
+ }
+ }
+
+ return (ret);
+}
diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test_fwinfo.c b/usr/src/test/util-tests/tests/smbios/smbios_test_fwinfo.c
new file mode 100644
index 0000000000..4567293590
--- /dev/null
+++ b/usr/src/test/util-tests/tests/smbios/smbios_test_fwinfo.c
@@ -0,0 +1,429 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2021 Oxide Computer Company
+ */
+
+/*
+ * Tests for SMBIOS type 46 - SMB_TYPE_STRPROP.
+ */
+
+#include "smbios_test.h"
+
+static const char *smbios_fwinfo_name = "Sheikah Slate";
+static const char *smbios_fwinfo_vers = "1.3.1";
+static const char *smbios_fwinfo_id = "ganon";
+static const char *smbios_fwinfo_reldate = "2017-03-03";
+static const char *smbios_fwinfo_mfg = "The Goddess Hylia";
+static const char *smbios_fwinfo_lsv = "zelda";
+static const uint64_t smbios_fwinfo_size = 0xb0111b;
+static const uint_t smbios_fwinfo_ncomps = 23;
+static const uint8_t smbios_fwinfo_versid = 0x66;
+
+static void
+smbios_test_fwinfo_mktable_common_fwinfo(smb_fwinfo_t *fw)
+{
+ fw->smbfwii_hdr.smbh_type = SMB_TYPE_FWINFO;
+ fw->smbfwii_hdr.smbh_len = sizeof (*fw);
+ fw->smbfwii_name = 1;
+ fw->smbfwii_vers = 2;
+ fw->smbfwii_vers_fmt = smbios_fwinfo_versid;
+ fw->smbfwii_id = 3;
+ fw->smbfwii_id_fmt = smbios_fwinfo_versid;
+ fw->smbfwii_reldate = 4;
+ fw->smbfwii_mfg = 5;
+ fw->smbfwii_lsv = 6;
+ fw->smbfwii_imgsz = htole64(smbios_fwinfo_size);
+ fw->smbfwii_chars = SMB_FWC_WP;
+ fw->smbfwii_state = SMB_FWS_UA_OFFLINE;
+ fw->smbfwii_ncomps = 0;
+}
+
+static void
+smbios_test_fwinfo_mktable_common_fini(smbios_test_table_t *table)
+{
+ smbios_test_table_append_string(table, smbios_fwinfo_name);
+ smbios_test_table_append_string(table, smbios_fwinfo_vers);
+ smbios_test_table_append_string(table, smbios_fwinfo_id);
+ smbios_test_table_append_string(table, smbios_fwinfo_reldate);
+ smbios_test_table_append_string(table, smbios_fwinfo_mfg);
+ smbios_test_table_append_string(table, smbios_fwinfo_lsv);
+ smbios_test_table_str_fini(table);
+ smbios_test_table_append_eot(table);
+}
+
+/*
+ * Generate a table that's too short to get basic info.
+ */
+boolean_t
+smbios_test_fwinfo_mktable_invlen_base(smbios_test_table_t *table)
+{
+ smb_header_t hdr;
+
+ hdr.smbh_type = SMB_TYPE_FWINFO;
+ hdr.smbh_len = sizeof (hdr);
+
+ (void) smbios_test_table_append(table, &hdr, sizeof (hdr));
+ smbios_test_table_append_eot(table);
+
+ return (B_TRUE);
+}
+
+/*
+ * Generate a table where the table is too short for a specified number of
+ * components.
+ */
+boolean_t
+smbios_test_fwinfo_mktable_invlen_comps(smbios_test_table_t *table)
+{
+ smb_fwinfo_t fw;
+
+ smbios_test_fwinfo_mktable_common_fwinfo(&fw);
+ fw.smbfwii_ncomps = smbios_fwinfo_ncomps;
+ (void) smbios_test_table_append(table, &fw, sizeof (fw));
+ smbios_test_fwinfo_mktable_common_fini(table);
+
+ return (B_TRUE);
+}
+
+boolean_t
+smbios_test_fwinfo_mktable_nocomps(smbios_test_table_t *table)
+{
+ smb_fwinfo_t fw;
+
+ smbios_test_fwinfo_mktable_common_fwinfo(&fw);
+ (void) smbios_test_table_append(table, &fw, sizeof (fw));
+ smbios_test_fwinfo_mktable_common_fini(table);
+
+ return (B_TRUE);
+}
+
+boolean_t
+smbios_test_fwinfo_mktable_comps(smbios_test_table_t *table)
+{
+ smb_fwinfo_t fw;
+
+ smbios_test_fwinfo_mktable_common_fwinfo(&fw);
+
+ fw.smbfwii_hdr.smbh_len += smbios_fwinfo_ncomps * sizeof (uint16_t);
+ fw.smbfwii_ncomps = smbios_fwinfo_ncomps;
+ (void) smbios_test_table_append(table, &fw, sizeof (fw));
+
+ for (uint_t i = 0; i < fw.smbfwii_ncomps; i++) {
+ uint16_t comp = 0x2300 + i;
+
+ smbios_test_table_append_raw(table, &comp, sizeof (comp));
+ }
+ smbios_test_fwinfo_mktable_common_fini(table);
+
+ return (B_TRUE);
+}
+
+boolean_t
+smbios_test_fwinfo_verify_badtype(smbios_hdl_t *hdl)
+{
+ smbios_struct_t sp;
+ smbios_fwinfo_t fw;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_MEMDEVICE, &sp) == -1) {
+ warnx("failed to lookup SMBIOS memory device: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_fwinfo(hdl, sp.smbstr_id, &fw) != -1) {
+ warnx("accidentally parsed invalid fwinfo information as "
+ "valid");
+ return (B_FALSE);
+ }
+
+ if (smbios_errno(hdl) != ESMB_TYPE) {
+ warnx("encountered wrong error for fwinfo, expected: "
+ "0x%x, found: 0x%x", ESMB_SHORT, smbios_errno(hdl));
+ return (B_FALSE);
+ }
+
+ return (B_TRUE);
+}
+
+boolean_t
+smbios_test_fwinfo_verify_invlen_base(smbios_hdl_t *hdl)
+{
+ smbios_struct_t sp;
+ smbios_fwinfo_t fw;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_FWINFO, &sp) == -1) {
+ warnx("failed to lookup SMBIOS fwinfo: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_fwinfo(hdl, sp.smbstr_id, &fw) != -1) {
+ warnx("accidentally parsed invalid fwinfo information as "
+ "valid");
+ return (B_FALSE);
+ }
+
+ if (smbios_errno(hdl) != ESMB_SHORT) {
+ warnx("encountered wrong error for fwinfo, expected: "
+ "0x%x, found: 0x%x", ESMB_SHORT, smbios_errno(hdl));
+ return (B_FALSE);
+ }
+
+ return (B_TRUE);
+}
+
+static boolean_t
+smbios_test_fwinfo_verify_common(smbios_hdl_t *hdl, smbios_struct_t *sp,
+ const smbios_fwinfo_t *fw)
+{
+ boolean_t ret = B_TRUE;
+ smbios_info_t info;
+
+ if (strcmp(fw->smbfw_name, smbios_fwinfo_name) != 0) {
+ warnx("firmware inventory name mismatch, found %s",
+ fw->smbfw_name);
+ ret = B_FALSE;
+ }
+
+ if (strcmp(fw->smbfw_id, smbios_fwinfo_id) != 0) {
+ warnx("firmware inventory id mismatch, found %s",
+ fw->smbfw_id);
+ ret = B_FALSE;
+ }
+
+ if (strcmp(fw->smbfw_reldate, smbios_fwinfo_reldate) != 0) {
+ warnx("firmware inventory release date mismatch, found %s",
+ fw->smbfw_reldate);
+ ret = B_FALSE;
+ }
+
+ if (strcmp(fw->smbfw_lsv, smbios_fwinfo_lsv) != 0) {
+ warnx("firmware inventory lsv mismatch, found %s",
+ fw->smbfw_lsv);
+ ret = B_FALSE;
+ }
+
+ if (fw->smbfw_imgsz != smbios_fwinfo_size) {
+ warnx("firmware inventory size mismatch, found 0x%" PRIx64,
+ fw->smbfw_imgsz);
+ ret = B_FALSE;
+ }
+
+ if (fw->smbfw_chars != SMB_FWC_WP) {
+ warnx("firmware inventory chars mismatch, found 0x%x",
+ fw->smbfw_chars);
+ ret = B_FALSE;
+ }
+
+ if (fw->smbfw_state != SMB_FWS_UA_OFFLINE) {
+ warnx("firmware inventory state mismatch, found 0x%x",
+ fw->smbfw_state);
+ ret = B_FALSE;
+ }
+
+ if (fw->smbfw_vers_fmt != smbios_fwinfo_versid) {
+ warnx("firmware inventory version format mismatch, found 0x%x",
+ fw->smbfw_vers_fmt);
+ ret = B_FALSE;
+ }
+
+ if (fw->smbfw_id_fmt != smbios_fwinfo_versid) {
+ warnx("firmware inventory ID format mismatch, found 0x%x",
+ fw->smbfw_id_fmt);
+ ret = B_FALSE;
+ }
+
+ if (smbios_info_common(hdl, sp->smbstr_id, &info) == -1) {
+ warnx("failed to get firmware inventory common items: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (strcmp(info.smbi_manufacturer, smbios_fwinfo_mfg) != 0) {
+ warnx("firmware inventory manufacturer mismatch, found %s",
+ info.smbi_manufacturer);
+ ret = B_FALSE;
+ }
+
+ if (strcmp(info.smbi_version, smbios_fwinfo_vers) != 0) {
+ warnx("firmware inventory version mismatch, found %s",
+ info.smbi_version);
+ ret = B_FALSE;
+ }
+
+ return (ret);
+}
+
+boolean_t
+smbios_test_fwinfo_verify_nocomps(smbios_hdl_t *hdl)
+{
+ smbios_struct_t sp;
+ smbios_fwinfo_t fw;
+ uint_t ncomps;
+ smbios_fwinfo_comp_t *comps;
+ boolean_t ret = B_TRUE;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_FWINFO, &sp) == -1) {
+ warnx("failed to lookup SMBIOS fwinfo: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_fwinfo(hdl, sp.smbstr_id, &fw) == -1) {
+ warnx("failed to get firmware inventory: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (!smbios_test_fwinfo_verify_common(hdl, &sp, &fw)) {
+ ret = B_FALSE;
+ }
+
+ if (fw.smbfw_ncomps != 0) {
+ warnx("firmware inventory ncomps mismatch, found 0x%x",
+ fw.smbfw_ncomps);
+ ret = B_FALSE;
+ }
+
+ if (smbios_info_fwinfo_comps(hdl, sp.smbstr_id, &ncomps, &comps) != 0) {
+ warnx("failed to get components: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ ret = B_FALSE;
+ }
+
+ if (ncomps != 0) {
+ warnx("smbios_info_fwinfo_comps() returned wrong number of "
+ "comps: 0x%x", ncomps);
+ ret = B_FALSE;
+ }
+
+ if (comps != NULL) {
+ warnx("smbios_info_fwinfo_comps() gave a non-NULL comps "
+ "pointer: %p", comps);
+ ret = B_FALSE;
+ }
+
+ smbios_info_fwinfo_comps_free(hdl, ncomps, comps);
+
+ return (ret);
+}
+
+boolean_t
+smbios_test_fwinfo_verify_invlen_comps(smbios_hdl_t *hdl)
+{
+ smbios_struct_t sp;
+ smbios_fwinfo_t fw;
+ uint_t ncomps;
+ smbios_fwinfo_comp_t *comps;
+ boolean_t ret = B_TRUE;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_FWINFO, &sp) == -1) {
+ warnx("failed to lookup SMBIOS fwinfo: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_fwinfo(hdl, sp.smbstr_id, &fw) == -1) {
+ warnx("failed to get firmware inventory: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (!smbios_test_fwinfo_verify_common(hdl, &sp, &fw)) {
+ ret = B_FALSE;
+ }
+
+ if (fw.smbfw_ncomps != smbios_fwinfo_ncomps) {
+ warnx("firmware inventory ncomps mismatch, found 0x%x",
+ fw.smbfw_ncomps);
+ ret = B_FALSE;
+ }
+
+ if (smbios_info_fwinfo_comps(hdl, sp.smbstr_id, &ncomps, &comps) !=
+ -1) {
+ warnx("accidentally parsed invalid fwinfo components as "
+ "valid");
+ return (B_FALSE);
+ }
+
+ if (smbios_errno(hdl) != ESMB_SHORT) {
+ warnx("encountered wrong error for fwinfo comps, expected: "
+ "0x%x, found: 0x%x", ESMB_SHORT, smbios_errno(hdl));
+ return (B_FALSE);
+ }
+
+ return (ret);
+}
+
+
+
+boolean_t
+smbios_test_fwinfo_verify_comps(smbios_hdl_t *hdl)
+{
+ smbios_struct_t sp;
+ smbios_fwinfo_t fw;
+ uint_t ncomps;
+ smbios_fwinfo_comp_t *comps;
+ boolean_t ret = B_TRUE;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_FWINFO, &sp) == -1) {
+ warnx("failed to lookup SMBIOS fwinfo: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_fwinfo(hdl, sp.smbstr_id, &fw) == -1) {
+ warnx("failed to get firmware inventory: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (!smbios_test_fwinfo_verify_common(hdl, &sp, &fw)) {
+ ret = B_FALSE;
+ }
+
+ if (fw.smbfw_ncomps != smbios_fwinfo_ncomps) {
+ warnx("firmware inventory ncomps mismatch, found 0x%x",
+ fw.smbfw_ncomps);
+ ret = B_FALSE;
+ }
+
+ if (smbios_info_fwinfo_comps(hdl, sp.smbstr_id, &ncomps, &comps) != 0) {
+ warnx("failed to get components: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ ret = B_FALSE;
+ }
+
+ if (ncomps != smbios_fwinfo_ncomps) {
+ warnx("smbios_info_fwinfo_comps() returned wrong number of "
+ "comps: 0x%x", ncomps);
+ ret = B_FALSE;
+ }
+
+ if (comps == NULL) {
+ warnx("smbios_info_fwinfo_comps() gave a NULL comps pointer");
+ ret = B_FALSE;
+ } else {
+ for (uint_t i = 0; i < smbios_fwinfo_ncomps; i++) {
+ if (comps[i].smbfwe_id != 0x2300 + i) {
+ warnx("component id %u is wrong: 0x%x", i,
+ comps[i]);
+ ret = B_FALSE;
+ }
+ }
+ }
+
+ smbios_info_fwinfo_comps_free(hdl, ncomps, comps);
+
+ return (ret);
+}
diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test_pinfo.c b/usr/src/test/util-tests/tests/smbios/smbios_test_pinfo.c
index 178de212ae..a3455f9de7 100644
--- a/usr/src/test/util-tests/tests/smbios/smbios_test_pinfo.c
+++ b/usr/src/test/util-tests/tests/smbios/smbios_test_pinfo.c
@@ -11,6 +11,7 @@
/*
* Copyright 2019 Robert Mustacchi
+ * Copyright 2021 Oxide Computer Company
*/
/*
@@ -330,13 +331,13 @@ smbios_test_pinfo_verify_riscv(smbios_hdl_t *hdl)
}
if (strcmp(smbios_riscv_isa_desc(SMB_RV_ISA_C), "Compressed") != 0) {
- warnx("SMB_RV_ISA_Q string desc mismatch, found %s",
+ warnx("SMB_RV_ISA_C string desc mismatch, found %s",
smbios_riscv_isa_desc(SMB_RV_ISA_C));
ret = B_FALSE;
}
if (strcmp(smbios_riscv_isa_desc(SMB_RV_ISA_Q),
- "Quad-precision floating-poit") != 0) {
+ "Quad-precision floating-point") != 0) {
warnx("SMB_RV_ISA_Q string desc mismatch, found %s",
smbios_riscv_isa_desc(SMB_RV_ISA_Q));
ret = B_FALSE;
diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c b/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c
index 95a709a088..819234aece 100644
--- a/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c
+++ b/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c
@@ -11,7 +11,7 @@
/*
* Copyright (c) 2018, Joyent, Inc.
- * Copyright 2020 Oxide Computer Company
+ * Copyright 2021 Oxide Computer Company
*/
/*
@@ -26,6 +26,8 @@ static uint8_t smbios_slot_df = 0x23;
static uint8_t smbios_slot_info = 0x65;
static uint16_t smbios_slot_pitch = 0x12af;
+static size_t smbios_slot_34_contlen = offsetof(smb_slot_cont_t, smbsl_height);
+
static void
smbios_test_slot_fill(smb_slot_t *slot)
{
@@ -50,7 +52,6 @@ smbios_test_slot_mktable(smbios_test_table_t *table)
{
smb_slot_t slot;
smb_slot_peer_t peers[2];
- const uint8_t endstring = 0;
smbios_test_slot_fill(&slot);
@@ -68,61 +69,72 @@ smbios_test_slot_mktable(smbios_test_table_t *table)
peers[1].smbspb_width = SMB_SLW_8X;
(void) smbios_test_table_append(table, &slot, sizeof (slot));
- (void) smbios_test_table_append_raw(table, peers, sizeof (peers));
- (void) smbios_test_table_append_string(table, smbios_test_name);
- (void) smbios_test_table_append_raw(table, &endstring,
- sizeof (endstring));
+ smbios_test_table_append_raw(table, peers, sizeof (peers));
+ smbios_test_table_append_string(table, smbios_test_name);
+ smbios_test_table_str_fini(table);
smbios_test_table_append_eot(table);
return (B_TRUE);
}
-/*
- * 3.4 introduced additional data after peers. This verison constructs a variant
- * with no peers.
- */
-boolean_t
-smbios_test_slot_mktable_34_nopeers(smbios_test_table_t *table)
+static boolean_t
+smbios_test_slot_mktable_nopeers(smbios_test_table_t *table, boolean_t is_35)
{
smb_slot_t slot;
smb_slot_cont_t cont;
- const uint8_t endstring = 0;
+ size_t contlen;
+
+ if (is_35) {
+ contlen = sizeof (cont);
+ } else {
+ contlen = smbios_slot_34_contlen;
+ }
smbios_test_slot_fill(&slot);
- slot.smbsl_hdr.smbh_len = SMB_SLOT_CONT_START + sizeof (cont);
+ slot.smbsl_hdr.smbh_len = SMB_SLOT_CONT_START + contlen;
cont.smbsl_info = smbios_slot_info;
cont.smbsl_pwidth = SMB_SLW_32X;
cont.smbsl_pitch = htole16(smbios_slot_pitch);
+ cont.smbsl_height = SMB_SLHT_LP;
(void) smbios_test_table_append(table, &slot, sizeof (slot));
- /*
- * Append a raw zero to fill in the gaps that the peers would have had
- * so the cont structure starts at the right offset.
- */
- (void) smbios_test_table_append_raw(table, &endstring,
- sizeof (endstring));
- (void) smbios_test_table_append_raw(table, &cont, sizeof (cont));
- (void) smbios_test_table_append_string(table, smbios_test_name);
- (void) smbios_test_table_append_raw(table, &endstring,
- sizeof (endstring));
+ smbios_test_table_append_raw(table, &cont, contlen);
+ smbios_test_table_append_string(table, smbios_test_name);
+ smbios_test_table_str_fini(table);
smbios_test_table_append_eot(table);
+
return (B_TRUE);
}
+/*
+ * 3.4 introduced additional data after peers. This version constructs a variant
+ * with no peers.
+ */
+boolean_t
+smbios_test_slot_mktable_34_nopeers(smbios_test_table_t *table)
+{
+ return (smbios_test_slot_mktable_nopeers(table, B_FALSE));
+}
+
+boolean_t
+smbios_test_slot_mktable_35(smbios_test_table_t *table)
+{
+ return (smbios_test_slot_mktable_nopeers(table, B_TRUE));
+}
+
boolean_t
smbios_test_slot_mktable_34_peers(smbios_test_table_t *table)
{
smb_slot_t slot;
smb_slot_cont_t cont;
smb_slot_peer_t peers[1];
- const uint8_t endstring = 0;
smbios_test_slot_fill(&slot);
slot.smbsl_npeers = 1;
slot.smbsl_hdr.smbh_len = SMB_SLOT_CONT_START + 5 * slot.smbsl_npeers +
- sizeof (cont);
+ smbios_slot_34_contlen;
peers[0].smbspb_group_no = htole16(1);
peers[0].smbspb_bus = 0x42;
@@ -134,18 +146,14 @@ smbios_test_slot_mktable_34_peers(smbios_test_table_t *table)
cont.smbsl_pitch = htole16(smbios_slot_pitch);
(void) smbios_test_table_append(table, &slot, sizeof (slot));
- (void) smbios_test_table_append_raw(table, peers, sizeof (peers));
- (void) smbios_test_table_append_raw(table, &endstring,
- sizeof (endstring));
- (void) smbios_test_table_append_raw(table, &cont, sizeof (cont));
- (void) smbios_test_table_append_string(table, smbios_test_name);
- (void) smbios_test_table_append_raw(table, &endstring,
- sizeof (endstring));
+ smbios_test_table_append_raw(table, peers, sizeof (peers));
+ smbios_test_table_append_raw(table, &cont, smbios_slot_34_contlen);
+ smbios_test_table_append_string(table, smbios_test_name);
+ smbios_test_table_str_fini(table);
smbios_test_table_append_eot(table);
return (B_TRUE);
}
-
static boolean_t
smbios_test_slot_common(smbios_slot_t *slot)
{
@@ -306,13 +314,64 @@ smbios_test_slot_verify(smbios_hdl_t *hdl)
return (B_TRUE);
}
+static boolean_t
+smbios_test_slot_common_nopeers(smbios_hdl_t *hdl, smbios_struct_t *sp,
+ smbios_slot_t *slot)
+{
+ uint_t errs = 0;
+ uint_t npeers;
+ smbios_slot_peer_t *peers;
+
+ if (slot->smbl_npeers != 0) {
+ warnx("incorrect number of slot peers, found %u",
+ slot->smbl_npeers);
+ errs++;
+ }
+
+ if (smbios_info_slot_peers(hdl, sp->smbstr_id, &npeers, &peers) != 0) {
+ warnx("failed to get SMBIOS peer info: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (npeers != 0) {
+ warnx("got wrong number of slot peers: %u", npeers);
+ errs++;
+ }
+
+ if (peers != NULL) {
+ warnx("expected NULL peers pointer, but found %p", peers);
+ errs++;
+ }
+
+ smbios_info_slot_peers_free(hdl, npeers, peers);
+
+ if (slot->smbl_info != smbios_slot_info) {
+ warnx("found wrong slot info: 0x%x, expected 0x%x",
+ slot->smbl_info, smbios_slot_info);
+ errs++;
+ }
+
+ if (slot->smbl_pwidth != SMB_SLW_32X) {
+ warnx("found wrong slot physical width: 0x%x, expected 0x%x",
+ slot->smbl_pwidth, SMB_SLW_32X);
+ errs++;
+ }
+
+ if (slot->smbl_pitch != smbios_slot_pitch) {
+ warnx("found wrong slot pitch: 0x%x, expected 0x%x",
+ slot->smbl_pitch, smbios_slot_pitch);
+ errs++;
+ }
+
+ return (errs == 0);
+}
+
boolean_t
smbios_test_slot_verify_34_nopeers(smbios_hdl_t *hdl)
{
smbios_struct_t sp;
smbios_slot_t slot;
- uint_t npeers;
- smbios_slot_peer_t *peers;
uint_t errs = 0;
if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) {
@@ -331,45 +390,98 @@ smbios_test_slot_verify_34_nopeers(smbios_hdl_t *hdl)
errs++;
}
- if (slot.smbl_npeers != 0) {
- warnx("incorrect number of slot peers, found %u",
- slot.smbl_npeers);
+ if (!smbios_test_slot_common_nopeers(hdl, &sp, &slot)) {
errs++;
}
- if (smbios_info_slot_peers(hdl, sp.smbstr_id, &npeers, &peers) != 0) {
- warnx("failed to get SMBIOS peer info: %s",
+ if (errs > 0) {
+ return (B_FALSE);
+ }
+
+ return (B_TRUE);
+}
+
+/*
+ * This is a variant of smbios_test_slot_verify_34_nopeers() that specifically
+ * uses an older library version and ensures that we don't overrun the
+ * smbios_slot_t.
+ */
+boolean_t
+smbios_test_slot_verify_34_overrun(smbios_hdl_t *hdl)
+{
+ smbios_struct_t sp;
+ smbios_slot_t slot;
+ uint_t errs = 0;
+
+ /*
+ * We purposefully set the values that are part of SMBIOS 3.5+ to bad
+ * values to make sure that we don't end up zeroing them.
+ */
+ slot.smbl_height = 0xba;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) {
+ warnx("failed to lookup SMBIOS slot: %s",
smbios_errmsg(smbios_errno(hdl)));
return (B_FALSE);
}
- if (npeers != 0) {
- warnx("got wrong number of slot peers: %u", npeers);
+ if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) {
+ warnx("failed to get SMBIOS slot info: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (slot.smbl_height != 0xba) {
+ warnx("smbios 3.4 slot structure was overrun, smbl_height "
+ "unexpectedly set to 0x%x", slot.smbl_height);
errs++;
}
- if (peers != NULL) {
- warnx("expected NULL peers pointer, but found %p", peers);
+ if (!smbios_test_slot_common(&slot)) {
errs++;
}
- smbios_info_slot_peers_free(hdl, npeers, peers);
+ if (!smbios_test_slot_common_nopeers(hdl, &sp, &slot)) {
+ errs++;
+ }
- if (slot.smbl_info != smbios_slot_info) {
- warnx("found wrong slot info: 0x%x, expected 0x%x",
- slot.smbl_info, smbios_slot_info);
+ if (errs > 0) {
+ return (B_FALSE);
+ }
+
+ return (B_TRUE);
+}
+
+boolean_t
+smbios_test_slot_verify_35(smbios_hdl_t *hdl)
+{
+ smbios_struct_t sp;
+ smbios_slot_t slot;
+ uint_t errs = 0;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) {
+ warnx("failed to lookup SMBIOS slot: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) {
+ warnx("failed to get SMBIOS slot info: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (!smbios_test_slot_common(&slot)) {
errs++;
}
- if (slot.smbl_pwidth != SMB_SLW_32X) {
- warnx("found wrong slot physical width: 0x%x, expected 0x%x",
- slot.smbl_pwidth, SMB_SLW_32X);
+ if (!smbios_test_slot_common_nopeers(hdl, &sp, &slot)) {
errs++;
}
- if (slot.smbl_pitch != smbios_slot_pitch) {
- warnx("found wrong slot pitch: 0x%x, expected 0x%x",
- slot.smbl_pitch, smbios_slot_pitch);
+ if (slot.smbl_height != SMB_SLHT_LP) {
+ warnx("found wrong slot height: 0x%x, expected 0x%x",
+ slot.smbl_height, SMB_SLHT_LP);
errs++;
}
diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test_strings.c b/usr/src/test/util-tests/tests/smbios/smbios_test_strings.c
new file mode 100644
index 0000000000..aef035266d
--- /dev/null
+++ b/usr/src/test/util-tests/tests/smbios/smbios_test_strings.c
@@ -0,0 +1,157 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2021 Oxide Computer Company
+ */
+
+/*
+ * This is a hodgepodge to validate that the string tables are directionally
+ * correct.
+ */
+
+#include "smbios_test.h"
+
+typedef const char *(*smbios_strfunc_f)(uint_t);
+
+typedef struct smbios_strtest {
+ smbios_strfunc_f ss_func;
+ uint_t ss_num;
+ const char *ss_str;
+} smbios_strtest_t;
+
+static smbios_strtest_t smbios_strs[] = {
+ { smbios_battery_chem_desc, SMB_BDC_LEADACID, "Lead Acid" },
+ { smbios_bboard_flag_name, SMB_BBFL_NEEDAUX, "SMB_BBFL_NEEDAUX" },
+ { smbios_bboard_flag_name, SMB_BBFL_HOTSWAP, "SMB_BBFL_HOTSWAP" },
+ { smbios_bboard_flag_desc, SMB_BBFL_REMOVABLE, "board is removable" },
+ { smbios_bboard_flag_desc, SMB_BBFL_HOTSWAP, "board is hot-swappable" },
+ { smbios_bboard_type_desc, SMB_BBT_PROC, "processor module" },
+ { smbios_bboard_type_desc, SMB_BBT_MOTHER, "motherboard" },
+ { smbios_bios_xb1_desc, SMB_BIOSXB1_ACPI, "ACPI is supported" },
+ { smbios_bios_xb1_name, SMB_BIOSXB1_ACPI, "SMB_BIOSXB1_ACPI" },
+ { smbios_bios_xb2_desc, SMB_BIOSXB2_VM, "SMBIOS table describes a VM" },
+ { smbios_bios_xb2_name, SMB_BIOSXB2_UEFI, "SMB_BIOSXB2_UEFI" },
+ { smbios_boot_desc, SMB_BOOT_NOMEDIA, "no bootable media" },
+ { smbios_cache_assoc_desc, SMB_CAA_4WAY, "4-way set associative" },
+ { smbios_cache_ctype_desc, SMB_CAT_BURST, "burst" },
+ { smbios_cache_ctype_desc, SMB_CAT_SYNC, "synchronous" },
+ { smbios_cache_ctype_name, SMB_CAT_ASYNC, "SMB_CAT_ASYNC" },
+ { smbios_cache_ecc_desc, SMB_CAE_PARITY, "parity" },
+ { smbios_cache_flag_desc, SMB_CAF_SOCKETED, "cache is socketed" },
+ { smbios_cache_flag_name, SMB_CAF_ENABLED, "SMB_CAF_ENABLED" },
+ { smbios_cache_logical_desc, SMB_CAG_INSTR, "instruction" },
+ { smbios_cache_mode_desc, SMB_CAM_WB, "write-back" },
+ { smbios_chassis_type_desc, SMB_CHT_PIZZA, "pizza box" },
+ { smbios_chassis_state_desc, SMB_CHST_SAFE, "safe" },
+ { smbios_evlog_flag_desc, SMB_EVFL_VALID, "log area valid" },
+ { smbios_evlog_flag_name, SMB_EVFL_FULL, "SMB_EVFL_FULL" },
+ { smbios_evlog_format_desc, SMB_EVHF_F1, "DMTF log header type 1" },
+ { smbios_evlog_method_desc, SMB_EVM_GPNV,
+ "GP Non-Volatile API Access" },
+ { smbios_fwinfo_ch_name, SMB_FWC_UPDATE, "SMB_FWC_UPDATE" },
+ { smbios_fwinfo_ch_desc, SMB_FWC_WP, "write-protect" },
+ { smbios_fwinfo_id_desc, SMB_FWI_UEFI, "UEFI GUID" },
+ { smbios_fwinfo_state_desc, SMB_FWS_DISABLED, "disabled" },
+ { smbios_fwinfo_state_desc, SMB_FWS_STB_SPARE, "standby spare" },
+ { smbios_fwinfo_vers_desc, SMB_FWV_HEX64, "64-bit hex" },
+ { smbios_vprobe_loc_desc, SMB_VPROBE_L_PROC, "processor" },
+ { smbios_vprobe_loc_desc, SMB_VPROBE_L_PROCMOD, "processor module" },
+ { smbios_vprobe_status_desc, SMB_VPROBE_S_CRIT, "critical" },
+ { smbios_cooldev_status_desc, SMB_COOLDEV_S_OK, "OK" },
+ { smbios_cooldev_type_desc, SMB_COOLDEV_T_FAN, "fan" },
+ { smbios_tprobe_loc_desc, SMB_TPROBE_L_DISK, "disk" },
+ { smbios_tprobe_status_desc, SMB_TPROBE_S_NONRECOV, "non-recoverable" },
+ { smbios_iprobe_loc_desc, SMB_IPROBE_L_AIC, "add-in card" },
+ { smbios_iprobe_status_desc, SMB_IPROBE_S_UNKNOWN, "unknown" },
+ { smbios_ipmi_flag_desc, SMB_IPMI_F_INTRHIGH,
+ "intr active high (else low)" },
+ { smbios_ipmi_flag_name, SMB_IPMI_F_IOADDR,
+ "SMB_IPMI_F_IOADDR" },
+ { smbios_ipmi_type_desc, SMB_IPMI_T_KCS,
+ "KCS: Keyboard Controller Style" },
+ { smbios_powersup_flag_name, SMB_POWERSUP_F_PRESENT,
+ "SMB_POWERSUP_F_PRESENT" },
+ { smbios_powersup_flag_desc, SMB_POWERSUP_F_HOT,
+ "PSU is hot-replaceable" },
+ { smbios_powersup_input_desc, SMB_POWERSUP_I_WIDE, "wide range" },
+ { smbios_powersup_status_desc, SMB_POWERSUP_S_OK, "OK" },
+ { smbios_powersup_type_desc, SMB_POWERSUP_T_UPS, "UPS" },
+ { smbios_hwsec_desc, SMB_HWSEC_PS_ENABLED, "password enabled" },
+ { smbios_memarray_loc_desc, SMB_MAL_NUBUS, "NuBus" },
+ { smbios_memarray_use_desc, SMB_MAU_CACHE, "cache memory" },
+ { smbios_memarray_ecc_desc, SMB_MAE_CRC, "CRC" },
+ { smbios_memdevice_form_desc, SMB_MDFF_ZIP, "ZIP" },
+ { smbios_memdevice_type_desc, SMB_MDT_LPDDR5, "LPDDR5" },
+ { smbios_memdevice_flag_name, SMB_MDF_EDO, "SMB_MDF_EDO" },
+ { smbios_memdevice_flag_desc, SMB_MDF_PSTATIC, "pseudo-static" },
+ { smbios_memdevice_rank_desc, SMB_MDR_OCTAL, "octal" },
+ { smbios_memdevice_memtech_desc, SMB_MTECH_DRAM, "DRAM" },
+ { smbios_memdevice_op_capab_name, SMB_MOMC_VOLATILE,
+ "SMB_MOMC_VOLATILE" },
+ { smbios_memdevice_op_capab_desc, SMB_MOMC_BLOCK_PM,
+ "Block-accessible persistent memory" },
+ { smbios_onboard_type_desc, SMB_OBT_SAS, "sas" },
+ { smbios_onboard_ext_type_desc, SMB_OBET_EMMC, "eMMC" },
+ { smbios_pointdev_iface_desc, SMB_PDI_PS2, "PS/2" },
+ { smbios_pointdev_type_desc, SMB_PDT_TOPAD, "Touch Pad" },
+ { smbios_port_conn_desc, SMB_POC_RJ45, "RJ-45" },
+ { smbios_port_type_desc, SMB_POT_NETWORK, "Network port" },
+ { smbios_processor_family_desc, SMB_PRF_HOBBIT, "Hobbit" },
+ { smbios_processor_status_desc, SMB_PRS_IDLE, "waiting to be enabled" },
+ { smbios_processor_type_desc, SMB_PRT_DSP, "DSP processor" },
+ { smbios_processor_upgrade_desc, SMB_PRU_SP3, "socket SP3" },
+ { smbios_processor_core_flag_name, SMB_PRC_PM, "SMB_PRC_PM" },
+ { smbios_processor_core_flag_desc, SMB_PRC_MC, "multi-core" },
+ { smbios_processor_info_type_desc, SMB_PROCINFO_T_AARCH64,
+ "64-bit ARM (aarch64)" },
+ { smbios_riscv_priv_desc, SMB_RV_PRIV_S, "Supervisor Mode" },
+ { smbios_riscv_priv_name, SMB_RV_PRIV_U, "SMB_RV_PRIV_U" },
+ { smbios_riscv_width_desc, SMB_RV_WIDTH_64B, "64-bit" },
+ { smbios_slot_type_desc, SMB_SLT_AGP, "AGP" },
+ { smbios_slot_width_desc, SMB_SLW_32X, "32x or x32" },
+ { smbios_slot_usage_desc, SMB_SLU_AVAIL, "available" },
+ { smbios_slot_length_desc, SMB_SLL_LONG, "long length" },
+ { smbios_slot_ch1_desc, SMB_SLCH1_33V, "provides 3.3V" },
+ { smbios_slot_ch1_name, SMB_SLCH1_PCMRR, "SMB_SLCH1_PCMRR" },
+ { smbios_slot_ch2_desc, SMB_SLCH2_HOTPLUG,
+ "slot supports hot-plug devices" },
+ { smbios_slot_ch2_name, SMB_SLCH2_CXL2, "SMB_SLCH2_CXL2" },
+ { smbios_slot_height_desc, SMB_SLHT_FULL, "full height" },
+ { smbios_strprop_id_desc, SMB_STRP_UEFI_DEVPATH, "UEFI device path" },
+ { smbios_type_desc, SMB_TYPE_COOLDEV, "cooling device" },
+ { smbios_type_name, SMB_TYPE_POWERSUP, "SMB_TYPE_POWERSUP" },
+ { smbios_system_wakeup_desc, SMB_WAKEUP_LAN, "LAN remote" },
+};
+
+boolean_t
+smbios_test_verify_strings(smbios_hdl_t *hdl)
+{
+ boolean_t ret = B_TRUE;
+
+ for (uint_t i = 0; i < ARRAY_SIZE(smbios_strs); i++) {
+ uint_t in = smbios_strs[i].ss_num;
+ const char *exp = smbios_strs[i].ss_str;
+ const char *out = smbios_strs[i].ss_func(in);
+
+ if (out == NULL) {
+ warnx("failed to look up string, expected %u->%s",
+ in, exp);
+ ret = B_FALSE;
+ } else if (strcmp(exp, out) != 0) {
+ warnx("found wrong string for %u->%s: %s", in, exp,
+ out);
+ ret = B_FALSE;
+ }
+ }
+
+ return (ret);
+}
diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test_strprop.c b/usr/src/test/util-tests/tests/smbios/smbios_test_strprop.c
new file mode 100644
index 0000000000..20d0928ebb
--- /dev/null
+++ b/usr/src/test/util-tests/tests/smbios/smbios_test_strprop.c
@@ -0,0 +1,255 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2021 Oxide Computer Company
+ */
+
+/*
+ * Tests for SMBIOS type 46 - SMB_TYPE_STRPROP.
+ */
+
+#include "smbios_test.h"
+
+static const char *smbios_strprop_path = "/not/really/uefi";
+static uint16_t smbios_strprop_hdl = 0xcafe;
+
+boolean_t
+smbios_test_strprop_mktable_basic(smbios_test_table_t *table)
+{
+ smb_strprop_t str;
+
+ str.smbstrp_hdr.smbh_type = SMB_TYPE_STRPROP;
+ str.smbstrp_hdr.smbh_len = sizeof (str);
+ str.smbstrp_prop_id = htole16(SMB_STRP_UEFI_DEVPATH);
+ str.smbstrp_prop_val = 1;
+ str.smbstrp_phdl = htole16(smbios_strprop_hdl);
+
+ (void) smbios_test_table_append(table, &str, sizeof (str));
+ smbios_test_table_append_string(table, smbios_strprop_path);
+ smbios_test_table_str_fini(table);
+ smbios_test_table_append_eot(table);
+
+ return (B_TRUE);
+}
+
+boolean_t
+smbios_test_strprop_mktable_badstr(smbios_test_table_t *table)
+{
+ smb_strprop_t str;
+
+ str.smbstrp_hdr.smbh_type = SMB_TYPE_STRPROP;
+ str.smbstrp_hdr.smbh_len = sizeof (str);
+ str.smbstrp_prop_id = htole16(SMB_STRP_UEFI_DEVPATH);
+ str.smbstrp_prop_val = 0x23;
+ str.smbstrp_phdl = htole16(smbios_strprop_hdl);
+
+ (void) smbios_test_table_append(table, &str, sizeof (str));
+ smbios_test_table_append_string(table, smbios_strprop_path);
+ smbios_test_table_str_fini(table);
+ smbios_test_table_append_eot(table);
+
+ return (B_TRUE);
+}
+
+boolean_t
+smbios_test_strprop_mktable_invlen1(smbios_test_table_t *table)
+{
+ smb_header_t hdr;
+
+ hdr.smbh_type = SMB_TYPE_STRPROP;
+ hdr.smbh_len = sizeof (hdr);
+
+ (void) smbios_test_table_append(table, &hdr, sizeof (hdr));
+ smbios_test_table_append_eot(table);
+
+ return (B_TRUE);
+}
+
+boolean_t
+smbios_test_strprop_mktable_invlen2(smbios_test_table_t *table)
+{
+ smb_strprop_t str;
+ const uint8_t endstring = 0;
+
+ str.smbstrp_hdr.smbh_type = SMB_TYPE_STRPROP;
+ str.smbstrp_hdr.smbh_len = sizeof (str) + 1;
+ str.smbstrp_prop_id = htole16(0);
+ str.smbstrp_prop_val = 0;
+ str.smbstrp_phdl = htole16(0);
+
+ /*
+ * Append the end string again as to get us to our additional byte of
+ * actual table length.
+ */
+ (void) smbios_test_table_append(table, &str, sizeof (str));
+ (void) smbios_test_table_append_raw(table, &endstring,
+ sizeof (endstring));
+ (void) smbios_test_table_append_string(table, smbios_strprop_path);
+ (void) smbios_test_table_append_raw(table, &endstring,
+ sizeof (endstring));
+ smbios_test_table_append_eot(table);
+
+ return (B_TRUE);
+}
+
+static boolean_t
+smbios_test_strprop_verify_badtable(smbios_hdl_t *hdl, int smberr)
+{
+ smbios_struct_t sp;
+ smbios_strprop_t prop;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_STRPROP, &sp) == -1) {
+ warnx("failed to lookup SMBIOS strprop: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_strprop(hdl, sp.smbstr_id, &prop) != -1) {
+ warnx("accidentally parsed invalid strprop information as "
+ "valid");
+ return (B_FALSE);
+ }
+
+ if (smbios_errno(hdl) != smberr) {
+ warnx("encountered wrong error for strprop, expected: "
+ "0x%x, found: 0x%x", smberr, smbios_errno(hdl));
+ return (B_FALSE);
+ }
+
+ return (B_TRUE);
+}
+
+boolean_t
+smbios_test_strprop_verify_invlen1(smbios_hdl_t *hdl)
+{
+ return (smbios_test_strprop_verify_badtable(hdl, ESMB_SHORT));
+}
+
+boolean_t
+smbios_test_strprop_verify_invlen2(smbios_hdl_t *hdl)
+{
+ return (smbios_test_strprop_verify_badtable(hdl, ESMB_CORRUPT));
+}
+
+boolean_t
+smbios_test_strprop_verify_badtype(smbios_hdl_t *hdl)
+{
+ smbios_struct_t sp;
+ smbios_strprop_t prop;
+
+ /*
+ * Here we've explicitly created a table with a memory device that we're
+ * going to try and look up as well, not that.
+ */
+ if (smbios_lookup_type(hdl, SMB_TYPE_MEMDEVICE, &sp) == -1) {
+ warnx("failed to lookup SMBIOS memory device: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_strprop(hdl, sp.smbstr_id, &prop) != -1) {
+ warnx("accidentally parsed invalid strprop information as "
+ "valid");
+ return (B_FALSE);
+ }
+
+ if (smbios_errno(hdl) != ESMB_TYPE) {
+ warnx("encountered wrong error for strprop, expected: "
+ "0x%x, found: 0x%x", ESMB_TYPE, smbios_errno(hdl));
+ return (B_FALSE);
+ }
+
+ return (B_TRUE);
+
+}
+
+boolean_t
+smbios_test_strprop_verify_basic(smbios_hdl_t *hdl)
+{
+ smbios_struct_t sp;
+ smbios_strprop_t prop;
+ boolean_t ret = B_TRUE;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_STRPROP, &sp) == -1) {
+ warnx("failed to lookup SMBIOS strprop: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_strprop(hdl, sp.smbstr_id, &prop) != 0) {
+ warnx("failed to get SMBIOS strprop: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (prop.smbsp_prop_id != SMB_STRP_UEFI_DEVPATH) {
+ warnx("property id incorrect, expected 0x%x, found 0x %x",
+ SMB_STRP_UEFI_DEVPATH, prop.smbsp_prop_id);
+ ret = B_FALSE;
+ }
+
+ if (strcmp(smbios_strprop_id_desc(prop.smbsp_prop_id),
+ "UEFI device path") != 0) {
+ warnx("property id string incorrect, found %s",
+ smbios_strprop_id_desc(prop.smbsp_prop_id));
+ ret = B_FALSE;
+ }
+
+ if (strcmp(prop.smbsp_prop_val, smbios_strprop_path) != 0) {
+ warnx("property value incorrect, found %s",
+ prop.smbsp_prop_val);
+ ret = B_FALSE;
+ }
+
+ return (ret);
+}
+
+boolean_t
+smbios_test_strprop_verify_badstr(smbios_hdl_t *hdl)
+{
+ smbios_struct_t sp;
+ smbios_strprop_t prop;
+ boolean_t ret = B_TRUE;
+
+ if (smbios_lookup_type(hdl, SMB_TYPE_STRPROP, &sp) == -1) {
+ warnx("failed to lookup SMBIOS strprop: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (smbios_info_strprop(hdl, sp.smbstr_id, &prop) != 0) {
+ warnx("failed to get SMBIOS strprop: %s",
+ smbios_errmsg(smbios_errno(hdl)));
+ return (B_FALSE);
+ }
+
+ if (prop.smbsp_prop_id != SMB_STRP_UEFI_DEVPATH) {
+ warnx("property id incorrect, expected 0x%x, found 0x %x",
+ SMB_STRP_UEFI_DEVPATH, prop.smbsp_prop_id);
+ ret = B_FALSE;
+ }
+
+ if (strcmp(smbios_strprop_id_desc(prop.smbsp_prop_id),
+ "UEFI device path") != 0) {
+ warnx("property id string incorrect, found %s",
+ smbios_strprop_id_desc(prop.smbsp_prop_id));
+ ret = B_FALSE;
+ }
+
+ if (strcmp(prop.smbsp_prop_val, "") != 0) {
+ warnx("property value incorrect, found %s",
+ prop.smbsp_prop_val);
+ ret = B_FALSE;
+ }
+
+ return (ret);
+}
diff --git a/usr/src/uts/common/sys/smbios.h b/usr/src/uts/common/sys/smbios.h
index b8b470b79a..3ce9e2c7a3 100644
--- a/usr/src/uts/common/sys/smbios.h
+++ b/usr/src/uts/common/sys/smbios.h
@@ -22,7 +22,7 @@
/*
* Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
* Copyright (c) 2018, Joyent, Inc.
- * Copyright 2020 Oxide Computer Company
+ * Copyright 2021 Oxide Computer Company
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -158,12 +158,14 @@ typedef union {
#define SMB_TYPE_MCHI 42 /* mgmt controller host interface */
#define SMB_TYPE_TPM 43 /* TPM device */
#define SMB_TYPE_PROCESSOR_INFO 44 /* Processor Additional Information */
+#define SMB_TYPE_FWINFO 45 /* Firmware Inventory Information */
+#define SMB_TYPE_STRPROP 46 /* String Property */
#define SMB_TYPE_INACTIVE 126 /* inactive table entry */
#define SMB_TYPE_EOT 127 /* end of table */
#define SMB_TYPE_OEM_LO 128 /* start of OEM-specific type range */
#define SUN_OEM_EXT_PROCESSOR 132 /* processor extended info */
-#define SUN_OEM_EXT_PORT 136 /* port exteded info */
+#define SUN_OEM_EXT_PORT 136 /* port extended info */
#define SUN_OEM_PCIEXRC 138 /* PCIE RootComplex/RootPort info */
#define SUN_OEM_EXT_MEMARRAY 144 /* phys memory array extended info */
#define SUN_OEM_EXT_MEMDEVICE 145 /* memory device extended info */
@@ -202,8 +204,6 @@ typedef struct smbios_version {
uint8_t smbv_minor; /* version minor number */
} smbios_version_t;
-#define SMB_CONT_BYTE 1 /* contained elements are byte size */
-#define SMB_CONT_WORD 2 /* contained elements are word size */
#define SMB_CONT_MAX 255 /* maximum contained objects */
/*
@@ -286,6 +286,8 @@ typedef struct smbios_bios {
#define SMB_BIOSXB2_ETCDIST 0x04 /* Enable Targeted Content Distrib. */
#define SMB_BIOSXB2_UEFI 0x08 /* UEFI Specification supported */
#define SMB_BIOSXB2_VM 0x10 /* SMBIOS table describes a VM */
+#define SMB_BIOSXB2_MFG_MODE 0x20 /* Manufacturing mode is supported */
+#define SMB_BIOSXB2_MFG_EN 0x40 /* Manufacturing mode is enabled */
/*
* SMBIOS System Information. See DSP0134 Section 7.2 for more information.
@@ -323,7 +325,7 @@ typedef struct smbios_bboard {
#define SMB_BBFL_MOTHERBOARD 0x01 /* board is a motherboard */
#define SMB_BBFL_NEEDAUX 0x02 /* auxiliary card or daughter req'd */
#define SMB_BBFL_REMOVABLE 0x04 /* board is removable */
-#define SMB_BBFL_REPLACABLE 0x08 /* board is field-replacable */
+#define SMB_BBFL_REPLACABLE 0x08 /* board is field-replaceable */
#define SMB_BBFL_HOTSWAP 0x10 /* board is hot-swappable */
#define SMB_BBT_UNKNOWN 0x1 /* unknown */
@@ -356,7 +358,7 @@ typedef struct smbios_chassis {
uint8_t smbc_cords; /* number of power cords */
uint8_t smbc_elems; /* number of element records (n) */
uint8_t smbc_elemlen; /* length of contained element (m) */
- char smbc_sku[256]; /* SKU number (as a string) */
+ const char *smbc_sku; /* SKU number (as a string) */
} smbios_chassis_t;
#define SMB_CHT_OTHER 0x01 /* other */
@@ -410,6 +412,19 @@ typedef struct smbios_chassis {
#define SMB_CHSC_EIENAB 0x05 /* external interface enabled */
/*
+ * Chassis element record types
+ */
+typedef struct smbios_chassis_entry {
+ uint8_t smbce_type; /* Type of elt */
+ uint8_t smbce_elt; /* Containing Element */
+ uint8_t smbce_min; /* minimum number of elt */
+ uint8_t smbce_max; /* minimum number of elt */
+} smbios_chassis_entry_t;
+
+#define SMB_CELT_BBOARD 0 /* smbce_elt is a base board type */
+#define SMB_CELT_SMBIOS 1 /* smbce_elt is an smbios type */
+
+/*
* SMBIOS Processor description. See DSP0134 Section 7.5 for more details.
* If the L1, L2, or L3 cache handle is -1, the cache information is unknown.
* If the handle refers to something of size 0, that type of cache is absent.
@@ -530,6 +545,7 @@ typedef struct smbios_processor {
#define SMB_PRU_BGA1528 0x3C /* Socket BGA1528 */
#define SMB_PRU_LGA4189 0x3D /* Socket LGA4189 */
#define SMB_PRU_LGA1200 0x3E /* Socket LGA1200 */
+#define SMB_PRU_LGA4677 0x3F /* Socket LGA4677 */
#define SMB_PRC_RESERVED 0x0001 /* reserved */
#define SMB_PRC_UNKNOWN 0x0002 /* unknown */
@@ -950,6 +966,7 @@ typedef struct smbios_slot {
uint8_t smbl_info; /* slot info */
uint8_t smbl_pwidth; /* slot physical width */
uint32_t smbl_pitch; /* slot pitch in 10um */
+ uint8_t smbl_height; /* slot height */
} smbios_slot_t;
#define SMB_SLT_OTHER 0x01 /* other */
@@ -1081,6 +1098,12 @@ typedef struct smbios_slot {
#define SMB_SLCH2_CXL1 0x20 /* Flexbus slot, CXL 1.0 capable */
#define SMB_SLCH2_CXL2 0x40 /* Flexbus slot, CXL 2.0 capable */
+#define SMB_SLHT_NA 0x00 /* not applicable */
+#define SMB_SLHT_OTHER 0x01 /* other */
+#define SMB_SLHT_UNKNOWN 0x02 /* unknown */
+#define SMB_SLHT_FULL 0x03 /* full height */
+#define SMB_SLHT_LP 0x04 /* low profile */
+
/*
* SMBIOS 7.10.9 Slot Peer Devices
*
@@ -1404,7 +1427,9 @@ typedef struct smbios_pointdev {
#define SMB_PDI_ADB 0x08 /* ADB (Apple Desktop Bus) */
#define SMB_PDI_BUSM_DB9 0xA0 /* Bus mouse DB-9 */
#define SMB_PDI_BUSM_UDIN 0xA1 /* Bus mouse micro-DIN */
-#define SMB_PDI_BUSM_USB 0xA2 /* USB */
+#define SMB_PDI_USB 0xA2 /* USB */
+#define SMB_PDI_I2C 0xA3 /* I2C */
+#define SMB_PDI_SPI 0xA4 /* SPI */
/*
* SMBIOS Portable Battery. See DSP0134 Section 7.23 for more information.
@@ -1711,8 +1736,25 @@ typedef struct smbios_obdev_ext {
uint8_t smboe_df; /* device/function number */
} smbios_obdev_ext_t;
+#define SMB_OBET_OTHER 0x01 /* Other */
+#define SMB_OBET_UNKNOWN 0x02 /* Unknown */
+#define SMB_OBET_VIDEO 0x03 /* video */
+#define SMB_OBET_SCSI 0x04 /* SCSI */
+#define SMB_OBET_ETHERNET 0x05 /* Ethernet */
+#define SMB_OBET_TOKEN 0x06 /* Token Ring */
+#define SMB_OBET_SOUND 0x07 /* Sound */
+#define SMB_OBET_PATA 0x08 /* PATA */
+#define SMB_OBET_SATA 0x09 /* SATA */
+#define SMB_OBET_SAS 0x0A /* SAS */
+#define SMB_OBET_WLAN 0x0B /* Wireless LAN */
+#define SMB_OBET_BT 0x0C /* Bluetooth */
+#define SMB_OBET_WWAN 0x0D /* WWAN */
+#define SMB_OBET_EMMC 0x0E /* eMMC */
+#define SMB_OBET_NVME 0x0F /* NVMe */
+#define SMB_OBET_UFS 0x10 /* UFS */
+
/*
- * SMBIOS Processor Additional Information (Type 44). See sectoin 7.45 for more
+ * SMBIOS Processor Additional Information (Type 44). See section 7.45 for more
* information.
*/
typedef struct smbios_processor_info {
@@ -1784,7 +1826,7 @@ typedef struct smbios_processor_info_riscv {
#define SMB_RV_ISA_N (1 << 13) /* User-level interrupts */
#define SMB_RV_ISA_O (1 << 14) /* Reserved */
#define SMB_RV_ISA_P (1 << 15) /* Reserved */
-#define SMB_RV_ISA_Q (1 << 16) /* Quad-precision floating-poit */
+#define SMB_RV_ISA_Q (1 << 16) /* Quad-precision floating-point */
#define SMB_RV_ISA_R (1 << 17) /* Reserved */
#define SMB_RV_ISA_S (1 << 18) /* Supervisor mode */
#define SMB_RV_ISA_T (1 << 19) /* Reserved */
@@ -1797,11 +1839,78 @@ typedef struct smbios_processor_info_riscv {
/* END CSTYLED */
/*
+ * SMBIOS Firmware Inventory Information (Type 45).
+ */
+typedef struct smbios_fwinfo {
+ const char *smbfw_name; /* Firmware component name */
+ const char *smbfw_id; /* Firmware ID */
+ const char *smbfw_reldate; /* Release date */
+ const char *smbfw_lsv; /* Lowest supported version */
+ uint64_t smbfw_imgsz; /* Image size */
+ uint16_t smbfw_chars; /* Characteristics */
+ uint16_t smbfw_state; /* State */
+ uint16_t smbfw_ncomps; /* Number of associated components */
+ uint8_t smbfw_vers_fmt; /* Firmware version format */
+ uint8_t smbfw_id_fmt; /* Firmware ID format */
+} smbios_fwinfo_t;
+
+typedef struct smbios_fwinfo_comp {
+ id_t smbfwe_id; /* Contained element ID */
+} smbios_fwinfo_comp_t;
+
+/*
+ * Firmware version format constants.
+ */
+#define SMB_FWV_FF 0x00 /* free-form */
+#define SMB_FWV_MM 0x01 /* major.minor */
+#define SMB_FWV_HEX32 0x02 /* 32-bit hex */
+#define SMB_FWV_HEX64 0x03 /* 64-bit hex */
+
+/*
+ * Firmware ID format constants.
+ */
+#define SMB_FWI_FF 0x00 /* free-form */
+#define SMB_FWI_UEFI 0x01 /* UEFI GUID */
+
+/*
+ * Firmware characteristic bitfields.
+ */
+#define SMB_FWC_UPDATE 0x01 /* updatable */
+#define SMB_FWC_WP 0x02 /* write-protect */
+
+/*
+ * Firmware state constants.
+ */
+#define SMB_FWS_OTHER 0x01 /* other */
+#define SMB_FWS_UNKNOWN 0x02 /* unknown */
+#define SMB_FWS_DISABLED 0x03 /* disabled */
+#define SMB_FWS_ENABLED 0x04 /* enabled */
+#define SMB_FWS_ABSENT 0x05 /* absent */
+#define SMB_FWS_STB_OFFLINE 0x06 /* standby offline */
+#define SMB_FWS_STB_SPARE 0x07 /* standby spare */
+#define SMB_FWS_UA_OFFLINE 0x08 /* unavailable offline */
+
+/*
+ * SMBIOS String Property (Type 46). See section 7.47 for more information.
+ */
+typedef struct smbios_strprop {
+ uint32_t smbsp_prop_id; /* property ID */
+ const char *smbsp_prop_val; /* property Value */
+ id_t smbsp_parent; /* parent handle */
+} smbios_strprop_t;
+
+/*
+ * String Property IDs
+ */
+#define SMB_STRP_RESERVED 0x00 /* reserved */
+#define SMB_STRP_UEFI_DEVPATH 0x01 /* UEFI device path */
+
+/*
* SMBIOS OEM-specific (Type 132) Processor Extended Information.
*/
typedef struct smbios_processor_ext {
uint16_t smbpe_processor; /* extending processor handle */
- uint8_t smbpe_fru; /* FRU indicaor */
+ uint8_t smbpe_fru; /* FRU indicator */
uint8_t smbpe_n; /* number of APIC IDs */
uint16_t *smbpe_apicid; /* strand Inital APIC IDs */
} smbios_processor_ext_t;
@@ -1866,7 +1975,8 @@ typedef struct smbios_memdevice_ext {
#define SMB_VERSION_32 0x0302 /* SMBIOS encoding for DMTF spec 3.2 */
#define SMB_VERSION_33 0x0303 /* SMBIOS encoding for DMTF spec 3.3 */
#define SMB_VERSION_34 0x0304 /* SMBIOS encoding for DMTF spec 3.4 */
-#define SMB_VERSION SMB_VERSION_34 /* SMBIOS latest version definitions */
+#define SMB_VERSION_35 0x0305 /* SMBIOS encoding for DMTF spec 3.5 */
+#define SMB_VERSION SMB_VERSION_35 /* SMBIOS latest version definitions */
#define SMB_O_NOCKSUM 0x1 /* do not verify header checksums */
#define SMB_O_NOVERS 0x2 /* do not verify header versions */
@@ -1919,6 +2029,10 @@ extern id_t smbios_info_bios(smbios_hdl_t *, smbios_bios_t *);
extern id_t smbios_info_system(smbios_hdl_t *, smbios_system_t *);
extern int smbios_info_bboard(smbios_hdl_t *, id_t, smbios_bboard_t *);
extern int smbios_info_chassis(smbios_hdl_t *, id_t, smbios_chassis_t *);
+extern int smbios_info_chassis_elts(smbios_hdl_t *, id_t, uint_t *,
+ smbios_chassis_entry_t **);
+extern void smbios_info_chassis_elts_free(smbios_hdl_t *, uint_t,
+ smbios_chassis_entry_t *);
extern int smbios_info_processor(smbios_hdl_t *, id_t, smbios_processor_t *);
extern int smbios_info_extprocessor(smbios_hdl_t *, id_t,
smbios_processor_ext_t *);
@@ -1958,7 +2072,12 @@ extern int smbios_info_processor_info(smbios_hdl_t *, id_t,
smbios_processor_info_t *);
extern int smbios_info_processor_riscv(smbios_hdl_t *, id_t,
smbios_processor_info_riscv_t *);
-
+extern int smbios_info_strprop(smbios_hdl_t *, id_t, smbios_strprop_t *);
+extern int smbios_info_fwinfo(smbios_hdl_t *, id_t, smbios_fwinfo_t *);
+extern int smbios_info_fwinfo_comps(smbios_hdl_t *, id_t, uint_t *,
+ smbios_fwinfo_comp_t **);
+extern void smbios_info_fwinfo_comps_free(smbios_hdl_t *, uint_t,
+ smbios_fwinfo_comp_t *);
extern const char *smbios_psn(smbios_hdl_t *);
extern const char *smbios_csn(smbios_hdl_t *);
@@ -2004,6 +2123,12 @@ extern const char *smbios_evlog_flag_name(uint_t);
extern const char *smbios_evlog_format_desc(uint_t);
extern const char *smbios_evlog_method_desc(uint_t);
+extern const char *smbios_fwinfo_ch_name(uint_t);
+extern const char *smbios_fwinfo_ch_desc(uint_t);
+extern const char *smbios_fwinfo_id_desc(uint_t);
+extern const char *smbios_fwinfo_state_desc(uint_t);
+extern const char *smbios_fwinfo_vers_desc(uint_t);
+
extern const char *smbios_vprobe_loc_desc(uint_t);
extern const char *smbios_vprobe_status_desc(uint_t);
@@ -2042,6 +2167,7 @@ extern const char *smbios_memdevice_op_capab_name(uint_t);
extern const char *smbios_memdevice_op_capab_desc(uint_t);
extern const char *smbios_onboard_type_desc(uint_t);
+extern const char *smbios_onboard_ext_type_desc(uint_t);
extern const char *smbios_pointdev_iface_desc(uint_t);
extern const char *smbios_pointdev_type_desc(uint_t);
@@ -2071,6 +2197,9 @@ extern const char *smbios_slot_ch1_desc(uint_t);
extern const char *smbios_slot_ch1_name(uint_t);
extern const char *smbios_slot_ch2_desc(uint_t);
extern const char *smbios_slot_ch2_name(uint_t);
+extern const char *smbios_slot_height_desc(uint_t);
+
+extern const char *smbios_strprop_id_desc(uint_t);
extern const char *smbios_type_desc(uint_t);
extern const char *smbios_type_name(uint_t);
diff --git a/usr/src/uts/common/sys/smbios_impl.h b/usr/src/uts/common/sys/smbios_impl.h
index 4b951b702f..41424aa03a 100644
--- a/usr/src/uts/common/sys/smbios_impl.h
+++ b/usr/src/uts/common/sys/smbios_impl.h
@@ -22,7 +22,7 @@
/*
* Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
* Copyright (c) 2018, Joyent, Inc.
- * Copyright 2020 Oxide Computer Company
+ * Copyright 2021 Oxide Computer Company
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -134,14 +134,20 @@ typedef struct smb_chassis {
uint8_t smbch_cords; /* number of power cords */
uint8_t smbch_cn; /* number of contained records */
uint8_t smbch_cm; /* size of contained records */
- uint8_t smbch_cv[1]; /* array of contained records */
+ uint8_t smbch_cv[]; /* array of contained records */
} smb_chassis_t;
-/* WARNING: the argument is evaluated three times! */
-#define SMB_CH_SKU(smbcp) ((char *) \
- (smbcp)->smbch_cv + ((smbcp)->smbch_cn * (smbcp)->smbch_cm))
#define SMB_CHT_LOCK 0x80 /* lock bit within smbch_type */
+typedef struct smb_chassis_entry {
+ uint8_t smbce_type; /* Containing Element and Type */
+ uint8_t smbce_min; /* minimum number of elt */
+ uint8_t smbce_max; /* minimum number of elt */
+} smb_chassis_entry_t;
+
+#define SMB_CHE_TYPE_IS_SMB(x) (((x) & 0x80) == 0x80)
+#define SMB_CHE_TYPE_TYPE(x) (((x) & 0x7f))
+
/*
* SMBIOS implementation structure for SMB_TYPE_PROCESSOR.
*/
@@ -263,12 +269,18 @@ typedef struct smb_slot_cont {
uint8_t smbsl_info; /* slot info */
uint8_t smbsl_pwidth; /* slot physical width */
uint16_t smbsl_pitch; /* slot pitch */
+ /* Added in SMBIOS 3.5 */
+ uint8_t smbsl_height; /* slot height */
} smb_slot_cont_t;
/*
- * The first byte that the smb_slot_cont_t is defined to start at.
+ * The first byte that the smb_slot_cont_t is defined to start at. Note, this
+ * was originally indicated to be 0x14 in the SMBIOS 3.4 specification. This has
+ * been noted as an errata. Right now we assume that most things have the
+ * updated behavior in SMBIOS 3.5. However, if we encounter things in the wild
+ * that have the other offset then we will need to condition this on 3.4.
*/
-#define SMB_SLOT_CONT_START 0x14
+#define SMB_SLOT_CONT_START 0x13
/*
* SMBIOS implementation structure for SMB_TYPE_OBDEVS.
@@ -650,6 +662,36 @@ typedef struct smb_processor_info_riscv {
} smb_processor_info_riscv_t;
/*
+ * SMBIOS implementation structure for SMBIOS_TYPE_FWINFO.
+ */
+typedef struct smb_fwinfo {
+ smb_header_t smbfwii_hdr; /* structure handle */
+ uint8_t smbfwii_name; /* Firmware component name */
+ uint8_t smbfwii_vers; /* Firmware version */
+ uint8_t smbfwii_vers_fmt; /* Version format */
+ uint8_t smbfwii_id; /* Firmware ID */
+ uint8_t smbfwii_id_fmt; /* Firmware ID format */
+ uint8_t smbfwii_reldate; /* Release Date */
+ uint8_t smbfwii_mfg; /* Manufacturer */
+ uint8_t smbfwii_lsv; /* Lowest supported version */
+ uint64_t smbfwii_imgsz; /* Image size */
+ uint16_t smbfwii_chars; /* Characteristics */
+ uint8_t smbfwii_state; /* State */
+ uint8_t smbfwii_ncomps; /* Number of associated components */
+ uint16_t smbfwii_comps[]; /* Variable handles */
+} smb_fwinfo_t;
+
+/*
+ * SMBIOS implementation structure for SMBIOS_TYPE_STRPROP.
+ */
+typedef struct smb_strprop {
+ smb_header_t smbstrp_hdr; /* structure handle */
+ uint16_t smbstrp_prop_id; /* string property ID */
+ uint8_t smbstrp_prop_val; /* string property value */
+ uint16_t smbstrp_phdl; /* parent handle */
+} smb_strprop_t;
+
+/*
* SMBIOS implementation structure for SUN_OEM_EXT_PROCESSOR.
*/
typedef struct smb_processor_ext {
@@ -883,6 +925,28 @@ typedef struct smb_base_slot {
uint8_t smbbl_df; /* device/function number */
} smb_base_slot_t;
+/*
+ * Prior to reivison 3.5 of the library and interface we had embedded a 256 byte
+ * string for the SKU into here rather than pointing to constant data. This,
+ * combined withe bugs in the implementation, generally led to strings with
+ * garbage. As part of fixing this with the 3.5 support, we moved the struct to
+ * ve more inline with everything else.
+ */
+typedef struct smb_chassis_pre35 {
+ uint32_t smbc_oemdata; /* OEM-specific data */
+ uint8_t smbc_lock; /* lock present? */
+ uint8_t smbc_type; /* type */
+ uint8_t smbc_bustate; /* boot-up state */
+ uint8_t smbc_psstate; /* power supply state */
+ uint8_t smbc_thstate; /* thermal state */
+ uint8_t smbc_security; /* security status */
+ uint8_t smbc_uheight; /* enclosure height in U's */
+ uint8_t smbc_cords; /* number of power cords */
+ uint8_t smbc_elems; /* number of element records (n) */
+ uint8_t smbc_elemlen; /* length of contained element (m) */
+ char smbc_sku[256];
+} smb_chassis_pre35_t;
+
#ifdef __cplusplus
}
#endif