diff options
Diffstat (limited to 'usr/src/test/util-tests')
| -rw-r--r-- | usr/src/test/util-tests/cmd/utiltest.ksh | 2 | ||||
| -rw-r--r-- | usr/src/test/util-tests/runfiles/default.run | 7 | ||||
| -rw-r--r-- | usr/src/test/util-tests/tests/Makefile | 2 | ||||
| -rw-r--r-- | usr/src/test/util-tests/tests/sleep/Makefile | 47 | ||||
| -rw-r--r-- | usr/src/test/util-tests/tests/sleep/sleep.awk | 22 | ||||
| -rw-r--r-- | usr/src/test/util-tests/tests/sleep/sleep.d | 40 | ||||
| -rw-r--r-- | usr/src/test/util-tests/tests/sleep/sleeptest.ksh | 180 | ||||
| -rw-r--r-- | usr/src/test/util-tests/tests/smbios/Makefile | 20 | ||||
| -rw-r--r-- | usr/src/test/util-tests/tests/smbios/smbios.c | 376 | ||||
| -rw-r--r-- | usr/src/test/util-tests/tests/smbios/smbios_test.h | 110 | ||||
| -rw-r--r-- | usr/src/test/util-tests/tests/smbios/smbios_test_errors.c | 28 | ||||
| -rw-r--r-- | usr/src/test/util-tests/tests/smbios/smbios_test_memdevice.c | 355 | ||||
| -rw-r--r-- | usr/src/test/util-tests/tests/smbios/smbios_test_pinfo.c | 585 | ||||
| -rw-r--r-- | usr/src/test/util-tests/tests/smbios/smbios_test_slot.c | 188 |
14 files changed, 1754 insertions, 208 deletions
diff --git a/usr/src/test/util-tests/cmd/utiltest.ksh b/usr/src/test/util-tests/cmd/utiltest.ksh index 231415fba8..e701aeb854 100644 --- a/usr/src/test/util-tests/cmd/utiltest.ksh +++ b/usr/src/test/util-tests/cmd/utiltest.ksh @@ -17,6 +17,8 @@ # Copyright 2014 Garrett D'Amore <garrett@damore.org> # +export PATH="${PATH}:/opt/onbld/bin/$(uname -p)" +export LC_ALL="C" export MY_TESTS="/opt/util-tests" runner="/opt/test-runner/bin/run" diff --git a/usr/src/test/util-tests/runfiles/default.run b/usr/src/test/util-tests/runfiles/default.run index 3170859794..628982c82d 100644 --- a/usr/src/test/util-tests/runfiles/default.run +++ b/usr/src/test/util-tests/runfiles/default.run @@ -35,6 +35,13 @@ outputdir = /var/tmp/test_results [/opt/util-tests/tests/libjedec_test] [/opt/util-tests/tests/smbios] +# +# The sleep tests require destructive DTrace. Therefore they must be run +# as root. +# +[/opt/util-tests/tests/sleep/sleeptest] +user = root + [/opt/util-tests/tests/xargs_test] [/opt/util-tests/tests/mergeq/mqt] diff --git a/usr/src/test/util-tests/tests/Makefile b/usr/src/test/util-tests/tests/Makefile index 6fab960d55..a39762c2fc 100644 --- a/usr/src/test/util-tests/tests/Makefile +++ b/usr/src/test/util-tests/tests/Makefile @@ -19,7 +19,7 @@ # SUBDIRS = date dis dladm iconv libnvpair_json libsff printf xargs grep_xpg4 -SUBDIRS += demangle mergeq workq chown ctf smbios libjedec awk make +SUBDIRS += demangle mergeq workq chown ctf smbios libjedec awk make sleep SUBDIRS += bunyan include $(SRC)/test/Makefile.com diff --git a/usr/src/test/util-tests/tests/sleep/Makefile b/usr/src/test/util-tests/tests/sleep/Makefile new file mode 100644 index 0000000000..3cf11e1f40 --- /dev/null +++ b/usr/src/test/util-tests/tests/sleep/Makefile @@ -0,0 +1,47 @@ +# +# 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 2019 Robert Mustacchi +# + +include $(SRC)/cmd/Makefile.cmd +include $(SRC)/test/Makefile.com + +ROOTOPTPKG = $(ROOT)/opt/util-tests/tests/sleep +PROG = sleeptest +DATAFILES = sleep.d sleep.awk + +ROOTPROG = $(PROG:%=$(ROOTOPTPKG)/%) +ROOTDATA = $(DATAFILES:%=$(ROOTOPTPKG)/%) + +$(ROOTDATA) := FILEMODE = 0444 + +all: + +install: $(ROOTPROG) $(ROOTDATA) + +lint: + +clobber: clean + +clean: + +$(CMDS): $(TESTDIR) + +$(ROOTOPTPKG): + $(INS.dir) + +$(ROOTOPTPKG)/%: %.ksh $(ROOTOPTPKG) + $(INS.rename) + +$(ROOTOPTPKG)/%: % $(ROOTOPTPKG) + $(INS.file) diff --git a/usr/src/test/util-tests/tests/sleep/sleep.awk b/usr/src/test/util-tests/tests/sleep/sleep.awk new file mode 100644 index 0000000000..856773c815 --- /dev/null +++ b/usr/src/test/util-tests/tests/sleep/sleep.awk @@ -0,0 +1,22 @@ +# +# 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 2019 Robert Mustacchi +# + +{ + if ($1 == "slp") { + if ($2 >= min && $2 <= min * factor) { + exit 42 + } + } +} diff --git a/usr/src/test/util-tests/tests/sleep/sleep.d b/usr/src/test/util-tests/tests/sleep/sleep.d new file mode 100644 index 0000000000..23bfcea65c --- /dev/null +++ b/usr/src/test/util-tests/tests/sleep/sleep.d @@ -0,0 +1,40 @@ +/* + * 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 2019 Robert Mustacchi + */ + +/* + * This is a companion DTrace script that is used by the sleep test. It + * checks if the executed program asks to sleep for the right amount of + * time and then exits in a way to indicate this. At the same time, it + * always uses the SIGALRM feature of sleep(1) to make sure that sleep + * doesn't continue executing (and also to make sure that the feature + * works). + * + * We expect the number of seconds in $1 and the number of nanoseconds + * in $2. This script should be invoked as dtrace -s sleep.d -c + * '/usr/bin/sleep <waittime>' <seconds> <nanoseconds>. + */ +pid$target::nanosleep:entry +/args[0]->tv_sec == $1 && args[0]->tv_nsec == $2/ +{ + raise(SIGALRM); + exit(0); +} + +pid$target::nanosleep:entry +{ + print(*args[0]); + raise(SIGALRM); + exit(1); +} diff --git a/usr/src/test/util-tests/tests/sleep/sleeptest.ksh b/usr/src/test/util-tests/tests/sleep/sleeptest.ksh new file mode 100644 index 0000000000..3cc107acf5 --- /dev/null +++ b/usr/src/test/util-tests/tests/sleep/sleeptest.ksh @@ -0,0 +1,180 @@ +#!/bin/ksh +# +# 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 2019 Robert Mustacchi +# + +# +# Basic tests of sleep(1). sleep is a little hard to test, especially +# for longer running cases. Therefore to test it, we basically take +# advantage of our knowledge of how it is implemented. We see that it +# properly is sleeping for the right amount of time by looking at the +# call to nanosleep in libc and make sure that the structures time is +# what we expect. +# + +unalias -a +set -o pipefail + +# +# Set the locale for the start of the test to be C.UTF-8 to make sure +# that we have a good starting point and correct fractional +# interpretation. +# +export LC_ALL=C.UTF-8 + +sleep_arg0="$(basename $0)" +sleep_prog=/usr/bin/sleep +sleep_dir="$(dirname $0)" +sleep_dscript=$sleep_dir/sleep.d +sleep_awk=$sleep_dir/sleep.awk +sleep_exit=0 + +# +# This is the factor by which we're going to basically say that the slp +# microstate has to complete within. Because the system will usually +# have a bit of additional latency, we will usually be greater than that +# as well. This determines how much we should actually do that by. +# +sleep_factor=1.5 + +warn() +{ + typeset msg="$*" + [[ -z "$msg" ]] && msg="failed" + echo "TEST FAILED: $sleep_arg0: $msg" >&2 +} + +sleep_bound() +{ + typeset min=$1 + typeset test="sleep $min: bounding" + + ptime -m $sleep_prog $min 2>&1 | nawk -f $sleep_awk min=$min \ + factor=$sleep_factor + if [[ $? -ne 42 ]]; then + warn "$test" + sleep_exit=1 + else + printf "TEST PASSED: %s\n" "$test" + fi +} + +sleep_one() +{ + typeset arg=$1 + typeset secs=$2 + typeset nsecs=$3 + typeset test="sleep $arg: $secs secs $nsecs ns" + + if ! dtrace -qws $sleep_dscript -c "$sleep_prog $arg" $secs $nsecs; then + warn "$test" + sleep_exit=1 + else + printf "TEST PASSED: %s\n" "$test" + fi +} + +sleep_err() +{ + typeset test="negative test: sleep $*" + + if $sleep_prog $* 2>/dev/null; then + warn "$test" + sleep_exit=1 + else + printf "TEST PASSED: %s\n" "$test" + fi +} + +if [[ -n $SLEEP ]]; then + sleep_prog=$SLEEP +fi + +# +# First test basic integer values. Both in base 10 and hex. +# +sleep_one 1 1 0 +sleep_one 23 23 0 +sleep_one 0xff 0xff 0 +sleep_one 123456789 123456789 0 +sleep_one 1e8 100000000 0 + +# +# Fractional values. +# +sleep_one 2.5 2 500000000 +sleep_one 0.9 0 900000000 +sleep_one 34.0051 34 5100000 +sleep_one 0x654.100 0x654 62500000 + +# +# Large values that are basically the same as infinity. The current +# implementation will do a sleep in groups of INT32_MAX at a time. So +# make sure our large values are the same. +# +sleep_one Inf 0x7fffffff 0 +sleep_one +Inf 0x7fffffff 0 +sleep_one 1e100 0x7fffffff 0 +sleep_one 0x123456789abc 0x7fffffff 0 + +# +# That all of our suffixes for time increments work and make sense. +# +sleep_one 1s 1 0 +sleep_one 1m 60 0 +sleep_one 1h 3600 0 +sleep_one 1d 86400 0 +sleep_one 1w 604800 0 +sleep_one 1y 31536000 0 + +sleep_one 3.5s 3 500000000 +sleep_one 3.6d 311040 0 +sleep_one 2.001y 63103536 0 + +# +# Now we need to go through and use ptime -m to get the slp time for +# things and make sure it is always greater than what we asked for and +# less than a bound. +# +sleep_bound 0.01 +sleep_bound 0.1 +sleep_bound 0.25 +sleep_bound 0.5 +sleep_bound 0.75 + +# +# The next set of tests are negative tests that make sure that sleep +# does not correctly execute in these cases. +# +sleep_err \"\" +sleep_err 1 2 3 +sleep_err 1@23 +sleep_err 0,56 +sleep_err "hello" +sleep_err s +sleep_err 1z +sleep_err -- -0.3 + +# +# Test a locale that uses a ',' character (de_DE.UTF-8 is one) as the +# decimal point to make sure that sleep correctly is using LC_NUMERIC. +# +export LANG=de_DE.UTF-8 +sleep_err 21.45 +sleep_one 2,5 2 500000000 +sleep_one 34,0051 34 5100000 +sleep_one 3,6d 311040 0 +export LANG=C.UTF-8 + +exit $sleep_exit diff --git a/usr/src/test/util-tests/tests/smbios/Makefile b/usr/src/test/util-tests/tests/smbios/Makefile index 5016e81a6d..e783a337dc 100644 --- a/usr/src/test/util-tests/tests/smbios/Makefile +++ b/usr/src/test/util-tests/tests/smbios/Makefile @@ -18,10 +18,13 @@ include $(SRC)/Makefile.master ROOTOPTPKG = $(ROOT)/opt/util-tests TESTDIR = $(ROOTOPTPKG)/tests/ +OBJS = smbios.o \ + smbios_test_errors.o \ + smbios_test_memdevice.o \ + smbios_test_pinfo.o \ + smbios_test_slot.o PROGS = smbios -LINTS = $(PROGS:%=%.ln) - include $(SRC)/cmd/Makefile.cmd include $(SRC)/test/Makefile.com @@ -33,16 +36,15 @@ CFLAGS += -_gcc=-Wall -_gcc=-Wextra -_gcc=-Wno-unknown-pragmas all: $(PROGS) -install: all $(CMDS) $(OUTFILES) +install: all $(CMDS) clobber: clean - -$(RM) $(PROGS) $(LINTS) - -lint: + -$(RM) $(PROGS) clean: + -$(RM) $(OBJS) -$(CMDS): $(TESTDIR) $(PROG) +$(CMDS): $(TESTDIR) $(PROGS) $(TESTDIR): $(INS.dir) @@ -50,6 +52,6 @@ $(TESTDIR): $(TESTDIR)/%: % $(INS.file) -%: %.c - $(LINK.c) -o $@ $< $(LDLIBS) +$(PROGS): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) $(POST_PROCESS) diff --git a/usr/src/test/util-tests/tests/smbios/smbios.c b/usr/src/test/util-tests/tests/smbios/smbios.c index 96b887c3cc..364cb9344f 100644 --- a/usr/src/test/util-tests/tests/smbios/smbios.c +++ b/usr/src/test/util-tests/tests/smbios/smbios.c @@ -19,33 +19,8 @@ * This should be evolved into a much fuller test suite. */ -#include <smbios.h> #include <umem.h> -#include <stdint.h> -#include <endian.h> -#include <stdio.h> -#include <err.h> - -#include <sys/smbios.h> -#include <sys/smbios_impl.h> - -static const char *smbios_test_name = "The One Slot"; - -/* - * Number of bytes we allocate at a given time for an SMBIOS table. - */ -#define SMBIOS_TEST_ALLOC_SIZE 1024 - -typedef struct smbios_test_table { - smbios_entry_point_t stt_type; - void *stt_data; - size_t stt_buflen; - size_t stt_offset; - uint_t stt_nents; - uint_t stt_version; - uint_t stt_nextid; - smbios_entry_t stt_entry; -} smbios_test_table_t; +#include "smbios_test.h" const char * _umem_debug_init(void) @@ -59,7 +34,7 @@ _umem_logging_init(void) return ("fail,contents"); } -static smbios_test_table_t * +smbios_test_table_t * smbios_test_table_init(smbios_entry_point_t type, uint_t version) { smbios_test_table_t *table; @@ -122,21 +97,21 @@ smbios_test_table_append_common(smbios_test_table_t *table, const void *buf, return (start); } -static void +void smbios_test_table_append_raw(smbios_test_table_t *table, const void *buf, size_t len) { (void) smbios_test_table_append_common(table, buf, len); } -static void +void smbios_test_table_append_string(smbios_test_table_t *table, const char *str) { size_t len = strlen(str) + 1; (void) smbios_test_table_append_common(table, str, len); } -static uint16_t +uint16_t smbios_test_table_append(smbios_test_table_t *table, const void *buf, size_t len) { @@ -153,6 +128,25 @@ smbios_test_table_append(smbios_test_table_t *table, const void *buf, return (id); } +void +smbios_test_table_append_eot(smbios_test_table_t *table) +{ + smb_header_t eot; + uint8_t endstring = 0; + + bzero(&eot, sizeof (eot)); + eot.smbh_type = SMB_TYPE_EOT; + eot.smbh_len = 4; + (void) smbios_test_table_append(table, &eot, sizeof (eot)); + (void) smbios_test_table_append_raw(table, &endstring, + sizeof (endstring)); + smbios_test_table_append_raw(table, &endstring, + sizeof (endstring)); + smbios_test_table_append_raw(table, &endstring, + sizeof (endstring)); + +} + static uint8_t smbios_test_table_checksum(const uint8_t *buf, size_t len) { @@ -217,195 +211,181 @@ smbios_test_table_fini(smbios_test_table_t *table) umem_free(table, sizeof (smbios_test_table_t)); } -static void -smbios_test_mktable(smbios_test_table_t *table) +static const smbios_test_t smbios_tests[] = { + { + .st_entry = SMBIOS_ENTRY_POINT_30, + .st_tvers = SMB_VERSION_32, + .st_libvers = SMB_VERSION, + .st_mktable = smbios_test_slot_mktable, + .st_canopen = B_TRUE, + .st_verify = smbios_test_slot_verify, + .st_desc = "slot 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_32, + .st_libvers = SMB_VERSION_32, + .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_entry = SMBIOS_ENTRY_POINT_30, + .st_tvers = SMB_VERSION_32, + .st_libvers = SMB_VERSION_33, + .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_entry = SMBIOS_ENTRY_POINT_30, + .st_tvers = SMB_VERSION_33, + .st_libvers = SMB_VERSION_33, + .st_mktable = smbios_test_memdevice_mktable_33, + .st_canopen = B_TRUE, + .st_verify = smbios_test_memdevice_verify_33, + .st_desc = "memory device 3.3" + }, { + .st_entry = SMBIOS_ENTRY_POINT_30, + .st_tvers = SMB_VERSION_33, + .st_libvers = SMB_VERSION_33, + .st_mktable = smbios_test_memdevice_mktable_33ext, + .st_canopen = B_TRUE, + .st_verify = smbios_test_memdevice_verify_33ext, + .st_desc = "memory device 3.3" + }, { + .st_entry = SMBIOS_ENTRY_POINT_30, + .st_tvers = SMB_VERSION, + .st_libvers = SMB_VERSION, + .st_mktable = smbios_test_pinfo_mktable_amd64, + .st_canopen = B_TRUE, + .st_verify = smbios_test_pinfo_verify_amd64, + .st_desc = "processor additional information - amd64" + }, { + .st_entry = SMBIOS_ENTRY_POINT_30, + .st_tvers = SMB_VERSION, + .st_libvers = SMB_VERSION, + .st_mktable = smbios_test_pinfo_mktable_riscv, + .st_canopen = B_TRUE, + .st_verify = smbios_test_pinfo_verify_riscv, + .st_desc = "processor additional information - riscv" + }, { + .st_entry = SMBIOS_ENTRY_POINT_30, + .st_tvers = SMB_VERSION, + .st_libvers = SMB_VERSION, + .st_mktable = smbios_test_pinfo_mktable_invlen1, + .st_canopen = B_TRUE, + .st_verify = smbios_test_pinfo_verify_invlen1, + .st_desc = "processor additional information - bad table length 1" + }, { + .st_entry = SMBIOS_ENTRY_POINT_30, + .st_tvers = SMB_VERSION, + .st_libvers = SMB_VERSION, + .st_mktable = smbios_test_pinfo_mktable_invlen2, + .st_canopen = B_TRUE, + .st_verify = smbios_test_pinfo_verify_invlen2, + .st_desc = "processor additional information - bad table length 2" + }, { + .st_entry = SMBIOS_ENTRY_POINT_30, + .st_tvers = SMB_VERSION, + .st_libvers = SMB_VERSION, + .st_mktable = smbios_test_pinfo_mktable_invlen3, + .st_canopen = B_TRUE, + .st_verify = smbios_test_pinfo_verify_invlen3, + .st_desc = "processor additional information - bad table length 3" + }, { + .st_entry = SMBIOS_ENTRY_POINT_30, + .st_tvers = SMB_VERSION, + .st_libvers = SMB_VERSION, + .st_mktable = smbios_test_pinfo_mktable_invlen4, + .st_canopen = B_TRUE, + .st_verify = smbios_test_pinfo_verify_invlen4, + .st_desc = "processor additional information - bad table length 4" + }, { + .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_pinfo_verify_badtype, + .st_desc = "processor additional information - bad type" + }, + +}; + +static boolean_t +smbios_test_run_one(const smbios_test_t *test) { - smb_slot_t slot; - smb_slot_peer_t peers[2]; - smb_header_t eot; - 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; - slot.smbsl_npeers = 2; - peers[0].smbspb_group_no = htole16(1); - peers[0].smbspb_bus = 0x42; - peers[0].smbspb_df = 0x42; - peers[0].smbspb_width = SMB_SLW_8X; - - peers[1].smbspb_group_no = htole16(1); - peers[1].smbspb_bus = 0x23; - peers[1].smbspb_df = 0x31; - 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)); - - bzero(&eot, sizeof (eot)); - eot.smbh_type = SMB_TYPE_EOT; - eot.smbh_len = 4; - (void) smbios_test_table_append(table, &eot, sizeof (eot)); - (void) smbios_test_table_append_raw(table, &endstring, - sizeof (endstring)); - (void) smbios_test_table_append_raw(table, &endstring, - sizeof (endstring)); -} - -static void -smbios_test_verify_table(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) { - errx(EXIT_FAILURE, "failed to lookup SMBIOS slot: %s", - smbios_errmsg(smbios_errno(hdl))); - } - - if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) { - errx(EXIT_FAILURE, "failed to get SMBIOS slot info: %s", - smbios_errmsg(smbios_errno(hdl))); - } - - /* - * 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); - errs++; - } - - if (slot.smbl_npeers != 2) { - warnx("incorrect number of slot peers, found %u", - slot.smbl_npeers); - errs++; - } - - if (smbios_info_slot_peers(hdl, sp.smbstr_id, &npeers, &peers) != 0) { - errx(EXIT_FAILURE, "failed to get SMBIOS peer info: %s", - smbios_errmsg(smbios_errno(hdl))); - } - - if (npeers != 2) { - errx(EXIT_FAILURE, "got wrong number of slot peers: %u\n", - npeers); - } - - 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++; - } + smbios_test_table_t *table = NULL; + smbios_hdl_t *hdl = NULL; + void *buf; + size_t len; + smbios_entry_t *entry; + int err = 0; + boolean_t ret = B_FALSE; - if (peers[0].smblp_device != (0x42 >> 3)) { - warnx("incorrect PCI device for peer 0: %u", - peers[0].smblp_device); - errs++; + table = smbios_test_table_init(test->st_entry, test->st_tvers); + if (!test->st_mktable(table)) { + goto out; } - if (peers[0].smblp_function != (0x42 & 0x7)) { - warnx("incorrect PCI function for peer 0: %u", - peers[0].smblp_function); - errs++; + smbios_test_table_snapshot(table, &entry, &buf, &len); + hdl = smbios_bufopen(entry, buf, len, test->st_libvers, SMB_FL_DEBUG, + &err); + if (test->st_canopen) { + if (hdl == NULL) { + warnx("failed to create table for test %s: %s", + test->st_desc, smbios_errmsg(err)); + goto out; + } + } else { + if (hdl != NULL) { + warnx("accidentally created table for test %s, " + "expected failure", test->st_desc); + } else { + ret = B_TRUE; + } + goto out; } - if (peers[1].smblp_group != 1) { - warnx("incorrect group for peer 1: %u", peers[1].smblp_group); - errs++; + if (test->st_verify(hdl)) { + ret = B_TRUE; } - if (peers[1].smblp_device != (0x31 >> 3)) { - warnx("incorrect PCI device for peer 1: %u", - peers[1].smblp_device); - errs++; +out: + if (hdl != NULL) { + smbios_close(hdl); } - if (peers[1].smblp_function != (0x31 & 0x7)) { - warnx("incorrect PCI function for peer 1: %u", - peers[1].smblp_function); - errs++; + if (table != NULL) { + smbios_test_table_fini(table); } - if (peers[1].smblp_data_width != SMB_SLW_8X) { - warnx("incorrect data width for peer 1: %u", - peers[1].smblp_data_width); - errs++; + if (ret) { + (void) printf("TEST PASSED: %s\n", test->st_desc); + } else { + (void) printf("TEST FAILED: %s\n", test->st_desc); } - smbios_info_slot_peers_free(hdl, npeers, peers); - - if (errs > 0) { - errx(EXIT_FAILURE, "encountered fatal errors"); - } + return (ret); } int main(void) { - void *buf; - size_t len; - smbios_test_table_t *table; - smbios_entry_t *entry; - smbios_hdl_t *hdl; int err = 0; + size_t i; - table = smbios_test_table_init(SMBIOS_ENTRY_POINT_30, SMB_VERSION_32); - smbios_test_mktable(table); - smbios_test_table_snapshot(table, &entry, &buf, &len); - - hdl = smbios_bufopen(entry, buf, len, SMB_VERSION_32, SMB_FL_DEBUG, - &err); - if (hdl == NULL) { - errx(EXIT_FAILURE, "failed to create fake smbios table: %s", - smbios_errmsg(err)); + for (i = 0; i < ARRAY_SIZE(smbios_tests); i++) { + if (!smbios_test_run_one(&smbios_tests[i])) { + err = 1; + } } - smbios_test_verify_table(hdl); - smbios_close(hdl); - smbios_test_table_fini(table); - return (0); + return (err); } diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test.h b/usr/src/test/util-tests/tests/smbios/smbios_test.h new file mode 100644 index 0000000000..62baed7813 --- /dev/null +++ b/usr/src/test/util-tests/tests/smbios/smbios_test.h @@ -0,0 +1,110 @@ +/* + * 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 2019 Robert Mustacchi + */ + +#ifndef _SMBIOS_TEST_H +#define _SMBIOS_TEST_H + +/* + * Test framework for SMBIOS tests + */ + +#include <smbios.h> +#include <sys/smbios.h> +#include <sys/smbios_impl.h> +#include <err.h> +#include <stdint.h> +#include <endian.h> +#include <stdlib.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Number of bytes we allocate at a given time for an SMBIOS table. + */ +#define SMBIOS_TEST_ALLOC_SIZE 1024 + +typedef struct smbios_test_table { + smbios_entry_point_t stt_type; + void *stt_data; + size_t stt_buflen; + size_t stt_offset; + uint_t stt_nents; + uint_t stt_version; + uint_t stt_nextid; + smbios_entry_t stt_entry; +} smbios_test_table_t; + +/* + * General Interfaces used to construct tables. + */ +extern smbios_test_table_t *smbios_test_table_init(smbios_entry_point_t, + uint_t); +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 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 *); + +typedef boolean_t (*smbios_test_mktable_f)(smbios_test_table_t *); +typedef boolean_t (*smbios_test_verify_f)(smbios_hdl_t *); + +typedef struct smbios_test { + int st_entry; + int st_tvers; + int st_libvers; + smbios_test_mktable_f st_mktable; + boolean_t st_canopen; + smbios_test_verify_f st_verify; + const char *st_desc; +} smbios_test_t; + +/* + * Test functions + */ +extern boolean_t smbios_test_slot_mktable(smbios_test_table_t *); +extern boolean_t smbios_test_slot_verify(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 *); +extern boolean_t smbios_test_memdevice_mktable_33(smbios_test_table_t *); +extern boolean_t smbios_test_memdevice_mktable_33ext(smbios_test_table_t *); +extern boolean_t smbios_test_memdevice_verify_32(smbios_hdl_t *); +extern boolean_t smbios_test_memdevice_verify_32_33(smbios_hdl_t *); +extern boolean_t smbios_test_memdevice_verify_33(smbios_hdl_t *); +extern boolean_t smbios_test_memdevice_verify_33ext(smbios_hdl_t *); + +extern boolean_t smbios_test_pinfo_mktable_amd64(smbios_test_table_t *); +extern boolean_t smbios_test_pinfo_verify_amd64(smbios_hdl_t *); +extern boolean_t smbios_test_pinfo_mktable_riscv(smbios_test_table_t *); +extern boolean_t smbios_test_pinfo_verify_riscv(smbios_hdl_t *); +extern boolean_t smbios_test_pinfo_mktable_invlen1(smbios_test_table_t *); +extern boolean_t smbios_test_pinfo_mktable_invlen2(smbios_test_table_t *); +extern boolean_t smbios_test_pinfo_mktable_invlen3(smbios_test_table_t *); +extern boolean_t smbios_test_pinfo_mktable_invlen4(smbios_test_table_t *); +extern boolean_t smbios_test_pinfo_verify_invlen1(smbios_hdl_t *); +extern boolean_t smbios_test_pinfo_verify_invlen2(smbios_hdl_t *); +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 *); + +#ifdef __cplusplus +} +#endif + +#endif /* _SMBIOS_TEST_H */ 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 new file mode 100644 index 0000000000..0bca13c7bb --- /dev/null +++ b/usr/src/test/util-tests/tests/smbios/smbios_test_errors.c @@ -0,0 +1,28 @@ +/* + * 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 2019 Robert Mustacchi + */ + +/* + * Collection of functions to be used with tests that will cause a handle to + * fail to open. + */ + +#include "smbios_test.h" + +boolean_t +smbios_test_badvers_mktable(smbios_test_table_t *table) +{ + smbios_test_table_append_eot(table); + return (B_TRUE); +} diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test_memdevice.c b/usr/src/test/util-tests/tests/smbios/smbios_test_memdevice.c new file mode 100644 index 0000000000..7e6e3b02d4 --- /dev/null +++ b/usr/src/test/util-tests/tests/smbios/smbios_test_memdevice.c @@ -0,0 +1,355 @@ +/* + * 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 2019 Robert Mustacchi + */ + +/* + * Basic testing of the SMBIOS 3.3 memory device extensions. We test these in a + * few different ways: + * + * 1. Using a 3.2 table with a 3.2 library to make sure we get the old fields. + * We also need to verify that we don't clobber memory in this case. + * 2. Using a 3.2 table with a 3.3 library to make sure we get the new fields. + * populated with the corresponding 3.2 values. + * 3. Using a 3.3 table with only the old values as valid. + * 4. Using a 3.3 table with both the old and new values as valid. + * memory. + */ + +#include <stdlib.h> +#include "smbios_test.h" + +static uint16_t smbios_memdevice_speed = 0xdeed; +static uint16_t smbios_memdevice_clkspeed = 0xf00f; +static uint32_t smbios_memdevice_extspeed = 0xbaddeed; +static uint32_t smbios_memdevice_extclkspeed = 0xbadf00f; + +/* + * Fill in the basics of a single memory device. Callers need to fill in the + * speed, extspeed, clkspeed, and extclkspeed members. + */ +static void +smbios_test_memdevice_fill(smb_memdevice_t *mem) +{ + mem->smbmdev_hdr.smbh_type = SMB_TYPE_MEMDEVICE; + mem->smbmdev_hdr.smbh_len = sizeof (smb_memdevice_t); + + mem->smbmdev_array = 0xffff; + mem->smbmdev_error = htole16(0xfffe); + mem->smbmdev_twidth = 64; + mem->smbmdev_dwidth = 64; + mem->smbmdev_size = 0x7fff; + mem->smbmdev_form = SMB_MDFF_FBDIMM; + mem->smbmdev_set = 0; + mem->smbmdev_dloc = 0; + mem->smbmdev_bloc = 0; + mem->smbmdev_type = SMB_MDT_DDR4; + mem->smbmdev_manufacturer = 0; + mem->smbmdev_asset = 0; + mem->smbmdev_part = 0; + mem->smbmdev_attrs = 2; + mem->smbmdev_extsize = htole32(0x123456); + mem->smbmdev_minvolt = 0; + mem->smbmdev_maxvolt = 0; + mem->smbmdev_confvolt = 0; + mem->smbmdev_memtech = 0; + mem->smbmdev_opmode = 1 << 3; + mem->smbmdev_fwver = 0; + mem->smbmdev_modulemfgid = 0; + mem->smbmdev_moduleprodid = 0; + mem->smbmdev_memsysmfgid = 0; + mem->smbmdev_memsysprodid = 0; + mem->smbmdev_nvsize = htole64(UINT64_MAX); + mem->smbmdev_volsize = htole64(UINT64_MAX); + mem->smbmdev_cachesize = htole64(UINT64_MAX); + mem->smbmdev_logicalsize = htole64(UINT64_MAX); +} + +boolean_t +smbios_test_memdevice_mktable_32(smbios_test_table_t *table) +{ + smb_memdevice_t mem; + size_t len = 0x54; + + smbios_test_memdevice_fill(&mem); + mem.smbmdev_speed = htole16(smbios_memdevice_speed); + mem.smbmdev_clkspeed = htole16(smbios_memdevice_clkspeed); + mem.smbmdev_extspeed = htole32(0); + mem.smbmdev_extclkspeed = htole32(0); + + /* + * Because we're emulating an SMBIOS 3.2 table, we have to set it to the + * specification's defined size for that revision - 0x54. + */ + mem.smbmdev_hdr.smbh_len = len; + (void) smbios_test_table_append(table, &mem, len); + smbios_test_table_append_eot(table); + + return (B_TRUE); +} + +boolean_t +smbios_test_memdevice_mktable_33(smbios_test_table_t *table) +{ + smb_memdevice_t mem; + + smbios_test_memdevice_fill(&mem); + mem.smbmdev_speed = htole16(smbios_memdevice_speed); + mem.smbmdev_clkspeed = htole16(smbios_memdevice_clkspeed); + mem.smbmdev_extspeed = htole32(0); + mem.smbmdev_extclkspeed = htole32(0); + + (void) smbios_test_table_append(table, &mem, sizeof (mem)); + smbios_test_table_append_eot(table); + + return (B_TRUE); +} + +boolean_t +smbios_test_memdevice_mktable_33ext(smbios_test_table_t *table) +{ + smb_memdevice_t mem; + + smbios_test_memdevice_fill(&mem); + mem.smbmdev_speed = htole16(0xffff); + mem.smbmdev_clkspeed = htole16(0xffff); + mem.smbmdev_extspeed = htole32(smbios_memdevice_extspeed); + mem.smbmdev_extclkspeed = htole32(smbios_memdevice_extclkspeed); + + (void) smbios_test_table_append(table, &mem, sizeof (mem)); + smbios_test_table_append_eot(table); + + return (B_TRUE); +} + +static boolean_t +smbios_test_memdevice_verify_common(smbios_memdevice_t *mem) +{ + boolean_t ret = B_TRUE; + + if (mem->smbmd_dwidth != 64) { + warnx("found wrong dwidth: %u", mem->smbmd_dwidth); + ret = B_FALSE; + } + + if (mem->smbmd_twidth != 64) { + warnx("found wrong twidth: %u", mem->smbmd_twidth); + ret = B_FALSE; + } + + if (mem->smbmd_form != SMB_MDFF_FBDIMM) { + warnx("found wrong form: %u", mem->smbmd_form); + ret = B_FALSE; + } + + if (mem->smbmd_size != 0x123456ULL * 1024 * 1024) { + warnx("found wrong size: %u", mem->smbmd_size); + ret = B_FALSE; + } + + return (ret); +} + +boolean_t +smbios_test_memdevice_verify_32(smbios_hdl_t *hdl) +{ + smbios_struct_t sp; + smbios_memdevice_t mem; + boolean_t ret = B_TRUE; + uint64_t rval; + + /* + * We expect that the SMBIOS 3.2 memory device values should not be + * touched here. As such we set them to a random value to verify and + * verify that it hasn't been set. + */ + arc4random_buf(&rval, sizeof (rval)); + mem.smbmd_extspeed = rval; + mem.smbmd_extclkspeed = rval; + + 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_memdevice(hdl, sp.smbstr_id, &mem) != 0) { + warnx("failed to get SMBIOS memory device info: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (mem.smbmd_extspeed != rval || mem.smbmd_extclkspeed != rval) { + warnx("smbios_memdevice_t had its memory cloberred!"); + return (B_FALSE); + } + + if (!smbios_test_memdevice_verify_common(&mem)) { + return (B_FALSE); + } + + if (mem.smbmd_speed != smbios_memdevice_speed) { + warnx("found wrong device speed: %u", mem.smbmd_speed); + ret = B_FALSE; + } + + if (mem.smbmd_clkspeed != smbios_memdevice_clkspeed) { + warnx("found wrong device clkspeed: %u", mem.smbmd_clkspeed); + ret = B_FALSE; + } + + return (ret); +} + +/* + * This is a variant of smbios_test_memdevice_verify_32(), but instead of using + * an SMBIOS 3.2 library, we use an SMBIOS 3.3 handle. This means that we expect + * the extended values to be populated with the base values. + */ +boolean_t +smbios_test_memdevice_verify_32_33(smbios_hdl_t *hdl) +{ + smbios_struct_t sp; + smbios_memdevice_t mem; + boolean_t ret = B_TRUE; + + 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_memdevice(hdl, sp.smbstr_id, &mem) != 0) { + warnx("failed to get SMBIOS memory device info: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (!smbios_test_memdevice_verify_common(&mem)) { + return (B_FALSE); + } + + if (mem.smbmd_speed != smbios_memdevice_speed) { + warnx("found wrong device speed: %u", mem.smbmd_speed); + ret = B_FALSE; + } + + if (mem.smbmd_clkspeed != smbios_memdevice_clkspeed) { + warnx("found wrong device clkspeed: %u", mem.smbmd_clkspeed); + ret = B_FALSE; + } + + if (mem.smbmd_extspeed != smbios_memdevice_speed) { + warnx("found wrong device speed: %u", mem.smbmd_extspeed); + ret = B_FALSE; + } + + if (mem.smbmd_extclkspeed != smbios_memdevice_clkspeed) { + warnx("found wrong device clkspeed: %u", mem.smbmd_extclkspeed); + ret = B_FALSE; + } + + return (ret); +} + +boolean_t +smbios_test_memdevice_verify_33(smbios_hdl_t *hdl) +{ + smbios_struct_t sp; + smbios_memdevice_t mem; + boolean_t ret = B_TRUE; + + 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_memdevice(hdl, sp.smbstr_id, &mem) != 0) { + warnx("failed to get SMBIOS memory device info: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (!smbios_test_memdevice_verify_common(&mem)) { + return (B_FALSE); + } + + if (mem.smbmd_speed != smbios_memdevice_speed) { + warnx("found wrong device speed: %u", mem.smbmd_speed); + ret = B_FALSE; + } + + if (mem.smbmd_clkspeed != smbios_memdevice_clkspeed) { + warnx("found wrong device clkspeed: %u", mem.smbmd_clkspeed); + ret = B_FALSE; + } + + if (mem.smbmd_extspeed != smbios_memdevice_speed) { + warnx("found wrong device speed: %u", mem.smbmd_extspeed); + ret = B_FALSE; + } + + if (mem.smbmd_extclkspeed != smbios_memdevice_clkspeed) { + warnx("found wrong device clkspeed: %u", mem.smbmd_extclkspeed); + ret = B_FALSE; + } + + return (ret); +} + +boolean_t +smbios_test_memdevice_verify_33ext(smbios_hdl_t *hdl) +{ + smbios_struct_t sp; + smbios_memdevice_t mem; + boolean_t ret = B_TRUE; + + 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_memdevice(hdl, sp.smbstr_id, &mem) != 0) { + warnx("failed to get SMBIOS memory device info: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (!smbios_test_memdevice_verify_common(&mem)) { + return (B_FALSE); + } + + if (mem.smbmd_speed != 0xffff) { + warnx("found wrong device speed: %u", mem.smbmd_speed); + ret = B_FALSE; + } + + if (mem.smbmd_clkspeed != 0xffff) { + warnx("found wrong device clkspeed: %u", mem.smbmd_clkspeed); + ret = B_FALSE; + } + + if (mem.smbmd_extspeed != smbios_memdevice_extspeed) { + warnx("found wrong device speed: %u", mem.smbmd_extspeed); + ret = B_FALSE; + } + + if (mem.smbmd_extclkspeed != smbios_memdevice_extclkspeed) { + warnx("found wrong device clkspeed: %u", mem.smbmd_extclkspeed); + ret = B_FALSE; + } + + 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 new file mode 100644 index 0000000000..178de212ae --- /dev/null +++ b/usr/src/test/util-tests/tests/smbios/smbios_test_pinfo.c @@ -0,0 +1,585 @@ +/* + * 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 2019 Robert Mustacchi + */ + +/* + * Tests for SMBIOS type 44 - SMB_TYPE_PROCESSOR_INFO and the per-CPU type + * follow ups. + */ + +#include "smbios_test.h" + +static uint16_t smbios_pinfo_phandle = 0x1; +static uint64_t smbios_pinfo_isa = 0x4010d; +static uint8_t smbios_pinfo_hartid[16]; +static uint8_t smbios_pinfo_vendid[16]; +static uint8_t smbios_pinfo_archid[16]; +static uint8_t smbios_pinfo_machid[16]; +static uint8_t smbios_pinfo_metdi[16]; +static uint8_t smbios_pinfo_mitdi[16]; + +boolean_t +smbios_test_pinfo_mktable_amd64(smbios_test_table_t *table) +{ + smb_processor_info_t pi; + + pi.smbpai_hdr.smbh_type = SMB_TYPE_PROCESSOR_INFO; + pi.smbpai_hdr.smbh_len = sizeof (smb_processor_info_t); + pi.smbpai_proc = htole16(smbios_pinfo_phandle); + pi.smbpai_len = 0; + pi.smbpai_type = SMB_PROCINFO_T_AMD64; + + (void) smbios_test_table_append(table, &pi, sizeof (pi)); + smbios_test_table_append_eot(table); + + return (B_TRUE); +} + +boolean_t +smbios_test_pinfo_verify_amd64(smbios_hdl_t *hdl) +{ + smbios_struct_t sp; + smbios_processor_info_t pinfo; + smbios_processor_info_riscv_t rv; + boolean_t ret = B_TRUE; + + if (smbios_lookup_type(hdl, SMB_TYPE_PROCESSOR_INFO, &sp) == -1) { + warnx("failed to lookup SMBIOS processor additional " + "information: %s", smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (smbios_info_processor_info(hdl, sp.smbstr_id, &pinfo) != 0) { + + warnx("failed to get SMBIOS processor additional " + "information: %s", smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (pinfo.smbpi_processor != smbios_pinfo_phandle) { + warnx("processor handle incorrect, found 0x%x", + pinfo.smbpi_processor); + ret = B_FALSE; + } + + if (pinfo.smbpi_ptype != SMB_PROCINFO_T_AMD64) { + warnx("processor type incorrect, found 0x%x", + pinfo.smbpi_ptype); + ret = B_FALSE; + } + + if (strcmp(smbios_processor_info_type_desc(pinfo.smbpi_ptype), + "X64 (x86-64, Intel64, AMD64, EMT64)") != 0) { + warnx("processor type incorrect, found %s", + smbios_processor_info_type_desc(pinfo.smbpi_ptype)); + ret = B_FALSE; + } + + if (smbios_info_processor_riscv(hdl, sp.smbstr_id, &rv) != -1) { + warnx("accidentally got riscv info on non-riscv handle"); + ret = B_FALSE; + } + + if (smbios_errno(hdl) != ESMB_TYPE) { + warnx("encountered wrong errno for RISC-V info, found: 0x%x", + smbios_errno(hdl)); + ret = B_FALSE; + } + + return (ret); +} + +boolean_t +smbios_test_pinfo_mktable_riscv(smbios_test_table_t *table) +{ + smb_processor_info_t pi; + smb_processor_info_riscv_t rv; + + pi.smbpai_hdr.smbh_type = SMB_TYPE_PROCESSOR_INFO; + pi.smbpai_hdr.smbh_len = sizeof (smb_processor_info_t) + + sizeof (smb_processor_info_riscv_t); + pi.smbpai_proc = htole16(smbios_pinfo_phandle); + pi.smbpai_len = sizeof (smb_processor_info_riscv_t); + pi.smbpai_type = SMB_PROCINFO_T_RV64; + + (void) smbios_test_table_append(table, &pi, sizeof (pi)); + + rv.smbpairv_vers = 1; + rv.smbpairv_len = sizeof (smb_processor_info_riscv_t); + arc4random_buf(smbios_pinfo_hartid, sizeof (smbios_pinfo_hartid)); + bcopy(smbios_pinfo_hartid, rv.smbpairv_hartid, + sizeof (smbios_pinfo_hartid)); + rv.smbpairv_boot = 1; + arc4random_buf(smbios_pinfo_vendid, sizeof (smbios_pinfo_vendid)); + bcopy(smbios_pinfo_vendid, rv.smbpairv_vendid, + sizeof (smbios_pinfo_vendid)); + arc4random_buf(smbios_pinfo_archid, sizeof (smbios_pinfo_archid)); + bcopy(smbios_pinfo_archid, rv.smbpairv_archid, + sizeof (smbios_pinfo_archid)); + arc4random_buf(smbios_pinfo_machid, sizeof (smbios_pinfo_machid)); + bcopy(smbios_pinfo_machid, rv.smbpairv_machid, + sizeof (smbios_pinfo_machid)); + rv.smbpairv_boot = 1; + rv.smbpairv_isa = htole64(smbios_pinfo_isa); + rv.smbpairv_privlvl = SMB_RV_PRIV_M | SMB_RV_PRIV_S; + arc4random_buf(smbios_pinfo_metdi, sizeof (smbios_pinfo_metdi)); + bcopy(smbios_pinfo_metdi, rv.smbpairv_metdi, + sizeof (smbios_pinfo_metdi)); + arc4random_buf(smbios_pinfo_mitdi, sizeof (smbios_pinfo_mitdi)); + bcopy(smbios_pinfo_mitdi, rv.smbpairv_mitdi, + sizeof (smbios_pinfo_mitdi)); + rv.smbpairv_xlen = SMB_RV_WIDTH_64B; + rv.smbpairv_mxlen = SMB_RV_WIDTH_64B; + rv.smbpairv_sxlen = SMB_RV_WIDTH_128B; + rv.smbpairv_uxlen = SMB_RV_WIDTH_32B; + + smbios_test_table_append_raw(table, &rv, sizeof (rv)); + smbios_test_table_append_eot(table); + + return (B_TRUE); +} + +static void +smbios_test_pinfo_id_mismatch(uint8_t *act, uint8_t *exp) +{ + uint_t i; + (void) fprintf(stderr, "found: "); + for (i = 0; i < 16; i++) { + (void) fprintf(stderr, " %02x", act[i]); + } + (void) fprintf(stderr, "\nexpected: "); + for (i = 0; i < 16; i++) { + (void) fprintf(stderr, " %02x", exp[i]); + } + (void) fprintf(stderr, "\n"); +} + +boolean_t +smbios_test_pinfo_verify_riscv(smbios_hdl_t *hdl) +{ + smbios_struct_t sp; + smbios_processor_info_t pinfo; + smbios_processor_info_riscv_t rv; + boolean_t ret = B_TRUE; + + if (smbios_lookup_type(hdl, SMB_TYPE_PROCESSOR_INFO, &sp) == -1) { + warnx("failed to lookup SMBIOS processor additional " + "information: %s", smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (smbios_info_processor_info(hdl, sp.smbstr_id, &pinfo) != 0) { + warnx("failed to get SMBIOS processor additional " + "information: %s", smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (pinfo.smbpi_processor != smbios_pinfo_phandle) { + warnx("processor handle incorrect, found 0x%x", + pinfo.smbpi_processor); + ret = B_FALSE; + } + + if (pinfo.smbpi_ptype != SMB_PROCINFO_T_RV64) { + warnx("processor type incorrect, found 0x%x", + pinfo.smbpi_ptype); + ret = B_FALSE; + } + + if (strcmp(smbios_processor_info_type_desc(pinfo.smbpi_ptype), + "64-bit RISC-V (RV64)") != 0) { + warnx("processor type incorrect, found %s", + smbios_processor_info_type_desc(pinfo.smbpi_ptype)); + ret = B_FALSE; + } + + if (smbios_info_processor_riscv(hdl, sp.smbstr_id, &rv) != 0) { + + warnx("failed to get SMBIOS processor additional " + "information for RISC-V: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (bcmp(rv.smbpirv_hartid, smbios_pinfo_hartid, + sizeof (smbios_pinfo_hartid)) != 0) { + warnx("RISC-V hart id's don't match"); + smbios_test_pinfo_id_mismatch(rv.smbpirv_hartid, + smbios_pinfo_hartid); + ret = B_FALSE; + } + + if (bcmp(rv.smbpirv_vendid, smbios_pinfo_vendid, + sizeof (smbios_pinfo_vendid)) != 0) { + warnx("RISC-V vend id's don't match"); + smbios_test_pinfo_id_mismatch(rv.smbpirv_vendid, + smbios_pinfo_vendid); + ret = B_FALSE; + } + + if (bcmp(rv.smbpirv_archid, smbios_pinfo_archid, + sizeof (smbios_pinfo_archid)) != 0) { + warnx("RISC-V arch id's don't match"); + smbios_test_pinfo_id_mismatch(rv.smbpirv_archid, + smbios_pinfo_archid); + ret = B_FALSE; + } + + if (bcmp(rv.smbpirv_machid, smbios_pinfo_machid, + sizeof (smbios_pinfo_machid)) != 0) { + warnx("RISC-V mach id's don't match"); + smbios_test_pinfo_id_mismatch(rv.smbpirv_machid, + smbios_pinfo_machid); + ret = B_FALSE; + } + + if (bcmp(rv.smbpirv_metdi, smbios_pinfo_metdi, + sizeof (smbios_pinfo_metdi)) != 0) { + warnx("RISC-V METDI don't match"); + smbios_test_pinfo_id_mismatch(rv.smbpirv_metdi, + smbios_pinfo_metdi); + ret = B_FALSE; + } + + if (bcmp(rv.smbpirv_mitdi, smbios_pinfo_mitdi, + sizeof (smbios_pinfo_mitdi)) != 0) { + warnx("RISC-V METDI don't match"); + smbios_test_pinfo_id_mismatch(rv.smbpirv_mitdi, + smbios_pinfo_mitdi); + ret = B_FALSE; + } + + if (rv.smbpirv_isa != smbios_pinfo_isa) { + warnx("RISC-V ISA mismatch"); + ret = B_FALSE; + } + + if (rv.smbpirv_privlvl != (SMB_RV_PRIV_M | SMB_RV_PRIV_S)) { + warnx("RISC-V privilege level mismatch, found: 0x%x", + rv.smbpirv_privlvl); + ret = B_FALSE; + } + + if (rv.smbpirv_xlen != SMB_RV_WIDTH_64B) { + warnx("RISC-V xlen mismatch, found: 0x%x", rv.smbpirv_xlen); + ret = B_FALSE; + } + + if (rv.smbpirv_mxlen != SMB_RV_WIDTH_64B) { + warnx("RISC-V mxlen mismatch, found: 0x%x", rv.smbpirv_mxlen); + ret = B_FALSE; + } + + if (rv.smbpirv_sxlen != SMB_RV_WIDTH_128B) { + warnx("RISC-V sxlen mismatch, found: 0x%x", rv.smbpirv_sxlen); + ret = B_FALSE; + } + + if (rv.smbpirv_uxlen != SMB_RV_WIDTH_32B) { + warnx("RISC-V uxlen mismatch, found: 0x%x", rv.smbpirv_uxlen); + ret = B_FALSE; + } + + /* + * Finally, use this to spot check several of the different RISC-V + * strings. + */ + if (strcmp(smbios_riscv_priv_desc(SMB_RV_PRIV_M), "Machine Mode") != + 0) { + warnx("SMB_RV_PRIV_M string desc mismatch, found %s", + smbios_riscv_priv_desc(SMB_RV_PRIV_M)); + ret = B_FALSE; + } + + if (strcmp(smbios_riscv_priv_name(SMB_RV_PRIV_U), "SMB_RV_PRIV_U") != + 0) { + warnx("SMB_RV_PRIV_U string name mismatch, found %s", + smbios_riscv_priv_name(SMB_RV_PRIV_U)); + ret = B_FALSE; + } + + if (strcmp(smbios_riscv_width_desc(SMB_RV_WIDTH_64B), "64-bit") != + 0) { + warnx("SMB_RV_WIDTH_64B string desc mismatch, found %s", + smbios_riscv_width_desc(SMB_RV_WIDTH_64B)); + ret = B_FALSE; + } + + if (strcmp(smbios_riscv_width_desc(SMB_RV_WIDTH_128B), "128-bit") != + 0) { + warnx("SMB_RV_WIDTH_128B string desc mismatch, found %s", + smbios_riscv_width_desc(SMB_RV_WIDTH_128B)); + ret = B_FALSE; + } + + if (strcmp(smbios_riscv_isa_desc(SMB_RV_ISA_A), "Atomic") != 0) { + warnx("SMB_RV_ISA_A string desc mismatch, found %s", + smbios_riscv_isa_desc(SMB_RV_ISA_A)); + ret = B_FALSE; + } + + if (strcmp(smbios_riscv_isa_desc(SMB_RV_ISA_C), "Compressed") != 0) { + warnx("SMB_RV_ISA_Q 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) { + warnx("SMB_RV_ISA_Q string desc mismatch, found %s", + smbios_riscv_isa_desc(SMB_RV_ISA_Q)); + ret = B_FALSE; + } + + if (strcmp(smbios_riscv_isa_name(SMB_RV_ISA_A), "SMB_RV_ISA_A") != 0) { + warnx("SMB_RV_ISA_A string name mismatch, found %s", + smbios_riscv_isa_name(SMB_RV_ISA_A)); + ret = B_FALSE; + } + + if (strcmp(smbios_riscv_isa_name(SMB_RV_ISA_C), "SMB_RV_ISA_C") != 0) { + warnx("SMB_RV_ISA_Q string name mismatch, found %s", + smbios_riscv_isa_name(SMB_RV_ISA_C)); + ret = B_FALSE; + } + + if (strcmp(smbios_riscv_isa_name(SMB_RV_ISA_Q), "SMB_RV_ISA_Q") != 0) { + warnx("SMB_RV_ISA_Q string name mismatch, found %s", + smbios_riscv_isa_name(SMB_RV_ISA_Q)); + ret = B_FALSE; + } + + return (ret); +} + +/* + * This shows having an invalid table length. + */ +boolean_t +smbios_test_pinfo_mktable_invlen1(smbios_test_table_t *table) +{ + smb_processor_info_t pi; + + pi.smbpai_hdr.smbh_type = SMB_TYPE_PROCESSOR_INFO; + pi.smbpai_hdr.smbh_len = 2; + pi.smbpai_proc = htole16(smbios_pinfo_phandle); + pi.smbpai_len = 0; + pi.smbpai_type = SMB_PROCINFO_T_AMD64; + + (void) smbios_test_table_append(table, &pi, sizeof (pi)); + smbios_test_table_append_eot(table); + + return (B_TRUE); +} + +/* + * This sets the internal length of the additional processor information data to + * go beyond the length of the basic structure. + */ +boolean_t +smbios_test_pinfo_mktable_invlen2(smbios_test_table_t *table) +{ + smb_processor_info_t pi; + smb_processor_info_riscv_t rv; + + pi.smbpai_hdr.smbh_type = SMB_TYPE_PROCESSOR_INFO; + pi.smbpai_hdr.smbh_len = sizeof (smb_processor_info_t); + pi.smbpai_proc = htole16(smbios_pinfo_phandle); + pi.smbpai_len = sizeof (smb_processor_info_riscv_t); + pi.smbpai_type = SMB_PROCINFO_T_RV64; + + (void) smbios_test_table_append(table, &pi, sizeof (pi)); + + arc4random_buf(&rv, sizeof (rv)); + rv.smbpairv_vers = 1; + rv.smbpairv_len = sizeof (smb_processor_info_riscv_t); + + smbios_test_table_append_raw(table, &rv, sizeof (rv)); + smbios_test_table_append_eot(table); + + return (B_TRUE); +} + +/* + * This verifies that we can detect a header length that doesn't properly + * contain both the risc-v and base structure. + */ +boolean_t +smbios_test_pinfo_mktable_invlen3(smbios_test_table_t *table) +{ + smb_processor_info_t pi; + smb_processor_info_riscv_t rv; + + pi.smbpai_hdr.smbh_type = SMB_TYPE_PROCESSOR_INFO; + pi.smbpai_hdr.smbh_len = sizeof (smb_processor_info_t); + pi.smbpai_proc = htole16(smbios_pinfo_phandle); + pi.smbpai_len = 0; + pi.smbpai_type = SMB_PROCINFO_T_RV64; + + (void) smbios_test_table_append(table, &pi, sizeof (pi)); + + arc4random_buf(&rv, sizeof (rv)); + rv.smbpairv_vers = 1; + rv.smbpairv_len = sizeof (smb_processor_info_riscv_t); + + smbios_test_table_append_raw(table, &rv, sizeof (rv)); + smbios_test_table_append_eot(table); + + return (B_TRUE); +} + +/* + * This verifies that we can detect an inner risc-v additional processor + * information section that declares its size to be beyond the header of the + * structure. + */ +boolean_t +smbios_test_pinfo_mktable_invlen4(smbios_test_table_t *table) +{ + smb_processor_info_t pi; + smb_processor_info_riscv_t rv; + + pi.smbpai_hdr.smbh_type = SMB_TYPE_PROCESSOR_INFO; + pi.smbpai_hdr.smbh_len = sizeof (smb_processor_info_t) + + sizeof (smb_processor_info_riscv_t); + pi.smbpai_proc = htole16(smbios_pinfo_phandle); + pi.smbpai_len = sizeof (smb_processor_info_riscv_t); + pi.smbpai_type = SMB_PROCINFO_T_RV64; + + (void) smbios_test_table_append(table, &pi, sizeof (pi)); + + arc4random_buf(&rv, sizeof (rv)); + rv.smbpairv_vers = 1; + rv.smbpairv_len = sizeof (smb_processor_info_riscv_t) * 2; + + smbios_test_table_append_raw(table, &rv, sizeof (rv)); + smbios_test_table_append_eot(table); + + return (B_TRUE); +} +static boolean_t +smbios_test_pinfo_verify_badtable(smbios_hdl_t *hdl, int smberr, + boolean_t valid_pinfo) +{ + smbios_struct_t sp; + smbios_processor_info_t pinfo; + smbios_processor_info_riscv_t rv; + boolean_t ret = B_TRUE; + + if (smbios_lookup_type(hdl, SMB_TYPE_PROCESSOR_INFO, &sp) == -1) { + warnx("failed to lookup SMBIOS processor additional " + "information: %s", smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (!valid_pinfo) { + if (smbios_info_processor_info(hdl, sp.smbstr_id, &pinfo) != + -1) { + warnx("accidentally parsed invalid processor " + "additional information as valid"); + ret = B_FALSE; + } + + if (smbios_errno(hdl) != smberr) { + warnx("encountered wrong error for processor info, " + "found: 0x%x", smbios_errno(hdl)); + ret = B_FALSE; + } + } else { + if (smbios_info_processor_info(hdl, sp.smbstr_id, &pinfo) != + 0) { + warnx("failed to get SMBIOS processor additional " + "information: %s", + smbios_errmsg(smbios_errno(hdl))); + ret = B_FALSE; + } + } + + if (smbios_info_processor_riscv(hdl, sp.smbstr_id, &rv) != -1) { + warnx("accidentally got riscv info on invalid handle"); + ret = B_FALSE; + } + + if (smbios_errno(hdl) != smberr) { + warnx("encountered wrong error for amd64 info, found: 0x%x", + smbios_errno(hdl)); + ret = B_FALSE; + } + + return (ret); +} + +boolean_t +smbios_test_pinfo_verify_invlen1(smbios_hdl_t *hdl) +{ + return (smbios_test_pinfo_verify_badtable(hdl, ESMB_SHORT, B_FALSE)); +} + +boolean_t +smbios_test_pinfo_verify_invlen2(smbios_hdl_t *hdl) +{ + return (smbios_test_pinfo_verify_badtable(hdl, ESMB_CORRUPT, B_FALSE)); +} + +boolean_t +smbios_test_pinfo_verify_invlen3(smbios_hdl_t *hdl) +{ + return (smbios_test_pinfo_verify_badtable(hdl, ESMB_SHORT, B_TRUE)); +} + +boolean_t +smbios_test_pinfo_verify_invlen4(smbios_hdl_t *hdl) +{ + return (smbios_test_pinfo_verify_badtable(hdl, ESMB_CORRUPT, B_TRUE)); +} + +boolean_t +smbios_test_pinfo_verify_badtype(smbios_hdl_t *hdl) +{ + smbios_struct_t sp; + smbios_processor_info_t pinfo; + smbios_processor_info_riscv_t rv; + boolean_t ret = B_TRUE; + + if (smbios_lookup_type(hdl, SMB_TYPE_MEMDEVICE, &sp) == -1) { + warnx("failed to lookup SMBIOS memory device information: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (smbios_info_processor_info(hdl, sp.smbstr_id, &pinfo) != -1) { + warnx("accidentally parsed invalid processor additional " + "information as valid"); + ret = B_FALSE; + } + + if (smbios_errno(hdl) != ESMB_TYPE) { + warnx("encountered wrong error for processor info, found: 0x%x", + smbios_errno(hdl)); + ret = B_FALSE; + } + + if (smbios_info_processor_riscv(hdl, sp.smbstr_id, &rv) != -1) { + warnx("accidentally got riscv info on invalid handle"); + ret = B_FALSE; + } + + if (smbios_errno(hdl) != ESMB_TYPE) { + warnx("encountered wrong error for processor info, found: 0x%x", + smbios_errno(hdl)); + ret = B_FALSE; + } + + return (ret); +} 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 new file mode 100644 index 0000000000..d84cc10e91 --- /dev/null +++ b/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c @@ -0,0 +1,188 @@ +/* + * 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 (c) 2018, Joyent, Inc. + */ + +/* + * Basic testing of the SMBIOS 3.2 Slot extensions. + */ + +#include "smbios_test.h" + +static const char *smbios_test_name = "The One Slot"; + +boolean_t +smbios_test_slot_mktable(smbios_test_table_t *table) +{ + smb_slot_t slot; + 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; + slot.smbsl_npeers = 2; + peers[0].smbspb_group_no = htole16(1); + peers[0].smbspb_bus = 0x42; + peers[0].smbspb_df = 0x42; + peers[0].smbspb_width = SMB_SLW_8X; + + peers[1].smbspb_group_no = htole16(1); + peers[1].smbspb_bus = 0x23; + peers[1].smbspb_df = 0x31; + 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_eot(table); + + return (B_TRUE); +} + +boolean_t +smbios_test_slot_verify(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); + } + + /* + * 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); + errs++; + } + + if (slot.smbl_npeers != 2) { + 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 != 2) { + warnx("got wrong number of slot peers: %u\n", + npeers); + return (B_FALSE); + } + + 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_device != (0x42 >> 3)) { + warnx("incorrect PCI device for peer 0: %u", + peers[0].smblp_device); + errs++; + } + + if (peers[0].smblp_function != (0x42 & 0x7)) { + warnx("incorrect PCI function for peer 0: %u", + peers[0].smblp_function); + errs++; + } + + if (peers[1].smblp_group != 1) { + warnx("incorrect group for peer 1: %u", peers[1].smblp_group); + errs++; + } + + if (peers[1].smblp_device != (0x31 >> 3)) { + warnx("incorrect PCI device for peer 1: %u", + peers[1].smblp_device); + errs++; + } + + if (peers[1].smblp_function != (0x31 & 0x7)) { + warnx("incorrect PCI function for peer 1: %u", + peers[1].smblp_function); + errs++; + } + + if (peers[1].smblp_data_width != SMB_SLW_8X) { + warnx("incorrect data width for peer 1: %u", + peers[1].smblp_data_width); + errs++; + } + + smbios_info_slot_peers_free(hdl, npeers, peers); + + if (errs > 0) { + return (B_FALSE); + } + + return (B_TRUE); +} |
