summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@fingolfin.org>2020-09-09 22:30:42 -0700
committerRobert Mustacchi <rm@fingolfin.org>2020-09-10 08:31:47 -0700
commitdf8c2508aa717e719c0726c616d47f2c94a58dab (patch)
tree1bf25ab867fdce0ffb4fde229fbcbf03f49242fe /usr
parent9dc804b9db4598936de071708cbc40525f06eb5d (diff)
downloadillumos-joyent-df8c2508aa717e719c0726c616d47f2c94a58dab.tar.gz
13119 Want support for SMBIOS 3.4
Change-Id: I88fd5a7e8f5b49b806f27d550bf49921b5fb8a28
Diffstat (limited to 'usr')
-rw-r--r--usr/src/cmd/smbios/smbios.c22
-rw-r--r--usr/src/common/smbios/smb_info.c42
-rw-r--r--usr/src/common/smbios/smb_open.c1
-rw-r--r--usr/src/test/util-tests/tests/smbios/smbios.c19
-rw-r--r--usr/src/test/util-tests/tests/smbios/smbios_test.h5
-rw-r--r--usr/src/test/util-tests/tests/smbios/smbios_test_slot.c375
-rw-r--r--usr/src/uts/common/sys/smbios.h38
-rw-r--r--usr/src/uts/common/sys/smbios_impl.h18
8 files changed, 466 insertions, 54 deletions
diff --git a/usr/src/cmd/smbios/smbios.c b/usr/src/cmd/smbios/smbios.c
index 5597e04fc5..dedfe29e9c 100644
--- a/usr/src/cmd/smbios/smbios.c
+++ b/usr/src/cmd/smbios/smbios.c
@@ -22,6 +22,7 @@
/*
* Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
* Copyright (c) 2017, Joyent, Inc.
+ * Copyright 2020 Oxide Computer Company
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -716,7 +717,7 @@ print_slot(smbios_hdl_t *shp, id_t id, FILE *fp)
oprintf(fp, " Slot Peer %u:\n", i);
oprintf(fp, " Segment group: %u\n",
peer[i].smblp_group);
- oprintf(fp, " Bus/Device/Function: %u/%u/%u",
+ oprintf(fp, " Bus/Device/Function: %u/%u/%u\n",
peer[i].smblp_bus, peer[i].smblp_device,
peer[i].smblp_function);
oprintf(fp, " Electrical width: %u\n",
@@ -725,6 +726,25 @@ print_slot(smbios_hdl_t *shp, id_t id, FILE *fp)
smbios_info_slot_peers_free(shp, npeers, peer);
}
+
+ if (s.smbl_info != 0) {
+ if (s.smbl_type >= SMB_SLT_PCIE &&
+ s.smbl_type <= SMB_SLT_PCIEG6P) {
+ oprintf(fp, " PCIe Generation: %d\n", s.smbl_info);
+ } else {
+ oprintf(fp, " Slot Type: 0x%x\n", s.smbl_info);
+ }
+ }
+
+ if (s.smbl_pwidth != 0) {
+ desc_printf(smbios_slot_width_desc(s.smbl_pwidth),
+ fp, " Physical Width: 0x%x", s.smbl_pwidth);
+ }
+
+ if (s.smbl_pitch != 0) {
+ oprintf(fp, " Slot Pitch: %u.%u mm\n", s.smbl_pitch / 100,
+ s.smbl_pitch % 100);
+ }
}
static void
diff --git a/usr/src/common/smbios/smb_info.c b/usr/src/common/smbios/smb_info.c
index 47c19e7fcb..9aba4deba8 100644
--- a/usr/src/common/smbios/smb_info.c
+++ b/usr/src/common/smbios/smb_info.c
@@ -22,6 +22,7 @@
/*
* Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
* Copyright 2019 Joyent, Inc.
+ * Copyright 2020 Oxide Computer Company
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -232,13 +233,24 @@ smb_info_strptr(const smb_struct_t *stp, uint8_t off, int *n)
}
static void
+smb_info_bcopy_offset(const smb_header_t *hp, void *dst, size_t dstlen,
+ size_t offset)
+{
+ if (offset >= hp->smbh_len) {
+ bzero(dst, dstlen);
+ } else if (offset + dstlen > hp->smbh_len) {
+ size_t nvalid = MIN(hp->smbh_len - offset, dstlen);
+ bcopy((char *)hp + offset, dst, nvalid);
+ bzero((char *)dst + nvalid, dstlen - nvalid);
+ } else {
+ bcopy((char *)hp + offset, dst, dstlen);
+ }
+}
+
+static void
smb_info_bcopy(const smb_header_t *hp, void *dst, size_t dstlen)
{
- if (dstlen > hp->smbh_len) {
- bcopy(hp, dst, hp->smbh_len);
- bzero((char *)dst + hp->smbh_len, dstlen - hp->smbh_len);
- } else
- bcopy(hp, dst, dstlen);
+ return (smb_info_bcopy_offset(hp, dst, dstlen, 0));
}
smbios_entry_point_t
@@ -674,6 +686,8 @@ smbios_info_slot(smbios_hdl_t *shp, id_t id, smbios_slot_t *sp)
{
const smb_struct_t *stp = smb_lookup_id(shp, id);
smb_slot_t s;
+ smb_slot_cont_t cont;
+ size_t off;
if (stp == NULL)
return (-1); /* errno is set for us */
@@ -701,6 +715,24 @@ smbios_info_slot(smbios_hdl_t *shp, id_t id, smbios_slot_t *sp)
sp->smbl_npeers = s.smbsl_npeers;
}
+ if (!smb_libgteq(shp, SMB_VERSION_34)) {
+ return (0);
+ }
+
+ /*
+ * In SMBIOS 3.4, several members were added to follow the variable
+ * number of peers. These are defined to start at byte 0x14 + 5 *
+ * npeers. If the table is from before 3.4, we simple zero things out.
+ * Otherwise we check if the length covers the peers and this addendum
+ * to include it as the table length is allowed to be less than this and
+ * not include it.
+ */
+ off = SMB_SLOT_CONT_START + 5 * s.smbsl_npeers;
+ smb_info_bcopy_offset(stp->smbst_hdr, &cont, sizeof (cont), off);
+ sp->smbl_info = cont.smbsl_info;
+ sp->smbl_pwidth = cont.smbsl_pwidth;
+ sp->smbl_pitch = cont.smbsl_pitch;
+
return (0);
}
diff --git a/usr/src/common/smbios/smb_open.c b/usr/src/common/smbios/smb_open.c
index 372b2b619b..6747c84499 100644
--- a/usr/src/common/smbios/smb_open.c
+++ b/usr/src/common/smbios/smb_open.c
@@ -231,6 +231,7 @@ smbios_bufopen(const smbios_entry_t *ep, const void *buf, size_t len,
case SMB_VERSION_31:
case SMB_VERSION_32:
case SMB_VERSION_33:
+ case SMB_VERSION_34:
break;
default:
return (smb_open_error(shp, errp, ESMB_VERSION));
diff --git a/usr/src/test/util-tests/tests/smbios/smbios.c b/usr/src/test/util-tests/tests/smbios/smbios.c
index 364cb9344f..429d4f81be 100644
--- a/usr/src/test/util-tests/tests/smbios/smbios.c
+++ b/usr/src/test/util-tests/tests/smbios/smbios.c
@@ -11,6 +11,7 @@
/*
* Copyright (c) 2018, Joyent, Inc.
+ * Copyright 2020 Oxide Computer Company
*/
/*
@@ -219,7 +220,23 @@ static const smbios_test_t smbios_tests[] = {
.st_mktable = smbios_test_slot_mktable,
.st_canopen = B_TRUE,
.st_verify = smbios_test_slot_verify,
- .st_desc = "slot tests"
+ .st_desc = "slot 3.2"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION_34,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_slot_mktable_34_nopeers,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_slot_verify_34_nopeers,
+ .st_desc = "slot 3.4 without peers"
+ }, {
+ .st_entry = SMBIOS_ENTRY_POINT_30,
+ .st_tvers = SMB_VERSION_34,
+ .st_libvers = SMB_VERSION,
+ .st_mktable = smbios_test_slot_mktable_34_peers,
+ .st_canopen = B_TRUE,
+ .st_verify = smbios_test_slot_verify_34_peers,
+ .st_desc = "slot 3.4 with peers"
}, {
.st_entry = SMBIOS_ENTRY_POINT_30,
.st_tvers = SMB_VERSION,
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 62baed7813..c6490f1d13 100644
--- a/usr/src/test/util-tests/tests/smbios/smbios_test.h
+++ b/usr/src/test/util-tests/tests/smbios/smbios_test.h
@@ -11,6 +11,7 @@
/*
* Copyright 2019 Robert Mustacchi
+ * Copyright 2020 Oxide Computer Company
*/
#ifndef _SMBIOS_TEST_H
@@ -78,7 +79,11 @@ typedef struct smbios_test {
* Test functions
*/
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_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_badvers_mktable(smbios_test_table_t *);
extern boolean_t smbios_test_memdevice_mktable_32(smbios_test_table_t *);
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 d84cc10e91..95a709a088 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,6 +11,7 @@
/*
* Copyright (c) 2018, Joyent, Inc.
+ * Copyright 2020 Oxide Computer Company
*/
/*
@@ -20,6 +21,29 @@
#include "smbios_test.h"
static const char *smbios_test_name = "The One Slot";
+static uint8_t smbios_slot_bus = 0x42;
+static uint8_t smbios_slot_df = 0x23;
+static uint8_t smbios_slot_info = 0x65;
+static uint16_t smbios_slot_pitch = 0x12af;
+
+static void
+smbios_test_slot_fill(smb_slot_t *slot)
+{
+ bzero(slot, sizeof (smb_slot_t));
+ slot->smbsl_hdr.smbh_type = SMB_TYPE_SLOT;
+ slot->smbsl_hdr.smbh_len = sizeof (smb_slot_t);
+ slot->smbsl_name = 1;
+ slot->smbsl_type = SMB_SLT_PCIE3G16;
+ slot->smbsl_width = SMB_SLW_16X;
+ slot->smbsl_length = SMB_SLL_SHORT;
+ slot->smbsl_id = htole16(1);
+ slot->smbsl_ch1 = SMB_SLCH1_33V;
+ slot->smbsl_ch2 = SMB_SLCH2_PME;
+ slot->smbsl_sg = htole16(1);
+ slot->smbsl_bus = smbios_slot_bus;
+ slot->smbsl_df = smbios_slot_df;
+ slot->smbsl_dbw = SMB_SLW_16X;
+}
boolean_t
smbios_test_slot_mktable(smbios_test_table_t *table)
@@ -28,21 +52,11 @@ smbios_test_slot_mktable(smbios_test_table_t *table)
smb_slot_peer_t peers[2];
const uint8_t endstring = 0;
- slot.smbsl_hdr.smbh_type = SMB_TYPE_SLOT;
- slot.smbsl_hdr.smbh_len = sizeof (smb_slot_t) + sizeof (peers);
-
- slot.smbsl_name = 1;
- slot.smbsl_type = SMB_SLT_PCIE3G16;
- slot.smbsl_width = SMB_SLW_16X;
- slot.smbsl_length = SMB_SLL_SHORT;
- slot.smbsl_id = htole16(1);
- slot.smbsl_ch1 = SMB_SLCH1_33V;
- slot.smbsl_ch2 = SMB_SLCH2_PME;
- slot.smbsl_sg = htole16(1);
- slot.smbsl_bus = 0x42;
- slot.smbsl_df = 0x23;
- slot.smbsl_dbw = SMB_SLW_16X;
+ smbios_test_slot_fill(&slot);
+
+ slot.smbsl_hdr.smbh_len += sizeof (peers);
slot.smbsl_npeers = 2;
+
peers[0].smbspb_group_no = htole16(1);
peers[0].smbspb_bus = 0x42;
peers[0].smbspb_df = 0x42;
@@ -64,6 +78,121 @@ smbios_test_slot_mktable(smbios_test_table_t *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)
+{
+ smb_slot_t slot;
+ smb_slot_cont_t cont;
+ const uint8_t endstring = 0;
+
+ smbios_test_slot_fill(&slot);
+ slot.smbsl_hdr.smbh_len = SMB_SLOT_CONT_START + sizeof (cont);
+
+ cont.smbsl_info = smbios_slot_info;
+ cont.smbsl_pwidth = SMB_SLW_32X;
+ cont.smbsl_pitch = htole16(smbios_slot_pitch);
+
+ (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_eot(table);
+ return (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);
+
+ peers[0].smbspb_group_no = htole16(1);
+ peers[0].smbspb_bus = 0x42;
+ peers[0].smbspb_df = 0x9a;
+ peers[0].smbspb_width = SMB_SLW_8X;
+
+ cont.smbsl_info = smbios_slot_info;
+ cont.smbsl_pwidth = SMB_SLW_32X;
+ 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_eot(table);
+ return (B_TRUE);
+}
+
+
+static boolean_t
+smbios_test_slot_common(smbios_slot_t *slot)
+{
+ uint_t errs = 0;
+
+ if (strcmp(slot->smbl_name, smbios_test_name) != 0) {
+ warnx("slot name mismatch, expected %s, found %s",
+ smbios_test_name, slot->smbl_name);
+ errs++;
+ }
+
+ if (slot->smbl_type != SMB_SLT_PCIE3G16) {
+ warnx("incorrect slot type, found %u", slot->smbl_type);
+ errs++;
+ }
+
+ if (slot->smbl_width != SMB_SLW_16X) {
+ warnx("incorrect slot width, found %u", slot->smbl_width);
+ errs++;
+ }
+
+ if (slot->smbl_length != SMB_SLL_SHORT) {
+ warnx("incorrect slot length, found %u", slot->smbl_length);
+ errs++;
+ }
+
+ if (slot->smbl_dbw != SMB_SLW_16X) {
+ warnx("incorrect slot data bus width, found %u",
+ slot->smbl_dbw);
+ errs++;
+ }
+
+ if (slot->smbl_bus != smbios_slot_bus) {
+ warnx("incorrect slot bus id, found 0x%x\n", slot->smbl_bus);
+ }
+
+ if (slot->smbl_df != smbios_slot_df) {
+ warnx("incorrect slot df id, found 0x%x\n", slot->smbl_df);
+ }
+
+ if (errs > 0) {
+ return (B_FALSE);
+ }
+
+ return (B_TRUE);
+}
+
boolean_t
smbios_test_slot_verify(smbios_hdl_t *hdl)
{
@@ -85,32 +214,7 @@ smbios_test_slot_verify(smbios_hdl_t *hdl)
return (B_FALSE);
}
- /*
- * Verify everything we'd expect about the slot.
- */
- if (strcmp(slot.smbl_name, smbios_test_name) != 0) {
- warnx("slot name mismatch, expected %s, found %s",
- smbios_test_name, slot.smbl_name);
- errs++;
- }
-
- if (slot.smbl_type != SMB_SLT_PCIE3G16) {
- warnx("incorrect slot type, found %u", slot.smbl_type);
- errs++;
- }
-
- if (slot.smbl_width != SMB_SLW_16X) {
- warnx("incorrect slot width, found %u", slot.smbl_width);
- errs++;
- }
-
- if (slot.smbl_length != SMB_SLL_SHORT) {
- warnx("incorrect slot length, found %u", slot.smbl_length);
- errs++;
- }
-
- if (slot.smbl_dbw != SMB_SLW_16X) {
- warnx("incorrect slot data bus width, found %u", slot.smbl_dbw);
+ if (!smbios_test_slot_common(&slot)) {
errs++;
}
@@ -127,8 +231,7 @@ smbios_test_slot_verify(smbios_hdl_t *hdl)
}
if (npeers != 2) {
- warnx("got wrong number of slot peers: %u\n",
- npeers);
+ warnx("got wrong number of slot peers: %u", npeers);
return (B_FALSE);
}
@@ -180,6 +283,194 @@ smbios_test_slot_verify(smbios_hdl_t *hdl)
smbios_info_slot_peers_free(hdl, npeers, peers);
+ if (slot.smbl_info != 0) {
+ warnx("found wrong slot info: 0x%x", slot.smbl_info);
+ errs++;
+ }
+
+ if (slot.smbl_pwidth != 0) {
+ warnx("found wrong slot physical width: 0x%x",
+ slot.smbl_pwidth);
+ errs++;
+ }
+
+ if (slot.smbl_pitch != 0) {
+ warnx("found wrong slot pitch: 0x%x", slot.smbl_pitch);
+ errs++;
+ }
+
+ if (errs > 0) {
+ return (B_FALSE);
+ }
+
+ return (B_TRUE);
+}
+
+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) {
+ 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_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++;
+ }
+
+ if (errs > 0) {
+ return (B_FALSE);
+ }
+
+ return (B_TRUE);
+}
+
+boolean_t
+smbios_test_slot_verify_34_peers(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) {
+ 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_npeers != 1) {
+ 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 != 1) {
+ warnx("got wrong number of slot peers: %u", npeers);
+ errs++;
+ }
+
+ if (peers[0].smblp_group != 1) {
+ warnx("incorrect group for peer 0: %u", peers[0].smblp_group);
+ errs++;
+ }
+
+ if (peers[0].smblp_data_width != SMB_SLW_8X) {
+ warnx("incorrect data width for peer 0: %u",
+ peers[0].smblp_data_width);
+ errs++;
+ }
+
+ if (peers[0].smblp_bus != 0x42) {
+ warnx("incorrect PCI bus for peer 0: %u",
+ peers[0].smblp_bus);
+ errs++;
+ }
+
+ if (peers[0].smblp_device != (0x9a >> 3)) {
+ warnx("incorrect PCI device for peer 0: %u",
+ peers[0].smblp_device);
+ errs++;
+ }
+
+ if (peers[0].smblp_function != (0x9a & 0x7)) {
+ warnx("incorrect PCI function for peer 0: %u",
+ peers[0].smblp_function);
+ 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++;
+ }
+
if (errs > 0) {
return (B_FALSE);
}
diff --git a/usr/src/uts/common/sys/smbios.h b/usr/src/uts/common/sys/smbios.h
index 55048d549d..debe1fe72d 100644
--- a/usr/src/uts/common/sys/smbios.h
+++ b/usr/src/uts/common/sys/smbios.h
@@ -22,6 +22,7 @@
/*
* Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
* Copyright (c) 2018, Joyent, Inc.
+ * Copyright 2020 Oxide Computer Company
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -527,6 +528,8 @@ typedef struct smbios_processor {
#define SMB_PRU_BGA1392 0x3A /* Socket BGA1392 */
#define SMB_PRU_BGA1510 0x3B /* Socket BGA1510 */
#define SMB_PRU_BGA1528 0x3C /* Socket BGA1528 */
+#define SMB_PRU_LGA4189 0x3D /* Socket LGA4189 */
+#define SMB_PRU_LGA1200 0x3E /* Socket LGA1200 */
#define SMB_PRC_RESERVED 0x0001 /* reserved */
#define SMB_PRC_UNKNOWN 0x0002 /* unknown */
@@ -944,6 +947,9 @@ typedef struct smbios_slot {
uint8_t smbl_df; /* device/function number */
uint8_t smbl_dbw; /* data bus width */
uint8_t smbl_npeers; /* PCIe bifurcation peers */
+ uint8_t smbl_info; /* slot info */
+ uint8_t smbl_pwidth; /* slot physical width */
+ uint32_t smbl_pitch; /* slot pitch in 10um */
} smbios_slot_t;
#define SMB_SLT_OTHER 0x01 /* other */
@@ -976,8 +982,8 @@ typedef struct smbios_slot {
#define SMB_SLT_MXM_V 0x1C /* MXM Type IV */
#define SMB_SLT_MXM3_A 0x1D /* MXM 3.0 Type A */
#define SMB_SLT_MXM3_B 0x1E /* MXM 3.0 Type B */
-#define SMB_SLT_PCIEG2_SFF 0x1F /* PCI Express Gen 2 SFF-8639 */
-#define SMB_SLT_PCIEG3_SFF 0x20 /* PCI Express Gen 3 SFF-8639 */
+#define SMB_SLT_PCIEG2_SFF 0x1F /* PCI Express Gen 2 SFF-8639 U.2) */
+#define SMB_SLT_PCIEG3_SFF 0x20 /* PCI Express Gen 3 SFF-8639 (U.2) */
/*
* These lines must be on one line for the string generating code.
*/
@@ -986,6 +992,11 @@ typedef struct smbios_slot {
#define SMB_SLT_PCIE_M52_WOBSKO 0x22 /* PCI Express Mini 52-pin without bottom-side keep-outs */
/* END CSTYLED */
#define SMB_SLT_PCIE_M76 0x23 /* PCI Express Mini 72-pin */
+#define SMB_SLT_PCIEG4_SFF 0x24 /* PCI Express Gen 4 SFF-8639 (U.2) */
+#define SMB_SLT_PCIEG5_SFF 0x25 /* PCI Express Gen 5 SFF-8639 (U.2) */
+#define SMB_SLT_OCP3_SFF 0x26 /* OCP NIC 3.0 Small Form Factor */
+#define SMB_SLT_OCP3_LFF 0x27 /* OCP NIC 3.0 Large Form Factor */
+#define SMB_SLT_OCP_PRE 0x28 /* OCP NIC prior to 3.0 */
#define SMB_SLT_CXL1 0x30 /* CXL Flexbus 1.0 */
#define SMB_SLT_PC98_C20 0xA0 /* PC-98/C20 */
#define SMB_SLT_PC98_C24 0xA1 /* PC-98/C24 */
@@ -1016,6 +1027,15 @@ typedef struct smbios_slot {
#define SMB_SLT_PCIE4G4 0xBB /* PCI Exp. Gen 4 x4 */
#define SMB_SLT_PCIE4G8 0xBC /* PCI Exp. Gen 4 x8 */
#define SMB_SLT_PCIE4G16 0xBD /* PCI Exp. Gen 4 x16 */
+#define SMB_SLT_PCIE5G 0xBE /* PCI Exp. Gen 5 */
+#define SMB_SLT_PCIE5G1 0xBF /* PCI Exp. Gen 5 x1 */
+#define SMB_SLT_PCIE5G2 0xC0 /* PCI Exp. Gen 5 x2 */
+#define SMB_SLT_PCIE5G4 0xC1 /* PCI Exp. Gen 5 x4 */
+#define SMB_SLT_PCIE5G8 0xC2 /* PCI Exp. Gen 5 x8 */
+#define SMB_SLT_PCIE5G16 0xC3 /* PCI Exp. Gen 5 x16 */
+#define SMB_SLT_PCIEG6P 0xC4 /* PCI Exp. Gen 6+ */
+#define SMB_SLT_EDSFF_E1 0xC5 /* Ent. and DC 1U E1 Form Factor */
+#define SMB_SLT_EDSFF_E3 0xC6 /* Ent. and DC 3" E3 Form Factor */
#define SMB_SLW_OTHER 0x01 /* other */
#define SMB_SLW_UNKNOWN 0x02 /* unknown */
@@ -1041,6 +1061,8 @@ typedef struct smbios_slot {
#define SMB_SLL_UNKNOWN 0x02 /* unknown */
#define SMB_SLL_SHORT 0x03 /* short length */
#define SMB_SLL_LONG 0x04 /* long length */
+#define SMB_SLL_2IN5 0x05 /* 2.5" drive form factor */
+#define SMB_SLL_3IN5 0x06 /* 3.5" drive form factor */
#define SMB_SLCH1_UNKNOWN 0x01 /* characteristics unknown */
#define SMB_SLCH1_5V 0x02 /* provides 5.0V */
@@ -1055,6 +1077,9 @@ typedef struct smbios_slot {
#define SMB_SLCH2_HOTPLUG 0x02 /* slot supports hot-plug devices */
#define SMB_SLCH2_SMBUS 0x04 /* slot supports SMBus signal */
#define SMB_SLCH2_BIFUR 0x08 /* slot supports PCIe bifurcation */
+#define SMB_SLCH2_SURPREM 0x10 /* slot supports surprise removal */
+#define SMB_SLCH2_CXL1 0x20 /* Flexbus slot, CXL 1.0 capable */
+#define SMB_SLCH2_CXL2 0x40 /* Flexbus slot, CXL 2.0 capable */
/*
* SMBIOS 7.10.9 Slot Peer Devices
@@ -1178,7 +1203,7 @@ typedef struct smbios_memarray {
#define SMB_MAL_PC98C24 0xA1 /* PC-98/C24 add-on card */
#define SMB_MAL_PC98E 0xA2 /* PC-98/E add-on card */
#define SMB_MAL_PC98LB 0xA3 /* PC-98/Local bus add-on card */
-#define SMB_MAL_CXL1 0xA4 /* CXL Flexbus 1.0 add-on card */
+#define SMB_MAL_CXL1 0xA4 /* CXL add-on card */
#define SMB_MAU_OTHER 0x01 /* other */
#define SMB_MAU_UNKNOWN 0x02 /* unknown */
@@ -1285,6 +1310,8 @@ typedef struct smbios_memdevice {
#define SMB_MDT_LOGNV 0x1F /* Logical non-volatile device */
#define SMB_MDT_HBM 0x20 /* High Bandwidth Memory */
#define SMB_MDT_HBM2 0x21 /* High Bandwidth Memory 2 */
+#define SMB_MDT_DDR5 0x22 /* DDR5 */
+#define SMB_MDT_LPDDR5 0x23 /* LPDDR5 */
#define SMB_MDF_OTHER 0x0002 /* other */
#define SMB_MDF_UNKNOWN 0x0004 /* unknown */
@@ -1313,7 +1340,7 @@ typedef struct smbios_memdevice {
#define SMB_MTECH_NVDIMM_N 0x04 /* NVDIMM-N */
#define SMB_MTECH_NVDIMM_F 0x05 /* NVDIMM-F */
#define SMB_MTECH_NVDIMM_P 0x06 /* NVDIMM-P */
-#define SMB_MTECH_INTCPM 0x07 /* Intel Optane DC Persistent Memory */
+#define SMB_MTECH_INTCPM 0x07 /* Intel Optane persistent memory */
#define SMB_MOMC_RESERVED 0x01 /* reserved */
#define SMB_MOMC_OTHER 0x02 /* other */
@@ -1838,7 +1865,8 @@ typedef struct smbios_memdevice_ext {
#define SMB_VERSION_31 0x0301 /* SMBIOS encoding for DMTF spec 3.1 */
#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 SMB_VERSION_33 /* SMBIOS latest version definitions */
+#define SMB_VERSION_34 0x0304 /* SMBIOS encoding for DMTF spec 3.4 */
+#define SMB_VERSION SMB_VERSION_34 /* SMBIOS latest version definitions */
#define SMB_O_NOCKSUM 0x1 /* do not verify header checksums */
#define SMB_O_NOVERS 0x2 /* do not verify header versions */
diff --git a/usr/src/uts/common/sys/smbios_impl.h b/usr/src/uts/common/sys/smbios_impl.h
index 69ca79e94f..4b951b702f 100644
--- a/usr/src/uts/common/sys/smbios_impl.h
+++ b/usr/src/uts/common/sys/smbios_impl.h
@@ -22,6 +22,7 @@
/*
* Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
* Copyright (c) 2018, Joyent, Inc.
+ * Copyright 2020 Oxide Computer Company
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -250,9 +251,26 @@ typedef struct smb_slot {
uint8_t smbsl_dbw; /* Data bus width */
uint8_t smbsl_npeers; /* Peer bdf groups */
smb_slot_peer_t smbsl_peers[]; /* bifurcation peers */
+ /* There are later additions in 3.4+, see smbios_slot_cont_t */
} smb_slot_t;
/*
+ * After the variable number of smbsl_peers, the smbios_slot has continued in
+ * size and has the following members defined as of version 3.4. These occur
+ * starting at byte 14 + 5 * smbsl_npeers.
+ */
+typedef struct smb_slot_cont {
+ uint8_t smbsl_info; /* slot info */
+ uint8_t smbsl_pwidth; /* slot physical width */
+ uint16_t smbsl_pitch; /* slot pitch */
+} smb_slot_cont_t;
+
+/*
+ * The first byte that the smb_slot_cont_t is defined to start at.
+ */
+#define SMB_SLOT_CONT_START 0x14
+
+/*
* SMBIOS implementation structure for SMB_TYPE_OBDEVS.
*/
typedef struct smb_obdev {