summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormws <none@none>2005-08-27 15:17:06 -0700
committermws <none@none>2005-08-27 15:17:06 -0700
commit84ab085a13f931bc78e7415e7ce921dbaa14fcb3 (patch)
tree7e11d8ecfa91e3947c8c99dbe116ae10a8e8076f
parent89518a1cfe5021ecf5ad8d04c40f53cf947e95d9 (diff)
downloadillumos-joyent-84ab085a13f931bc78e7415e7ce921dbaa14fcb3.tar.gz
PSARC 2005/483 SMBIOS Support for Solaris
6313638 SMBIOS Support for Solaris 6230033 prtdiag should be implemented for Solaris x86 6313668 bmc driver should not have its own private smbios reader 6313670 post_startup_mmu_initialization() is useless and can be deleted
-rw-r--r--usr/src/Makefile.lint2
-rw-r--r--usr/src/cmd/Makefile1
-rw-r--r--usr/src/cmd/devfsadm/i386/misc_link_i386.c12
-rw-r--r--usr/src/cmd/file/magic3
-rw-r--r--usr/src/cmd/prtdiag/Makefile36
-rw-r--r--usr/src/cmd/prtdiag/Makefile.com50
-rw-r--r--usr/src/cmd/prtdiag/Makefile.targ15
-rw-r--r--usr/src/cmd/prtdiag/i386/Makefile45
-rw-r--r--usr/src/cmd/prtdiag/i386/i86pc/Makefile43
-rw-r--r--usr/src/cmd/prtdiag/i386/i86pc/smbios.c268
-rw-r--r--usr/src/cmd/prtdiag/main.c69
-rw-r--r--usr/src/cmd/smbios/Makefile56
-rw-r--r--usr/src/cmd/smbios/smbios.c1067
-rw-r--r--usr/src/common/smbios/mktables.sh145
-rw-r--r--usr/src/common/smbios/smb_error.c79
-rw-r--r--usr/src/common/smbios/smb_info.c785
-rw-r--r--usr/src/common/smbios/smb_open.c370
-rw-r--r--usr/src/lib/Makefile2
-rw-r--r--usr/src/lib/libsmbios/Makefile57
-rw-r--r--usr/src/lib/libsmbios/Makefile.com74
-rw-r--r--usr/src/lib/libsmbios/amd64/Makefile32
-rw-r--r--usr/src/lib/libsmbios/common/llib-lsmbios32
-rw-r--r--usr/src/lib/libsmbios/common/smb_lib.c204
-rw-r--r--usr/src/lib/libsmbios/common/smb_subr.c93
-rw-r--r--usr/src/lib/libsmbios/common/smbios.h55
-rw-r--r--usr/src/lib/libsmbios/i386/Makefile31
-rw-r--r--usr/src/lib/libsmbios/sparc/Makefile31
-rw-r--r--usr/src/lib/libsmbios/sparcv9/Makefile32
-rw-r--r--usr/src/lib/libsmbios/spec/Makefile28
-rw-r--r--usr/src/lib/libsmbios/spec/Makefile.targ32
-rw-r--r--usr/src/lib/libsmbios/spec/amd64/Makefile35
-rw-r--r--usr/src/lib/libsmbios/spec/i386/Makefile34
-rw-r--r--usr/src/lib/libsmbios/spec/smbios.spec374
-rw-r--r--usr/src/lib/libsmbios/spec/sparc/Makefile34
-rw-r--r--usr/src/lib/libsmbios/spec/sparcv9/Makefile35
-rw-r--r--usr/src/lib/libsmbios/spec/versions42
-rw-r--r--usr/src/pkgdefs/SUNWarc/prototype_com2
-rw-r--r--usr/src/pkgdefs/SUNWarc/prototype_i3863
-rw-r--r--usr/src/pkgdefs/SUNWarc/prototype_sparc3
-rw-r--r--usr/src/pkgdefs/SUNWckr/prototype_i3863
-rw-r--r--usr/src/pkgdefs/SUNWcsl/prototype_com6
-rw-r--r--usr/src/pkgdefs/SUNWcsl/prototype_i3866
-rw-r--r--usr/src/pkgdefs/SUNWcsl/prototype_sparc6
-rw-r--r--usr/src/pkgdefs/SUNWcsu/prototype_com1
-rw-r--r--usr/src/pkgdefs/SUNWhea/prototype_com3
-rw-r--r--usr/src/pkgdefs/SUNWkvm.i/prototype_com1
-rw-r--r--usr/src/pkgdefs/common_files/i.minorperm_i3861
-rw-r--r--usr/src/uts/common/Makefile.files2
-rw-r--r--usr/src/uts/common/Makefile.rules7
-rw-r--r--usr/src/uts/common/io/smbios.c331
-rw-r--r--usr/src/uts/common/io/smbios.conf29
-rw-r--r--usr/src/uts/common/os/smb_subr.c73
-rw-r--r--usr/src/uts/common/sys/Makefile2
-rw-r--r--usr/src/uts/common/sys/smbios.h1183
-rw-r--r--usr/src/uts/common/sys/smbios_impl.h440
-rw-r--r--usr/src/uts/i86pc/Makefile.files6
-rw-r--r--usr/src/uts/i86pc/os/smb_dev.c129
-rw-r--r--usr/src/uts/i86pc/os/startup.c18
-rw-r--r--usr/src/uts/i86pc/sys/machsystm.h2
-rw-r--r--usr/src/uts/i86pc/vm/vm_machdep.c7
-rw-r--r--usr/src/uts/intel/Makefile.intel1
-rw-r--r--usr/src/uts/intel/os/minor_perm1
-rw-r--r--usr/src/uts/intel/os/name_to_major1
-rw-r--r--usr/src/uts/intel/smbios/Makefile61
64 files changed, 6500 insertions, 131 deletions
diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint
index 163cb0217d..eac3e63f7e 100644
--- a/usr/src/Makefile.lint
+++ b/usr/src/Makefile.lint
@@ -229,6 +229,7 @@ COMMON_SUBDIRS = \
cmd/runat \
cmd/sed_xpg4 \
cmd/smartcard \
+ cmd/smbios \
cmd/smserverd \
cmd/sort \
cmd/split \
@@ -332,6 +333,7 @@ COMMON_SUBDIRS = \
lib/libsendfile \
lib/libsldap \
lib/libslp \
+ lib/libsmbios \
lib/libsmedia \
lib/libthread \
lib/libumem \
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile
index d7fb9d6310..1b82ddce22 100644
--- a/usr/src/cmd/Makefile
+++ b/usr/src/cmd/Makefile
@@ -346,6 +346,7 @@ COMMON_SUBDIRS= \
sh \
sleep \
smartcard \
+ smbios \
smserverd \
soelim \
sort \
diff --git a/usr/src/cmd/devfsadm/i386/misc_link_i386.c b/usr/src/cmd/devfsadm/i386/misc_link_i386.c
index bbce133dff..d588d0a828 100644
--- a/usr/src/cmd/devfsadm/i386/misc_link_i386.c
+++ b/usr/src/cmd/devfsadm/i386/misc_link_i386.c
@@ -41,6 +41,7 @@ static int diskette(di_minor_t minor, di_node_t node);
static int vt00(di_minor_t minor, di_node_t node);
static int kdmouse(di_minor_t minor, di_node_t node);
static int bmc(di_minor_t minor, di_node_t node);
+static int smbios(di_minor_t minor, di_node_t node);
static int agp_process(di_minor_t minor, di_node_t node);
static devfsadm_create_t misc_cbt[] = {
@@ -53,6 +54,9 @@ static devfsadm_create_t misc_cbt[] = {
{ "pseudo", "ddi_pseudo", "bmc",
TYPE_EXACT | DRV_EXACT, ILEVEL_0, bmc,
},
+ { "pseudo", "ddi_pseudo", "smbios",
+ TYPE_EXACT | DRV_EXACT, ILEVEL_1, smbios,
+ },
{ "disk", "ddi_block:diskette", NULL,
TYPE_EXACT, ILEVEL_1, diskette
},
@@ -295,6 +299,14 @@ bmc(di_minor_t minor, di_node_t node)
(void) devfsadm_mklink("bmc", node, minor, 0);
return (DEVFSADM_CONTINUE);
}
+
+static int
+smbios(di_minor_t minor, di_node_t node)
+{
+ (void) devfsadm_mklink("smbios", node, minor, 0);
+ return (DEVFSADM_CONTINUE);
+}
+
static int
agp_process(di_minor_t minor, di_node_t node)
{
diff --git a/usr/src/cmd/file/magic b/usr/src/cmd/file/magic
index b8c45b816e..c1dfa3e7fd 100644
--- a/usr/src/cmd/file/magic
+++ b/usr/src/cmd/file/magic
@@ -539,3 +539,6 @@
>6 ushort x rev %u,
>8 ushort x from esc v%u
>10 ushort x rev %u
+0 string _SM_ DMTF SMBIOS image
+>6 byte x version %u
+>7 byte x .%u
diff --git a/usr/src/cmd/prtdiag/Makefile b/usr/src/cmd/prtdiag/Makefile
index a335f3d632..2265dbd099 100644
--- a/usr/src/cmd/prtdiag/Makefile
+++ b/usr/src/cmd/prtdiag/Makefile
@@ -19,40 +19,30 @@
#
# CDDL HEADER END
#
+
#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 2001 by Sun Microsystems, Inc.
-# All rights reserved.
-#
-# src/cmd/prtdiag/Makefile
-#
-# builds occur in kernel-architecture subdirectories using Makefile.com
-# in this directory.
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
+#ident "%Z%%M% %I% %E% SMI"
include ../Makefile.cmd
-PROG = prtdiag
-
-sparc_SUBDIRS = sparc
-i386_SUBDIRS =
-
-SUBDIRS = $($(MACH)_SUBDIRS)
+PROG = prtdiag
+SUBDIRS = $(MACH)
-# conditional assignments
-all:= TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-_msg := TARGET= _msg
+all := TARGET = all
+install := TARGET = install
+clean := TARGET = clean
+clobber := TARGET = clobber
+lint := TARGET = lint
+_msg := TARGET = _msg
.KEEP_STATE:
all install clean clobber lint _msg: $(SUBDIRS)
-install: $(SUBDIRS)
+install: $(SUBDIRS)
$(RM) $(ROOTUSRSBINPROG)
$(LN) $(PLATEXEC) $(ROOTUSRSBINPROG)
diff --git a/usr/src/cmd/prtdiag/Makefile.com b/usr/src/cmd/prtdiag/Makefile.com
index 258df05f24..efc9462c39 100644
--- a/usr/src/cmd/prtdiag/Makefile.com
+++ b/usr/src/cmd/prtdiag/Makefile.com
@@ -19,63 +19,49 @@
#
# CDDL HEADER END
#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 1992, 1999 by Sun Microsystems, Inc.
-# All rights reserved.
-#
-# cmd/prtdiag/Makefile.com
-#
#
-# Create default so empty rules don't
-# confuse make
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
-CLASS = 32
+#ident "%Z%%M% %I% %E% SMI"
include $(SRCDIR)/../Makefile.cmd
include $(SRCDIR)/../../Makefile.psm
PROG = prtdiag
+OBJS = main.o
+CLASS = 32
FILEMODE = 2755
DIRMODE = 755
OWNER = root
GROUP = sys
-OBJS= main.o
-
-# allow additional kernel-architecture dependent objects to be specified.
-
-OBJS += $(KARCHOBJS)
-
-SRCS = $(OBJS:%.o=%.c)
-
-LINT_OBJS = $(OBJS:%.o=%.ln)
-
-
+LINTFILES = $(OBJS:%.o=%.ln)
POFILE = prtdiag_$(PLATFORM).po
POFILES = $(OBJS:%.o=%.po)
+.PARALLEL: $(OBJS) $(LINTFILES)
-# These names describe the layout on the target machine
-
-IFLAGS = -I$(SRCDIR) -I$(USR_PSM_INCL_DIR) -I./
-
-CPPFLAGS = $(IFLAGS) $(CPPFLAGS.master) -D_SYSCALL32
-
-.PARALLEL: $(OBJS)
-
-# build rules
+%.o: %.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
%.o: $(SRCDIR)/%.c
$(COMPILE.c) -o $@ $<
$(POST_PROCESS_O)
+%.po: %.c
+ $(COMPILE.cpp) $< > $<.i
+ $(BUILD.po)
+
%.po: $(SRCDIR)/%.c
$(COMPILE.cpp) $< > $<.i
$(BUILD.po)
+%.ln: %.c
+ $(LINT.c) -c $<
+
%.ln: $(SRCDIR)/%.c
- $(LINT) -u -c $(CPPFLAGS) $<
+ $(LINT.c) -c $<
diff --git a/usr/src/cmd/prtdiag/Makefile.targ b/usr/src/cmd/prtdiag/Makefile.targ
index cc13fd5844..59e3072099 100644
--- a/usr/src/cmd/prtdiag/Makefile.targ
+++ b/usr/src/cmd/prtdiag/Makefile.targ
@@ -19,14 +19,12 @@
#
# CDDL HEADER END
#
+
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
-# cmd/prtdiag/Makefile.targ
-#
+#ident "%Z%%M% %I% %E% SMI"
install: all $(USR_PSM_SBIN_PROG) $(USR_PSM_SBIN_PROG_LINKS)
@@ -35,11 +33,10 @@ $(PROG): $(OBJS)
$(POST_PROCESS)
clean:
- -$(RM) $(OBJS)
- -$(RM) $(LINT_OBJS)
+ -$(RM) $(OBJS) $(LINTFILES)
-lint: $(LINT_OBJS)
- $(LINT.c) $(LINT_OBJS) $(LDLIBS.cmd)
+lint: $(LINTFILES)
+ $(LINT) $(LINTFILES) $(LDLIBS)
$(POFILE): $(POFILES)
$(RM) $@
diff --git a/usr/src/cmd/prtdiag/i386/Makefile b/usr/src/cmd/prtdiag/i386/Makefile
new file mode 100644
index 0000000000..985fd3411a
--- /dev/null
+++ b/usr/src/cmd/prtdiag/i386/Makefile
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+SUBDIRS = i86pc
+
+all := TARGET = all
+install := TARGET = install
+clean := TARGET = clean
+clobber := TARGET = clobber
+lint := TARGET = lint
+_msg := TARGET = _msg
+
+.KEEP_STATE:
+
+all install clean clobber lint _msg: $(SUBDIRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
diff --git a/usr/src/cmd/prtdiag/i386/i86pc/Makefile b/usr/src/cmd/prtdiag/i386/i86pc/Makefile
new file mode 100644
index 0000000000..77891ef8e4
--- /dev/null
+++ b/usr/src/cmd/prtdiag/i386/i86pc/Makefile
@@ -0,0 +1,43 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+SRCDIR = ../..
+PLATFORM = i86pc
+PLATLINKS =
+
+include $(SRCDIR)/Makefile.com
+
+FILEMODE = 555
+LDLIBS += -lsmbios
+OBJS += smbios.o
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+include $(SRCDIR)/Makefile.targ
diff --git a/usr/src/cmd/prtdiag/i386/i86pc/smbios.c b/usr/src/cmd/prtdiag/i386/i86pc/smbios.c
new file mode 100644
index 0000000000..819cd04551
--- /dev/null
+++ b/usr/src/cmd/prtdiag/i386/i86pc/smbios.c
@@ -0,0 +1,268 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * x86 System Management BIOS prtdiag
+ *
+ * Most modern x86 systems support a System Management BIOS, which is a memory
+ * buffer filled in by the BIOS at boot time that describes the hardware. This
+ * data format is described by DMTF specification DSP0134 (see http://dmtf.org)
+ * This file implements a rudimentary prtdiag(1M) display using the SMBIOS.
+ * Access to the data is provided by libsmbios: see <sys/smbios.h> for info.
+ *
+ * NOTE: It is important to understand that x86 hardware varies extremely
+ * widely and that the DMTF SMBIOS specification leaves way too much latitude
+ * for implementors, and provides no standardized validation mechanism. As
+ * such, it is not uncommon to find out-of-spec SMBIOSes or fields that
+ * contain strange and possibly even incorrect information. As such, this
+ * file should not be extended to report every SMBIOS tidbit or structure in
+ * the spec unless we have good reason to believe it tends to be reliable.
+ *
+ * Similarly, the prtdiag(1M) utility itself should not be used to spit out
+ * every possible bit of x86 configuration data from every possible source;
+ * otherwise this code will become an unmaintainable and untestable disaster.
+ * Extensions to prtdiag should prefer to use more stable kernel mechanisms
+ * that actually discover the true hardware when such subsystems are available,
+ * and should generally limit themselves to commonly needed h/w data. As such,
+ * extensions to x86 prtdiag should focus on integration with the device tree.
+ *
+ * The prtdiag(1M) utility is for service personnel and system administrators:
+ * it is not your personal ACPI disassembler or CPUID decoder ring. The
+ * complete SMBIOS data is available from smbdump(1), and other specialized
+ * tools can be created to display the state of other x86 features, especially
+ * when that information is more for kernel developers than box administrators.
+ */
+
+#include <smbios.h>
+#include <alloca.h>
+#include <locale.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+
+/*ARGSUSED*/
+static int
+do_procs(smbios_hdl_t *shp, const smbios_struct_t *sp, void *arg)
+{
+ smbios_processor_t p;
+ smbios_info_t info;
+ const char *v;
+ char *s;
+ size_t n;
+
+ if (sp->smbstr_type == SMB_TYPE_PROCESSOR &&
+ smbios_info_processor(shp, sp->smbstr_id, &p) != SMB_ERR &&
+ smbios_info_common(shp, sp->smbstr_id, &info) != SMB_ERR &&
+ SMB_PRSTATUS_PRESENT(p.smbp_status)) {
+
+ /*
+ * Obtaining a decent string for the type of processor is
+ * messy: the BIOS has hopefully filled in the SMBIOS record.
+ * If so, strip trailing spaces and \r (seen in some BIOSes).
+ * If not, fall back to the family name for p.smbp_family.
+ */
+ if (info.smbi_version != NULL && *info.smbi_version != '\0') {
+ n = strlen(info.smbi_version);
+ v = s = alloca(n + 1);
+ (void) strcpy(s, info.smbi_version);
+
+ if (s[n - 1] == '\r')
+ s[--n] = '\0';
+
+ while (n != 0 && isspace(s[n - 1]))
+ s[--n] = '\0';
+
+ } else if ((v = smbios_processor_family_desc(
+ p.smbp_family)) == NULL) {
+ v = gettext("Unknown");
+ }
+
+ (void) printf(gettext("%-32s %s\n"), v, info.smbi_location);
+ }
+
+ return (0);
+}
+
+/*
+ * NOTE: It would be very convenient to print the DIMM size in do_memdevs.
+ * Unfortunately, SMBIOS can only be relied upon to tell us whether a DIMM is
+ * present or not (smbmd_size == 0). Some BIOSes do fill in an accurate size
+ * for DIMMs, whereas others fill in the maximum size, and still others insert
+ * a wrong value. Sizes will need to wait for x86 memory controller interfaces
+ * or integration with IPMI, which can actually read the true DIMM SPD data.
+ */
+/*ARGSUSED*/
+static int
+do_memdevs(smbios_hdl_t *shp, const smbios_struct_t *sp, void *arg)
+{
+ smbios_memdevice_t md;
+
+ if (sp->smbstr_type == SMB_TYPE_MEMDEVICE &&
+ smbios_info_memdevice(shp, sp->smbstr_id, &md) != SMB_ERR) {
+
+ const char *t = smbios_memdevice_type_desc(md.smbmd_type);
+ char buf[8];
+
+ if (md.smbmd_set != (uint8_t)-1)
+ (void) snprintf(buf, sizeof (buf), "%u", md.smbmd_set);
+ else
+ (void) strcpy(buf, "-");
+
+ (void) printf(gettext("%-7s %-6s %-3s %-19s %s\n"),
+ t ? t : gettext("Unknown"),
+ md.smbmd_size ? gettext("in use") : gettext("empty"),
+ buf, md.smbmd_dloc, md.smbmd_bloc);
+ }
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+do_obdevs(smbios_hdl_t *shp, const smbios_struct_t *sp, void *arg)
+{
+ smbios_obdev_t *argv;
+ int i, argc;
+
+ if (sp->smbstr_type == SMB_TYPE_OBDEVS &&
+ (argc = smbios_info_obdevs(shp, sp->smbstr_id, 0, NULL)) > 0) {
+ argv = alloca(sizeof (smbios_obdev_t) * argc);
+ (void) smbios_info_obdevs(shp, sp->smbstr_id, argc, argv);
+ for (i = 0; i < argc; i++)
+ (void) printf(gettext("%s\n"), argv[i].smbd_name);
+ }
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+do_slots(smbios_hdl_t *shp, const smbios_struct_t *sp, void *arg)
+{
+ smbios_slot_t s;
+
+ if (sp->smbstr_type == SMB_TYPE_SLOT &&
+ smbios_info_slot(shp, sp->smbstr_id, &s) != SMB_ERR) {
+
+ const char *t = smbios_slot_type_desc(s.smbl_type);
+ const char *u = smbios_slot_usage_desc(s.smbl_usage);
+
+ (void) printf(gettext("%-3u %-9s %-16s %s\n"),
+ s.smbl_id, u ? u : gettext("Unknown"),
+ t ? t : gettext("Unknown"), s.smbl_name);
+ }
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+do_prominfo(int opt_v, char *progname, int opt_l, int opt_p)
+{
+ smbios_hdl_t *shp;
+ smbios_system_t sys;
+ smbios_bios_t bios;
+ smbios_ipmi_t ipmi;
+ smbios_info_t info;
+
+ const char *s;
+ id_t id;
+ int err;
+
+ if ((shp = smbios_open(NULL, SMB_VERSION, 0, &err)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("%s: failed to open SMBIOS: %s\n"),
+ progname, smbios_errmsg(err));
+ return (1);
+ }
+
+ if ((id = smbios_info_system(shp, &sys)) != SMB_ERR &&
+ smbios_info_common(shp, id, &info) != SMB_ERR) {
+ (void) printf(gettext("System Configuration: %s %s\n"),
+ info.smbi_manufacturer, info.smbi_product);
+ } else {
+ (void) fprintf(stderr,
+ gettext("%s: failed to get system info: %s\n"),
+ progname, smbios_errmsg(smbios_errno(shp)));
+ }
+
+ if (smbios_info_bios(shp, &bios) != SMB_ERR) {
+ (void) printf(gettext("BIOS Configuration: %s %s %s\n"),
+ bios.smbb_vendor, bios.smbb_version, bios.smbb_reldate);
+ } else {
+ (void) fprintf(stderr,
+ gettext("%s: failed to get bios info: %s\n"),
+ progname, smbios_errmsg(smbios_errno(shp)));
+ }
+
+ if (smbios_info_ipmi(shp, &ipmi) != SMB_ERR) {
+ if ((s = smbios_ipmi_type_desc(ipmi.smbip_type)) == NULL)
+ s = gettext("Unknown");
+
+ (void) printf(gettext("BMC Configuration: IPMI %u.%u (%s)\n"),
+ ipmi.smbip_vers.smbv_major, ipmi.smbip_vers.smbv_minor, s);
+ }
+
+ (void) printf(gettext(
+ "\n==== Processor Sockets ====================================\n"));
+
+ (void) printf(gettext("\n%-32s %s"), "Version", "Location Tag");
+
+ (void) printf(gettext(
+ "\n-------------------------------- --------------------------\n"));
+ (void) smbios_iter(shp, do_procs, NULL);
+
+ (void) printf(gettext(
+ "\n==== Memory Device Sockets ================================\n"));
+
+ (void) printf(gettext("\n%-7s %-6s %-3s %-19s %s"),
+ "Type", "Status", "Set", "Device Locator", "Bank Locator");
+
+ (void) printf(gettext(
+ "\n------- ------ --- ------------------- --------------------\n"));
+ (void) smbios_iter(shp, do_memdevs, NULL);
+
+ (void) printf(gettext(
+ "\n==== On-Board Devices =====================================\n"));
+ (void) smbios_iter(shp, do_obdevs, NULL);
+
+ (void) printf(gettext(
+ "\n==== Upgradeable Slots ====================================\n"));
+
+ (void) printf(gettext("\n%-3s %-9s %-16s %s"),
+ "ID", "Status", "Type", "Description");
+
+ (void) printf(gettext(
+ "\n--- --------- ---------------- ----------------------------\n"));
+ (void) smbios_iter(shp, do_slots, NULL);
+
+ smbios_close(shp);
+ return (0);
+}
diff --git a/usr/src/cmd/prtdiag/main.c b/usr/src/cmd/prtdiag/main.c
index 303a6d042d..6a666c8c7c 100644
--- a/usr/src/cmd/prtdiag/main.c
+++ b/usr/src/cmd/prtdiag/main.c
@@ -19,8 +19,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,47 +30,48 @@
* All rights reserved.
*/
+#pragma ident "%Z%%M% %I% %E% SMI"
-#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.7 */
+#include <stdio.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <libintl.h>
+#include <string.h>
+#include <unistd.h>
+#include <zone.h>
-#include <stdio.h>
-#include <locale.h>
-#include <stdlib.h>
-#include <libintl.h>
-#include <string.h>
-#include <unistd.h>
-#include <zone.h>
-#include <sys/openpromio.h>
+extern int do_prominfo(int, char *, int, int);
-/*
- * function prototypes
- */
-extern int do_prominfo(int syserrlog, char *progname,
- int logging, int print_flag);
-static char *setprogname(char *name);
+static char *
+setprogname(char *name)
+{
+ char *p;
+
+ if (p = strrchr(name, '/'))
+ return (p + 1);
+ else
+ return (name);
+}
-void
+int
main(int argc, char *argv[])
{
int c;
int syserrlog = 0;
- char *usage = "%s [ -v ] [ -l ]\n";
- char *progname;
+ char *progname = setprogname(argv[0]);
int print_flag = 1;
int logging = 0;
- /* set up for internationalization */
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
- progname = setprogname(argv[0]);
if (getzoneid() != GLOBAL_ZONEID) {
(void) fprintf(stderr,
gettext("%s can only be run in the global zone\n"),
progname);
- exit(1);
- /*NOTREACHED*/
+ return (1);
}
+
while ((c = getopt(argc, argv, "vl")) != -1) {
switch (c) {
case 'v':
@@ -81,25 +83,10 @@ main(int argc, char *argv[])
break;
default:
- (void) fprintf(stderr, usage, progname);
- exit(1);
- /*NOTREACHED*/
+ (void) fprintf(stderr, "Usage: %s [-lv]\n", progname);
+ return (1);
}
}
- /*
- * for sun4u do_prominfo() is in libprtdiag
- */
- exit(do_prominfo(syserrlog, progname, logging, print_flag));
-}
-
-static char *
-setprogname(char *name)
-{
- char *p;
-
- if (p = strrchr(name, '/'))
- return (p + 1);
- else
- return (name);
+ return (do_prominfo(syserrlog, progname, logging, print_flag));
}
diff --git a/usr/src/cmd/smbios/Makefile b/usr/src/cmd/smbios/Makefile
new file mode 100644
index 0000000000..84eef2582c
--- /dev/null
+++ b/usr/src/cmd/smbios/Makefile
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+PROG = smbios
+OBJS = smbios.o
+SRCS = $(OBJS:%.o=%.c)
+
+include ../Makefile.cmd
+
+CFLAGS += $(CCVERBOSE)
+LDLIBS += -lsmbios
+
+FILEMODE = 0555
+GROUP = bin
+STRIPFLAG =
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+clean:
+ $(RM) $(OBJS)
+
+install: $(ROOTUSRSBINPROG)
+
+lint: lint_SRCS
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/smbios/smbios.c b/usr/src/cmd/smbios/smbios.c
new file mode 100644
index 0000000000..09373dc1be
--- /dev/null
+++ b/usr/src/cmd/smbios/smbios.c
@@ -0,0 +1,1067 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/sysmacros.h>
+#include <sys/param.h>
+
+#include <smbios.h>
+#include <alloca.h>
+#include <limits.h>
+#include <unistd.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+
+#define SMBIOS_SUCCESS 0
+#define SMBIOS_ERROR 1
+#define SMBIOS_USAGE 2
+
+static const char *g_pname;
+static int g_hdr;
+
+static int opt_e;
+static int opt_i = -1;
+static int opt_O;
+static int opt_s;
+static int opt_t = -1;
+static int opt_x;
+
+/*PRINTFLIKE2*/
+static void
+oprintf(FILE *fp, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ (void) vfprintf(fp, format, ap);
+ va_end(ap);
+}
+
+/*PRINTFLIKE3*/
+static void
+desc_printf(const char *d, FILE *fp, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ (void) vfprintf(fp, format, ap);
+ va_end(ap);
+
+ if (d != NULL)
+ (void) fprintf(fp, " (%s)\n", d);
+ else
+ (void) fprintf(fp, "\n");
+}
+
+static void
+flag_printf(FILE *fp, const char *s, uint_t flags, size_t bits,
+ const char *(*flag_name)(uint_t), const char *(*flag_desc)(uint_t))
+{
+ size_t i;
+
+ oprintf(fp, " %s: 0x%x\n", s, flags);
+
+ for (i = 0; i < bits; i++) {
+ uint_t f = 1 << i;
+ const char *n;
+
+ if (!(flags & f))
+ continue;
+
+ if ((n = flag_name(f)) != NULL)
+ desc_printf(flag_desc(f), fp, "\t%s", n);
+ else
+ desc_printf(flag_desc(f), fp, "\t0x%x", f);
+ }
+}
+
+static void
+flag64_printf(FILE *fp, const char *s, uint64_t flags, size_t bits,
+ const char *(*flag_name)(uint64_t), const char *(*flag_desc)(uint64_t))
+{
+ size_t i;
+
+ oprintf(fp, " %s: 0x%llx\n", s, (u_longlong_t)flags);
+
+ for (i = 0; i < bits; i++) {
+ u_longlong_t f = 1ULL << i;
+ const char *n;
+
+ if (!(flags & f))
+ continue;
+
+ if ((n = flag_name(f)) != NULL)
+ desc_printf(flag_desc(f), fp, "\t%s", n);
+ else
+ desc_printf(flag_desc(f), fp, "\t0x%llx", f);
+ }
+}
+
+static void
+id_printf(FILE *fp, const char *s, id_t id)
+{
+ switch (id) {
+ case SMB_ID_NONE:
+ oprintf(fp, "%sNone\n", s);
+ break;
+ case SMB_ID_NOTSUP:
+ oprintf(fp, "%sNot Supported\n", s);
+ break;
+ default:
+ oprintf(fp, "%s%u\n", s, (uint_t)id);
+ }
+}
+
+static void
+print_smbios(smbios_hdl_t *shp, FILE *fp)
+{
+ smbios_entry_t ep;
+ int i;
+
+ smbios_info_smbios(shp, &ep);
+
+ oprintf(fp, "Entry Point Anchor Tag: %*.*s\n",
+ (int)sizeof (ep.smbe_eanchor), (int)sizeof (ep.smbe_eanchor),
+ ep.smbe_eanchor);
+
+ oprintf(fp, "Entry Point Checksum: 0x%x\n", ep.smbe_ecksum);
+ oprintf(fp, "Entry Point Length: %u\n", ep.smbe_elen);
+ oprintf(fp, "Entry Point Version: %u.%u\n",
+ ep.smbe_major, ep.smbe_minor);
+ oprintf(fp, "Max Structure Size: %u\n", ep.smbe_maxssize);
+ oprintf(fp, "Entry Point Revision: 0x%x\n", ep.smbe_revision);
+
+ oprintf(fp, "Entry Point Revision Data:");
+ for (i = 0; i < sizeof (ep.smbe_format); i++)
+ oprintf(fp, " 0x%02x", ep.smbe_format[i]);
+ oprintf(fp, "\n");
+
+ oprintf(fp, "Intermediate Anchor Tag: %*.*s\n",
+ (int)sizeof (ep.smbe_ianchor), (int)sizeof (ep.smbe_ianchor),
+ ep.smbe_ianchor);
+
+ oprintf(fp, "Intermediate Checksum: 0x%x\n", ep.smbe_icksum);
+ oprintf(fp, "Structure Table Length: %u\n", ep.smbe_stlen);
+ oprintf(fp, "Structure Table Address: 0x%x\n", ep.smbe_staddr);
+ oprintf(fp, "Structure Table Entries: %u\n", ep.smbe_stnum);
+ oprintf(fp, "DMI BCD Revision: 0x%x\n", ep.smbe_bcdrev);
+}
+
+static void
+print_common(const smbios_info_t *ip, FILE *fp)
+{
+ if (ip->smbi_manufacturer[0] != '\0')
+ oprintf(fp, " Manufacturer: %s\n", ip->smbi_manufacturer);
+ if (ip->smbi_product[0] != '\0')
+ oprintf(fp, " Product: %s\n", ip->smbi_product);
+ if (ip->smbi_version[0] != '\0')
+ oprintf(fp, " Version: %s\n", ip->smbi_version);
+ if (ip->smbi_serial[0] != '\0')
+ oprintf(fp, " Serial Number: %s\n", ip->smbi_serial);
+ if (ip->smbi_asset[0] != '\0')
+ oprintf(fp, " Asset Tag: %s\n", ip->smbi_asset);
+ if (ip->smbi_location[0] != '\0')
+ oprintf(fp, " Location Tag: %s\n", ip->smbi_location);
+ if (ip->smbi_part[0] != '\0')
+ oprintf(fp, " Part Number: %s\n", ip->smbi_part);
+}
+
+static void
+print_bios(smbios_hdl_t *shp, FILE *fp)
+{
+ smbios_bios_t b;
+
+ (void) smbios_info_bios(shp, &b);
+
+ oprintf(fp, " Vendor: %s\n", b.smbb_vendor);
+ oprintf(fp, " Version String: %s\n", b.smbb_version);
+ oprintf(fp, " Release Date: %s\n", b.smbb_reldate);
+ oprintf(fp, " Address Segment: 0x%x\n", b.smbb_segment);
+ oprintf(fp, " ROM Size: %u bytes\n", b.smbb_romsize);
+ oprintf(fp, " Image Size: %u bytes\n", b.smbb_runsize);
+
+ flag64_printf(fp, "Characteristics",
+ b.smbb_cflags, sizeof (b.smbb_cflags) * NBBY,
+ smbios_bios_flag_name, smbios_bios_flag_desc);
+
+ if (b.smbb_nxcflags > SMB_BIOSXB_1) {
+ flag_printf(fp, "Characteristics Extension Byte 1",
+ b.smbb_xcflags[SMB_BIOSXB_1],
+ sizeof (b.smbb_xcflags[SMB_BIOSXB_1]) * NBBY,
+ smbios_bios_xb1_name, smbios_bios_xb1_desc);
+ }
+
+ if (b.smbb_nxcflags > SMB_BIOSXB_2) {
+ flag_printf(fp, "Characteristics Extension Byte 2",
+ b.smbb_xcflags[SMB_BIOSXB_2],
+ sizeof (b.smbb_xcflags[SMB_BIOSXB_2]) * NBBY,
+ smbios_bios_xb2_name, smbios_bios_xb2_desc);
+ }
+
+ if (b.smbb_nxcflags > SMB_BIOSXB_BIOS_MIN) {
+ oprintf(fp, " Version Number: %u.%u\n",
+ b.smbb_biosv.smbv_major, b.smbb_biosv.smbv_minor);
+ }
+
+ if (b.smbb_nxcflags > SMB_BIOSXB_ECFW_MIN) {
+ oprintf(fp, " Embedded Ctlr Firmware Version Number: %u.%u\n",
+ b.smbb_ecfwv.smbv_major, b.smbb_ecfwv.smbv_minor);
+ }
+}
+
+static void
+print_system(smbios_hdl_t *shp, FILE *fp)
+{
+ smbios_system_t s;
+ uint_t i;
+
+ (void) smbios_info_system(shp, &s);
+
+ oprintf(fp, " UUID: ");
+ for (i = 0; i < s.smbs_uuidlen; i++) {
+ oprintf(fp, "%02x", s.smbs_uuid[i]);
+ if (i == 3 || i == 5 || i == 7 || i == 9)
+ oprintf(fp, "-");
+ }
+ oprintf(fp, "\n");
+
+ desc_printf(smbios_system_wakeup_desc(s.smbs_wakeup),
+ fp, " Wake-Up Event: 0x%x", s.smbs_wakeup);
+
+ oprintf(fp, " SKU Number: %s\n", s.smbs_sku);
+ oprintf(fp, " Family: %s\n", s.smbs_family);
+}
+
+static void
+print_bboard(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_bboard_t b;
+
+ (void) smbios_info_bboard(shp, id, &b);
+
+ oprintf(fp, " Chassis: %u\n", (uint_t)b.smbb_chassis);
+
+ flag_printf(fp, "Flags", b.smbb_flags, sizeof (b.smbb_flags) * NBBY,
+ smbios_bboard_flag_name, smbios_bboard_flag_desc);
+
+ desc_printf(smbios_bboard_type_desc(b.smbb_type),
+ fp, " Board Type: 0x%x", b.smbb_type);
+}
+
+static void
+print_chassis(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_chassis_t c;
+
+ (void) smbios_info_chassis(shp, id, &c);
+
+ oprintf(fp, " OEM Data: 0x%x\n", c.smbc_oemdata);
+ oprintf(fp, " Lock Present: %s\n", c.smbc_lock ? "Y" : "N");
+
+ desc_printf(smbios_chassis_type_desc(c.smbc_type),
+ fp, " Chassis Type: 0x%x", c.smbc_type);
+
+ desc_printf(smbios_chassis_state_desc(c.smbc_bustate),
+ fp, " Boot-Up State: 0x%x", c.smbc_bustate);
+
+ desc_printf(smbios_chassis_state_desc(c.smbc_psstate),
+ fp, " Power Supply State: 0x%x", c.smbc_psstate);
+
+ desc_printf(smbios_chassis_state_desc(c.smbc_thstate),
+ fp, " Thermal State: 0x%x", c.smbc_thstate);
+
+ oprintf(fp, " Chassis Height: %uu\n", c.smbc_uheight);
+ oprintf(fp, " Power Cords: %u\n", c.smbc_cords);
+ oprintf(fp, " Element Records: %u\n", c.smbc_elems);
+}
+
+static void
+print_processor(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_processor_t p;
+ uint_t status;
+
+ (void) smbios_info_processor(shp, id, &p);
+ status = SMB_PRSTATUS_STATUS(p.smbp_status);
+
+ desc_printf(smbios_processor_family_desc(p.smbp_family),
+ fp, " Family: %u", p.smbp_family);
+
+ oprintf(fp, " CPUID: 0x%llx\n", (u_longlong_t)p.smbp_cpuid);
+
+ desc_printf(smbios_processor_type_desc(p.smbp_type),
+ fp, " Type: %u", p.smbp_type);
+
+ desc_printf(smbios_processor_upgrade_desc(p.smbp_upgrade),
+ fp, " Socket Upgrade: %u", p.smbp_upgrade);
+
+ oprintf(fp, " Socket Status: %s\n",
+ SMB_PRSTATUS_PRESENT(p.smbp_status) ?
+ "Populated" : "Not Populated");
+
+ desc_printf(smbios_processor_status_desc(status),
+ fp, " Processor Status: %u", status);
+
+ if (SMB_PRV_LEGACY(p.smbp_voltage)) {
+ oprintf(fp, " Supported Voltages:");
+ switch (p.smbp_voltage) {
+ case SMB_PRV_5V:
+ oprintf(fp, " 5.0V");
+ break;
+ case SMB_PRV_33V:
+ oprintf(fp, " 3.3V");
+ break;
+ case SMB_PRV_29V:
+ oprintf(fp, " 2.9V");
+ break;
+ }
+ oprintf(fp, "\n");
+ } else {
+ oprintf(fp, " Supported Voltages: %.1fV\n",
+ (float)SMB_PRV_VOLTAGE(p.smbp_voltage) / 10);
+ }
+
+ if (p.smbp_clkspeed != 0)
+ oprintf(fp, " External Clock Speed: %uMHz\n", p.smbp_clkspeed);
+ else
+ oprintf(fp, " External Clock Speed: Unknown\n");
+
+ if (p.smbp_maxspeed != 0)
+ oprintf(fp, " Maximum Speed: %uMHz\n", p.smbp_maxspeed);
+ else
+ oprintf(fp, " Maximum Speed: Unknown\n");
+
+ if (p.smbp_curspeed != 0)
+ oprintf(fp, " Current Speed: %uMHz\n", p.smbp_curspeed);
+ else
+ oprintf(fp, " Current Speed: Unknown\n");
+
+ id_printf(fp, " L1 Cache: ", p.smbp_l1cache);
+ id_printf(fp, " L2 Cache: ", p.smbp_l2cache);
+ id_printf(fp, " L3 Cache: ", p.smbp_l3cache);
+}
+
+static void
+print_cache(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_cache_t c;
+
+ (void) smbios_info_cache(shp, id, &c);
+
+ oprintf(fp, " Level: %u\n", c.smba_level);
+ oprintf(fp, " Maximum Installed Size: %u bytes\n", c.smba_maxsize);
+
+ if (c.smba_size != 0)
+ oprintf(fp, " Installed Size: %u bytes\n", c.smba_size);
+ else
+ oprintf(fp, " Installed Size: Not Installed\n");
+
+ if (c.smba_speed != 0)
+ oprintf(fp, " Speed: %uns\n", c.smba_speed);
+ else
+ oprintf(fp, " Speed: Unknown\n");
+
+ flag_printf(fp, "Supported SRAM Types",
+ c.smba_stype, sizeof (c.smba_stype) * NBBY,
+ smbios_cache_ctype_name, smbios_cache_ctype_desc);
+
+ desc_printf(smbios_cache_ctype_desc(c.smba_ctype),
+ fp, " Current SRAM Type: 0x%x", c.smba_ctype);
+
+ desc_printf(smbios_cache_ecc_desc(c.smba_etype),
+ fp, " Error Correction Type: %u", c.smba_etype);
+
+ desc_printf(smbios_cache_logical_desc(c.smba_ltype),
+ fp, " Logical Cache Type: %u", c.smba_ltype);
+
+ desc_printf(smbios_cache_assoc_desc(c.smba_assoc),
+ fp, " Associativity: %u", c.smba_assoc);
+
+ desc_printf(smbios_cache_mode_desc(c.smba_mode),
+ fp, " Mode: %u", c.smba_mode);
+
+ desc_printf(smbios_cache_loc_desc(c.smba_location),
+ fp, " Location: %u", c.smba_location);
+
+ flag_printf(fp, "Flags", c.smba_flags, sizeof (c.smba_flags) * NBBY,
+ smbios_cache_flag_name, smbios_cache_flag_desc);
+}
+
+static void
+print_port(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_port_t p;
+
+ (void) smbios_info_port(shp, id, &p);
+
+ oprintf(fp, " Internal Reference Designator: %s\n", p.smbo_iref);
+ oprintf(fp, " External Reference Designator: %s\n", p.smbo_eref);
+
+ desc_printf(smbios_port_conn_desc(p.smbo_itype),
+ fp, " Internal Connector Type: %u", p.smbo_itype);
+
+ desc_printf(smbios_port_conn_desc(p.smbo_etype),
+ fp, " External Connector Type: %u", p.smbo_etype);
+
+ desc_printf(smbios_port_type_desc(p.smbo_ptype),
+ fp, " Port Type: %u", p.smbo_ptype);
+}
+
+static void
+print_slot(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_slot_t s;
+
+ (void) smbios_info_slot(shp, id, &s);
+
+ oprintf(fp, " Reference Designator: %s\n", s.smbl_name);
+ oprintf(fp, " Slot ID: 0x%x\n", s.smbl_id);
+
+ desc_printf(smbios_slot_type_desc(s.smbl_type),
+ fp, " Type: 0x%x", s.smbl_type);
+
+ desc_printf(smbios_slot_width_desc(s.smbl_width),
+ fp, " Width: 0x%x", s.smbl_width);
+
+ desc_printf(smbios_slot_usage_desc(s.smbl_usage),
+ fp, " Usage: 0x%x", s.smbl_usage);
+
+ desc_printf(smbios_slot_length_desc(s.smbl_length),
+ fp, " Length: 0x%x", s.smbl_length);
+
+ flag_printf(fp, "Slot Characteristics 1",
+ s.smbl_ch1, sizeof (s.smbl_ch1) * NBBY,
+ smbios_slot_ch1_name, smbios_slot_ch1_desc);
+
+ flag_printf(fp, "Slot Characteristics 2",
+ s.smbl_ch2, sizeof (s.smbl_ch2) * NBBY,
+ smbios_slot_ch2_name, smbios_slot_ch2_desc);
+}
+
+static void
+print_obdevs(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_obdev_t *argv;
+ int i, argc;
+
+ if ((argc = smbios_info_obdevs(shp, id, 0, NULL)) > 0) {
+ argv = alloca(sizeof (smbios_obdev_t) * argc);
+ (void) smbios_info_obdevs(shp, id, argc, argv);
+ for (i = 0; i < argc; i++)
+ oprintf(fp, " %s\n", argv[i].smbd_name);
+ }
+}
+
+static void
+print_strtab(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ const char **argv;
+ int i, argc;
+
+ if ((argc = smbios_info_strtab(shp, id, 0, NULL)) > 0) {
+ argv = alloca(sizeof (char *) * argc);
+ (void) smbios_info_strtab(shp, id, argc, argv);
+ for (i = 0; i < argc; i++)
+ oprintf(fp, " %s\n", argv[i]);
+ }
+}
+
+static void
+print_lang(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_lang_t l;
+
+ (void) smbios_info_lang(shp, &l);
+
+ oprintf(fp, " Current Language: %s\n", l.smbla_cur);
+ oprintf(fp, " Language String Format: %u\n", l.smbla_fmt);
+ oprintf(fp, " Number of Installed Languages: %u\n", l.smbla_num);
+ oprintf(fp, " Installed Languages:\n");
+
+ print_strtab(shp, id, fp);
+}
+
+/*ARGSUSED*/
+static void
+print_evlog(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_evlog_t ev;
+ uint32_t i;
+
+ (void) smbios_info_eventlog(shp, &ev);
+
+ oprintf(fp, " Log Area Size: %lu bytes\n", (ulong_t)ev.smbev_size);
+ oprintf(fp, " Header Offset: %lu\n", (ulong_t)ev.smbev_hdr);
+ oprintf(fp, " Data Offset: %lu\n", (ulong_t)ev.smbev_data);
+
+ desc_printf(smbios_evlog_method_desc(ev.smbev_method),
+ fp, " Data Access Method: %u", ev.smbev_method);
+
+ flag_printf(fp, "Log Flags",
+ ev.smbev_flags, sizeof (ev.smbev_flags) * NBBY,
+ smbios_evlog_flag_name, smbios_evlog_flag_desc);
+
+ desc_printf(smbios_evlog_format_desc(ev.smbev_format),
+ fp, " Log Header Format: %u", ev.smbev_format);
+
+ oprintf(fp, " Update Token: 0x%x\n", ev.smbev_token);
+ oprintf(fp, " Data Access Address: ");
+
+ switch (ev.smbev_method) {
+ case SMB_EVM_1x1i_1x1d:
+ case SMB_EVM_2x1i_1x1d:
+ case SMB_EVM_1x2i_1x1d:
+ oprintf(fp, "Index Address 0x%x, Data Address 0x%x\n",
+ ev.smbev_addr.eva_io.evi_iaddr,
+ ev.smbev_addr.eva_io.evi_daddr);
+ break;
+ case SMB_EVM_GPNV:
+ oprintf(fp, "0x%x\n", ev.smbev_addr.eva_gpnv);
+ break;
+ default:
+ oprintf(fp, "0x%x\n", ev.smbev_addr.eva_addr);
+ }
+
+ oprintf(fp, " Type Descriptors:\n");
+
+ for (i = 0; i < ev.smbev_typec; i++) {
+ oprintf(fp, " %u: Log Type 0x%x, Data Type 0x%x\n", i,
+ ev.smbev_typev[i].smbevt_ltype,
+ ev.smbev_typev[i].smbevt_dtype);
+ }
+}
+
+static void
+print_bytes(const uint8_t *data, size_t size, FILE *fp)
+{
+ size_t row, rows = P2ROUNDUP(size, 16) / 16;
+ size_t col, cols;
+
+ char buf[17];
+ uint8_t x;
+
+ oprintf(fp, "\n offset: 0 1 2 3 4 5 6 7 8 9 a b c d e f "
+ "0123456789abcdef\n");
+
+ for (row = 0; row < rows; row++) {
+ oprintf(fp, " %#4lx: ", (ulong_t)row * 16);
+ cols = MIN(size - row * 16, 16);
+
+ for (col = 0; col < cols; col++) {
+ if (col % 4 == 0)
+ oprintf(fp, " ");
+ x = *data++;
+ oprintf(fp, "%02x", x);
+ buf[col] = x <= ' ' || x > '~' ? '.' : x;
+ }
+
+ for (; col < 16; col++) {
+ if (col % 4 == 0)
+ oprintf(fp, " ");
+ oprintf(fp, " ");
+ buf[col] = ' ';
+ }
+
+ buf[col] = '\0';
+ oprintf(fp, " %s\n", buf);
+ }
+
+ oprintf(fp, "\n");
+}
+
+static void
+print_memarray(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_memarray_t ma;
+
+ (void) smbios_info_memarray(shp, id, &ma);
+
+ desc_printf(smbios_memarray_loc_desc(ma.smbma_location),
+ fp, " Location: %u", ma.smbma_location);
+
+ desc_printf(smbios_memarray_use_desc(ma.smbma_use),
+ fp, " Use: %u", ma.smbma_use);
+
+ desc_printf(smbios_memarray_ecc_desc(ma.smbma_ecc),
+ fp, " ECC: %u", ma.smbma_ecc);
+
+ oprintf(fp, " Number of Slots/Sockets: %u\n", ma.smbma_ndevs);
+ id_printf(fp, " Memory Error Data: ", ma.smbma_err);
+ oprintf(fp, " Max Capacity: %llu bytes\n",
+ (u_longlong_t)ma.smbma_size);
+}
+
+static void
+print_memdevice(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_memdevice_t md;
+
+ (void) smbios_info_memdevice(shp, id, &md);
+
+ id_printf(fp, " Physical Memory Array: ", md.smbmd_array);
+ id_printf(fp, " Memory Error Data: ", md.smbmd_error);
+
+ if (md.smbmd_twidth != -1u)
+ oprintf(fp, " Total Width: %u bits\n", md.smbmd_twidth);
+ else
+ oprintf(fp, " Total Width: Unknown\n");
+
+ if (md.smbmd_dwidth != -1u)
+ oprintf(fp, " Data Width: %u bits\n", md.smbmd_dwidth);
+ else
+ oprintf(fp, " Data Width: Unknown\n");
+
+ switch (md.smbmd_size) {
+ case -1ull:
+ oprintf(fp, " Size: Unknown\n");
+ break;
+ case 0:
+ oprintf(fp, " Size: Not Populated\n");
+ break;
+ default:
+ oprintf(fp, " Size: %llu bytes\n",
+ (u_longlong_t)md.smbmd_size);
+ }
+
+ desc_printf(smbios_memdevice_form_desc(md.smbmd_form),
+ fp, " Form Factor: %u", md.smbmd_form);
+
+ if (md.smbmd_set == 0)
+ oprintf(fp, " Set: None\n");
+ else if (md.smbmd_set == (uint8_t)-1u)
+ oprintf(fp, " Set: Unknown\n");
+ else
+ oprintf(fp, " Set: %u\n", md.smbmd_set);
+
+ desc_printf(smbios_memdevice_type_desc(md.smbmd_type),
+ fp, " Memory Type: %u", md.smbmd_type);
+
+ flag_printf(fp, "Flags", md.smbmd_flags, sizeof (md.smbmd_flags) * NBBY,
+ smbios_memdevice_flag_name, smbios_memdevice_flag_desc);
+
+ if (md.smbmd_speed != 0)
+ oprintf(fp, " Speed: %uns\n", md.smbmd_speed);
+ else
+ oprintf(fp, " Speed: Unknown\n");
+
+ oprintf(fp, " Device Locator: %s\n", md.smbmd_dloc);
+ oprintf(fp, " Bank Locator: %s\n", md.smbmd_bloc);
+}
+
+static void
+print_memarrmap(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_memarrmap_t ma;
+
+ (void) smbios_info_memarrmap(shp, id, &ma);
+
+ id_printf(fp, " Physical Memory Array: ", ma.smbmam_array);
+ oprintf(fp, " Devices per Row: %u\n", ma.smbmam_width);
+
+ oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n",
+ (u_longlong_t)ma.smbmam_addr, (u_longlong_t)ma.smbmam_size);
+}
+
+static void
+print_memdevmap(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_memdevmap_t md;
+
+ (void) smbios_info_memdevmap(shp, id, &md);
+
+ id_printf(fp, " Memory Device: ", md.smbmdm_device);
+ id_printf(fp, " Memory Array Mapped Address: ", md.smbmdm_arrmap);
+
+ oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n",
+ (u_longlong_t)md.smbmdm_addr, (u_longlong_t)md.smbmdm_size);
+
+ oprintf(fp, " Partition Row Position: %u\n", md.smbmdm_rpos);
+ oprintf(fp, " Interleave Position: %u\n", md.smbmdm_ipos);
+ oprintf(fp, " Interleave Data Depth: %u\n", md.smbmdm_idepth);
+}
+
+static void
+print_hwsec(smbios_hdl_t *shp, FILE *fp)
+{
+ smbios_hwsec_t h;
+
+ (void) smbios_info_hwsec(shp, &h);
+
+ desc_printf(smbios_hwsec_desc(h.smbh_pwr_ps),
+ fp, " Power-On Password Status: %u", h.smbh_pwr_ps);
+ desc_printf(smbios_hwsec_desc(h.smbh_kbd_ps),
+ fp, " Keyboard Password Status: %u", h.smbh_kbd_ps);
+ desc_printf(smbios_hwsec_desc(h.smbh_adm_ps),
+ fp, " Administrator Password Status: %u", h.smbh_adm_ps);
+ desc_printf(smbios_hwsec_desc(h.smbh_pan_ps),
+ fp, " Front Panel Reset Status: %u", h.smbh_pan_ps);
+}
+
+static void
+print_boot(smbios_hdl_t *shp, FILE *fp)
+{
+ smbios_boot_t b;
+
+ (void) smbios_info_boot(shp, &b);
+
+ desc_printf(smbios_boot_desc(b.smbt_status),
+ fp, " Boot Status Code: 0x%x", b.smbt_status);
+
+ if (b.smbt_size != 0) {
+ oprintf(fp, " Boot Data (%lu bytes):\n", (ulong_t)b.smbt_size);
+ print_bytes(b.smbt_data, b.smbt_size, fp);
+ }
+}
+
+static void
+print_ipmi(smbios_hdl_t *shp, FILE *fp)
+{
+ smbios_ipmi_t i;
+
+ (void) smbios_info_ipmi(shp, &i);
+
+ desc_printf(smbios_ipmi_type_desc(i.smbip_type),
+ fp, " Type: %u", i.smbip_type);
+
+ oprintf(fp, " BMC IPMI Version: %u.%u\n",
+ i.smbip_vers.smbv_major, i.smbip_vers.smbv_minor);
+
+ oprintf(fp, " i2c Bus Slave Address: 0x%x\n", i.smbip_i2c);
+ oprintf(fp, " NV Storage Device Bus ID: 0x%x\n", i.smbip_bus);
+ oprintf(fp, " BMC Base Address: 0x%llx\n", (u_longlong_t)i.smbip_addr);
+ oprintf(fp, " Interrupt Number: %u\n", i.smbip_intr);
+ oprintf(fp, " Register Spacing: %u\n", i.smbip_regspacing);
+
+ flag_printf(fp, "Flags", i.smbip_flags, sizeof (i.smbip_flags) * NBBY,
+ smbios_ipmi_flag_name, smbios_ipmi_flag_desc);
+}
+
+static int
+print_struct(smbios_hdl_t *shp, const smbios_struct_t *sp, void *fp)
+{
+ smbios_info_t info;
+ int hex = opt_x;
+ const char *s;
+
+ if (opt_t != -1 && opt_t != sp->smbstr_type)
+ return (0); /* skip struct if type doesn't match -t */
+
+ if (!opt_O && (sp->smbstr_type == SMB_TYPE_MEMCTL ||
+ sp->smbstr_type == SMB_TYPE_MEMMOD))
+ return (0); /* skip struct if type is obsolete */
+
+ if (g_hdr++ == 0 || !opt_s)
+ oprintf(fp, "%-5s %-4s %s\n", "ID", "SIZE", "TYPE");
+
+ oprintf(fp, "%-5u %-4lu",
+ (uint_t)sp->smbstr_id, (ulong_t)sp->smbstr_size);
+
+ if ((s = smbios_type_name(sp->smbstr_type)) != NULL)
+ oprintf(fp, " %s", s);
+ else if (sp->smbstr_type > SMB_TYPE_OEM_LO &&
+ sp->smbstr_type < SMB_TYPE_OEM_HI)
+ oprintf(fp, " %s+%u", "SMB_TYPE_OEM_LO",
+ sp->smbstr_type - SMB_TYPE_OEM_LO);
+ else
+ oprintf(fp, " %u", sp->smbstr_type);
+
+ if ((s = smbios_type_desc(sp->smbstr_type)) != NULL)
+ oprintf(fp, " (%s)\n", s);
+ else
+ oprintf(fp, "\n");
+
+ if (opt_s)
+ return (0); /* only print header line if -s specified */
+
+ if (smbios_info_common(shp, sp->smbstr_id, &info) == 0) {
+ oprintf(fp, "\n");
+ print_common(&info, fp);
+ }
+
+ switch (sp->smbstr_type) {
+ case SMB_TYPE_BIOS:
+ oprintf(fp, "\n");
+ print_bios(shp, fp);
+ break;
+ case SMB_TYPE_SYSTEM:
+ oprintf(fp, "\n");
+ print_system(shp, fp);
+ break;
+ case SMB_TYPE_BASEBOARD:
+ oprintf(fp, "\n");
+ print_bboard(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_CHASSIS:
+ oprintf(fp, "\n");
+ print_chassis(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_PROCESSOR:
+ oprintf(fp, "\n");
+ print_processor(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_CACHE:
+ oprintf(fp, "\n");
+ print_cache(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_PORT:
+ oprintf(fp, "\n");
+ print_port(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_SLOT:
+ oprintf(fp, "\n");
+ print_slot(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_OBDEVS:
+ oprintf(fp, "\n");
+ print_obdevs(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_OEMSTR:
+ case SMB_TYPE_SYSCONFSTR:
+ oprintf(fp, "\n");
+ print_strtab(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_LANG:
+ oprintf(fp, "\n");
+ print_lang(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_EVENTLOG:
+ oprintf(fp, "\n");
+ print_evlog(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_MEMARRAY:
+ oprintf(fp, "\n");
+ print_memarray(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_MEMDEVICE:
+ oprintf(fp, "\n");
+ print_memdevice(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_MEMARRAYMAP:
+ oprintf(fp, "\n");
+ print_memarrmap(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_MEMDEVICEMAP:
+ oprintf(fp, "\n");
+ print_memdevmap(shp, sp->smbstr_id, fp);
+ break;
+ case SMB_TYPE_SECURITY:
+ oprintf(fp, "\n");
+ print_hwsec(shp, fp);
+ break;
+ case SMB_TYPE_BOOT:
+ oprintf(fp, "\n");
+ print_boot(shp, fp);
+ break;
+ case SMB_TYPE_IPMIDEV:
+ oprintf(fp, "\n");
+ print_ipmi(shp, fp);
+ break;
+ default:
+ hex++;
+ }
+
+ if (hex)
+ print_bytes(sp->smbstr_data, sp->smbstr_size, fp);
+ else
+ oprintf(fp, "\n");
+
+ return (0);
+}
+
+static uint16_t
+getu16(const char *name, const char *s)
+{
+ u_longlong_t val;
+ char *p;
+
+ errno = 0;
+ val = strtoull(s, &p, 0);
+
+ if (errno != 0 || p == s || *p != '\0' || val > UINT16_MAX) {
+ (void) fprintf(stderr, "%s: invalid %s argument -- %s\n",
+ g_pname, name, s);
+ exit(SMBIOS_USAGE);
+ }
+
+ return ((uint16_t)val);
+}
+
+static uint16_t
+getstype(const char *name, const char *s)
+{
+ const char *ts;
+ uint16_t t;
+
+ for (t = 0; t < SMB_TYPE_OEM_LO; t++) {
+ if ((ts = smbios_type_name(t)) != NULL && strcmp(s, ts) == 0)
+ return (t);
+ }
+
+ (void) fprintf(stderr, "%s: invalid %s argument -- %s\n",
+ g_pname, name, s);
+
+ exit(SMBIOS_USAGE);
+ /*NOTREACHED*/
+}
+
+static int
+usage(FILE *fp)
+{
+ (void) fprintf(fp, "Usage: %s "
+ "[-BeOsx] [-i id] [-t type] [-w file] [file]\n\n", g_pname);
+
+ (void) fprintf(fp,
+ "\t-B disable header validation for broken BIOSes\n"
+ "\t-e display SMBIOS entry point information\n"
+ "\t-i display only the specified structure\n"
+ "\t-O display obsolete structure types\n"
+ "\t-s display only a summary of structure identifiers and types\n"
+ "\t-t display only the specified structure type\n"
+ "\t-w write the raw data to the specified file\n"
+ "\t-x display raw data for structures\n");
+
+ return (SMBIOS_USAGE);
+}
+
+int
+main(int argc, char *argv[])
+{
+ const char *ifile = NULL;
+ const char *ofile = NULL;
+ int oflags = 0;
+
+ smbios_hdl_t *shp;
+ smbios_struct_t s;
+ int err, fd, c;
+ char *p;
+
+ if ((p = strrchr(argv[0], '/')) == NULL)
+ g_pname = argv[0];
+ else
+ g_pname = p + 1;
+
+ while (optind < argc) {
+ while ((c = getopt(argc, argv, "Bei:Ost:w:xZ")) != EOF) {
+ switch (c) {
+ case 'B':
+ oflags |= SMB_O_NOCKSUM | SMB_O_NOVERS;
+ break;
+ case 'e':
+ opt_e++;
+ break;
+ case 'i':
+ opt_i = getu16("struct ID", optarg);
+ break;
+ case 'O':
+ opt_O++;
+ break;
+ case 's':
+ opt_s++;
+ break;
+ case 't':
+ if (isdigit(optarg[0]))
+ opt_t = getu16("struct type", optarg);
+ else
+ opt_t = getstype("struct type", optarg);
+ break;
+ case 'w':
+ ofile = optarg;
+ break;
+ case 'x':
+ opt_x++;
+ break;
+ case 'Z':
+ oflags |= SMB_O_ZIDS; /* undocumented */
+ break;
+ default:
+ return (usage(stderr));
+ }
+ }
+
+ if (optind < argc) {
+ if (ifile != NULL) {
+ (void) fprintf(stderr, "%s: illegal "
+ "argument -- %s\n", g_pname, argv[optind]);
+ return (SMBIOS_USAGE);
+ }
+ ifile = argv[optind++];
+ }
+ }
+
+ if ((shp = smbios_open(ifile, SMB_VERSION, oflags, &err)) == NULL) {
+ (void) fprintf(stderr, "%s: failed to load SMBIOS: %s\n",
+ g_pname, smbios_errmsg(err));
+ return (SMBIOS_ERROR);
+ }
+
+ if (ofile != NULL) {
+ if ((fd = open(ofile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) {
+ (void) fprintf(stderr, "%s: failed to open %s: %s\n",
+ g_pname, ofile, strerror(errno));
+ err = SMBIOS_ERROR;
+ } else if (smbios_write(shp, fd) != 0) {
+ (void) fprintf(stderr, "%s: failed to write %s: %s\n",
+ g_pname, ofile, smbios_errmsg(smbios_errno(shp)));
+ err = SMBIOS_ERROR;
+ }
+ smbios_close(shp);
+ return (err);
+ }
+
+ if (opt_e) {
+ print_smbios(shp, stdout);
+ smbios_close(shp);
+ return (SMBIOS_SUCCESS);
+ }
+
+ if (opt_O && (opt_i != -1 || opt_t != -1))
+ opt_O++; /* -i or -t imply displaying obsolete records */
+
+ if (opt_i != -1)
+ err = smbios_lookup_id(shp, opt_i, &s);
+ else
+ err = smbios_iter(shp, print_struct, stdout);
+
+ if (err != 0) {
+ (void) fprintf(stderr, "%s: failed to access SMBIOS: %s\n",
+ g_pname, smbios_errmsg(smbios_errno(shp)));
+ smbios_close(shp);
+ return (SMBIOS_ERROR);
+ }
+
+ if (opt_i != -1)
+ (void) print_struct(shp, &s, stdout);
+
+ smbios_close(shp);
+ return (SMBIOS_SUCCESS);
+}
diff --git a/usr/src/common/smbios/mktables.sh b/usr/src/common/smbios/mktables.sh
new file mode 100644
index 0000000000..2cb4db46fa
--- /dev/null
+++ b/usr/src/common/smbios/mktables.sh
@@ -0,0 +1,145 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+#
+# The SMBIOS interfaces defined in <sys/smbios.h> include a set of integer-to-
+# string conversion routines for the various constants defined in the SMBIOS
+# spec. These functions are used by smbios(1M) and prtdiag(1M) and can be
+# leveraged by other clients as well. To simplify maintenance of the source
+# base, this shell script automatically generates the source code for all of
+# these functions from the <sys/smbios.h> header file and its comments. Each
+# set of constants should be given a unique #define prefix, listed in the
+# tables below. The smbios_*_name() functions return the identifier of the
+# cpp define, and the smbios_*_desc() functions return the text of the comment.
+#
+
+name_funcs='
+SMB_BBFL_ smbios_bboard_flag_name uint_t
+SMB_BIOSFL_ smbios_bios_flag_name uint64_t
+SMB_BIOSXB1_ smbios_bios_xb1_name uint_t
+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_IPMI_F_ smbios_ipmi_flag_name uint_t
+SMB_MDF_ smbios_memdevice_flag_name uint_t
+SMB_TYPE_ smbios_type_name uint_t
+SMB_SLCH1_ smbios_slot_ch1_name uint_t
+SMB_SLCH2_ smbios_slot_ch2_name uint_t
+'
+
+desc_funcs='
+SMB_BBFL_ smbios_bboard_flag_desc uint_t
+SMB_BBT_ smbios_bboard_type_desc uint_t
+SMB_BIOSFL_ smbios_bios_flag_desc uint64_t
+SMB_BIOSXB1_ smbios_bios_xb1_desc uint_t
+SMB_BIOSXB2_ smbios_bios_xb2_desc uint_t
+SMB_BOOT_ smbios_boot_desc uint_t
+SMB_CAA_ smbios_cache_assoc_desc uint_t
+SMB_CAT_ smbios_cache_ctype_desc uint_t
+SMB_CAE_ smbios_cache_ecc_desc uint_t
+SMB_CAF_ smbios_cache_flag_desc uint_t
+SMB_CAL_ smbios_cache_loc_desc uint_t
+SMB_CAG_ smbios_cache_logical_desc uint_t
+SMB_CAM_ smbios_cache_mode_desc uint_t
+SMB_CHST_ smbios_chassis_state_desc uint_t
+SMB_CHT_ smbios_chassis_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_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
+SMB_MAL_ smbios_memarray_loc_desc uint_t
+SMB_MAU_ smbios_memarray_use_desc uint_t
+SMB_MAE_ smbios_memarray_ecc_desc uint_t
+SMB_MDF_ smbios_memdevice_flag_desc uint_t
+SMB_MDFF_ smbios_memdevice_form_desc uint_t
+SMB_MDT_ smbios_memdevice_type_desc uint_t
+SMB_POC_ smbios_port_conn_desc uint_t
+SMB_POT_ smbios_port_type_desc uint_t
+SMB_PRF_ smbios_processor_family_desc uint_t
+SMB_PRS_ smbios_processor_status_desc uint_t
+SMB_PRT_ smbios_processor_type_desc uint_t
+SMB_PRU_ smbios_processor_upgrade_desc uint_t
+SMB_SLCH1_ smbios_slot_ch1_desc uint_t
+SMB_SLCH2_ smbios_slot_ch2_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_TYPE_ smbios_type_desc uint_t
+SMB_WAKEUP_ smbios_system_wakeup_desc uint_t
+'
+
+if [ $# -ne 1 ]; then
+ echo "Usage: $0 file.h > file.c" >&2
+ exit 2
+fi
+
+echo "\
+/*\n\
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.\n\
+ * Use is subject to license terms.\n\
+ */\n\
+\n\
+#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n\
+\n\
+#include <smbios.h>"
+
+echo "$name_funcs" | while read p name type; do
+ [ -z "$p" ] && continue
+ 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) {"
+ sed -n "s@$pattern@$replace@p" < $1 || exit 1
+ echo "\t}\n\treturn (NULL);\n}"
+done
+
+#
+# Generate the description functions based on the comment next to a #define.
+# The transformations for descriptive comments are slightly more complicated
+# than those used for the identifier->name functions above:
+#
+# (1) strip any [RO] suffix from the comment (a header file convention)
+# (2) replace any " with \" so it is escaped for the final output string
+# (3) replace return (...); with return ("..."); to finish the code
+#
+echo "$desc_funcs" | while read p name type; do
+ [ -z "$p" ] && continue
+ pattern="^#define[ ]\($p[A-Za-z0-9_]*\)[ ]*.*/\\* \(.*\) \\*/$"
+ replace=' case \1: return (\2);'
+
+ echo "\nconst char *\n$name($type x)\n{\n\tswitch (x) {"
+ sed -n "s@$pattern@$replace@p" < $1 | sed 's/ ([RO]))/)/' | \
+ sed 's/"/\\"/g' | sed 's/(/("/;s/);$/");/' || exit 1
+ echo "\t}\n\treturn (NULL);\n}"
+done
+
+exit 0
diff --git a/usr/src/common/smbios/smb_error.c b/usr/src/common/smbios/smb_error.c
new file mode 100644
index 0000000000..7c0ad4ddbf
--- /dev/null
+++ b/usr/src/common/smbios/smb_error.c
@@ -0,0 +1,79 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/smbios_impl.h>
+
+static const char *const _smb_errlist[] = {
+ "System does not export an SMBIOS table", /* ESMB_NOTFOUND */
+ "Failed to map SMBIOS table", /* ESMB_MAPDEV */
+ "Failed to locate specified structure", /* ESMB_NOENT */
+ "Failed to allocate memory", /* ESMB_NOMEM */
+ "Failed to read SMBIOS entry point", /* ESMB_NOHDR */
+ "Failed to read SMBIOS structure table", /* ESMB_NOSTAB */
+ "Generic info not available for structure", /* ESMB_NOINFO */
+ "Structure table is shorter than expected", /* ESMB_SHORT */
+ "SMBIOS data structure is corrupted", /* ESMB_CORRUPT */
+ "Requested library version is not supported", /* ESMB_VERSION */
+ "Structure type is not supported by this BIOS", /* ESMB_NOTSUP */
+ "Header is not a valid SMBIOS entry point", /* ESMB_HEADER */
+ "SMBIOS format is too old for processing", /* ESMB_OLD */
+ "SMBIOS format is new and not yet supported", /* ESMB_NEW */
+ "SMBIOS header checksum mismatch", /* ESMB_CKSUM */
+ "Invalid argument specified in library call", /* ESMB_INVAL */
+ "Structure is not of the expected type", /* ESMB_TYPE */
+ "Unknown SMBIOS error" /* ESMB_UNKNOWN */
+};
+
+static const int _smb_nerr = sizeof (_smb_errlist) / sizeof (_smb_errlist[0]);
+
+const char *
+smbios_errmsg(int error)
+{
+ const char *str;
+
+ if (error >= ESMB_BASE && (error - ESMB_BASE) < _smb_nerr)
+ str = _smb_errlist[error - ESMB_BASE];
+ else
+ str = smb_strerror(error);
+
+ return (str ? str : "Unknown error");
+}
+
+int
+smbios_errno(smbios_hdl_t *shp)
+{
+ return (shp->sh_err);
+}
+
+int
+smb_set_errno(smbios_hdl_t *shp, int error)
+{
+ shp->sh_err = error;
+ return (SMB_ERR);
+}
diff --git a/usr/src/common/smbios/smb_info.c b/usr/src/common/smbios/smb_info.c
new file mode 100644
index 0000000000..ae0be44c72
--- /dev/null
+++ b/usr/src/common/smbios/smb_info.c
@@ -0,0 +1,785 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * SMBIOS Information Routines
+ *
+ * The routines in this file are used to convert from the SMBIOS data format to
+ * a more reasonable and stable set of structures offered as part of our ABI.
+ * These functions take the general form:
+ *
+ * stp = smb_lookup_type(shp, foo);
+ * smb_foo_t foo;
+ *
+ * smb_info_bcopy(stp->smbst_hdr, &foo, sizeof (foo));
+ * bzero(caller's struct);
+ *
+ * copy/convert foo members into caller's struct
+ *
+ * We copy the internal structure on to an automatic variable so as to avoid
+ * checks everywhere for structures that the BIOS has improperly truncated, and
+ * also to automatically handle the case of a structure that has been extended.
+ * When necessary, this code can use smb_gteq() to determine whether the SMBIOS
+ * data is of a particular revision that is supposed to contain a new field.
+ */
+
+#include <sys/smbios_impl.h>
+
+/*
+ * 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
+ * helpfully have different names and offsets and sometimes aren't consistent.
+ * To simplify life for our clients, we factor these common things out into
+ * smbios_info_t, which can be retrieved for any structure. The following
+ * table describes the mapping from a given structure to the smbios_info_t.
+ */
+static const struct smb_infospec {
+ uint8_t is_type; /* structure type */
+ uint8_t is_manu; /* manufacturer offset */
+ uint8_t is_product; /* product name offset */
+ uint8_t is_version; /* version offset */
+ uint8_t is_serial; /* serial number offset */
+ uint8_t is_asset; /* asset tag offset */
+ uint8_t is_location; /* location string offset */
+ uint8_t is_part; /* part number offset */
+} _smb_infospecs[] = {
+ { SMB_TYPE_SYSTEM,
+ offsetof(smb_system_t, smbsi_manufacturer),
+ offsetof(smb_system_t, smbsi_product),
+ offsetof(smb_system_t, smbsi_version),
+ offsetof(smb_system_t, smbsi_serial),
+ 0,
+ 0,
+ 0 },
+ { SMB_TYPE_BASEBOARD,
+ offsetof(smb_bboard_t, smbbb_manufacturer),
+ offsetof(smb_bboard_t, smbbb_product),
+ offsetof(smb_bboard_t, smbbb_version),
+ offsetof(smb_bboard_t, smbbb_serial),
+ offsetof(smb_bboard_t, smbbb_asset),
+ offsetof(smb_bboard_t, smbbb_location),
+ 0 },
+ { SMB_TYPE_CHASSIS,
+ offsetof(smb_chassis_t, smbch_manufacturer),
+ 0,
+ offsetof(smb_chassis_t, smbch_version),
+ offsetof(smb_chassis_t, smbch_serial),
+ offsetof(smb_chassis_t, smbch_asset),
+ 0,
+ 0 },
+ { SMB_TYPE_PROCESSOR,
+ offsetof(smb_processor_t, smbpr_manufacturer),
+ 0,
+ offsetof(smb_processor_t, smbpr_version),
+ offsetof(smb_processor_t, smbpr_serial),
+ offsetof(smb_processor_t, smbpr_asset),
+ offsetof(smb_processor_t, smbpr_socket),
+ offsetof(smb_processor_t, smbpr_part) },
+ { SMB_TYPE_CACHE,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ offsetof(smb_cache_t, smbca_socket),
+ 0 },
+ { SMB_TYPE_PORT,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ offsetof(smb_port_t, smbpo_iref),
+ 0 },
+ { SMB_TYPE_SLOT,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ offsetof(smb_slot_t, smbsl_name),
+ 0 },
+ { SMB_TYPE_MEMDEVICE,
+ offsetof(smb_memdevice_t, smbmdev_manufacturer),
+ 0,
+ 0,
+ offsetof(smb_memdevice_t, smbmdev_serial),
+ offsetof(smb_memdevice_t, smbmdev_asset),
+ offsetof(smb_memdevice_t, smbmdev_dloc),
+ offsetof(smb_memdevice_t, smbmdev_part) },
+ { SMB_TYPE_POWERSUP,
+ offsetof(smb_powersup_t, smbpsup_manufacturer),
+ offsetof(smb_powersup_t, smbpsup_devname),
+ offsetof(smb_powersup_t, smbpsup_rev),
+ offsetof(smb_powersup_t, smbpsup_serial),
+ offsetof(smb_powersup_t, smbpsup_asset),
+ offsetof(smb_powersup_t, smbpsup_loc),
+ offsetof(smb_powersup_t, smbpsup_part) },
+ { SMB_TYPE_EOT }
+};
+
+static const char *
+smb_info_strptr(const smb_struct_t *stp, uint8_t off, int *n)
+{
+ const uint8_t *sp = (const uint8_t *)(uintptr_t)stp->smbst_hdr;
+
+ if (off != 0 && sp + off < stp->smbst_end) {
+ (*n)++; /* indicate success for caller */
+ return (smb_strptr(stp, sp[off]));
+ }
+
+ return (smb_strptr(stp, 0));
+}
+
+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);
+}
+
+void
+smbios_info_smbios(smbios_hdl_t *shp, smbios_entry_t *ep)
+{
+ bcopy(&shp->sh_ent, ep, sizeof (smbios_entry_t));
+}
+
+int
+smbios_info_common(smbios_hdl_t *shp, id_t id, smbios_info_t *ip)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ const struct smb_infospec *isp;
+ int n = 0;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ for (isp = _smb_infospecs; isp->is_type != SMB_TYPE_EOT; isp++) {
+ if (isp->is_type == stp->smbst_hdr->smbh_type)
+ break;
+ }
+
+ ip->smbi_manufacturer = smb_info_strptr(stp, isp->is_manu, &n);
+ ip->smbi_product = smb_info_strptr(stp, isp->is_product, &n);
+ ip->smbi_version = smb_info_strptr(stp, isp->is_version, &n);
+ ip->smbi_serial = smb_info_strptr(stp, isp->is_serial, &n);
+ ip->smbi_asset = smb_info_strptr(stp, isp->is_asset, &n);
+ ip->smbi_location = smb_info_strptr(stp, isp->is_location, &n);
+ ip->smbi_part = smb_info_strptr(stp, isp->is_part, &n);
+
+ /*
+ * If we have a port with an empty internal reference designator string
+ * try using the external reference designator string instead.
+ */
+ if (isp->is_type == SMB_TYPE_PORT && ip->smbi_location[0] == '\0') {
+ ip->smbi_location = smb_info_strptr(stp,
+ offsetof(smb_port_t, smbpo_eref), &n);
+ }
+
+ return (n ? 0 : smb_set_errno(shp, ESMB_NOINFO));
+}
+
+id_t
+smbios_info_bios(smbios_hdl_t *shp, smbios_bios_t *bp)
+{
+ const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_BIOS);
+ const smb_bios_t *bip;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_len < sizeof (smb_bios_t) - sizeof (uint8_t))
+ return (smb_set_errno(shp, ESMB_CORRUPT));
+
+ bip = (smb_bios_t *)(uintptr_t)stp->smbst_hdr;
+ bzero(bp, sizeof (smbios_bios_t));
+
+ bp->smbb_vendor = smb_strptr(stp, bip->smbbi_vendor);
+ bp->smbb_version = smb_strptr(stp, bip->smbbi_version);
+ bp->smbb_segment = bip->smbbi_segment;
+ bp->smbb_reldate = smb_strptr(stp, bip->smbbi_reldate);
+ bp->smbb_romsize = 64 * 1024 * ((uint32_t)bip->smbbi_romsize + 1);
+ bp->smbb_runsize = 16 * (0x10000 - (uint32_t)bip->smbbi_segment);
+ bp->smbb_cflags = bip->smbbi_cflags;
+
+ /*
+ * If one or more extension bytes are present, reset smbb_xcflags to
+ * point to them. Otherwise leave this member set to NULL.
+ */
+ if (stp->smbst_hdr->smbh_len >= sizeof (smb_bios_t)) {
+ bp->smbb_xcflags = bip->smbbi_xcflags;
+ bp->smbb_nxcflags = stp->smbst_hdr->smbh_len -
+ sizeof (smb_bios_t) + 1;
+
+ if (bp->smbb_nxcflags > SMB_BIOSXB_ECFW_MIN &&
+ smb_gteq(shp, SMB_VERSION_24)) {
+ bp->smbb_biosv.smbv_major =
+ bip->smbbi_xcflags[SMB_BIOSXB_BIOS_MAJ];
+ bp->smbb_biosv.smbv_minor =
+ bip->smbbi_xcflags[SMB_BIOSXB_BIOS_MIN];
+ bp->smbb_ecfwv.smbv_major =
+ bip->smbbi_xcflags[SMB_BIOSXB_ECFW_MAJ];
+ bp->smbb_ecfwv.smbv_minor =
+ bip->smbbi_xcflags[SMB_BIOSXB_ECFW_MIN];
+ }
+ }
+
+ return (stp->smbst_hdr->smbh_hdl);
+}
+
+id_t
+smbios_info_system(smbios_hdl_t *shp, smbios_system_t *sip)
+{
+ const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_SYSTEM);
+ smb_system_t si;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ smb_info_bcopy(stp->smbst_hdr, &si, sizeof (si));
+ bzero(sip, sizeof (smbios_system_t));
+
+ sip->smbs_uuid = ((smb_system_t *)stp->smbst_hdr)->smbsi_uuid;
+ sip->smbs_uuidlen = sizeof (si.smbsi_uuid);
+ sip->smbs_wakeup = si.smbsi_wakeup;
+ sip->smbs_sku = smb_strptr(stp, si.smbsi_sku);
+ sip->smbs_family = smb_strptr(stp, si.smbsi_family);
+
+ return (stp->smbst_hdr->smbh_hdl);
+}
+
+int
+smbios_info_bboard(smbios_hdl_t *shp, id_t id, smbios_bboard_t *bbp)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ smb_bboard_t bb;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_BASEBOARD)
+ return (smb_set_errno(shp, ESMB_TYPE));
+
+ smb_info_bcopy(stp->smbst_hdr, &bb, sizeof (bb));
+ bzero(bbp, sizeof (smbios_bboard_t));
+
+ /*
+ * At present, we do not provide support for the contained object
+ * handles portion of the Base Board structure, as none of the 2.3+
+ * BIOSes commonly in use appear to implement it at present.
+ */
+ bbp->smbb_chassis = bb.smbbb_chassis;
+ bbp->smbb_flags = bb.smbbb_flags;
+ bbp->smbb_type = bb.smbbb_type;
+
+ return (0);
+}
+
+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);
+ smb_chassis_t ch;
+
+ 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));
+
+ smb_info_bcopy(stp->smbst_hdr, &ch, sizeof (ch));
+ bzero(chp, sizeof (smbios_chassis_t));
+
+ /*
+ * At present, we do not provide support for the contained object
+ * handles portion of the Chassis structure, as none of the 2.3+
+ * BIOSes commonly in use appear to implement it at present.
+ */
+ 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;
+
+ return (0);
+}
+
+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);
+ smb_processor_t p;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_PROCESSOR)
+ return (smb_set_errno(shp, ESMB_TYPE));
+
+ smb_info_bcopy(stp->smbst_hdr, &p, sizeof (p));
+ bzero(pp, sizeof (smbios_processor_t));
+
+ pp->smbp_cpuid = p.smbpr_cpuid;
+ pp->smbp_type = p.smbpr_type;
+ pp->smbp_family = p.smbpr_family;
+ pp->smbp_voltage = p.smbpr_voltage;
+ pp->smbp_maxspeed = p.smbpr_maxspeed;
+ pp->smbp_curspeed = p.smbpr_curspeed;
+ pp->smbp_status = p.smbpr_status;
+ pp->smbp_upgrade = p.smbpr_upgrade;
+ pp->smbp_l1cache = p.smbpr_l1cache;
+ pp->smbp_l2cache = p.smbpr_l2cache;
+ pp->smbp_l3cache = p.smbpr_l3cache;
+
+ return (0);
+}
+
+int
+smbios_info_cache(smbios_hdl_t *shp, id_t id, smbios_cache_t *cap)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ smb_cache_t c;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_CACHE)
+ return (smb_set_errno(shp, ESMB_TYPE));
+
+ smb_info_bcopy(stp->smbst_hdr, &c, sizeof (c));
+ bzero(cap, sizeof (smbios_cache_t));
+
+ cap->smba_maxsize = SMB_CACHE_SIZE(c.smbca_maxsize);
+ cap->smba_size = SMB_CACHE_SIZE(c.smbca_size);
+ cap->smba_stype = c.smbca_stype;
+ cap->smba_ctype = c.smbca_ctype;
+ cap->smba_speed = c.smbca_speed;
+ cap->smba_etype = c.smbca_etype;
+ cap->smba_ltype = c.smbca_ltype;
+ cap->smba_assoc = c.smbca_assoc;
+ cap->smba_level = SMB_CACHE_CFG_LEVEL(c.smbca_config);
+ cap->smba_mode = SMB_CACHE_CFG_MODE(c.smbca_config);
+ cap->smba_location = SMB_CACHE_CFG_LOCATION(c.smbca_config);
+
+ if (SMB_CACHE_CFG_ENABLED(c.smbca_config))
+ cap->smba_flags |= SMB_CAF_ENABLED;
+
+ if (SMB_CACHE_CFG_SOCKETED(c.smbca_config))
+ cap->smba_flags |= SMB_CAF_SOCKETED;
+
+ return (0);
+}
+
+int
+smbios_info_port(smbios_hdl_t *shp, id_t id, smbios_port_t *pop)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ smb_port_t p;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_PORT)
+ return (smb_set_errno(shp, ESMB_TYPE));
+
+ smb_info_bcopy(stp->smbst_hdr, &p, sizeof (p));
+ bzero(pop, sizeof (smbios_port_t));
+
+ pop->smbo_iref = smb_strptr(stp, p.smbpo_iref);
+ pop->smbo_eref = smb_strptr(stp, p.smbpo_eref);
+
+ pop->smbo_itype = p.smbpo_itype;
+ pop->smbo_etype = p.smbpo_etype;
+ pop->smbo_ptype = p.smbpo_ptype;
+
+ return (0);
+}
+
+int
+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;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_SLOT)
+ return (smb_set_errno(shp, ESMB_TYPE));
+
+ smb_info_bcopy(stp->smbst_hdr, &s, sizeof (s));
+ bzero(sp, sizeof (smbios_slot_t));
+
+ sp->smbl_name = smb_strptr(stp, s.smbsl_name);
+ sp->smbl_type = s.smbsl_type;
+ sp->smbl_width = s.smbsl_width;
+ sp->smbl_usage = s.smbsl_usage;
+ sp->smbl_length = s.smbsl_length;
+ sp->smbl_id = s.smbsl_id;
+ sp->smbl_ch1 = s.smbsl_ch1;
+ sp->smbl_ch2 = s.smbsl_ch2;
+
+ return (0);
+}
+
+int
+smbios_info_obdevs(smbios_hdl_t *shp, id_t id, int obc, smbios_obdev_t *obp)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ const smb_obdev_t *op;
+ int i, m, n;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_OBDEVS)
+ return (smb_set_errno(shp, ESMB_TYPE));
+
+ op = (smb_obdev_t *)((uintptr_t)stp->smbst_hdr + sizeof (smb_header_t));
+ m = (stp->smbst_hdr->smbh_len - sizeof (smb_header_t)) / sizeof (*op);
+ n = MIN(m, obc);
+
+ for (i = 0; i < n; i++, op++, obp++) {
+ obp->smbd_name = smb_strptr(stp, op->smbob_name);
+ obp->smbd_type = op->smbob_type & ~SMB_OBT_ENABLED;
+ obp->smbd_enabled = (op->smbob_type & SMB_OBT_ENABLED) != 0;
+ }
+
+ return (m);
+}
+
+/*
+ * The implementation structures for OEMSTR, SYSCONFSTR, and LANG all use the
+ * first byte to indicate the size of a string table at the end of the record.
+ * Therefore, smbios_info_strtab() can be used to retrieve the table size and
+ * strings for any of these underlying record types.
+ */
+int
+smbios_info_strtab(smbios_hdl_t *shp, id_t id, int argc, const char *argv[])
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ smb_strtab_t s;
+ int i, n;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_OEMSTR &&
+ stp->smbst_hdr->smbh_type != SMB_TYPE_SYSCONFSTR &&
+ stp->smbst_hdr->smbh_type != SMB_TYPE_LANG)
+ return (smb_set_errno(shp, ESMB_TYPE));
+
+ smb_info_bcopy(stp->smbst_hdr, &s, sizeof (s));
+ n = MIN(s.smbtb_count, argc);
+
+ for (i = 0; i < n; i++)
+ argv[i] = smb_strptr(stp, i + 1);
+
+ return (s.smbtb_count);
+}
+
+id_t
+smbios_info_lang(smbios_hdl_t *shp, smbios_lang_t *lp)
+{
+ const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_LANG);
+ smb_lang_t l;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ smb_info_bcopy(stp->smbst_hdr, &l, sizeof (l));
+ bzero(lp, sizeof (smbios_lang_t));
+
+ lp->smbla_cur = smb_strptr(stp, l.smblang_cur);
+ lp->smbla_fmt = l.smblang_flags & 1;
+ lp->smbla_num = l.smblang_num;
+
+ return (stp->smbst_hdr->smbh_hdl);
+}
+
+id_t
+smbios_info_eventlog(smbios_hdl_t *shp, smbios_evlog_t *evp)
+{
+ const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_EVENTLOG);
+ const smb_sel_t *sel;
+ size_t len;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_len < sizeof (smb_sel_t) - sizeof (uint8_t))
+ return (smb_set_errno(shp, ESMB_CORRUPT));
+
+ sel = (smb_sel_t *)(uintptr_t)stp->smbst_hdr;
+ len = stp->smbst_hdr->smbh_len - sizeof (smb_sel_t) + sizeof (uint8_t);
+ bzero(evp, sizeof (smbios_evlog_t));
+
+ if (len < sel->smbsel_typec * sel->smbsel_typesz)
+ return (smb_set_errno(shp, ESMB_CORRUPT));
+
+ evp->smbev_size = sel->smbsel_len;
+ evp->smbev_hdr = sel->smbsel_hdroff;
+ evp->smbev_data = sel->smbsel_dataoff;
+ evp->smbev_method = sel->smbsel_method;
+ evp->smbev_flags = sel->smbsel_status;
+ evp->smbev_format = sel->smbsel_format;
+ evp->smbev_token = sel->smbsel_token;
+ evp->smbev_addr.eva_addr = sel->smbsel_addr;
+
+ if (sel->smbsel_typesz == sizeof (smbios_evtype_t)) {
+ evp->smbev_typec = sel->smbsel_typec;
+ evp->smbev_typev = (void *)(uintptr_t)sel->smbsel_typev;
+ }
+
+ return (stp->smbst_hdr->smbh_hdl);
+}
+
+int
+smbios_info_memarray(smbios_hdl_t *shp, id_t id, smbios_memarray_t *map)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ smb_memarray_t m;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMARRAY)
+ return (smb_set_errno(shp, ESMB_TYPE));
+
+ smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m));
+ bzero(map, sizeof (smbios_memarray_t));
+
+ map->smbma_location = m.smbmarr_loc;
+ map->smbma_use = m.smbmarr_use;
+ map->smbma_ecc = m.smbmarr_ecc;
+ map->smbma_ndevs = m.smbmarr_ndevs;
+ map->smbma_err = m.smbmarr_err;
+
+ if (m.smbmarr_cap != 0x80000000)
+ map->smbma_size = (uint64_t)m.smbmarr_cap * 1024;
+ else
+ map->smbma_size = 0; /* unknown */
+
+ return (0);
+}
+
+int
+smbios_info_memarrmap(smbios_hdl_t *shp, id_t id, smbios_memarrmap_t *map)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ smb_memarrmap_t m;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMARRAYMAP)
+ return (smb_set_errno(shp, ESMB_TYPE));
+
+ smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m));
+ bzero(map, sizeof (smbios_memarrmap_t));
+
+ map->smbmam_array = m.smbamap_array;
+ map->smbmam_width = m.smbamap_width;
+ map->smbmam_addr = (uint64_t)m.smbamap_start * 1024;
+ map->smbmam_size = (uint64_t)
+ (m.smbamap_end - m.smbamap_start + 1) * 1024;
+
+ return (0);
+}
+
+int
+smbios_info_memdevice(smbios_hdl_t *shp, id_t id, smbios_memdevice_t *mdp)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ smb_memdevice_t m;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMDEVICE)
+ return (smb_set_errno(shp, ESMB_TYPE));
+
+ smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m));
+ bzero(mdp, sizeof (smbios_memdevice_t));
+
+ mdp->smbmd_array = m.smbmdev_array;
+ mdp->smbmd_error = m.smbmdev_error;
+ mdp->smbmd_twidth = m.smbmdev_twidth == 0xFFFF ? -1U : m.smbmdev_twidth;
+ mdp->smbmd_dwidth = m.smbmdev_dwidth == 0xFFFF ? -1U : m.smbmdev_dwidth;
+
+ if (mdp->smbmd_size != 0xFFFF) {
+ mdp->smbmd_size = (uint64_t)(m.smbmdev_size & ~SMB_MDS_KBYTES);
+ if (m.smbmdev_size & SMB_MDS_KBYTES)
+ mdp->smbmd_size *= 1024;
+ else
+ mdp->smbmd_size *= 1024 * 1024;
+ } else
+ mdp->smbmd_size = -1ULL; /* size unknown */
+
+ mdp->smbmd_form = m.smbmdev_form;
+ mdp->smbmd_set = m.smbmdev_set;
+ mdp->smbmd_type = m.smbmdev_type;
+ mdp->smbmd_flags = m.smbmdev_flags;
+ mdp->smbmd_dloc = smb_strptr(stp, m.smbmdev_dloc);
+ mdp->smbmd_bloc = smb_strptr(stp, m.smbmdev_bloc);
+
+ if (m.smbmdev_speed != 0)
+ mdp->smbmd_speed = 1000 / m.smbmdev_speed; /* MHz -> nsec */
+
+ return (0);
+}
+
+int
+smbios_info_memdevmap(smbios_hdl_t *shp, id_t id, smbios_memdevmap_t *mdp)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ smb_memdevmap_t m;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMDEVICEMAP)
+ return (smb_set_errno(shp, ESMB_TYPE));
+
+ smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m));
+ bzero(mdp, sizeof (smbios_memdevmap_t));
+
+ mdp->smbmdm_device = m.smbdmap_device;
+ mdp->smbmdm_arrmap = m.smbdmap_array;
+ mdp->smbmdm_addr = (uint64_t)m.smbdmap_start * 1024;
+ mdp->smbmdm_size = (uint64_t)
+ (m.smbdmap_end - m.smbdmap_start + 1) * 1024;
+ mdp->smbmdm_rpos = m.smbdmap_rpos;
+ mdp->smbmdm_ipos = m.smbdmap_ipos;
+ mdp->smbmdm_idepth = m.smbdmap_idepth;
+
+ return (0);
+}
+
+id_t
+smbios_info_hwsec(smbios_hdl_t *shp, smbios_hwsec_t *hsp)
+{
+ const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_SECURITY);
+ smb_hwsec_t hs;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ smb_info_bcopy(stp->smbst_hdr, &hs, sizeof (hs));
+ bzero(hsp, sizeof (smbios_hwsec_t));
+
+ hsp->smbh_pwr_ps = SMB_HWS_PWR_PS(hs.smbhs_settings);
+ hsp->smbh_kbd_ps = SMB_HWS_KBD_PS(hs.smbhs_settings);
+ hsp->smbh_adm_ps = SMB_HWS_ADM_PS(hs.smbhs_settings);
+ hsp->smbh_pan_ps = SMB_HWS_PAN_PS(hs.smbhs_settings);
+
+ return (stp->smbst_hdr->smbh_hdl);
+}
+
+id_t
+smbios_info_boot(smbios_hdl_t *shp, smbios_boot_t *bp)
+{
+ const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_BOOT);
+ const smb_boot_t *b = (smb_boot_t *)(uintptr_t)stp->smbst_hdr;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ bzero(bp, sizeof (smbios_boot_t));
+
+ bp->smbt_status = b->smbbo_status[0];
+ bp->smbt_size = stp->smbst_hdr->smbh_len - sizeof (smb_boot_t);
+ bp->smbt_data = bp->smbt_size ? &b->smbbo_status[1] : NULL;
+
+ return (stp->smbst_hdr->smbh_hdl);
+}
+
+id_t
+smbios_info_ipmi(smbios_hdl_t *shp, smbios_ipmi_t *ip)
+{
+ const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_IPMIDEV);
+ smb_ipmi_t i;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ smb_info_bcopy(stp->smbst_hdr, &i, sizeof (i));
+ bzero(ip, sizeof (smbios_ipmi_t));
+
+ ip->smbip_type = i.smbipm_type;
+ ip->smbip_vers.smbv_major = SMB_IPM_SPEC_MAJOR(i.smbipm_spec);
+ ip->smbip_vers.smbv_minor = SMB_IPM_SPEC_MINOR(i.smbipm_spec);
+ ip->smbip_i2c = i.smbipm_i2c;
+ ip->smbip_addr = i.smbipm_addr & ~SMB_IPM_ADDR_IO;
+ ip->smbip_intr = i.smbipm_intr;
+
+ if (i.smbipm_bus != (uint8_t)-1)
+ ip->smbip_bus = i.smbipm_bus;
+ else
+ ip->smbip_bus = -1u;
+
+ if (SMB_IPM_INFO_LSB(i.smbipm_info))
+ ip->smbip_addr |= 1; /* turn on least-significant bit of addr */
+
+ if (i.smbipm_addr & SMB_IPM_ADDR_IO) {
+ switch (SMB_IPM_INFO_REGS(i.smbipm_info)) {
+ case SMB_IPM_REGS_1B:
+ ip->smbip_regspacing = 1;
+ break;
+ case SMB_IPM_REGS_4B:
+ ip->smbip_regspacing = 4;
+ break;
+ case SMB_IPM_REGS_16B:
+ ip->smbip_regspacing = 16;
+ break;
+ default:
+ ip->smbip_regspacing = 1;
+ }
+ ip->smbip_flags |= SMB_IPMI_F_IOADDR;
+ }
+
+ if (SMB_IPM_INFO_ISPEC(i.smbipm_info))
+ ip->smbip_flags |= SMB_IPMI_F_INTRSPEC;
+
+ if (SMB_IPM_INFO_IPOL(i.smbipm_info) == SMB_IPM_IPOL_HI)
+ ip->smbip_flags |= SMB_IPMI_F_INTRHIGH;
+
+ if (SMB_IPM_INFO_IMODE(i.smbipm_info) == SMB_IPM_IMODE_EDGE)
+ ip->smbip_flags |= SMB_IPMI_F_INTREDGE;
+
+ return (stp->smbst_hdr->smbh_hdl);
+}
diff --git a/usr/src/common/smbios/smb_open.c b/usr/src/common/smbios/smb_open.c
new file mode 100644
index 0000000000..c7c3fb666d
--- /dev/null
+++ b/usr/src/common/smbios/smb_open.c
@@ -0,0 +1,370 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/smbios_impl.h>
+
+static const uint_t _smb_hashlen = 64; /* hash length (must be Pof2) */
+static const char _smb_emptystr[] = ""; /* empty string to return */
+int _smb_debug = 0; /* default debug mode */
+
+/*
+ * Strip out identification information for you privacy weenies. This is quite
+ * simple using our smbios_info_common() abstraction: we just locate any serial
+ * numbers and asset tags for each record, and then zero out those strings.
+ * Then we must handle two special cases: SMB_TYPE_SYSTEM holds a 16-byte UUID
+ * and SMB_TYPE_BATTERY stores a Smart Battery Data Spec 16-bit serial number.
+ * We use a literal '0' rather than '\0' for zeroing strings because \0\0 in
+ * the SMBIOS string table has a special meaning (denotes end-of-record).
+ */
+static void
+smb_strip(smbios_hdl_t *shp)
+{
+ uint_t i;
+
+ for (i = 0; i < shp->sh_nstructs; i++) {
+ const smb_header_t *hp = shp->sh_structs[i].smbst_hdr;
+ smbios_info_t info;
+ char *p;
+
+ if (hp->smbh_type == SMB_TYPE_SYSTEM &&
+ hp->smbh_len >= offsetof(smb_system_t, smbsi_wakeup)) {
+ smb_system_t *sp = (smb_system_t *)(uintptr_t)hp;
+ bzero(sp->smbsi_uuid, sizeof (sp->smbsi_uuid));
+ }
+
+ if (hp->smbh_type == SMB_TYPE_BATTERY &&
+ hp->smbh_len >= offsetof(smb_battery_t, smbbat_sdate)) {
+ smb_battery_t *bp = (smb_battery_t *)(uintptr_t)hp;
+ bp->smbbat_ssn = 0;
+ }
+
+ if (smbios_info_common(shp, hp->smbh_hdl, &info) != SMB_ERR) {
+ for (p = (char *)info.smbi_serial; *p != '\0'; p++)
+ *p = '0';
+ for (p = (char *)info.smbi_asset; *p != '\0'; p++)
+ *p = '0';
+ }
+ }
+}
+
+smbios_hdl_t *
+smbios_bufopen(const smbios_entry_t *ep, const void *buf, size_t len,
+ int version, int flags, int *errp)
+{
+ smbios_hdl_t *shp = smb_zalloc(sizeof (smbios_hdl_t));
+ const smb_header_t *hp, *nhp;
+ const uchar_t *p, *q, *s;
+ uint_t i, h;
+
+ switch (version) {
+ case SMB_VERSION_23:
+ case SMB_VERSION_24:
+ break;
+ default:
+ return (smb_open_error(shp, errp, ESMB_VERSION));
+ }
+
+ if (ep == NULL || buf == NULL || len == 0 || (flags & ~SMB_O_MASK))
+ return (smb_open_error(shp, errp, ESMB_INVAL));
+
+ if (shp == NULL)
+ return (smb_open_error(shp, errp, ESMB_NOMEM));
+
+ if (_smb_debug)
+ shp->sh_flags |= SMB_FL_DEBUG;
+
+ if (strncmp(ep->smbe_eanchor, SMB_ENTRY_EANCHOR, SMB_ENTRY_EANCHORLEN))
+ return (smb_open_error(shp, errp, ESMB_HEADER));
+
+ if (strncmp(ep->smbe_ianchor, SMB_ENTRY_IANCHOR, SMB_ENTRY_IANCHORLEN))
+ return (smb_open_error(shp, errp, ESMB_HEADER));
+
+ smb_dprintf(shp, "opening SMBIOS version %u.%u bcdrev 0x%x\n",
+ ep->smbe_major, ep->smbe_minor, ep->smbe_bcdrev);
+
+ if (!(flags & SMB_O_NOVERS)) {
+ if (ep->smbe_major > SMB_MAJOR(SMB_VERSION))
+ return (smb_open_error(shp, errp, ESMB_NEW));
+
+ if (ep->smbe_major < SMB_MAJOR(SMB_VERSION_23) || (
+ ep->smbe_major == SMB_MAJOR(SMB_VERSION_23) &&
+ ep->smbe_minor < SMB_MINOR(SMB_VERSION_23)))
+ return (smb_open_error(shp, errp, ESMB_OLD));
+ }
+
+ if (len < sizeof (smb_header_t) ||
+ ep->smbe_stlen < sizeof (smb_header_t) || len < ep->smbe_stlen)
+ return (smb_open_error(shp, errp, ESMB_SHORT));
+
+ if (!(flags & SMB_O_NOCKSUM)) {
+ uint8_t esum = 0, isum = 0;
+ q = (uchar_t *)ep;
+
+ for (p = q; p < q + ep->smbe_elen; p++)
+ esum += *p;
+
+ for (p = (uchar_t *)ep->smbe_ianchor; p < q + sizeof (*ep); p++)
+ isum += *p;
+
+ if (esum != 0 || isum != 0) {
+ smb_dprintf(shp, "bad cksum: e=%x i=%x\n", esum, isum);
+ return (smb_open_error(shp, errp, ESMB_CKSUM));
+ }
+ }
+
+ bcopy(ep, &shp->sh_ent, sizeof (smbios_entry_t));
+ shp->sh_buf = buf;
+ shp->sh_buflen = len;
+ shp->sh_structs = smb_alloc(sizeof (smb_struct_t) * ep->smbe_stnum);
+ shp->sh_nstructs = 0;
+ shp->sh_hashlen = _smb_hashlen;
+ shp->sh_hash = smb_zalloc(sizeof (smb_struct_t *) * shp->sh_hashlen);
+ shp->sh_libvers = version;
+ shp->sh_smbvers = SMB_MAJMIN(ep->smbe_major, ep->smbe_minor);
+
+ if (shp->sh_structs == NULL || shp->sh_hash == NULL)
+ return (smb_open_error(shp, errp, ESMB_NOMEM));
+
+ hp = shp->sh_buf;
+ q = (const uchar_t *)buf + MIN(ep->smbe_stlen, len);
+
+ for (i = 0; i < ep->smbe_stnum; i++, hp = nhp) {
+ smb_struct_t *stp = &shp->sh_structs[i];
+ uint_t n = 0;
+
+ if ((const uchar_t *)hp + sizeof (smb_header_t) > q)
+ return (smb_open_error(shp, errp, ESMB_CORRUPT));
+
+ smb_dprintf(shp, "struct [%u] type %u len %u hdl %u at %p\n",
+ i, hp->smbh_type, hp->smbh_len, hp->smbh_hdl, (void *)hp);
+
+ if ((const uchar_t *)hp + hp->smbh_len > q - 2)
+ return (smb_open_error(shp, errp, ESMB_CORRUPT));
+
+ if (hp->smbh_type == SMB_TYPE_EOT)
+ break; /* ignore any entries beyond end-of-table */
+
+ h = hp->smbh_hdl & (shp->sh_hashlen - 1);
+ p = s = (const uchar_t *)hp + hp->smbh_len;
+
+ while (p <= q - 2 && (p[0] != '\0' || p[1] != '\0')) {
+ if (*p++ == '\0')
+ n++; /* count strings until \0\0 delimiter */
+ }
+
+ if (p > q - 2)
+ return (smb_open_error(shp, errp, ESMB_CORRUPT));
+
+ if (p > s)
+ n++; /* add one for final string in string table */
+
+ stp->smbst_hdr = hp;
+ stp->smbst_str = s;
+ stp->smbst_end = p;
+ stp->smbst_next = shp->sh_hash[h];
+ stp->smbst_strtab = smb_alloc(sizeof (uint16_t) * n);
+ stp->smbst_strtablen = n;
+
+ if (n != 0 && stp->smbst_strtab == NULL)
+ return (smb_open_error(shp, errp, ESMB_NOMEM));
+
+ shp->sh_hash[h] = stp;
+ nhp = (void *)(p + 2);
+ shp->sh_nstructs++;
+
+ for (n = 0, p = s; n < stp->smbst_strtablen; p++) {
+ if (*p == '\0') {
+ stp->smbst_strtab[n++] =
+ (uint16_t)(s - stp->smbst_str);
+ s = p + 1;
+ }
+ }
+ }
+
+ if (flags & SMB_O_ZIDS)
+ smb_strip(shp);
+
+ return (shp);
+}
+
+void
+smbios_close(smbios_hdl_t *shp)
+{
+ const smbios_entry_t *ep = &shp->sh_ent;
+ uint_t i;
+
+ for (i = 0; i < shp->sh_nstructs; i++) {
+ smb_free(shp->sh_structs[i].smbst_strtab,
+ sizeof (uint16_t) * shp->sh_structs[i].smbst_strtablen);
+ }
+
+ smb_free(shp->sh_structs, sizeof (smb_struct_t) * ep->smbe_stnum);
+ smb_free(shp->sh_hash, sizeof (smb_struct_t *) * shp->sh_hashlen);
+
+ if (shp->sh_flags & SMB_FL_BUFALLOC)
+ smb_free((void *)shp->sh_buf, shp->sh_buflen);
+
+ smb_free(shp, sizeof (smbios_hdl_t));
+}
+
+/*
+ * Recompute the values of the entry point checksums based upon the content
+ * of the specified SMBIOS entry point. We don't need 'shp' but require it
+ * anyway in case future versioning requires variations in the algorithm.
+ */
+/*ARGSUSED*/
+void
+smbios_checksum(smbios_hdl_t *shp, smbios_entry_t *ep)
+{
+ uchar_t *p, *q = (uchar_t *)ep;
+ uint8_t esum = 0, isum = 0;
+
+ ep->smbe_ecksum = ep->smbe_icksum = 0;
+
+ for (p = (uchar_t *)ep->smbe_ianchor; p < q + sizeof (*ep); p++)
+ isum += *p;
+
+ ep->smbe_icksum = -isum;
+
+ for (p = q; p < q + ep->smbe_elen; p++)
+ esum += *p;
+
+ ep->smbe_ecksum = -esum;
+}
+
+const void *
+smbios_buf(smbios_hdl_t *shp)
+{
+ return (shp->sh_buf);
+}
+
+size_t
+smbios_buflen(smbios_hdl_t *shp)
+{
+ return (shp->sh_buflen);
+}
+
+static smbios_struct_t *
+smb_export(const smb_struct_t *stp, smbios_struct_t *sp)
+{
+ const smb_header_t *hdr = stp->smbst_hdr;
+
+ sp->smbstr_id = hdr->smbh_hdl;
+ sp->smbstr_type = hdr->smbh_type;
+ sp->smbstr_data = hdr;
+ sp->smbstr_size = (size_t)(stp->smbst_end - (uchar_t *)hdr);
+
+ return (sp);
+}
+
+int
+smbios_lookup_id(smbios_hdl_t *shp, id_t id, smbios_struct_t *sp)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (sp != NULL)
+ (void) smb_export(stp, sp);
+
+ return (0);
+}
+
+int
+smbios_iter(smbios_hdl_t *shp, smbios_struct_f *func, void *data)
+{
+ const smb_struct_t *sp = shp->sh_structs;
+ smbios_struct_t s;
+ int i, rv = 0;
+
+ for (i = 0; i < shp->sh_nstructs; i++, sp++) {
+ if (sp->smbst_hdr->smbh_type != SMB_TYPE_INACTIVE &&
+ (rv = func(shp, smb_export(sp, &s), data)) != 0)
+ break;
+ }
+
+ return (rv);
+}
+
+const smb_struct_t *
+smb_lookup_type(smbios_hdl_t *shp, uint_t type)
+{
+ uint_t i;
+
+ for (i = 0; i < shp->sh_nstructs; i++) {
+ if (shp->sh_structs[i].smbst_hdr->smbh_type == type)
+ return (&shp->sh_structs[i]);
+ }
+
+ (void) smb_set_errno(shp, ESMB_NOENT);
+ return (NULL);
+}
+
+const smb_struct_t *
+smb_lookup_id(smbios_hdl_t *shp, uint_t id)
+{
+ const smb_struct_t *stp = shp->sh_hash[id & (shp->sh_hashlen - 1)];
+
+ switch (id) {
+ case SMB_ID_NOTSUP:
+ (void) smb_set_errno(shp, ESMB_NOTSUP);
+ return (NULL);
+ case SMB_ID_NONE:
+ (void) smb_set_errno(shp, ESMB_NOENT);
+ return (NULL);
+ }
+
+ for (; stp != NULL; stp = stp->smbst_next) {
+ if (stp->smbst_hdr->smbh_hdl == id)
+ break;
+ }
+
+ if (stp == NULL)
+ (void) smb_set_errno(shp, ESMB_NOENT);
+
+ return (stp);
+}
+
+const char *
+smb_strptr(const smb_struct_t *stp, uint_t i)
+{
+ if (i == 0 || i > stp->smbst_strtablen)
+ return (_smb_emptystr);
+ else
+ return ((char *)stp->smbst_str + stp->smbst_strtab[i - 1]);
+}
+
+int
+smb_gteq(smbios_hdl_t *shp, int version)
+{
+ return (SMB_MAJOR(shp->sh_smbvers) > SMB_MAJOR(version) || (
+ SMB_MAJOR(shp->sh_smbvers) == SMB_MAJOR(version) &&
+ SMB_MINOR(shp->sh_smbvers) >= SMB_MINOR(version)));
+}
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile
index 9375332e21..758c917dab 100644
--- a/usr/src/lib/Makefile
+++ b/usr/src/lib/Makefile
@@ -104,6 +104,7 @@ SUBDIRS= \
libmalloc \
libmtmalloc \
libnls \
+ libsmbios \
libtecla \
libumem \
libnvpair .WAIT \
@@ -308,6 +309,7 @@ HDRSUBDIRS= libaio \
libproc \
librcm \
libscf \
+ libsmbios \
librestart \
librpcsvc \
librsm \
diff --git a/usr/src/lib/libsmbios/Makefile b/usr/src/lib/libsmbios/Makefile
new file mode 100644
index 0000000000..6869a3bc4e
--- /dev/null
+++ b/usr/src/lib/libsmbios/Makefile
@@ -0,0 +1,57 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+include ../Makefile.lib
+
+HDRS = smbios.h
+HDRDIR = common
+
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+.KEEP_STATE:
+
+all clean clobber install: spec .WAIT $(SUBDIRS)
+
+lint: $(SUBDIRS)
+
+install_h: $(ROOTHDRS)
+
+check: $(CHECKHDRS)
+
+spec $(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../Makefile.targ
diff --git a/usr/src/lib/libsmbios/Makefile.com b/usr/src/lib/libsmbios/Makefile.com
new file mode 100644
index 0000000000..83f112299b
--- /dev/null
+++ b/usr/src/lib/libsmbios/Makefile.com
@@ -0,0 +1,74 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+LIBRARY = libsmbios.a
+VERS = .1
+
+COMMON_OBJS = \
+ smb_error.o \
+ smb_info.o \
+ smb_open.o
+
+LIB_OBJS = \
+ smb_lib.o \
+ smb_subr.o \
+ smb_tables.o
+
+OBJECTS = $(COMMON_OBJS) $(LIB_OBJS)
+
+include ../../Makefile.lib
+
+COMMON_SRCDIR = ../../../common/smbios
+COMMON_HDR = $(SRC)/uts/common/sys/smbios.h
+
+SRCS = $(COMMON_OBJS:%.o=$(COMMON_SRCDIR)/%.c) $(LIB_OBJS:%.o=../common/%.c)
+LIBS = $(DYNLIB) $(LINTLIB)
+
+SRCDIR = ../common
+SPECMAPFILE = $(MAPDIR)/mapfile
+CLEANFILES += ../common/smb_tables.c
+
+CPPFLAGS += -I../common -I$(COMMON_SRCDIR)
+CFLAGS += $(CCVERBOSE)
+LDLIBS += -lc
+
+$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+include ../../Makefile.targ
+
+objs/%.o pics/%.o: ../../../common/smbios/%.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
+
+../common/smb_tables.c: $(COMMON_SRCDIR)/mktables.sh $(COMMON_HDR)
+ sh $(COMMON_SRCDIR)/mktables.sh $(COMMON_HDR) > $@
diff --git a/usr/src/lib/libsmbios/amd64/Makefile b/usr/src/lib/libsmbios/amd64/Makefile
new file mode 100644
index 0000000000..7b40f7053a
--- /dev/null
+++ b/usr/src/lib/libsmbios/amd64/Makefile
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+MAPDIR = ../spec/amd64
+include ../Makefile.com
+include ../../Makefile.lib.64
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
diff --git a/usr/src/lib/libsmbios/common/llib-lsmbios b/usr/src/lib/libsmbios/common/llib-lsmbios
new file mode 100644
index 0000000000..b0c74b31bd
--- /dev/null
+++ b/usr/src/lib/libsmbios/common/llib-lsmbios
@@ -0,0 +1,32 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*LINTLIBRARY*/
+/*PROTOLIB1*/
+
+#include <smbios.h>
diff --git a/usr/src/lib/libsmbios/common/smb_lib.c b/usr/src/lib/libsmbios/common/smb_lib.c
new file mode 100644
index 0000000000..c8bae93fa3
--- /dev/null
+++ b/usr/src/lib/libsmbios/common/smb_lib.c
@@ -0,0 +1,204 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/smbios_impl.h>
+#include <sys/sysmacros.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <limits.h>
+#include <unistd.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#pragma init(smb_init)
+static void
+smb_init(void)
+{
+ _smb_debug = getenv("SMB_DEBUG") != NULL;
+}
+
+static smbios_hdl_t *
+smb_fileopen(int fd, int version, int flags, int *errp)
+{
+ smbios_hdl_t *shp = NULL;
+ smbios_entry_t ep;
+ void *stbuf;
+ ssize_t n;
+
+ if ((n = pread64(fd, &ep, sizeof (ep), 0)) != sizeof (ep))
+ return (smb_open_error(shp, errp, n < 0 ? errno : ESMB_NOHDR));
+
+ if (strncmp(ep.smbe_eanchor, SMB_ENTRY_EANCHOR, SMB_ENTRY_EANCHORLEN))
+ return (smb_open_error(shp, errp, ESMB_HEADER));
+
+ if ((stbuf = smb_alloc(ep.smbe_stlen)) == NULL)
+ return (smb_open_error(shp, errp, ESMB_NOMEM));
+
+ if ((n = pread64(fd, stbuf, ep.smbe_stlen,
+ (off64_t)ep.smbe_staddr)) != ep.smbe_stlen) {
+ smb_free(stbuf, ep.smbe_stlen);
+ return (smb_open_error(shp, errp, n < 0 ? errno : ESMB_NOSTAB));
+ }
+
+ shp = smbios_bufopen(&ep, stbuf, ep.smbe_stlen, version, flags, errp);
+
+ if (shp != NULL)
+ shp->sh_flags |= SMB_FL_BUFALLOC;
+ else
+ smb_free(stbuf, ep.smbe_stlen);
+
+ return (shp);
+}
+
+static smbios_hdl_t *
+smb_biosopen(int fd, int version, int flags, int *errp)
+{
+ smbios_hdl_t *shp = NULL;
+ size_t pgsize, pgmask, pgoff;
+ void *stbuf, *bios, *p, *q;
+ smbios_entry_t ep;
+
+ bios = mmap(NULL, SMB_RANGE_LIMIT - SMB_RANGE_START + 1,
+ PROT_READ, MAP_SHARED, fd, (uint32_t)SMB_RANGE_START);
+
+ if (bios == MAP_FAILED)
+ return (smb_open_error(shp, errp, ESMB_MAPDEV));
+
+ q = (void *)((uintptr_t)bios + SMB_RANGE_LIMIT - SMB_RANGE_START + 1);
+
+ for (p = bios; p < q; p = (void *)((uintptr_t)p + 16)) {
+ if (strncmp(p, SMB_ENTRY_EANCHOR, SMB_ENTRY_EANCHORLEN) == 0)
+ break;
+ }
+
+ if (p >= q) {
+ (void) munmap(bios, SMB_RANGE_LIMIT - SMB_RANGE_START + 1);
+ return (smb_open_error(NULL, errp, ESMB_NOTFOUND));
+ }
+
+ bcopy(p, &ep, sizeof (smbios_entry_t));
+ (void) munmap(bios, SMB_RANGE_LIMIT - SMB_RANGE_START + 1);
+
+ pgsize = getpagesize();
+ pgmask = ~(pgsize - 1);
+ pgoff = ep.smbe_staddr & ~pgmask;
+
+ bios = mmap(NULL, ep.smbe_stlen + pgoff,
+ PROT_READ, MAP_SHARED, fd, ep.smbe_staddr & pgmask);
+
+ if (bios == MAP_FAILED)
+ return (smb_open_error(shp, errp, ESMB_MAPDEV));
+
+ if ((stbuf = smb_alloc(ep.smbe_stlen)) == NULL) {
+ (void) munmap(bios, ep.smbe_stlen + pgoff);
+ return (smb_open_error(shp, errp, ESMB_NOMEM));
+ }
+
+ bcopy((char *)bios + pgoff, stbuf, ep.smbe_stlen);
+ (void) munmap(bios, ep.smbe_stlen + pgoff);
+ shp = smbios_bufopen(&ep, stbuf, ep.smbe_stlen, version, flags, errp);
+
+ if (shp != NULL)
+ shp->sh_flags |= SMB_FL_BUFALLOC;
+ else
+ smb_free(stbuf, ep.smbe_stlen);
+
+ return (shp);
+}
+
+smbios_hdl_t *
+smbios_fdopen(int fd, int version, int flags, int *errp)
+{
+ struct stat64 st1, st2;
+
+ if (stat64(SMB_BIOS_DEVICE, &st1) == 0 && fstat64(fd, &st2) == 0 &&
+ S_ISCHR(st2.st_mode) && st1.st_rdev == st2.st_rdev)
+ return (smb_biosopen(fd, version, flags, errp));
+ else
+ return (smb_fileopen(fd, version, flags, errp));
+}
+
+smbios_hdl_t *
+smbios_open(const char *file, int version, int flags, int *errp)
+{
+ smbios_hdl_t *shp;
+ int fd;
+
+ if ((fd = open64(file ? file : SMB_SMBIOS_DEVICE, O_RDONLY)) == -1) {
+ if ((errno == ENOENT || errno == ENXIO) &&
+ (file == NULL || strcmp(file, SMB_SMBIOS_DEVICE) == 0))
+ errno = ESMB_NOTFOUND;
+ return (smb_open_error(NULL, errp, errno));
+ }
+
+ shp = smbios_fdopen(fd, version, flags, errp);
+ (void) close(fd);
+ return (shp);
+}
+
+static int
+smbios_xwrite(smbios_hdl_t *shp, int fd, const void *buf, size_t buflen)
+{
+ ssize_t resid = buflen;
+ ssize_t len;
+
+ while (resid != 0) {
+ if ((len = write(fd, buf, resid)) <= 0)
+ return (smb_set_errno(shp, errno));
+ resid -= len;
+ buf = (uchar_t *)buf + len;
+ }
+
+ return (0);
+}
+
+int
+smbios_write(smbios_hdl_t *shp, int fd)
+{
+ smbios_entry_t ep;
+ off64_t off = lseek64(fd, 0, SEEK_CUR) + P2ROUNDUP(sizeof (ep), 16);
+
+ if (off > UINT32_MAX)
+ return (smb_set_errno(shp, EOVERFLOW));
+
+ bcopy(&shp->sh_ent, &ep, sizeof (ep));
+ ep.smbe_staddr = (uint32_t)off;
+ smbios_checksum(shp, &ep);
+
+ if (smbios_xwrite(shp, fd, &ep, sizeof (ep)) == -1 ||
+ lseek64(fd, off, SEEK_SET) != off ||
+ smbios_xwrite(shp, fd, shp->sh_buf, shp->sh_buflen) == -1)
+ return (-1);
+
+ return (0);
+}
diff --git a/usr/src/lib/libsmbios/common/smb_subr.c b/usr/src/lib/libsmbios/common/smb_subr.c
new file mode 100644
index 0000000000..6d641456cc
--- /dev/null
+++ b/usr/src/lib/libsmbios/common/smb_subr.c
@@ -0,0 +1,93 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/smbios_impl.h>
+
+#include <strings.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+smbios_hdl_t *
+smb_open_error(smbios_hdl_t *shp, int *errp, int err)
+{
+ if (shp != NULL)
+ smbios_close(shp);
+
+ if (errp != NULL)
+ *errp = err;
+
+ return (NULL);
+}
+
+const char *
+smb_strerror(int err)
+{
+ return (strerror(err));
+}
+
+void *
+smb_alloc(size_t len)
+{
+ return (len ? malloc(len) : NULL);
+}
+
+void *
+smb_zalloc(size_t len)
+{
+ void *buf;
+
+ if ((buf = smb_alloc(len)) != NULL)
+ bzero(buf, len);
+
+ return (buf);
+}
+
+/*ARGSUSED*/
+void
+smb_free(void *buf, size_t len)
+{
+ free(buf);
+}
+
+/*PRINTFLIKE2*/
+void
+smb_dprintf(smbios_hdl_t *shp, const char *format, ...)
+{
+ va_list ap;
+
+ if (!(shp->sh_flags & SMB_FL_DEBUG))
+ return;
+
+ (void) fprintf(stderr, "smb DEBUG: ");
+ va_start(ap, format);
+ (void) vfprintf(stderr, format, ap);
+ va_end(ap);
+}
diff --git a/usr/src/lib/libsmbios/common/smbios.h b/usr/src/lib/libsmbios/common/smbios.h
new file mode 100644
index 0000000000..41c1abd431
--- /dev/null
+++ b/usr/src/lib/libsmbios/common/smbios.h
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SMBIOS_H
+#define _SMBIOS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/smbios.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This header file defines the interfaces available from the SMBIOS access
+ * library, libsmbios, and an equivalent kernel module. This API can be used
+ * to access DMTF SMBIOS data from a device, file, or raw memory buffer.
+ * This is NOT yet a public interface, although it may eventually become one in
+ * the fullness of time after we gain more experience with the interfaces.
+ *
+ * In the meantime, be aware that any program linked with this API in this
+ * release of Solaris is almost guaranteed to break in the next release.
+ *
+ * In short, do not user this header file or these routines for any purpose.
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SMBIOS_H */
diff --git a/usr/src/lib/libsmbios/i386/Makefile b/usr/src/lib/libsmbios/i386/Makefile
new file mode 100644
index 0000000000..5b2f167595
--- /dev/null
+++ b/usr/src/lib/libsmbios/i386/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+MAPDIR = ../spec/i386
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/libsmbios/sparc/Makefile b/usr/src/lib/libsmbios/sparc/Makefile
new file mode 100644
index 0000000000..dca1669f5d
--- /dev/null
+++ b/usr/src/lib/libsmbios/sparc/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+MAPDIR = ../spec/sparc
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/libsmbios/sparcv9/Makefile b/usr/src/lib/libsmbios/sparcv9/Makefile
new file mode 100644
index 0000000000..0f01536cf7
--- /dev/null
+++ b/usr/src/lib/libsmbios/sparcv9/Makefile
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+MAPDIR = ../spec/sparcv9
+include ../Makefile.com
+include ../../Makefile.lib.64
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
diff --git a/usr/src/lib/libsmbios/spec/Makefile b/usr/src/lib/libsmbios/spec/Makefile
new file mode 100644
index 0000000000..2cb984bfc9
--- /dev/null
+++ b/usr/src/lib/libsmbios/spec/Makefile
@@ -0,0 +1,28 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+include $(SRC)/lib/Makefile.spec.arch
diff --git a/usr/src/lib/libsmbios/spec/Makefile.targ b/usr/src/lib/libsmbios/spec/Makefile.targ
new file mode 100644
index 0000000000..6f45581c46
--- /dev/null
+++ b/usr/src/lib/libsmbios/spec/Makefile.targ
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+.KEEP_STATE:
+
+LIBRARY = libsmbios.a
+VERS = .1
+OBJECTS = smbios.o
diff --git a/usr/src/lib/libsmbios/spec/amd64/Makefile b/usr/src/lib/libsmbios/spec/amd64/Makefile
new file mode 100644
index 0000000000..ef98bd8314
--- /dev/null
+++ b/usr/src/lib/libsmbios/spec/amd64/Makefile
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+DISABLE_APPTRACE= $(POUND_SIGN)
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
+
+$(DISABLE_APPTRACE)install: $(ROOTABILIB64)
diff --git a/usr/src/lib/libsmbios/spec/i386/Makefile b/usr/src/lib/libsmbios/spec/i386/Makefile
new file mode 100644
index 0000000000..83d6a28b73
--- /dev/null
+++ b/usr/src/lib/libsmbios/spec/i386/Makefile
@@ -0,0 +1,34 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+DISABLE_APPTRACE= $(POUND_SIGN)
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.spec
+
+$(DISABLE_APPTRACE)install: $(ROOTABILIB)
diff --git a/usr/src/lib/libsmbios/spec/smbios.spec b/usr/src/lib/libsmbios/spec/smbios.spec
new file mode 100644
index 0000000000..3f6c32b542
--- /dev/null
+++ b/usr/src/lib/libsmbios/spec/smbios.spec
@@ -0,0 +1,374 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+data _smb_debug
+version SUNWprivate_1.1
+end
+
+function smbios_bboard_flag_desc
+version SUNWprivate_1.1
+end
+
+function smbios_bboard_flag_name
+version SUNWprivate_1.1
+end
+
+function smbios_bboard_type_desc
+version SUNWprivate_1.1
+end
+
+function smbios_bios_flag_desc
+version SUNWprivate_1.1
+end
+
+function smbios_bios_flag_name
+version SUNWprivate_1.1
+end
+
+function smbios_bios_xb1_desc
+version SUNWprivate_1.1
+end
+
+function smbios_bios_xb1_name
+version SUNWprivate_1.1
+end
+
+function smbios_bios_xb2_desc
+version SUNWprivate_1.1
+end
+
+function smbios_bios_xb2_name
+version SUNWprivate_1.1
+end
+
+function smbios_boot_desc
+version SUNWprivate_1.1
+end
+
+function smbios_buf
+version SUNWprivate_1.1
+end
+
+function smbios_buflen
+version SUNWprivate_1.1
+end
+
+function smbios_bufopen
+version SUNWprivate_1.1
+end
+
+function smbios_cache_assoc_desc
+version SUNWprivate_1.1
+end
+
+function smbios_cache_ctype_desc
+version SUNWprivate_1.1
+end
+
+function smbios_cache_ctype_name
+version SUNWprivate_1.1
+end
+
+function smbios_cache_ecc_desc
+version SUNWprivate_1.1
+end
+
+function smbios_cache_flag_desc
+version SUNWprivate_1.1
+end
+
+function smbios_cache_flag_name
+version SUNWprivate_1.1
+end
+
+function smbios_cache_loc_desc
+version SUNWprivate_1.1
+end
+
+function smbios_cache_logical_desc
+version SUNWprivate_1.1
+end
+
+function smbios_cache_mode_desc
+version SUNWprivate_1.1
+end
+
+function smbios_checksum
+version SUNWprivate_1.1
+end
+
+function smbios_chassis_state_desc
+version SUNWprivate_1.1
+end
+
+function smbios_chassis_type_desc
+version SUNWprivate_1.1
+end
+
+function smbios_close
+version SUNWprivate_1.1
+end
+
+function smbios_errmsg
+version SUNWprivate_1.1
+end
+
+function smbios_errno
+version SUNWprivate_1.1
+end
+
+function smbios_evlog_flag_desc
+version SUNWprivate_1.1
+end
+
+function smbios_evlog_flag_name
+version SUNWprivate_1.1
+end
+
+function smbios_evlog_format_desc
+version SUNWprivate_1.1
+end
+
+function smbios_evlog_method_desc
+version SUNWprivate_1.1
+end
+
+function smbios_fdopen
+version SUNWprivate_1.1
+end
+
+function smbios_hwsec_desc
+version SUNWprivate_1.1
+end
+
+function smbios_info_bboard
+version SUNWprivate_1.1
+end
+
+function smbios_info_bios
+version SUNWprivate_1.1
+end
+
+function smbios_info_boot
+version SUNWprivate_1.1
+end
+
+function smbios_info_cache
+version SUNWprivate_1.1
+end
+
+function smbios_info_chassis
+version SUNWprivate_1.1
+end
+
+function smbios_info_common
+version SUNWprivate_1.1
+end
+
+function smbios_info_eventlog
+version SUNWprivate_1.1
+end
+
+function smbios_info_hwsec
+version SUNWprivate_1.1
+end
+
+function smbios_info_ipmi
+version SUNWprivate_1.1
+end
+
+function smbios_info_lang
+version SUNWprivate_1.1
+end
+
+function smbios_info_memarray
+version SUNWprivate_1.1
+end
+
+function smbios_info_memarrmap
+version SUNWprivate_1.1
+end
+
+function smbios_info_memdevice
+version SUNWprivate_1.1
+end
+
+function smbios_info_memdevmap
+version SUNWprivate_1.1
+end
+
+function smbios_info_obdevs
+version SUNWprivate_1.1
+end
+
+function smbios_info_port
+version SUNWprivate_1.1
+end
+
+function smbios_info_processor
+version SUNWprivate_1.1
+end
+
+function smbios_info_slot
+version SUNWprivate_1.1
+end
+
+function smbios_info_smbios
+version SUNWprivate_1.1
+end
+
+function smbios_info_strtab
+version SUNWprivate_1.1
+end
+
+function smbios_info_system
+version SUNWprivate_1.1
+end
+
+function smbios_ipmi_flag_desc
+version SUNWprivate_1.1
+end
+
+function smbios_ipmi_flag_name
+version SUNWprivate_1.1
+end
+
+function smbios_ipmi_type_desc
+version SUNWprivate_1.1
+end
+
+function smbios_iter
+version SUNWprivate_1.1
+end
+
+function smbios_lookup_id
+version SUNWprivate_1.1
+end
+
+function smbios_memarray_loc_desc
+version SUNWprivate_1.1
+end
+
+function smbios_memarray_use_desc
+version SUNWprivate_1.1
+end
+
+function smbios_memarray_ecc_desc
+version SUNWprivate_1.1
+end
+
+function smbios_memdevice_flag_desc
+version SUNWprivate_1.1
+end
+
+function smbios_memdevice_flag_name
+version SUNWprivate_1.1
+end
+
+function smbios_memdevice_form_desc
+version SUNWprivate_1.1
+end
+
+function smbios_memdevice_type_desc
+version SUNWprivate_1.1
+end
+
+function smbios_open
+version SUNWprivate_1.1
+end
+
+function smbios_port_conn_desc
+version SUNWprivate_1.1
+end
+
+function smbios_port_type_desc
+version SUNWprivate_1.1
+end
+
+function smbios_processor_family_desc
+version SUNWprivate_1.1
+end
+
+function smbios_processor_status_desc
+version SUNWprivate_1.1
+end
+
+function smbios_processor_type_desc
+version SUNWprivate_1.1
+end
+
+function smbios_processor_upgrade_desc
+version SUNWprivate_1.1
+end
+
+function smbios_slot_ch1_desc
+version SUNWprivate_1.1
+end
+
+function smbios_slot_ch1_name
+version SUNWprivate_1.1
+end
+
+function smbios_slot_ch2_desc
+version SUNWprivate_1.1
+end
+
+function smbios_slot_ch2_name
+version SUNWprivate_1.1
+end
+
+function smbios_slot_length_desc
+version SUNWprivate_1.1
+end
+
+function smbios_slot_type_desc
+version SUNWprivate_1.1
+end
+
+function smbios_slot_usage_desc
+version SUNWprivate_1.1
+end
+
+function smbios_slot_width_desc
+version SUNWprivate_1.1
+end
+
+function smbios_system_wakeup_desc
+version SUNWprivate_1.1
+end
+
+function smbios_type_desc
+version SUNWprivate_1.1
+end
+
+function smbios_type_name
+version SUNWprivate_1.1
+end
+
+function smbios_write
+version SUNWprivate_1.1
+end
diff --git a/usr/src/lib/libsmbios/spec/sparc/Makefile b/usr/src/lib/libsmbios/spec/sparc/Makefile
new file mode 100644
index 0000000000..375f0ff614
--- /dev/null
+++ b/usr/src/lib/libsmbios/spec/sparc/Makefile
@@ -0,0 +1,34 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+DISABLE_APPTRACE= $(POUND_SIGN)
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.spec
+
+$(DISABLE_APPTRACE)install: $(ROOTABILIB)
diff --git a/usr/src/lib/libsmbios/spec/sparcv9/Makefile b/usr/src/lib/libsmbios/spec/sparcv9/Makefile
new file mode 100644
index 0000000000..ef98bd8314
--- /dev/null
+++ b/usr/src/lib/libsmbios/spec/sparcv9/Makefile
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+DISABLE_APPTRACE= $(POUND_SIGN)
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
+
+$(DISABLE_APPTRACE)install: $(ROOTABILIB64)
diff --git a/usr/src/lib/libsmbios/spec/versions b/usr/src/lib/libsmbios/spec/versions
new file mode 100644
index 0000000000..43aa0fe433
--- /dev/null
+++ b/usr/src/lib/libsmbios/spec/versions
@@ -0,0 +1,42 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+i386 {
+ SUNWprivate_1.1;
+}
+
+amd64 {
+ SUNWprivate_1.1;
+}
+
+sparc {
+ SUNWprivate_1.1;
+}
+
+sparcv9 {
+ SUNWprivate_1.1;
+}
diff --git a/usr/src/pkgdefs/SUNWarc/prototype_com b/usr/src/pkgdefs/SUNWarc/prototype_com
index 2a0981a573..ec3786391a 100644
--- a/usr/src/pkgdefs/SUNWarc/prototype_com
+++ b/usr/src/pkgdefs/SUNWarc/prototype_com
@@ -174,6 +174,8 @@ s none usr/lib/llib-lsendfile=../../lib/llib-lsendfile
s none usr/lib/llib-lsendfile.ln=../../lib/llib-lsendfile.ln
f none usr/lib/llib-lsldap.ln 644 root bin
f none usr/lib/llib-lsldap 644 root bin
+f none usr/lib/llib-lsmbios 644 root bin
+f none usr/lib/llib-lsmbios.ln 644 root bin
s none usr/lib/llib-lsocket=../../lib/llib-lsocket
s none usr/lib/llib-lsocket.ln=../../lib/llib-lsocket.ln
f none usr/lib/llib-lssagent 644 root bin
diff --git a/usr/src/pkgdefs/SUNWarc/prototype_i386 b/usr/src/pkgdefs/SUNWarc/prototype_i386
index 39200958b0..2e43c80892 100644
--- a/usr/src/pkgdefs/SUNWarc/prototype_i386
+++ b/usr/src/pkgdefs/SUNWarc/prototype_i386
@@ -20,7 +20,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -127,6 +127,7 @@ s none usr/lib/amd64/llib-lsec.ln=../../../lib/amd64/llib-lsec.ln
s none usr/lib/amd64/llib-lsecdb.ln=../../../lib/amd64/llib-lsecdb.ln
s none usr/lib/amd64/llib-lsendfile.ln=../../../lib/amd64/llib-lsendfile.ln
f none usr/lib/amd64/llib-lsldap.ln 644 root bin
+f none usr/lib/amd64/llib-lsmbios.ln 644 root bin
s none usr/lib/amd64/llib-lsocket.ln=../../../lib/amd64/llib-lsocket.ln
f none usr/lib/amd64/llib-lssagent.ln 644 root bin
f none usr/lib/amd64/llib-lssasnmp.ln 644 root bin
diff --git a/usr/src/pkgdefs/SUNWarc/prototype_sparc b/usr/src/pkgdefs/SUNWarc/prototype_sparc
index cc0ef01eda..1829e00669 100644
--- a/usr/src/pkgdefs/SUNWarc/prototype_sparc
+++ b/usr/src/pkgdefs/SUNWarc/prototype_sparc
@@ -20,7 +20,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -122,6 +122,7 @@ s none usr/lib/sparcv9/llib-lsec.ln=../../../lib/sparcv9/llib-lsec.ln
s none usr/lib/sparcv9/llib-lsecdb.ln=../../../lib/sparcv9/llib-lsecdb.ln
s none usr/lib/sparcv9/llib-lsendfile.ln=../../../lib/sparcv9/llib-lsendfile.ln
f none usr/lib/sparcv9/llib-lsldap.ln 644 root bin
+f none usr/lib/sparcv9/llib-lsmbios.ln 644 root bin
s none usr/lib/sparcv9/llib-lsocket.ln=../../../lib/sparcv9/llib-lsocket.ln
f none usr/lib/sparcv9/llib-lssagent.ln 644 root bin
f none usr/lib/sparcv9/llib-lssasnmp.ln 644 root bin
diff --git a/usr/src/pkgdefs/SUNWckr/prototype_i386 b/usr/src/pkgdefs/SUNWckr/prototype_i386
index a7041ad90e..ab3c2d6ab7 100644
--- a/usr/src/pkgdefs/SUNWckr/prototype_i386
+++ b/usr/src/pkgdefs/SUNWckr/prototype_i386
@@ -108,6 +108,8 @@ f none kernel/drv/scsi_vhci 755 root sys
f none kernel/drv/sctp 755 root sys
f none kernel/drv/sctp6 755 root sys
f none kernel/drv/sgen 755 root sys
+f none kernel/drv/smbios 755 root sys
+f none kernel/drv/smbios.conf 644 root sys
f none kernel/drv/spdsock 755 root sys
f none kernel/drv/st 755 root sys
f none kernel/drv/sy 755 root sys
@@ -271,6 +273,7 @@ f none kernel/drv/amd64/sctp 755 root sys
f none kernel/drv/amd64/sctp6 755 root sys
f none kernel/drv/amd64/sd 755 root sys
f none kernel/drv/amd64/sgen 755 root sys
+f none kernel/drv/amd64/smbios 755 root sys
f none kernel/drv/amd64/spdsock 755 root sys
f none kernel/drv/amd64/st 755 root sys
f none kernel/drv/amd64/sy 755 root sys
diff --git a/usr/src/pkgdefs/SUNWcsl/prototype_com b/usr/src/pkgdefs/SUNWcsl/prototype_com
index 4b2953e8d4..b89848b21c 100644
--- a/usr/src/pkgdefs/SUNWcsl/prototype_com
+++ b/usr/src/pkgdefs/SUNWcsl/prototype_com
@@ -224,10 +224,12 @@ s none usr/lib/libsec.so=../../lib/libsec.so.1
s none usr/lib/libsec.so.1=../../lib/libsec.so.1
s none usr/lib/libsecdb.so=../../lib/libsecdb.so.1
s none usr/lib/libsecdb.so.1=../../lib/libsecdb.so.1
-s none usr/lib/libsldap.so=libsldap.so.1
-f none usr/lib/libsldap.so.1 755 root bin
s none usr/lib/libsendfile.so=../../lib/libsendfile.so.1
s none usr/lib/libsendfile.so.1=../../lib/libsendfile.so.1
+s none usr/lib/libsldap.so=libsldap.so.1
+f none usr/lib/libsldap.so.1 755 root bin
+s none usr/lib/libsmbios.so=libsmbios.so.1
+f none usr/lib/libsmbios.so.1 755 root bin
s none usr/lib/libsocket.so=../../lib/libsocket.so.1
s none usr/lib/libsocket.so.1=../../lib/libsocket.so.1
s none usr/lib/libsys.so=./libsys.so.1
diff --git a/usr/src/pkgdefs/SUNWcsl/prototype_i386 b/usr/src/pkgdefs/SUNWcsl/prototype_i386
index abda5832d0..360d8bde2d 100644
--- a/usr/src/pkgdefs/SUNWcsl/prototype_i386
+++ b/usr/src/pkgdefs/SUNWcsl/prototype_i386
@@ -280,10 +280,12 @@ s none usr/lib/amd64/libsec.so.1=../../../lib/amd64/libsec.so.1
s none usr/lib/amd64/libsec.so=../../../lib/amd64/libsec.so.1
s none usr/lib/amd64/libsecdb.so.1=../../../lib/amd64/libsecdb.so.1
s none usr/lib/amd64/libsecdb.so=../../../lib/amd64/libsecdb.so.1
-f none usr/lib/amd64/libsldap.so.1 755 root bin
-s none usr/lib/amd64/libsldap.so=libsldap.so.1
s none usr/lib/amd64/libsendfile.so.1=../../../lib/amd64/libsendfile.so.1
s none usr/lib/amd64/libsendfile.so=../../../lib/amd64/libsendfile.so.1
+s none usr/lib/amd64/libsldap.so=libsldap.so.1
+f none usr/lib/amd64/libsldap.so.1 755 root bin
+s none usr/lib/amd64/libsmbios.so=libsmbios.so.1
+f none usr/lib/amd64/libsmbios.so.1 755 root bin
s none usr/lib/amd64/libsocket.so.1=../../../lib/amd64/libsocket.so.1
s none usr/lib/amd64/libsocket.so=../../../lib/amd64/libsocket.so.1
s none usr/lib/amd64/libsysevent.so=../../../lib/amd64/libsysevent.so.1
diff --git a/usr/src/pkgdefs/SUNWcsl/prototype_sparc b/usr/src/pkgdefs/SUNWcsl/prototype_sparc
index c6eb2ca33d..b0b1dcfe81 100644
--- a/usr/src/pkgdefs/SUNWcsl/prototype_sparc
+++ b/usr/src/pkgdefs/SUNWcsl/prototype_sparc
@@ -275,10 +275,12 @@ s none usr/lib/sparcv9/libsec.so.1=../../../lib/sparcv9/libsec.so.1
s none usr/lib/sparcv9/libsec.so=../../../lib/sparcv9/libsec.so.1
s none usr/lib/sparcv9/libsecdb.so.1=../../../lib/sparcv9/libsecdb.so.1
s none usr/lib/sparcv9/libsecdb.so=../../../lib/sparcv9/libsecdb.so.1
-f none usr/lib/sparcv9/libsldap.so.1 755 root bin
-s none usr/lib/sparcv9/libsldap.so=libsldap.so.1
s none usr/lib/sparcv9/libsendfile.so.1=../../../lib/sparcv9/libsendfile.so.1
s none usr/lib/sparcv9/libsendfile.so=../../../lib/sparcv9/libsendfile.so.1
+f none usr/lib/sparcv9/libsldap.so.1 755 root bin
+s none usr/lib/sparcv9/libsldap.so=libsldap.so.1
+f none usr/lib/sparcv9/libsmbios.so.1 755 root bin
+s none usr/lib/sparcv9/libsmbios.so=libsmbios.so.1
s none usr/lib/sparcv9/libsocket.so.1=../../../lib/sparcv9/libsocket.so.1
s none usr/lib/sparcv9/libsocket.so=../../../lib/sparcv9/libsocket.so.1
s none usr/lib/sparcv9/libsysevent.so.1=../../../lib/sparcv9/libsysevent.so.1
diff --git a/usr/src/pkgdefs/SUNWcsu/prototype_com b/usr/src/pkgdefs/SUNWcsu/prototype_com
index 1e7210d9a3..6b31d188e9 100644
--- a/usr/src/pkgdefs/SUNWcsu/prototype_com
+++ b/usr/src/pkgdefs/SUNWcsu/prototype_com
@@ -807,6 +807,7 @@ f none usr/sbin/setmnt 555 root bin
f none usr/sbin/share 555 root bin
f none usr/sbin/shareall 555 root bin
f none usr/sbin/shutdown 755 root sys
+f none usr/sbin/smbios 555 root bin
f none usr/sbin/strace 555 root sys
f none usr/sbin/strclean 555 root sys
f none usr/sbin/strerr 555 root sys
diff --git a/usr/src/pkgdefs/SUNWhea/prototype_com b/usr/src/pkgdefs/SUNWhea/prototype_com
index afc3165640..e29100ceb7 100644
--- a/usr/src/pkgdefs/SUNWhea/prototype_com
+++ b/usr/src/pkgdefs/SUNWhea/prototype_com
@@ -464,6 +464,7 @@ f none usr/include/sgtty.h 644 root bin
f none usr/include/shadow.h 644 root bin
f none usr/include/siginfo.h 644 root bin
f none usr/include/signal.h 644 root bin
+f none usr/include/smbios.h 644 root bin
f none usr/include/spawn.h 644 root bin
f none usr/include/stdarg.h 644 root bin
f none usr/include/stdbool.h 644 root bin
@@ -1010,6 +1011,8 @@ f none usr/include/sys/shm_impl.h 644 root bin
f none usr/include/sys/siginfo.h 644 root bin
f none usr/include/sys/signal.h 644 root bin
f none usr/include/sys/sleepq.h 644 root bin
+f none usr/include/sys/smbios.h 644 root bin
+f none usr/include/sys/smbios_impl.h 644 root bin
f none usr/include/sys/smedia.h 644 root bin
f none usr/include/sys/sobject.h 644 root bin
f none usr/include/sys/socket.h 644 root bin
diff --git a/usr/src/pkgdefs/SUNWkvm.i/prototype_com b/usr/src/pkgdefs/SUNWkvm.i/prototype_com
index b9d15d8323..c2e8d5e9f7 100644
--- a/usr/src/pkgdefs/SUNWkvm.i/prototype_com
+++ b/usr/src/pkgdefs/SUNWkvm.i/prototype_com
@@ -48,6 +48,7 @@ d none usr/platform 755 root sys
d none usr/platform/i86pc 755 root sys
d none usr/platform/i86pc/sbin 755 root bin
f none usr/platform/i86pc/sbin/eeprom 2555 root sys
+f none usr/platform/i86pc/sbin/prtdiag 555 root sys
d none usr/platform/i86pc/lib 755 root bin
#
# make the links to other machine types
diff --git a/usr/src/pkgdefs/common_files/i.minorperm_i386 b/usr/src/pkgdefs/common_files/i.minorperm_i386
index ccb5ab3af7..2048234fa3 100644
--- a/usr/src/pkgdefs/common_files/i.minorperm_i386
+++ b/usr/src/pkgdefs/common_files/i.minorperm_i386
@@ -219,6 +219,7 @@ bge:*
bmc:bmc
dld:*
aggr:*
+smbios:smbios
EOF
}
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index 18603b6b5f..550b7b2ab0 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -1186,6 +1186,8 @@ CTF_OBJS += ctf_create.o ctf_decl.o ctf_error.o ctf_hash.o ctf_labels.o \
ZMOD_OBJS += adler32.o infblock.o infcodes.o inffast.o inflate.o inftrees.o \
infutil.o zutil.o zmod.o
+SMBIOS_OBJS += smb_error.o smb_info.o smb_open.o smb_subr.o smb_dev.o
+
RPCIB_OBJS += rpcib.o
KMDB_OBJS += kdrv.o
diff --git a/usr/src/uts/common/Makefile.rules b/usr/src/uts/common/Makefile.rules
index 989e199b15..41090da940 100644
--- a/usr/src/uts/common/Makefile.rules
+++ b/usr/src/uts/common/Makefile.rules
@@ -94,6 +94,10 @@ $(OBJS_DIR)/%.o: $(COMMONBASE)/crypto/des/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
+$(OBJS_DIR)/%.o: $(COMMONBASE)/smbios/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
$(OBJS_DIR)/%.o: $(UTSBASE)/common/des/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
@@ -926,6 +930,9 @@ $(LINTS_DIR)/%.ln: $(COMMONBASE)/devid/%.c
$(LINTS_DIR)/%.ln: $(COMMONBASE)/crypto/des/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
+$(LINTS_DIR)/%.ln: $(COMMONBASE)/smbios/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
$(LINTS_DIR)/%.ln: $(UTSBASE)/common/des/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
diff --git a/usr/src/uts/common/io/smbios.c b/usr/src/uts/common/io/smbios.c
new file mode 100644
index 0000000000..533975e418
--- /dev/null
+++ b/usr/src/uts/common/io/smbios.c
@@ -0,0 +1,331 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * smbios(7D) driver
+ *
+ * This pseudo-driver makes available a snapshot of the system's SMBIOS image
+ * that can be accessed using libsmbios. Clients may access a snapshot using
+ * either read(2) or mmap(2). The driver returns the SMBIOS entry point data
+ * followed by the SMBIOS structure table. The entry point has its 'staddr'
+ * field set to indicate the byte offset of the structure table. The driver
+ * uses the common SMBIOS API defined in <sys/smbios.h> to access the image.
+ *
+ * At present, the kernel takes a single snapshot of SMBIOS at boot time and
+ * stores a handle for this snapshot in 'ksmbios'. To keep track of driver
+ * opens, we simply compare-and-swap this handle into an 'smb_clones' array.
+ * Future x86 systems may need to support dynamic SMBIOS updates: when that
+ * happens the SMBIOS API can be extended to support reference counting and
+ * handles for different snapshots can be stored in smb_clones[].
+ */
+
+#include <sys/smbios.h>
+#include <sys/sysmacros.h>
+#include <sys/cmn_err.h>
+#include <sys/vmsystm.h>
+#include <vm/seg_vn.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/modctl.h>
+#include <sys/conf.h>
+#include <sys/stat.h>
+
+typedef struct smb_clone {
+ smbios_hdl_t *c_hdl;
+ size_t c_eplen;
+ size_t c_stlen;
+} smb_clone_t;
+
+static dev_info_t *smb_devi;
+static smb_clone_t *smb_clones;
+static int smb_nclones;
+
+/*ARGSUSED*/
+static int
+smb_open(dev_t *dp, int flag, int otyp, cred_t *cred)
+{
+ minor_t c;
+
+ if (ksmbios == NULL)
+ return (ENXIO);
+
+ /*
+ * Locate and reserve a clone structure. We skip clone 0 as that is
+ * the real minor number, and we assign a new minor to each clone.
+ */
+ for (c = 1; c < smb_nclones; c++) {
+ if (casptr(&smb_clones[c].c_hdl, NULL, ksmbios) == NULL)
+ break;
+ }
+
+ if (c >= smb_nclones)
+ return (EAGAIN);
+
+ smb_clones[c].c_eplen = P2ROUNDUP(sizeof (smbios_entry_t), 16);
+ smb_clones[c].c_stlen = smbios_buflen(smb_clones[c].c_hdl);
+
+ *dp = makedevice(getemajor(*dp), c);
+
+ (void) ddi_prop_update_int(*dp, smb_devi, "size",
+ smb_clones[c].c_eplen + smb_clones[c].c_stlen);
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+smb_close(dev_t dev, int flag, int otyp, cred_t *cred)
+{
+ (void) ddi_prop_remove(dev, smb_devi, "size");
+ smb_clones[getminor(dev)].c_hdl = NULL;
+ return (0);
+}
+
+/*
+ * Common code to copy out the SMBIOS snapshot used for both read and mmap.
+ * The caller must validate uio_offset for us since semantics differ there.
+ * The copy is done in two stages, either of which can be skipped based on the
+ * offset and length: first we copy the entry point, with 'staddr' recalculated
+ * to indicate the offset of the data buffer, and second we copy the table.
+ */
+static int
+smb_uiomove(smb_clone_t *cp, uio_t *uio)
+{
+ off_t off = uio->uio_offset;
+ size_t len = uio->uio_resid;
+ int err = 0;
+
+ if (off + len > cp->c_eplen + cp->c_stlen)
+ len = cp->c_eplen + cp->c_stlen - off;
+
+ if (off < cp->c_eplen) {
+ smbios_entry_t *ep = kmem_zalloc(cp->c_eplen, KM_SLEEP);
+ size_t eprlen = MIN(len, cp->c_eplen - off);
+
+ smbios_info_smbios(cp->c_hdl, ep);
+ ep->smbe_staddr = (uint32_t)cp->c_eplen;
+ smbios_checksum(cp->c_hdl, ep);
+
+ err = uiomove((char *)ep + off, eprlen, UIO_READ, uio);
+ kmem_free(ep, cp->c_eplen);
+
+ off += eprlen;
+ len -= eprlen;
+ }
+
+ if (err == 0 && off >= cp->c_eplen) {
+ char *buf = (char *)smbios_buf(cp->c_hdl);
+ size_t bufoff = off - cp->c_eplen;
+
+ err = uiomove(buf + bufoff,
+ MIN(len, cp->c_stlen - bufoff), UIO_READ, uio);
+ }
+
+ return (err);
+}
+
+/*ARGSUSED*/
+static int
+smb_read(dev_t dev, uio_t *uio, cred_t *cred)
+{
+ smb_clone_t *cp = &smb_clones[getminor(dev)];
+
+ if (uio->uio_offset < 0 ||
+ uio->uio_offset >= cp->c_eplen + cp->c_stlen)
+ return (0);
+
+ return (smb_uiomove(cp, uio));
+}
+
+/*ARGSUSED*/
+static int
+smb_segmap(dev_t dev, off_t off, struct as *as, caddr_t *addrp, off_t len,
+ uint_t prot, uint_t maxprot, uint_t flags, cred_t *cred)
+{
+ smb_clone_t *cp = &smb_clones[getminor(dev)];
+
+ size_t alen = P2ROUNDUP(len, PAGESIZE);
+ caddr_t addr;
+
+ iovec_t iov;
+ uio_t uio;
+ int err;
+
+ if (len <= 0 || (flags & MAP_FIXED))
+ return (EINVAL);
+
+ if ((prot & PROT_WRITE) && (flags & MAP_SHARED))
+ return (EACCES);
+
+ if (off < 0 || off + len < off || off + len > cp->c_eplen + cp->c_stlen)
+ return (ENXIO);
+
+ as_rangelock(as);
+ map_addr(&addr, alen, 0, 1, 0);
+
+ if (addr != NULL)
+ err = as_map(as, addr, alen, segvn_create, zfod_argsp);
+ else
+ err = ENOMEM;
+
+ as_rangeunlock(as);
+ *addrp = addr;
+
+ if (err != 0)
+ return (err);
+
+ iov.iov_base = addr;
+ iov.iov_len = len;
+
+ bzero(&uio, sizeof (uio_t));
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = off;
+ uio.uio_segflg = UIO_USERSPACE;
+ uio.uio_extflg = UIO_COPY_DEFAULT;
+ uio.uio_resid = len;
+
+ if ((err = smb_uiomove(cp, &uio)) != 0)
+ (void) as_unmap(as, addr, alen);
+
+ return (err);
+}
+
+/*ARGSUSED*/
+static int
+smb_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
+{
+ switch (infocmd) {
+ case DDI_INFO_DEVT2DEVINFO:
+ *result = smb_devi;
+ return (DDI_SUCCESS);
+ case DDI_INFO_DEVT2INSTANCE:
+ *result = 0;
+ return (DDI_SUCCESS);
+ }
+ return (DDI_FAILURE);
+}
+
+static int
+smb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
+{
+ if (cmd != DDI_ATTACH)
+ return (DDI_FAILURE);
+
+ if (ddi_create_minor_node(devi, "smbios",
+ S_IFCHR, 0, DDI_PSEUDO, 0) == DDI_FAILURE) {
+ ddi_remove_minor_node(devi, NULL);
+ return (DDI_FAILURE);
+ }
+
+ smb_devi = devi;
+ return (DDI_SUCCESS);
+}
+
+static int
+smb_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
+{
+ if (cmd != DDI_DETACH)
+ return (DDI_FAILURE);
+
+ ddi_remove_minor_node(devi, NULL);
+ return (DDI_SUCCESS);
+}
+
+static struct cb_ops smb_cb_ops = {
+ smb_open, /* open */
+ smb_close, /* close */
+ nodev, /* strategy */
+ nodev, /* print */
+ nodev, /* dump */
+ smb_read, /* read */
+ nodev, /* write */
+ nodev, /* ioctl */
+ nodev, /* devmap */
+ nodev, /* mmap */
+ smb_segmap, /* segmap */
+ nochpoll, /* poll */
+ ddi_prop_op, /* prop_op */
+ NULL, /* streamtab */
+ D_NEW | D_MP /* flags */
+};
+
+static struct dev_ops smb_ops = {
+ DEVO_REV, /* rev */
+ 0, /* refcnt */
+ smb_info, /* info */
+ nulldev, /* identify */
+ nulldev, /* probe */
+ smb_attach, /* attach */
+ smb_detach, /* detach */
+ nodev, /* reset */
+ &smb_cb_ops, /* cb ops */
+ NULL /* bus ops */
+};
+
+static struct modldrv modldrv = {
+ &mod_driverops, "System Management BIOS driver", &smb_ops,
+};
+
+static struct modlinkage modlinkage = {
+ MODREV_1, { (void *)&modldrv }
+};
+
+int
+_init(void)
+{
+ int err;
+
+ if (smb_nclones <= 0)
+ smb_nclones = maxusers;
+
+ smb_clones = kmem_zalloc(sizeof (smb_clone_t) * smb_nclones, KM_SLEEP);
+
+ if ((err = mod_install(&modlinkage)) != 0)
+ kmem_free(smb_clones, sizeof (smb_clone_t) * smb_nclones);
+
+ return (err);
+}
+
+int
+_fini(void)
+{
+ int err;
+
+ if ((err = mod_remove(&modlinkage)) == 0)
+ kmem_free(smb_clones, sizeof (smb_clone_t) * smb_nclones);
+
+ return (err);
+}
+
+int
+_info(struct modinfo *mip)
+{
+ return (mod_info(&modlinkage, mip));
+}
diff --git a/usr/src/uts/common/io/smbios.conf b/usr/src/uts/common/io/smbios.conf
new file mode 100644
index 0000000000..9f6f84271a
--- /dev/null
+++ b/usr/src/uts/common/io/smbios.conf
@@ -0,0 +1,29 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+name="smbios" parent="pseudo" instance=0;
diff --git a/usr/src/uts/common/os/smb_subr.c b/usr/src/uts/common/os/smb_subr.c
new file mode 100644
index 0000000000..6084676b17
--- /dev/null
+++ b/usr/src/uts/common/os/smb_subr.c
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/smbios_impl.h>
+#include <sys/cmn_err.h>
+#include <sys/varargs.h>
+#include <sys/systm.h>
+#include <sys/kmem.h>
+
+/*ARGSUSED*/
+const char *
+smb_strerror(int err)
+{
+ return (NULL);
+}
+
+void *
+smb_alloc(size_t len)
+{
+ return (kmem_alloc(len, KM_SLEEP));
+}
+
+void *
+smb_zalloc(size_t len)
+{
+ return (kmem_zalloc(len, KM_SLEEP));
+}
+
+void
+smb_free(void *buf, size_t len)
+{
+ kmem_free(buf, len);
+}
+
+/*PRINTFLIKE2*/
+void
+smb_dprintf(smbios_hdl_t *shp, const char *format, ...)
+{
+ va_list ap;
+
+ if (!(shp->sh_flags & SMB_FL_DEBUG))
+ return;
+
+ va_start(ap, format);
+ vcmn_err(CE_CONT, format, ap);
+ va_end(ap);
+}
diff --git a/usr/src/uts/common/sys/Makefile b/usr/src/uts/common/sys/Makefile
index 259ceadd6d..e0b6d579b0 100644
--- a/usr/src/uts/common/sys/Makefile
+++ b/usr/src/uts/common/sys/Makefile
@@ -418,6 +418,8 @@ CHKHDRS= \
siginfo.h \
signal.h \
sleepq.h \
+ smbios.h \
+ smbios_impl.h \
sobject.h \
socket.h \
socket_impl.h \
diff --git a/usr/src/uts/common/sys/smbios.h b/usr/src/uts/common/sys/smbios.h
new file mode 100644
index 0000000000..7333c906ea
--- /dev/null
+++ b/usr/src/uts/common/sys/smbios.h
@@ -0,0 +1,1183 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * This header file defines the interfaces available from the SMBIOS access
+ * library, libsmbios, and an equivalent kernel module. This API can be used
+ * to access DMTF SMBIOS data from a device, file, or raw memory buffer.
+ * This is NOT yet a public interface, although it may eventually become one in
+ * the fullness of time after we gain more experience with the interfaces.
+ *
+ * In the meantime, be aware that any program linked with this API in this
+ * release of Solaris is almost guaranteed to break in the next release.
+ *
+ * In short, do not user this header file or these routines for any purpose.
+ */
+
+#ifndef _SYS_SMBIOS_H
+#define _SYS_SMBIOS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * SMBIOS Structure Table Entry Point. See DSP0134 2.1.1 for more information.
+ * The structure table entry point is located by searching for the anchor.
+ */
+typedef struct smbios_entry {
+ char smbe_eanchor[4]; /* anchor tag (SMB_ENTRY_EANCHOR) */
+ uint8_t smbe_ecksum; /* checksum of entry point structure */
+ uint8_t smbe_elen; /* length in bytes of entry point */
+ uint8_t smbe_major; /* major version of the SMBIOS spec */
+ uint8_t smbe_minor; /* minor version of the SMBIOS spec */
+ uint16_t smbe_maxssize; /* maximum size in bytes of a struct */
+ uint8_t smbe_revision; /* entry point structure revision */
+ uint8_t smbe_format[5]; /* entry point revision-specific data */
+ char smbe_ianchor[5]; /* intermed. tag (SMB_ENTRY_IANCHOR) */
+ uint8_t smbe_icksum; /* intermed. checksum */
+ uint16_t smbe_stlen; /* length in bytes of structure table */
+ uint32_t smbe_staddr; /* physical addr of structure table */
+ uint16_t smbe_stnum; /* number of structure table entries */
+ uint8_t smbe_bcdrev; /* BCD value representing DMI version */
+} smbios_entry_t;
+
+#define SMB_ENTRY_EANCHOR "_SM_" /* structure table entry point anchor */
+#define SMB_ENTRY_EANCHORLEN 4 /* length of entry point anchor */
+#define SMB_ENTRY_IANCHOR "_DMI_" /* intermediate anchor string */
+#define SMB_ENTRY_IANCHORLEN 5 /* length of intermediate anchor */
+
+/*
+ * Structure type codes. The comments next to each type include an (R) note to
+ * indicate a structure that is required as of SMBIOS v2.3 and an (O) note to
+ * indicate a structure that is obsolete as of SMBIOS v2.3.
+ */
+#define SMB_TYPE_BIOS 0 /* BIOS information (R) */
+#define SMB_TYPE_SYSTEM 1 /* system information (R) */
+#define SMB_TYPE_BASEBOARD 2 /* base board */
+#define SMB_TYPE_CHASSIS 3 /* system enclosure or chassis (R) */
+#define SMB_TYPE_PROCESSOR 4 /* processor (R) */
+#define SMB_TYPE_MEMCTL 5 /* memory controller (O) */
+#define SMB_TYPE_MEMMOD 6 /* memory module (O) */
+#define SMB_TYPE_CACHE 7 /* processor cache (R) */
+#define SMB_TYPE_PORT 8 /* port connector */
+#define SMB_TYPE_SLOT 9 /* upgradeable system slot (R) */
+#define SMB_TYPE_OBDEVS 10 /* on-board devices */
+#define SMB_TYPE_OEMSTR 11 /* OEM string table */
+#define SMB_TYPE_SYSCONFSTR 12 /* system configuration string table */
+#define SMB_TYPE_LANG 13 /* BIOS language information */
+#define SMB_TYPE_GROUP 14 /* group associations */
+#define SMB_TYPE_EVENTLOG 15 /* system event log */
+#define SMB_TYPE_MEMARRAY 16 /* physical memory array (R) */
+#define SMB_TYPE_MEMDEVICE 17 /* memory device (R) */
+#define SMB_TYPE_MEMERR32 18 /* 32-bit memory error information */
+#define SMB_TYPE_MEMARRAYMAP 19 /* memory array mapped address (R) */
+#define SMB_TYPE_MEMDEVICEMAP 20 /* memory device mapped address (R) */
+#define SMB_TYPE_POINTDEV 21 /* built-in pointing device */
+#define SMB_TYPE_BATTERY 22 /* portable battery */
+#define SMB_TYPE_RESET 23 /* system reset settings */
+#define SMB_TYPE_SECURITY 24 /* hardware security settings */
+#define SMB_TYPE_POWERCTL 25 /* system power controls */
+#define SMB_TYPE_VPROBE 26 /* voltage probe */
+#define SMB_TYPE_COOLDEV 27 /* cooling device */
+#define SMB_TYPE_TPROBE 28 /* temperature probe */
+#define SMB_TYPE_IPROBE 29 /* current probe */
+#define SMB_TYPE_OOBRA 30 /* out-of-band remote access facility */
+#define SMB_TYPE_BIS 31 /* boot integrity services */
+#define SMB_TYPE_BOOT 32 /* system boot status (R) */
+#define SMB_TYPE_MEMERR64 33 /* 64-bit memory error information */
+#define SMB_TYPE_MGMTDEV 34 /* management device */
+#define SMB_TYPE_MGMTDEVCP 35 /* management device component */
+#define SMB_TYPE_MGMTDEVDATA 36 /* management device threshold data */
+#define SMB_TYPE_MEMCHAN 37 /* memory channel */
+#define SMB_TYPE_IPMIDEV 38 /* IPMI device information */
+#define SMB_TYPE_POWERSUP 39 /* system power supply */
+#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 SMB_TYPE_OEM_HI 256 /* end of OEM-specific type range */
+
+/*
+ * SMBIOS Common Information. These structures do not correspond to anything
+ * in the SMBIOS specification, but allow library clients to more easily read
+ * information that is frequently encoded into the various SMBIOS structures.
+ */
+typedef struct smbios_info {
+ const char *smbi_manufacturer; /* manufacturer */
+ const char *smbi_product; /* product name */
+ const char *smbi_version; /* version */
+ const char *smbi_serial; /* serial number */
+ const char *smbi_asset; /* asset tag */
+ const char *smbi_location; /* location tag */
+ const char *smbi_part; /* part number */
+} smbios_info_t;
+
+typedef struct smbios_version {
+ uint8_t smbv_major; /* version major number */
+ uint8_t smbv_minor; /* version minor number */
+} smbios_version_t;
+
+/*
+ * SMBIOS Bios Information. See DSP0134 Section 3.3.1 for more information.
+ * smbb_romsize is converted from the implementation format into bytes.
+ */
+typedef struct smbios_bios {
+ const char *smbb_vendor; /* bios vendor string */
+ const char *smbb_version; /* bios version string */
+ const char *smbb_reldate; /* bios release date */
+ uint32_t smbb_segment; /* bios address segment location */
+ uint32_t smbb_romsize; /* bios rom size in bytes */
+ uint32_t smbb_runsize; /* bios image size in bytes */
+ uint64_t smbb_cflags; /* bios characteristics */
+ const uint8_t *smbb_xcflags; /* bios characteristics extensions */
+ size_t smbb_nxcflags; /* number of smbb_xcflags[] bytes */
+ smbios_version_t smbb_biosv; /* bios version */
+ smbios_version_t smbb_ecfwv; /* bios embedded ctrl f/w version */
+} smbios_bios_t;
+
+#define SMB_BIOSFL_RSV0 0x00000001 /* reserved bit zero */
+#define SMB_BIOSFL_RSV1 0x00000002 /* reserved bit one */
+#define SMB_BIOSFL_UNKNOWN 0x00000004 /* unknown */
+#define SMB_BIOSFL_BCNOTSUP 0x00000008 /* BIOS chars not supported */
+#define SMB_BIOSFL_ISA 0x00000010 /* ISA is supported */
+#define SMB_BIOSFL_MCA 0x00000020 /* MCA is supported */
+#define SMB_BIOSFL_EISA 0x00000040 /* EISA is supported */
+#define SMB_BIOSFL_PCI 0x00000080 /* PCI is supported */
+#define SMB_BIOSFL_PCMCIA 0x00000100 /* PCMCIA is supported */
+#define SMB_BIOSFL_PLUGNPLAY 0x00000200 /* Plug and Play is supported */
+#define SMB_BIOSFL_APM 0x00000400 /* APM is supported */
+#define SMB_BIOSFL_FLASH 0x00000800 /* BIOS is Flash Upgradeable */
+#define SMB_BIOSFL_SHADOW 0x00001000 /* BIOS shadowing is allowed */
+#define SMB_BIOSFL_VLVESA 0x00002000 /* VL-VESA is supported */
+#define SMB_BIOSFL_ESCD 0x00004000 /* ESCD support is available */
+#define SMB_BIOSFL_CDBOOT 0x00008000 /* Boot from CD is supported */
+#define SMB_BIOSFL_SELBOOT 0x00010000 /* Selectable Boot supported */
+#define SMB_BIOSFL_ROMSOCK 0x00020000 /* BIOS ROM is socketed */
+#define SMB_BIOSFL_PCMBOOT 0x00040000 /* Boot from PCMCIA supported */
+#define SMB_BIOSFL_EDD 0x00080000 /* EDD Spec is supported */
+#define SMB_BIOSFL_NEC9800 0x00100000 /* int 0x13 NEC 9800 floppy */
+#define SMB_BIOSFL_TOSHIBA 0x00200000 /* int 0x13 Toshiba floppy */
+#define SMB_BIOSFL_525_360K 0x00400000 /* int 0x13 5.25" 360K floppy */
+#define SMB_BIOSFL_525_12M 0x00800000 /* int 0x13 5.25" 1.2M floppy */
+#define SMB_BIOSFL_35_720K 0x01000000 /* int 0x13 3.5" 720K floppy */
+#define SMB_BIOSFL_35_288M 0x02000000 /* int 0x13 3.5" 2.88M floppy */
+#define SMB_BIOSFL_I5_PRINT 0x04000000 /* int 0x5 print screen svcs */
+#define SMB_BIOSFL_I9_KBD 0x08000000 /* int 0x9 8042 keyboard svcs */
+#define SMB_BIOSFL_I14_SER 0x10000000 /* int 0x14 serial svcs */
+#define SMB_BIOSFL_I17_PRINTER 0x20000000 /* int 0x17 printer svcs */
+#define SMB_BIOSFL_I10_CGA 0x40000000 /* int 0x10 CGA svcs */
+#define SMB_BIOSFL_NEC_PC98 0x80000000 /* NEC PC-98 */
+
+#define SMB_BIOSXB_1 0 /* bios extension byte 1 (3.3.1.2.1) */
+#define SMB_BIOSXB_2 1 /* bios extension byte 2 (3.3.1.2.2) */
+#define SMB_BIOSXB_BIOS_MAJ 2 /* bios major version */
+#define SMB_BIOSXB_BIOS_MIN 3 /* bios minor version */
+#define SMB_BIOSXB_ECFW_MAJ 4 /* extended ctlr f/w major version */
+#define SMB_BIOSXB_ECFW_MIN 5 /* extended ctlr f/w minor version */
+
+#define SMB_BIOSXB1_ACPI 0x01 /* ACPI is supported */
+#define SMB_BIOSXB1_USBL 0x02 /* USB legacy is supported */
+#define SMB_BIOSXB1_AGP 0x04 /* AGP is supported */
+#define SMB_BIOSXB1_I20 0x08 /* I2O boot is supported */
+#define SMB_BIOSXB1_LS120 0x10 /* LS-120 boot is supported */
+#define SMB_BIOSXB1_ATZIP 0x20 /* ATAPI ZIP drive boot is supported */
+#define SMB_BIOSXB1_1394 0x40 /* 1394 boot is supported */
+#define SMB_BIOSXB1_SMBAT 0x80 /* Smart Battery is supported */
+
+#define SMB_BIOSXB2_BBOOT 0x01 /* BIOS Boot Specification supported */
+#define SMB_BIOSXB2_FKNETSVC 0x02 /* F-key Network Svc boot supported */
+#define SMB_BIOSXB2_ETCDIST 0x04 /* Enable Targeted Content Distrib. */
+
+/*
+ * SMBIOS Bios Information. See DSP0134 Section 3.3.2 for more information.
+ * The current set of smbs_wakeup values is defined after the structure.
+ */
+typedef struct smbios_system {
+ const uint8_t *smbs_uuid; /* UUID byte array */
+ uint8_t smbs_uuidlen; /* UUID byte array length */
+ uint8_t smbs_wakeup; /* wake-up event */
+ const char *smbs_sku; /* SKU number */
+ const char *smbs_family; /* family */
+} smbios_system_t;
+
+#define SMB_WAKEUP_RSV0 0x00 /* reserved */
+#define SMB_WAKEUP_OTHER 0x01 /* other */
+#define SMB_WAKEUP_UNKNOWN 0x02 /* unknown */
+#define SMB_WAKEUP_APM 0x03 /* APM timer */
+#define SMB_WAKEUP_MODEM 0x04 /* modem ring */
+#define SMB_WAKEUP_LAN 0x05 /* LAN remote */
+#define SMB_WAKEUP_SWITCH 0x06 /* power switch */
+#define SMB_WAKEUP_PCIPME 0x07 /* PCI PME# */
+#define SMB_WAKEUP_AC 0x08 /* AC power restored */
+
+/*
+ * SMBIOS Base Board description. See DSP0134 Section 3.3.3 for more
+ * information. smbb_flags and smbb_type definitions are below.
+ */
+typedef struct smbios_bboard {
+ id_t smbb_chassis; /* chassis containing this board */
+ uint8_t smbb_flags; /* flags (see below) */
+ uint8_t smbb_type; /* board type (see below) */
+} smbios_bboard_t;
+
+#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_HOTSWAP 0x10 /* board is hot-swappable */
+
+#define SMB_BBT_UNKNOWN 0x1 /* unknown */
+#define SMB_BBT_OTHER 0x2 /* other */
+#define SMB_BBT_SBLADE 0x3 /* server blade */
+#define SMB_BBT_CSWITCH 0x4 /* connectivity switch */
+#define SMB_BBT_SMM 0x5 /* system management module */
+#define SMB_BBT_PROC 0x6 /* processor module */
+#define SMB_BBT_IO 0x7 /* i/o module */
+#define SMB_BBT_MEM 0x8 /* memory module */
+#define SMB_BBT_DAUGHTER 0x9 /* daughterboard */
+#define SMB_BBT_MOTHER 0xA /* motherboard */
+#define SMB_BBT_PROCMEM 0xB /* processor/memory module */
+#define SMB_BBT_PROCIO 0xC /* processor/i/o module */
+#define SMB_BBT_INTER 0xD /* interconnect board */
+
+/*
+ * SMBIOS Chassis description. See DSP0134 Section 3.3.4 for more information.
+ * We move the lock bit of the type field into smbc_lock for easier processing.
+ * NOTE: We do not currently export the contained element data for each chassis
+ * as this seems useless: see DSP0134 3.3.4.4. It can be added if necessary.
+ */
+typedef struct smbios_chassis {
+ 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 */
+} smbios_chassis_t;
+
+#define SMB_CHT_OTHER 0x01 /* other */
+#define SMB_CHT_UNKNOWN 0x02 /* unknown */
+#define SMB_CHT_DESKTOP 0x03 /* desktop */
+#define SMB_CHT_LPDESKTOP 0x04 /* low-profile desktop */
+#define SMB_CHT_PIZZA 0x05 /* pizza box */
+#define SMB_CHT_MINITOWER 0x06 /* mini-tower */
+#define SMB_CHT_TOWER 0x07 /* tower */
+#define SMB_CHT_PORTABLE 0x08 /* portable */
+#define SMB_CHT_LAPTOP 0x09 /* laptop */
+#define SMB_CHT_NOTEBOOK 0x0A /* notebook */
+#define SMB_CHT_HANDHELD 0x0B /* hand-held */
+#define SMB_CHT_DOCK 0x0C /* docking station */
+#define SMB_CHT_ALLIN1 0x0D /* all-in-one */
+#define SMB_CHT_SUBNOTE 0x0E /* sub-notebook */
+#define SMB_CHT_SPACESAVE 0x0F /* space-saving */
+#define SMB_CHT_LUNCHBOX 0x10 /* lunchbox */
+#define SMB_CHT_MAIN 0x11 /* main server chassis */
+#define SMB_CHT_EXPANSION 0x12 /* expansion chassis */
+#define SMB_CHT_SUB 0x13 /* sub-chassis */
+#define SMB_CHT_BUS 0x14 /* bus expansion chassis */
+#define SMB_CHT_PERIPHERAL 0x15 /* peripheral chassis */
+#define SMB_CHT_RAID 0x16 /* raid chassis */
+#define SMB_CHT_RACK 0x17 /* rack mount chassis */
+#define SMB_CHT_SEALED 0x18 /* sealed case pc */
+#define SMB_CHT_MULTI 0x19 /* multi-system chassis */
+
+#define SMB_CHST_OTHER 0x01 /* other */
+#define SMB_CHST_UNKNOWN 0x02 /* unknown */
+#define SMB_CHST_SAFE 0x03 /* safe */
+#define SMB_CHST_WARNING 0x04 /* warning */
+#define SMB_CHST_CRITICAL 0x05 /* critical */
+#define SMB_CHST_NONREC 0x06 /* non-recoverable */
+
+#define SMB_CHSC_OTHER 0x01 /* other */
+#define SMB_CHSC_UNKNOWN 0x02 /* unknown */
+#define SMB_CHSC_NONE 0x03 /* none */
+#define SMB_CHSC_EILOCK 0x04 /* external interface locked out */
+#define SMB_CHSC_EIENAB 0x05 /* external interface enabled */
+
+/*
+ * SMBIOS Processor description. See DSP0134 Section 3.3.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.
+ *
+ * NOTE: Although SMBIOS exports a 64-bit CPUID result, this value should not
+ * be used for any purpose other than BIOS debugging. Solaris itself computes
+ * its own CPUID value and applies knowledge of additional errata and processor
+ * specific CPUID variations, so this value should not be used for anything.
+ */
+typedef struct smbios_processor {
+ uint64_t smbp_cpuid; /* processor cpuid information */
+ uint32_t smbp_family; /* processor family */
+ uint8_t smbp_type; /* processor type (SMB_PRT_*) */
+ uint8_t smbp_voltage; /* voltage (SMB_PRV_*) */
+ uint8_t smbp_status; /* status (SMB_PRS_*) */
+ uint8_t smbp_upgrade; /* upgrade (SMB_PRU_*) */
+ uint32_t smbp_clkspeed; /* external clock speed in MHz */
+ uint32_t smbp_maxspeed; /* maximum speed in MHz */
+ uint32_t smbp_curspeed; /* current speed in MHz */
+ id_t smbp_l1cache; /* L1 cache handle */
+ id_t smbp_l2cache; /* L2 cache handle */
+ id_t smbp_l3cache; /* L3 cache handle */
+} smbios_processor_t;
+
+#define SMB_PRT_OTHER 0x01 /* other */
+#define SMB_PRT_UNKNOWN 0x02 /* unknown */
+#define SMB_PRT_CENTRAL 0x03 /* central processor */
+#define SMB_PRT_MATH 0x04 /* math processor */
+#define SMB_PRT_DSP 0x05 /* DSP processor */
+#define SMB_PRT_VIDEO 0x06 /* video processor */
+
+#define SMB_PRV_LEGACY(v) (!((v) & 0x80)) /* legacy voltage mode */
+#define SMB_PRV_FIXED(v) ((v) & 0x80) /* fixed voltage mode */
+
+#define SMB_PRV_5V 0x01 /* 5V is supported */
+#define SMB_PRV_33V 0x02 /* 3.3V is supported */
+#define SMB_PRV_29V 0x04 /* 2.9V is supported */
+
+#define SMB_PRV_VOLTAGE(v) ((v) & 0x7f)
+
+#define SMB_PRSTATUS_PRESENT(s) ((s) & 0x40) /* socket is populated */
+#define SMB_PRSTATUS_STATUS(s) ((s) & 0x07) /* status (see below) */
+
+#define SMB_PRS_UNKNOWN 0x0 /* unknown */
+#define SMB_PRS_ENABLED 0x1 /* enabled */
+#define SMB_PRS_BDISABLED 0x2 /* disabled in bios user setup */
+#define SMB_PRS_PDISABLED 0x3 /* disabled in bios from post error */
+#define SMB_PRS_IDLE 0x4 /* waiting to be enabled */
+#define SMB_PRS_OTHER 0x7 /* other */
+
+#define SMB_PRU_OTHER 0x01 /* other */
+#define SMB_PRU_UNKNOWN 0x02 /* unknown */
+#define SMB_PRU_DAUGHTER 0x03 /* daughter board */
+#define SMB_PRU_ZIF 0x04 /* ZIF socket */
+#define SMB_PRU_PIGGY 0x05 /* replaceable piggy back */
+#define SMB_PRU_NONE 0x06 /* none */
+#define SMB_PRU_LIF 0x07 /* LIF socket */
+#define SMB_PRU_SLOT1 0x08 /* slot 1 */
+#define SMB_PRU_SLOT2 0x09 /* slot 2 */
+#define SMB_PRU_370PIN 0x0A /* 370-pin socket */
+#define SMB_PRU_SLOTA 0x0B /* slot A */
+#define SMB_PRU_SLOTM 0x0C /* slot M */
+#define SMB_PRU_423 0x0D /* socket 423 */
+#define SMB_PRU_A 0x0E /* socket A (socket 462) */
+#define SMB_PRU_478 0x0F /* socket 478 */
+#define SMB_PRU_754 0x10 /* socket 754 */
+#define SMB_PRU_940 0x11 /* socket 940 */
+
+#define SMB_PRF_OTHER 0x01 /* other */
+#define SMB_PRF_UNKNOWN 0x02 /* unknown */
+#define SMB_PRF_8086 0x03 /* 8086 */
+#define SMB_PRF_80286 0x04 /* 80286 */
+#define SMB_PRF_I386 0x05 /* Intel 386 */
+#define SMB_PRF_I486 0x06 /* Intel 486 */
+#define SMB_PRF_8087 0x07 /* 8087 */
+#define SMB_PRF_80287 0x08 /* 80287 */
+#define SMB_PRF_80387 0x09 /* 80387 */
+#define SMB_PRF_80487 0x0A /* 80487 */
+#define SMB_PRF_PENTIUM 0x0B /* Pentium Family */
+#define SMB_PRF_PENTIUMPRO 0x0C /* Pentium Pro */
+#define SMB_PRF_PENTIUMII 0x0D /* Pentium II */
+#define SMB_PRF_PENTIUM_MMX 0x0E /* Pentium w/ MMX */
+#define SMB_PRF_CELERON 0x0F /* Celeron */
+#define SMB_PRF_PENTIUMII_XEON 0x10 /* Pentium II Xeon */
+#define SMB_PRF_PENTIUMIII 0x11 /* Pentium III */
+#define SMB_PRF_M1 0x12 /* M1 */
+#define SMB_PRF_M2 0x13 /* M2 */
+#define SMB_PRF_DURON 0x18 /* AMD Duron */
+#define SMB_PRF_K5 0x19 /* K5 */
+#define SMB_PRF_K6 0x1A /* K6 */
+#define SMB_PRF_K6_2 0x1B /* K6-2 */
+#define SMB_PRF_K6_3 0x1C /* K6-3 */
+#define SMB_PRF_ATHLON 0x1D /* Athlon */
+#define SMB_PRF_2900 0x1E /* AMD 2900 */
+#define SMB_PRF_K6_2PLUS 0x1F /* K6-2+ */
+#define SMB_PRF_PPC 0x20 /* PowerPC */
+#define SMB_PRF_PPC_601 0x21 /* PowerPC 601 */
+#define SMB_PRF_PPC_603 0x22 /* PowerPC 603 */
+#define SMB_PRF_PPC_603PLUS 0x23 /* PowerPC 603+ */
+#define SMB_PRF_PPC_604 0x24 /* PowerPC 604 */
+#define SMB_PRF_PPC_620 0x25 /* PowerPC 620 */
+#define SMB_PRF_PPC_704 0x26 /* PowerPC x704 */
+#define SMB_PRF_PPC_750 0x27 /* PowerPC 750 */
+#define SMB_PRF_ALPHA 0x30 /* Alpha */
+#define SMB_PRF_ALPHA_21064 0x31 /* Alpha 21064 */
+#define SMB_PRF_ALPHA_21066 0x32 /* Alpha 21066 */
+#define SMB_PRF_ALPHA_21164 0x33 /* Alpha 21164 */
+#define SMB_PRF_ALPHA_21164PC 0x34 /* Alpha 21164PC */
+#define SMB_PRF_ALPHA_21164A 0x35 /* Alpha 21164a */
+#define SMB_PRF_ALPHA_21264 0x36 /* Alpha 21264 */
+#define SMB_PRF_ALPHA_21364 0x37 /* Alpha 21364 */
+#define SMB_PRF_MIPS 0x40 /* MIPS */
+#define SMB_PRF_MIPS_R4000 0x41 /* MIPS R4000 */
+#define SMB_PRF_MIPS_R4200 0x42 /* MIPS R4200 */
+#define SMB_PRF_MIPS_R4400 0x43 /* MIPS R4400 */
+#define SMB_PRF_MIPS_R4600 0x44 /* MIPS R4600 */
+#define SMB_PRF_MIPS_R10000 0x45 /* MIPS R10000 */
+#define SMB_PRF_SPARC 0x50 /* SPARC */
+#define SMB_PRF_SUPERSPARC 0x51 /* SuperSPARC */
+#define SMB_PRF_MICROSPARCII 0x52 /* microSPARC II */
+#define SMB_PRF_MICROSPARCIIep 0x53 /* microSPARC IIep */
+#define SMB_PRF_ULTRASPARC 0x54 /* UltraSPARC */
+#define SMB_PRF_USII 0x55 /* UltraSPARC II */
+#define SMB_PRF_USIIi 0x56 /* UltraSPARC IIi */
+#define SMB_PRF_USIII 0x57 /* UltraSPARC III */
+#define SMB_PRF_USIIIi 0x58 /* UltraSPARC IIIi */
+#define SMB_PRF_68040 0x60 /* 68040 */
+#define SMB_PRF_68XXX 0x61 /* 68XXX */
+#define SMB_PRF_68000 0x62 /* 68000 */
+#define SMB_PRF_68010 0x63 /* 68010 */
+#define SMB_PRF_68020 0x64 /* 68020 */
+#define SMB_PRF_68030 0x65 /* 68030 */
+#define SMB_PRF_HOBBIT 0x70 /* Hobbit */
+#define SMB_PRF_TM5000 0x78 /* Crusoe TM5000 */
+#define SMB_PRF_TM3000 0x79 /* Crusoe TM3000 */
+#define SMB_PRF_TM8000 0x7A /* Efficeon TM8000 */
+#define SMB_PRF_WEITEK 0x80 /* Weitek */
+#define SMB_PRF_ITANIC 0x82 /* Itanium */
+#define SMB_PRF_ATHLON64 0x83 /* Athlon64 */
+#define SMB_PRF_OPTERON 0x84 /* Opteron */
+#define SMB_PRF_PA 0x90 /* PA-RISC */
+#define SMB_PRF_PA8500 0x91 /* PA-RISC 8500 */
+#define SMB_PRF_PA8000 0x92 /* PA-RISC 8000 */
+#define SMB_PRF_PA7300LC 0x93 /* PA-RISC 7300LC */
+#define SMB_PRF_PA7200 0x94 /* PA-RISC 7200 */
+#define SMB_PRF_PA7100LC 0x95 /* PA-RISC 7100LC */
+#define SMB_PRF_PA7100 0x96 /* PA-RISC 7100 */
+#define SMB_PRF_V30 0xA0 /* V30 */
+#define SMB_PRF_PENTIUMIII_XEON 0xB0 /* Pentium III Xeon */
+#define SMB_PRF_PENTIUMIII_SS 0xB1 /* Pentium III with SpeedStep */
+#define SMB_PRF_P4 0xB2 /* Pentium 4 */
+#define SMB_PRF_XEON 0xB3 /* Intel Xeon */
+#define SMB_PRF_AS400 0xB4 /* AS400 */
+#define SMB_PRF_XEON_MP 0xB5 /* Intel Xeon MP */
+#define SMB_PRF_ATHLON_XP 0xB6 /* AMD Athlon XP */
+#define SMB_PRF_ATHLON_MP 0xB7 /* AMB Athlon MP */
+#define SMB_PRF_ITANIC2 0xB8 /* Itanium 2 */
+#define SMB_PRF_PENTIUM_M 0xB9 /* Pentium M */
+#define SMB_PRF_IBM390 0xC8 /* IBM 390 */
+#define SMB_PRF_G4 0xC9 /* G4 */
+#define SMB_PRF_G5 0xCA /* G5 */
+#define SMB_PRF_I860 0xFA /* i860 */
+#define SMB_PRF_I960 0xFB /* i960 */
+
+/*
+ * SMBIOS Cache Information. See DSP0134 Section 3.3.8 for more information.
+ * If smba_size is zero, this indicates the specified cache is not present.
+ */
+typedef struct smbios_cache {
+ uint32_t smba_maxsize; /* maximum installed size in bytes */
+ uint32_t smba_size; /* installed size in bytes */
+ uint16_t smba_stype; /* supported SRAM types (SMB_CAT_*) */
+ uint16_t smba_ctype; /* current SRAM type (SMB_CAT_*) */
+ uint8_t smba_speed; /* speed in nanoseconds */
+ uint8_t smba_etype; /* error correction type (SMB_CAE_*) */
+ uint8_t smba_ltype; /* logical cache type (SMB_CAG_*) */
+ uint8_t smba_assoc; /* associativity (SMB_CAA_*) */
+ uint8_t smba_level; /* cache level */
+ uint8_t smba_mode; /* cache mode (SMB_CAM_*) */
+ uint8_t smba_location; /* cache location (SMB_CAL_*) */
+ uint8_t smba_flags; /* cache flags (SMB_CAF_*) */
+} smbios_cache_t;
+
+#define SMB_CAT_OTHER 0x0001 /* other */
+#define SMB_CAT_UNKNOWN 0x0002 /* unknown */
+#define SMB_CAT_NONBURST 0x0004 /* non-burst */
+#define SMB_CAT_BURST 0x0008 /* burst */
+#define SMB_CAT_PBURST 0x0010 /* pipeline burst */
+#define SMB_CAT_SYNC 0x0020 /* synchronous */
+#define SMB_CAT_ASYNC 0x0040 /* asynchronous */
+
+#define SMB_CAE_OTHER 0x01 /* other */
+#define SMB_CAE_UNKNOWN 0x02 /* unknown */
+#define SMB_CAE_NONE 0x03 /* none */
+#define SMB_CAE_PARITY 0x04 /* parity */
+#define SMB_CAE_SBECC 0x05 /* single-bit ECC */
+#define SMB_CAE_MBECC 0x06 /* multi-bit ECC */
+
+#define SMB_CAG_OTHER 0x01 /* other */
+#define SMB_CAG_UNKNOWN 0x02 /* unknown */
+#define SMB_CAG_INSTR 0x03 /* instruction */
+#define SMB_CAG_DATA 0x04 /* data */
+#define SMB_CAG_UNIFIED 0x05 /* unified */
+
+#define SMB_CAA_OTHER 0x01 /* other */
+#define SMB_CAA_UNKNOWN 0x02 /* unknown */
+#define SMB_CAA_DIRECT 0x03 /* direct mapped */
+#define SMB_CAA_2WAY 0x04 /* 2-way set associative */
+#define SMB_CAA_4WAY 0x05 /* 4-way set associative */
+#define SMB_CAA_FULL 0x06 /* fully associative */
+#define SMB_CAA_8WAY 0x07 /* 8-way set associative */
+#define SMB_CAA_16WAY 0x08 /* 16-way set associative */
+
+#define SMB_CAM_WT 0x00 /* write-through */
+#define SMB_CAM_WB 0x01 /* write-back */
+#define SMB_CAM_VARY 0x02 /* varies by address */
+#define SMB_CAM_UNKNOWN 0x03 /* unknown */
+
+#define SMB_CAL_INTERNAL 0x00 /* internal */
+#define SMB_CAL_EXTERNAL 0x01 /* external */
+#define SMB_CAL_RESERVED 0x02 /* reserved */
+#define SMB_CAL_UNKNOWN 0x03 /* unknown */
+
+#define SMB_CAF_ENABLED 0x01 /* enabled at boot time */
+#define SMB_CAF_SOCKETED 0x02 /* cache is socketed */
+
+/*
+ * SMBIOS Port Information. See DSP0134 Section 3.3.9 for more information.
+ * The internal reference designator string is also mapped to the location.
+ */
+typedef struct smbios_port {
+ const char *smbo_iref; /* internal reference designator */
+ const char *smbo_eref; /* external reference designator */
+ uint8_t smbo_itype; /* internal connector type (SMB_POC_*) */
+ uint8_t smbo_etype; /* external connector type (SMB_POC_*) */
+ uint8_t smbo_ptype; /* port type (SMB_POT_*) */
+ uint8_t smbo_pad; /* padding */
+} smbios_port_t;
+
+#define SMB_POC_NONE 0x00 /* none */
+#define SMB_POC_CENT 0x01 /* Centronics */
+#define SMB_POC_MINICENT 0x02 /* Mini-Centronics */
+#define SMB_POC_PROPRIETARY 0x03 /* proprietary */
+#define SMB_POC_DB25M 0x04 /* DB-25 pin male */
+#define SMB_POC_DB25F 0x05 /* DB-25 pin female */
+#define SMB_POC_DB15M 0x06 /* DB-15 pin male */
+#define SMB_POC_DB15F 0x07 /* DB-15 pin female */
+#define SMB_POC_DB9M 0x08 /* DB-9 pin male */
+#define SMB_POC_DB9F 0x09 /* DB-9 pin female */
+#define SMB_POC_RJ11 0x0A /* RJ-11 */
+#define SMB_POC_RJ45 0x0B /* RJ-45 */
+#define SMB_POC_MINISCSI 0x0C /* 50-pin MiniSCSI */
+#define SMB_POC_MINIDIN 0x0D /* Mini-DIN */
+#define SMB_POC_MICRODIN 0x0E /* Micro-DIN */
+#define SMB_POC_PS2 0x0F /* PS/2 */
+#define SMB_POC_IR 0x10 /* Infrared */
+#define SMB_POC_HPHIL 0x11 /* HP-HIL */
+#define SMB_POC_USB 0x12 /* USB */
+#define SMB_POC_SSA 0x13 /* SSA SCSI */
+#define SMB_POC_DIN8M 0x14 /* Circular DIN-8 male */
+#define SMB_POC_DIN8F 0x15 /* Circular DIN-8 female */
+#define SMB_POC_OBIDE 0x16 /* on-board IDE */
+#define SMB_POC_OBFLOPPY 0x17 /* on-board floppy */
+#define SMB_POC_DI9 0x18 /* 9p dual inline (p10 cut) */
+#define SMB_POC_DI25 0x19 /* 25p dual inline (p26 cut) */
+#define SMB_POC_DI50 0x1A /* 50p dual inline */
+#define SMB_POC_DI68 0x1B /* 68p dual inline */
+#define SMB_POC_CDROM 0x1C /* on-board sound from CDROM */
+#define SMB_POC_MINI14 0x1D /* Mini-Centronics Type 14 */
+#define SMB_POC_MINI26 0x1E /* Mini-Centronics Type 26 */
+#define SMB_POC_MINIJACK 0x1F /* Mini-jack (headphones) */
+#define SMB_POC_BNC 0x20 /* BNC */
+#define SMB_POC_1394 0x21 /* 1394 */
+#define SMB_POC_PC98 0xA0 /* PC-98 */
+#define SMB_POC_PC98HR 0xA1 /* PC-98Hireso */
+#define SMB_POC_PCH98 0xA2 /* PC-H98 */
+#define SMB_POC_PC98NOTE 0xA3 /* PC-98Note */
+#define SMB_POC_PC98FULL 0xA4 /* PC-98Full */
+#define SMB_POC_OTHER 0xFF /* other */
+
+#define SMB_POT_NONE 0x00 /* none */
+#define SMB_POT_PP_XTAT 0x01 /* Parallel Port XT/AT compat */
+#define SMB_POT_PP_PS2 0x02 /* Parallel Port PS/2 */
+#define SMB_POT_PP_ECP 0x03 /* Parallel Port ECP */
+#define SMB_POT_PP_EPP 0x04 /* Parallel Port EPP */
+#define SMB_POT_PP_ECPEPP 0x05 /* Parallel Port ECP/EPP */
+#define SMB_POT_SP_XTAT 0x06 /* Serial Port XT/AT compat */
+#define SMB_POT_SP_16450 0x07 /* Serial Port 16450 compat */
+#define SMB_POT_SP_16550 0x08 /* Serial Port 16550 compat */
+#define SMB_POT_SP_16550A 0x09 /* Serial Port 16550A compat */
+#define SMB_POT_SCSI 0x0A /* SCSI port */
+#define SMB_POT_MIDI 0x0B /* MIDI port */
+#define SMB_POT_JOYSTICK 0x0C /* Joystick port */
+#define SMB_POT_KEYBOARD 0x0D /* Keyboard port */
+#define SMB_POT_MOUSE 0x0E /* Mouse port */
+#define SMB_POT_SSA 0x0F /* SSA SCSI */
+#define SMB_POT_USB 0x10 /* USB */
+#define SMB_POT_FIREWIRE 0x11 /* FireWrite (IEEE P1394) */
+#define SMB_POT_PCMII 0x12 /* PCMCIA Type II */
+#define SMB_POT_PCMIIa 0x13 /* PCMCIA Type II (alternate) */
+#define SMB_POT_PCMIII 0x14 /* PCMCIA Type III */
+#define SMB_POT_CARDBUS 0x15 /* Cardbus */
+#define SMB_POT_ACCESS 0x16 /* Access Bus Port */
+#define SMB_POT_SCSI2 0x17 /* SCSI II */
+#define SMB_POT_SCSIW 0x18 /* SCSI Wide */
+#define SMB_POT_PC98 0x19 /* PC-98 */
+#define SMB_POT_PC98HR 0x1A /* PC-98Hireso */
+#define SMB_POT_PCH98 0x1B /* PC-H98 */
+#define SMB_POT_VIDEO 0x1C /* Video port */
+#define SMB_POT_AUDIO 0x1D /* Audio port */
+#define SMB_POT_MODEM 0x1E /* Modem port */
+#define SMB_POT_NETWORK 0x1F /* Network port */
+#define SMB_POT_8251 0xA0 /* 8251 compatible */
+#define SMB_POT_8251F 0xA1 /* 8251 FIFO compatible */
+#define SMB_POT_OTHER 0xFF /* other */
+
+/*
+ * SMBIOS Slot Information. See DSP0134 Section 3.3.10 for more information.
+ * See DSP0134 3.3.10.5 for how to interpret the value of smbl_id.
+ */
+typedef struct smbios_slot {
+ const char *smbl_name; /* reference designation */
+ uint8_t smbl_type; /* slot type */
+ uint8_t smbl_width; /* slot data bus width */
+ uint8_t smbl_usage; /* current usage */
+ uint8_t smbl_length; /* slot length */
+ uint16_t smbl_id; /* slot ID */
+ uint8_t smbl_ch1; /* slot characteristics 1 */
+ uint8_t smbl_ch2; /* slot characteristics 2 */
+} smbios_slot_t;
+
+#define SMB_SLT_OTHER 0x01 /* other */
+#define SMB_SLT_UNKNOWN 0x02 /* unknown */
+#define SMB_SLT_ISA 0x03 /* ISA */
+#define SMB_SLT_MCA 0x04 /* MCA */
+#define SMB_SLT_EISA 0x05 /* EISA */
+#define SMB_SLT_PCI 0x06 /* PCI */
+#define SMB_SLT_PCMCIA 0x07 /* PCMCIA */
+#define SMB_SLT_VLVESA 0x08 /* VL-VESA */
+#define SMB_SLT_PROPRIETARY 0x09 /* proprietary */
+#define SMB_SLT_PROC 0x0A /* processor card slot */
+#define SMB_SLT_MEM 0x0B /* proprietary memory card slot */
+#define SMB_SLT_IOR 0x0C /* I/O riser card slot */
+#define SMB_SLT_NUBUS 0x0D /* NuBus */
+#define SMB_SLT_PCI66 0x0E /* PCI (66MHz capable) */
+#define SMB_SLT_AGP 0x0F /* AGP */
+#define SMB_SLT_AGP2X 0x10 /* AGP 2X */
+#define SMB_SLT_AGP4X 0x11 /* AGP 4X */
+#define SMB_SLT_PCIX 0x12 /* PCI-X */
+#define SMB_SLT_AGP8X 0x13 /* AGP 8X */
+#define SMB_SLT_PC98_C20 0xA0 /* PC-98/C20 */
+#define SMB_SLT_PC98_C24 0xA1 /* PC-98/C24 */
+#define SMB_SLT_PC98_E 0xA2 /* PC-98/E */
+#define SMB_SLT_PC98_LB 0xA3 /* PC-98/Local Bus */
+#define SMB_SLT_PC98_C 0xA4 /* PC-98/Card */
+#define SMB_SLT_PCIE 0xA5 /* PCI Express */
+
+#define SMB_SLW_OTHER 0x01 /* other */
+#define SMB_SLW_UNKNOWN 0x02 /* unknown */
+#define SMB_SLW_8 0x03 /* 8 bit */
+#define SMB_SLW_16 0x04 /* 16 bit */
+#define SMB_SLW_32 0x05 /* 32 bit */
+#define SMB_SLW_64 0x06 /* 64 bit */
+#define SMB_SLW_128 0x07 /* 128 bit */
+#define SMB_SLW_1X 0x08 /* 1x or x1 */
+#define SMB_SLW_2X 0x09 /* 2x or x2 */
+#define SMB_SLW_4X 0x0A /* 4x or x4 */
+#define SMB_SLW_8X 0x0B /* 8x or x8 */
+#define SMB_SLW_12X 0x0C /* 12x or x12 */
+#define SMB_SLW_16X 0x0D /* 16x or x16 */
+#define SMB_SLW_32X 0x0E /* 32x or x32 */
+
+#define SMB_SLU_OTHER 0x01 /* other */
+#define SMB_SLU_UNKNOWN 0x02 /* unknown */
+#define SMB_SLU_AVAIL 0x03 /* available */
+#define SMB_SLU_INUSE 0x04 /* in use */
+
+#define SMB_SLL_OTHER 0x01 /* other */
+#define SMB_SLL_UNKNOWN 0x02 /* unknown */
+#define SMB_SLL_SHORT 0x03 /* short length */
+#define SMB_SLL_LONG 0x04 /* long length */
+
+#define SMB_SLCH1_UNKNOWN 0x01 /* characteristics unknown */
+#define SMB_SLCH1_5V 0x02 /* provides 5.0V */
+#define SMB_SLCH1_33V 0x04 /* provides 3.3V */
+#define SMB_SLCH1_SHARED 0x08 /* opening shared with other slot */
+#define SMB_SLCH1_PC16 0x10 /* slot supports PC Card-16 */
+#define SMB_SLCH1_PCCB 0x20 /* slot supports CardBus */
+#define SMB_SLCH1_PCZV 0x40 /* slot supports Zoom Video */
+#define SMB_SLCH1_PCMRR 0x80 /* slot supports Modem Ring Resume */
+
+#define SMB_SLCH2_PME 0x01 /* slot supports PME# signal */
+#define SMB_SLCH2_HOTPLUG 0x02 /* slot supports hot-plug devices */
+#define SMB_SLCH2_SMBUS 0x04 /* slot supports SMBus signal */
+
+/*
+ * SMBIOS On-Board Device Information. See DSP0134 Section 3.3.11 for more
+ * information. Any number of on-board device sections may be present, each
+ * containing one or more records. The smbios_info_obdevs() function permits
+ * the caller to retrieve one or more of the records from a given section.
+ */
+typedef struct smbios_obdev {
+ const char *smbd_name; /* description string for this device */
+ uint8_t smbd_type; /* type code (SMB_OBT_*) */
+ uint8_t smbd_enabled; /* boolean (device is enabled) */
+} smbios_obdev_t;
+
+#define SMB_OBT_OTHER 0x01 /* other */
+#define SMB_OBT_UNKNOWN 0x02 /* unknown */
+#define SMB_OBT_VIDEO 0x03 /* video */
+#define SMB_OBT_SCSI 0x04 /* scsi */
+#define SMB_OBT_ETHERNET 0x05 /* ethernet */
+#define SMB_OBT_TOKEN 0x06 /* token ring */
+#define SMB_OBT_SOUND 0x07 /* sound */
+
+/*
+ * SMBIOS BIOS Language Information. See DSP0134 Section 3.3.14 for more
+ * information. The smbios_info_strtab() function can be applied using a
+ * count of smbla_num to retrieve the other possible language settings.
+ */
+typedef struct smbios_lang {
+ const char *smbla_cur; /* current language setting */
+ uint_t smbla_fmt; /* language name format (see below) */
+ uint_t smbla_num; /* number of installed languages */
+} smbios_lang_t;
+
+#define SMB_LFMT_LONG 0 /* <ISO639>|<ISO3166>|Encoding Method */
+#define SMB_LFMT_SHORT 1 /* <ISO930><ISO3166> */
+
+/*
+ * SMBIOS System Event Log Information. See DSP0134 Section 3.3.16 for more
+ * information. Accessing the event log itself requires additional interfaces.
+ */
+typedef struct smbios_evtype {
+ uint8_t smbevt_ltype; /* log type */
+ uint8_t smbevt_dtype; /* variable data format type */
+} smbios_evtype_t;
+
+typedef struct smbios_evlog {
+ size_t smbev_size; /* size in bytes of log area */
+ size_t smbev_hdr; /* offset or index of header */
+ size_t smbev_data; /* offset or index of data */
+ uint8_t smbev_method; /* data access method (see below) */
+ uint8_t smbev_flags; /* flags (see below) */
+ uint8_t smbev_format; /* log header format (see below) */
+ uint8_t smbev_pad; /* padding */
+ uint32_t smbev_token; /* data update change token */
+ union {
+ struct {
+ uint16_t evi_iaddr; /* index address */
+ uint16_t evi_daddr; /* data address */
+ } eva_io; /* i/o address for SMB_EVM_XxY */
+ uint32_t eva_addr; /* address for SMB_EVM_MEM32 */
+ uint16_t eva_gpnv; /* handle for SMB_EVM_GPNV */
+ } smbev_addr;
+ uint32_t smbev_typec; /* number of type descriptors */
+ const smbios_evtype_t *smbev_typev; /* type descriptor array */
+} smbios_evlog_t;
+
+#define SMB_EVM_1x1i_1x1d 0 /* I/O: 1 1b idx port, 1 1b data port */
+#define SMB_EVM_2x1i_1x1d 1 /* I/O: 2 1b idx port, 1 1b data port */
+#define SMB_EVM_1x2i_1x1d 2 /* I/O: 1 2b idx port, 1 1b data port */
+#define SMB_EVM_MEM32 3 /* Memory-Mapped 32-bit Physical Addr */
+#define SMB_EVM_GPNV 4 /* GP Non-Volatile API Access */
+
+#define SMB_EVFL_VALID 0x1 /* log area valid */
+#define SMB_EVFL_FULL 0x2 /* log area full */
+
+#define SMB_EVHF_NONE 0 /* no log headers used */
+#define SMB_EVHF_F1 1 /* DMTF log header type 1 */
+
+/*
+ * SMBIOS Physical Memory Array Information. See DSP0134 Section 3.3.17 for
+ * more information. This describes a collection of physical memory devices.
+ */
+typedef struct smbios_memarray {
+ uint8_t smbma_location; /* physical device location */
+ uint8_t smbma_use; /* physical device functional purpose */
+ uint8_t smbma_ecc; /* error detect/correct mechanism */
+ uint8_t smbma_pad0; /* padding */
+ uint32_t smbma_pad1; /* padding */
+ uint32_t smbma_ndevs; /* number of slots or sockets */
+ id_t smbma_err; /* handle of error (if any) */
+ uint64_t smbma_size; /* maximum capacity in bytes */
+} smbios_memarray_t;
+
+#define SMB_MAL_OTHER 0x01 /* other */
+#define SMB_MAL_UNKNOWN 0x02 /* unknown */
+#define SMB_MAL_SYSMB 0x03 /* system board or motherboard */
+#define SMB_MAL_ISA 0x04 /* ISA add-on card */
+#define SMB_MAL_EISA 0x05 /* EISA add-on card */
+#define SMB_MAL_PCI 0x06 /* PCI add-on card */
+#define SMB_MAL_MCA 0x07 /* MCA add-on card */
+#define SMB_MAL_PCMCIA 0x08 /* PCMCIA add-on card */
+#define SMB_MAL_PROP 0x09 /* proprietary add-on card */
+#define SMB_MAL_NUBUS 0x0A /* NuBus */
+#define SMB_MAL_PC98C20 0xA0 /* PC-98/C20 add-on card */
+#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_MAU_OTHER 0x01 /* other */
+#define SMB_MAU_UNKNOWN 0x02 /* unknown */
+#define SMB_MAU_SYSTEM 0x03 /* system memory */
+#define SMB_MAU_VIDEO 0x04 /* video memory */
+#define SMB_MAU_FLASH 0x05 /* flash memory */
+#define SMB_MAU_NVRAM 0x06 /* non-volatile RAM */
+#define SMB_MAU_CACHE 0x07 /* cache memory */
+
+#define SMB_MAE_OTHER 0x01 /* other */
+#define SMB_MAE_UNKNOWN 0x02 /* unknown */
+#define SMB_MAE_NONE 0x03 /* none */
+#define SMB_MAE_PARITY 0x04 /* parity */
+#define SMB_MAE_SECC 0x05 /* single-bit ECC */
+#define SMB_MAE_MECC 0x06 /* multi-bit ECC */
+#define SMB_MAE_CRC 0x07 /* CRC */
+
+/*
+ * SMBIOS Memory Device Information. See DSP0134 Section 3.3.18 for more
+ * information. One or more of these structures are associated with each
+ * smbios_memarray_t. A structure is present even for unpopulated sockets.
+ * Unknown values are set to -1. A smbmd_size of 0 indicates unpopulated.
+ * WARNING: Some BIOSes appear to export the *maximum* size of the device
+ * that can appear in the corresponding socket as opposed to the current one.
+ */
+typedef struct smbios_memdevice {
+ id_t smbmd_array; /* handle of physical memory array */
+ id_t smbmd_error; /* handle of memory error data */
+ uint32_t smbmd_twidth; /* total width in bits including ecc */
+ uint32_t smbmd_dwidth; /* data width in bits */
+ uint64_t smbmd_size; /* size in bytes (see note above) */
+ uint8_t smbmd_form; /* form factor */
+ uint8_t smbmd_set; /* set (0x00=none, 0xFF=unknown) */
+ uint8_t smbmd_type; /* memory type */
+ uint8_t smbmd_pad; /* padding */
+ uint32_t smbmd_flags; /* flags (see below) */
+ uint32_t smbmd_speed; /* speed in nanoseconds */
+ const char *smbmd_dloc; /* physical device locator string */
+ const char *smbmd_bloc; /* physical bank locator string */
+} smbios_memdevice_t;
+
+#define SMB_MDFF_OTHER 0x01 /* other */
+#define SMB_MDFF_UNKNOWN 0x02 /* unknown */
+#define SMB_MDFF_SIMM 0x03 /* SIMM */
+#define SMB_MDFF_SIP 0x04 /* SIP */
+#define SMB_MDFF_CHIP 0x05 /* chip */
+#define SMB_MDFF_DIP 0x06 /* DIP */
+#define SMB_MDFF_ZIP 0x07 /* ZIP */
+#define SMB_MDFF_PROP 0x08 /* proprietary card */
+#define SMB_MDFF_DIMM 0x09 /* DIMM */
+#define SMB_MDFF_TSOP 0x0A /* TSOP */
+#define SMB_MDFF_CHIPROW 0x0B /* row of chips */
+#define SMB_MDFF_RIMM 0x0C /* RIMM */
+#define SMB_MDFF_SODIMM 0x0D /* SODIMM */
+#define SMB_MDFF_SRIMM 0x0E /* SRIMM */
+
+#define SMB_MDT_OTHER 0x01 /* other */
+#define SMB_MDT_UNKNOWN 0x02 /* unknown */
+#define SMB_MDT_DRAM 0x03 /* DRAM */
+#define SMB_MDT_EDRAM 0x04 /* EDRAM */
+#define SMB_MDT_VRAM 0x05 /* VRAM */
+#define SMB_MDT_SRAM 0x06 /* SRAM */
+#define SMB_MDT_RAM 0x07 /* RAM */
+#define SMB_MDT_ROM 0x08 /* ROM */
+#define SMB_MDT_FLASH 0x09 /* FLASH */
+#define SMB_MDT_EEPROM 0x0A /* EEPROM */
+#define SMB_MDT_FEPROM 0x0B /* FEPROM */
+#define SMB_MDT_EPROM 0x0C /* EPROM */
+#define SMB_MDT_CDRAM 0x0D /* CDRAM */
+#define SMB_MDT_3DRAM 0x0E /* 3DRAM */
+#define SMB_MDT_SDRAM 0x0F /* SDRAM */
+#define SMB_MDT_SGRAM 0x10 /* SGRAM */
+#define SMB_MDT_RDRAM 0x11 /* RDRAM */
+#define SMB_MDT_DDR 0x12 /* DDR */
+#define SMB_MDT_DDR2 0x13 /* DDR2 */
+
+#define SMB_MDF_OTHER 0x0002 /* other */
+#define SMB_MDF_UNKNOWN 0x0004 /* unknown */
+#define SMB_MDF_FASTPG 0x0008 /* fast-paged */
+#define SMB_MDF_STATIC 0x0010 /* static column */
+#define SMB_MDF_PSTATIC 0x0020 /* pseudo-static */
+#define SMB_MDF_RAMBUS 0x0040 /* RAMBUS */
+#define SMB_MDF_SYNC 0x0080 /* synchronous */
+#define SMB_MDF_CMOS 0x0100 /* CMOS */
+#define SMB_MDF_EDO 0x0200 /* EDO */
+#define SMB_MDF_WDRAM 0x0400 /* Window DRAM */
+#define SMB_MDF_CDRAM 0x0800 /* Cache DRAM */
+#define SMB_MDF_NV 0x1000 /* non-volatile */
+
+/*
+ * SMBIOS Memory Array Mapped Address. See DSP0134 Section 3.3.20 for more
+ * information. We convert start/end addresses into addr/size for convenience.
+ */
+typedef struct smbios_memarrmap {
+ id_t smbmam_array; /* physical memory array handle */
+ uint32_t smbmam_width; /* number of devices that form a row */
+ uint64_t smbmam_addr; /* physical address of mapping */
+ uint64_t smbmam_size; /* size in bytes of address range */
+} smbios_memarrmap_t;
+
+/*
+ * SMBIOS Memory Device Mapped Address. See DSP0134 Section 3.3.21 for more
+ * information. We convert start/end addresses into addr/size for convenience.
+ */
+typedef struct smbios_memdevmap {
+ id_t smbmdm_device; /* memory device handle */
+ id_t smbmdm_arrmap; /* memory array mapped address handle */
+ uint64_t smbmdm_addr; /* physical address of mapping */
+ uint64_t smbmdm_size; /* size in bytes of address range */
+ uint8_t smbmdm_rpos; /* partition row position */
+ uint8_t smbmdm_ipos; /* interleave position */
+ uint8_t smbmdm_idepth; /* interleave data depth */
+} smbios_memdevmap_t;
+
+/*
+ * SMBIOS Hardware Security Settings. See DSP0134 Section 3.3.25 for more
+ * information. Only one such record will be present in the SMBIOS.
+ */
+typedef struct smbios_hwsec {
+ uint8_t smbh_pwr_ps; /* power-on password status */
+ uint8_t smbh_kbd_ps; /* keyboard password status */
+ uint8_t smbh_adm_ps; /* administrator password status */
+ uint8_t smbh_pan_ps; /* front panel reset status */
+} smbios_hwsec_t;
+
+#define SMB_HWSEC_PS_DISABLED 0x00 /* password disabled */
+#define SMB_HWSEC_PS_ENABLED 0x01 /* password enabled */
+#define SMB_HWSEC_PS_NOTIMPL 0x02 /* password not implemented */
+#define SMB_HWSEC_PS_UNKNOWN 0x03 /* password status unknown */
+
+/*
+ * SMBIOS System Boot Information. See DSP0134 Section 3.3.33 for more
+ * information. The contents of the data varies by type and is undocumented
+ * from the perspective of DSP0134 -- it seems to be left as vendor-specific.
+ * The (D) annotation next to SMB_BOOT_* below indicates possible data payload.
+ */
+typedef struct smbios_boot {
+ uint8_t smbt_status; /* boot status code (see below) */
+ const void *smbt_data; /* data buffer specific to status */
+ size_t smbt_size; /* size of smbt_data buffer in bytes */
+} smbios_boot_t;
+
+#define SMB_BOOT_NORMAL 0 /* no errors detected */
+#define SMB_BOOT_NOMEDIA 1 /* no bootable media */
+#define SMB_BOOT_OSFAIL 2 /* normal o/s failed to load */
+#define SMB_BOOT_FWHWFAIL 3 /* firmware-detected hardware failure */
+#define SMB_BOOT_OSHWFAIL 4 /* o/s-detected hardware failure */
+#define SMB_BOOT_USERREQ 5 /* user-requested boot (keystroke) */
+#define SMB_BOOT_SECURITY 6 /* system security violation */
+#define SMB_BOOT_PREVREQ 7 /* previously requested image (D) */
+#define SMB_BOOT_WATCHDOG 8 /* watchdog initiated reboot */
+#define SMB_BOOT_RESV_LO 9 /* low end of reserved range */
+#define SMB_BOOT_RESV_HI 127 /* high end of reserved range */
+#define SMB_BOOT_OEM_LO 128 /* low end of OEM-specific range */
+#define SMB_BOOT_OEM_HI 191 /* high end of OEM-specific range */
+#define SMB_BOOT_PROD_LO 192 /* low end of product-specific range */
+#define SMB_BOOT_PROD_HI 255 /* high end of product-specific range */
+
+/*
+ * SMBIOS IPMI Device Information. See DSP0134 Section 3.3.39 and also
+ * Appendix C1 of the IPMI specification for more information on this record.
+ */
+typedef struct smbios_ipmi {
+ uint_t smbip_type; /* BMC interface type */
+ smbios_version_t smbip_vers; /* BMC's IPMI specification version */
+ uint32_t smbip_i2c; /* BMC I2C bus slave address */
+ uint32_t smbip_bus; /* bus ID of NV storage device, or -1 */
+ uint64_t smbip_addr; /* BMC base address */
+ uint32_t smbip_flags; /* flags (see below) */
+ uint16_t smbip_intr; /* interrupt number (or zero if none) */
+ uint16_t smbip_regspacing; /* i/o space register spacing (bytes) */
+} smbios_ipmi_t;
+
+#define SMB_IPMI_T_UNKNOWN 0x00 /* unknown */
+#define SMB_IPMI_T_KCS 0x01 /* KCS: Keyboard Controller Style */
+#define SMB_IPMI_T_SMIC 0x02 /* SMIC: Server Mgmt Interface Chip */
+#define SMB_IPMI_T_BT 0x03 /* BT: Block Transfer */
+#define SMB_IPMI_T_SSIF 0x04 /* SSIF: SMBus System Interface */
+
+#define SMB_IPMI_F_IOADDR 0x01 /* base address is in i/o space */
+#define SMB_IPMI_F_INTRSPEC 0x02 /* intr information is specified */
+#define SMB_IPMI_F_INTRHIGH 0x04 /* intr active high (else low) */
+#define SMB_IPMI_F_INTREDGE 0x08 /* intr is edge triggered (else lvl) */
+
+/*
+ * SMBIOS Interfaces. An SMBIOS image can be opened by either providing a file
+ * pathname, device pathname, file descriptor, or raw memory buffer. Once an
+ * image is opened the functions below can be used to iterate over the various
+ * structures and convert the underlying data representation into the simpler
+ * data structures described earlier in this header file. The SMB_VERSION
+ * constant specified when opening an image indicates the version of the ABI
+ * the caller expects and the DMTF SMBIOS version the client can understand.
+ * The library will then map older or newer data structures to that as needed.
+ */
+
+#define SMB_VERSION_23 0x0203 /* SMBIOS encoding for DMTF spec 2.3 */
+#define SMB_VERSION_24 0x0204 /* SMBIOS encoding for DMTF spec 2.4 */
+#define SMB_VERSION SMB_VERSION_24 /* SMBIOS latest version definitions */
+
+#define SMB_O_NOCKSUM 0x1 /* do not verify header checksums */
+#define SMB_O_NOVERS 0x2 /* do not verify header versions */
+#define SMB_O_ZIDS 0x4 /* strip out identification numbers */
+#define SMB_O_MASK 0x7 /* mask of valid smbios_*open flags */
+
+#define SMB_ID_NOTSUP 0xFFFE /* structure is not supported by BIOS */
+#define SMB_ID_NONE 0xFFFF /* structure is a null reference */
+
+#define SMB_ERR (-1) /* id_t value indicating error */
+
+typedef struct smbios_hdl smbios_hdl_t;
+
+typedef struct smbios_struct {
+ id_t smbstr_id; /* structure ID handle */
+ uint_t smbstr_type; /* structure type */
+ const void *smbstr_data; /* structure data */
+ size_t smbstr_size; /* structure size */
+} smbios_struct_t;
+
+typedef int smbios_struct_f(smbios_hdl_t *,
+ const smbios_struct_t *, void *);
+
+extern smbios_hdl_t *smbios_open(const char *, int, int, int *);
+extern smbios_hdl_t *smbios_fdopen(int, int, int, int *);
+extern smbios_hdl_t *smbios_bufopen(const smbios_entry_t *,
+ const void *, size_t, int, int, int *);
+
+extern const void *smbios_buf(smbios_hdl_t *);
+extern size_t smbios_buflen(smbios_hdl_t *);
+
+extern void smbios_checksum(smbios_hdl_t *, smbios_entry_t *);
+extern int smbios_write(smbios_hdl_t *, int);
+extern void smbios_close(smbios_hdl_t *);
+
+extern int smbios_errno(smbios_hdl_t *);
+extern const char *smbios_errmsg(int);
+
+extern int smbios_lookup_id(smbios_hdl_t *, id_t, smbios_struct_t *);
+extern int smbios_iter(smbios_hdl_t *, smbios_struct_f *, void *);
+
+extern void smbios_info_smbios(smbios_hdl_t *, smbios_entry_t *);
+extern int smbios_info_common(smbios_hdl_t *, id_t, smbios_info_t *);
+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_processor(smbios_hdl_t *, id_t, smbios_processor_t *);
+extern int smbios_info_cache(smbios_hdl_t *, id_t, smbios_cache_t *);
+extern int smbios_info_port(smbios_hdl_t *, id_t, smbios_port_t *);
+extern int smbios_info_slot(smbios_hdl_t *, id_t, smbios_slot_t *);
+extern int smbios_info_obdevs(smbios_hdl_t *, id_t, int, smbios_obdev_t *);
+extern int smbios_info_strtab(smbios_hdl_t *, id_t, int, const char *[]);
+extern id_t smbios_info_lang(smbios_hdl_t *, smbios_lang_t *);
+extern id_t smbios_info_eventlog(smbios_hdl_t *, smbios_evlog_t *);
+extern int smbios_info_memarray(smbios_hdl_t *, id_t, smbios_memarray_t *);
+extern int smbios_info_memarrmap(smbios_hdl_t *, id_t, smbios_memarrmap_t *);
+extern int smbios_info_memdevice(smbios_hdl_t *, id_t, smbios_memdevice_t *);
+extern int smbios_info_memdevmap(smbios_hdl_t *, id_t, smbios_memdevmap_t *);
+extern id_t smbios_info_hwsec(smbios_hdl_t *, smbios_hwsec_t *);
+extern id_t smbios_info_boot(smbios_hdl_t *, smbios_boot_t *);
+extern id_t smbios_info_ipmi(smbios_hdl_t *, smbios_ipmi_t *);
+
+#ifndef _KERNEL
+/*
+ * The smbios_*_desc() and smbios_*_name() interfaces can be used for utilities
+ * such as smbios(1M) that wish to decode SMBIOS fields for humans. The _desc
+ * functions return the comment string next to the #defines listed above, and
+ * the _name functions return the appropriate #define identifier itself.
+ */
+extern const char *smbios_bboard_flag_desc(uint_t);
+extern const char *smbios_bboard_flag_name(uint_t);
+extern const char *smbios_bboard_type_desc(uint_t);
+
+extern const char *smbios_bios_flag_desc(uint64_t);
+extern const char *smbios_bios_flag_name(uint64_t);
+
+extern const char *smbios_bios_xb1_desc(uint_t);
+extern const char *smbios_bios_xb1_name(uint_t);
+extern const char *smbios_bios_xb2_desc(uint_t);
+extern const char *smbios_bios_xb2_name(uint_t);
+
+extern const char *smbios_boot_desc(uint_t);
+
+extern const char *smbios_cache_assoc_desc(uint_t);
+extern const char *smbios_cache_ctype_desc(uint_t);
+extern const char *smbios_cache_ctype_name(uint_t);
+extern const char *smbios_cache_ecc_desc(uint_t);
+extern const char *smbios_cache_flag_desc(uint_t);
+extern const char *smbios_cache_flag_name(uint_t);
+extern const char *smbios_cache_loc_desc(uint_t);
+extern const char *smbios_cache_logical_desc(uint_t);
+extern const char *smbios_cache_mode_desc(uint_t);
+
+extern const char *smbios_chassis_state_desc(uint_t);
+extern const char *smbios_chassis_type_desc(uint_t);
+
+extern const char *smbios_evlog_flag_desc(uint_t);
+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_ipmi_flag_name(uint_t);
+extern const char *smbios_ipmi_flag_desc(uint_t);
+extern const char *smbios_ipmi_type_desc(uint_t);
+
+extern const char *smbios_hwsec_desc(uint_t);
+
+extern const char *smbios_memarray_loc_desc(uint_t);
+extern const char *smbios_memarray_use_desc(uint_t);
+extern const char *smbios_memarray_ecc_desc(uint_t);
+
+extern const char *smbios_memdevice_form_desc(uint_t);
+extern const char *smbios_memdevice_type_desc(uint_t);
+extern const char *smbios_memdevice_flag_name(uint_t);
+extern const char *smbios_memdevice_flag_desc(uint_t);
+
+extern const char *smbios_port_conn_desc(uint_t);
+extern const char *smbios_port_type_desc(uint_t);
+
+extern const char *smbios_processor_family_desc(uint_t);
+extern const char *smbios_processor_status_desc(uint_t);
+extern const char *smbios_processor_type_desc(uint_t);
+extern const char *smbios_processor_upgrade_desc(uint_t);
+
+extern const char *smbios_slot_type_desc(uint_t);
+extern const char *smbios_slot_width_desc(uint_t);
+extern const char *smbios_slot_usage_desc(uint_t);
+extern const char *smbios_slot_length_desc(uint_t);
+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_type_desc(uint_t);
+extern const char *smbios_type_name(uint_t);
+
+extern const char *smbios_system_wakeup_desc(uint_t);
+#endif /* !_KERNEL */
+
+#ifdef _KERNEL
+/*
+ * For SMBIOS clients within the kernel itself, ksmbios is used to refer to
+ * the kernel's current snapshot of the SMBIOS, if one exists, and the
+ * ksmbios_flags tunable is the set of flags for use with smbios_open().
+ */
+extern smbios_hdl_t *ksmbios;
+extern int ksmbios_flags;
+#endif /* _KERNEL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_SMBIOS_H */
diff --git a/usr/src/uts/common/sys/smbios_impl.h b/usr/src/uts/common/sys/smbios_impl.h
new file mode 100644
index 0000000000..2db36fd51d
--- /dev/null
+++ b/usr/src/uts/common/sys/smbios_impl.h
@@ -0,0 +1,440 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * This header file defines the implementation structures for the SMBIOS access
+ * library, libsmbios, and an equivalent kernel module. Clients should use
+ * the <smbios.h> or <sys/smbios.h> header files to access DMTF SMBIOS
+ * information, NOT these underlying implementation structures from the spec.
+ * In short, do not user this header file or these routines for any purpose.
+ */
+
+#ifndef _SYS_SMBIOS_IMPL_H
+#define _SYS_SMBIOS_IMPL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/smbios.h>
+#include <sys/sysmacros.h>
+
+#ifdef _KERNEL
+#include <sys/systm.h>
+#else
+#include <strings.h>
+#include <stddef.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma pack(1)
+
+typedef struct smb_header {
+ uint8_t smbh_type; /* structure type (SMB_TYPE_* value) */
+ uint8_t smbh_len; /* length in bytes of formatted area */
+ uint16_t smbh_hdl; /* structure handle */
+} smb_header_t;
+
+typedef struct smb_bios {
+ smb_header_t smbbi_hdr; /* structure header */
+ uint8_t smbbi_vendor; /* bios vendor string */
+ uint8_t smbbi_version; /* bios version string */
+ uint16_t smbbi_segment; /* segment location of bios address */
+ uint8_t smbbi_reldate; /* bios release date */
+ uint8_t smbbi_romsize; /* bios rom size (64k * (n + 1)) */
+ uint64_t smbbi_cflags; /* bios characteristics */
+ uint8_t smbbi_xcflags[1]; /* bios characteristics extensions */
+} smb_bios_t;
+
+typedef struct smb_system {
+ smb_header_t smbsi_hdr; /* structure header */
+ uint8_t smbsi_manufacturer; /* manufacturer */
+ uint8_t smbsi_product; /* product name */
+ uint8_t smbsi_version; /* version */
+ uint8_t smbsi_serial; /* serial number */
+ uint8_t smbsi_uuid[16]; /* UUID */
+ uint8_t smbsi_wakeup; /* wake-up type */
+ uint8_t smbsi_sku; /* SKU number */
+ uint8_t smbsi_family; /* family */
+} smb_system_t;
+
+typedef struct smb_bboard {
+ smb_header_t smbbb_hdr; /* structure header */
+ uint8_t smbbb_manufacturer; /* manufacturer */
+ uint8_t smbbb_product; /* product name */
+ uint8_t smbbb_version; /* version */
+ uint8_t smbbb_serial; /* serial number */
+ uint8_t smbbb_asset; /* asset tag */
+ uint8_t smbbb_flags; /* feature flags */
+ uint8_t smbbb_location; /* location in chassis */
+ uint16_t smbbb_chassis; /* chassis handle */
+ uint8_t smbbb_type; /* board type */
+ uint8_t smbbb_cn; /* number of contained handles */
+ uint16_t smbbb_cv[1]; /* array of contained handles */
+} smb_bboard_t;
+
+typedef struct smb_chassis {
+ smb_header_t smbch_hdr; /* structure header */
+ uint8_t smbch_manufacturer; /* manufacturer */
+ uint8_t smbch_type; /* type */
+ uint8_t smbch_version; /* version */
+ uint8_t smbch_serial; /* serial number */
+ uint8_t smbch_asset; /* asset tag */
+ uint8_t smbch_bustate; /* boot-up state */
+ uint8_t smbch_psstate; /* power supply state */
+ uint8_t smbch_thstate; /* thermal state */
+ uint8_t smbch_security; /* security state */
+ uint32_t smbch_oemdata; /* OEM-specific data */
+ uint8_t smbch_uheight; /* enclosure height */
+ 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 */
+} smb_chassis_t;
+
+#define SMB_CHT_LOCK 0x80 /* lock bit within smbch_type */
+
+typedef struct smb_processor {
+ smb_header_t smbpr_hdr; /* structure header */
+ uint8_t smbpr_socket; /* socket designation */
+ uint8_t smbpr_type; /* processor type (see <smbios.h>) */
+ uint8_t smbpr_family; /* processor family (see <smbios.h>) */
+ uint8_t smbpr_manufacturer; /* manufacturer */
+ uint64_t smbpr_cpuid; /* processor cpuid information */
+ uint8_t smbpr_version; /* version */
+ uint8_t smbpr_voltage; /* voltage */
+ uint16_t smbpr_clkspeed; /* external clock speed in MHz */
+ uint16_t smbpr_maxspeed; /* maximum speed in MHz */
+ uint16_t smbpr_curspeed; /* current speed in MHz */
+ uint8_t smbpr_status; /* status (see <smbios.h>) */
+ uint8_t smbpr_upgrade; /* upgrade */
+ uint16_t smbpr_l1cache; /* L1 cache handle (if any) */
+ uint16_t smbpr_l2cache; /* L2 cache handle (if any) */
+ uint16_t smbpr_l3cache; /* L3 cache handle (if any) */
+ uint8_t smbpr_serial; /* serial number */
+ uint8_t smbpr_asset; /* asset tag */
+ uint8_t smbpr_part; /* part number */
+} smb_processor_t;
+
+typedef struct smb_cache {
+ smb_header_t smbca_hdr; /* structure header */
+ uint8_t smbca_socket; /* socket designation */
+ uint16_t smbca_config; /* cache configuration */
+ uint16_t smbca_maxsize; /* maximum installed size */
+ uint16_t smbca_size; /* installed size */
+ uint16_t smbca_stype; /* supported SRAM type */
+ uint16_t smbca_ctype; /* current SRAM type */
+ uint8_t smbca_speed; /* speed in nanoseconds */
+ uint8_t smbca_etype; /* error correction type */
+ uint8_t smbca_ltype; /* logical cache type */
+ uint8_t smbca_assoc; /* associativity */
+} smb_cache_t;
+
+#define SMB_CACHE_SIZE(s) \
+ (((s) & 0x8000) ? (((s) & 0x7FFF) << 1) : (s))
+
+#define SMB_CACHE_CFG_MODE(c) (((c) >> 8) & 3)
+#define SMB_CACHE_CFG_ENABLED(c) (((c) >> 7) & 1)
+#define SMB_CACHE_CFG_LOCATION(c) (((c) >> 5) & 3)
+#define SMB_CACHE_CFG_SOCKETED(c) (((c) >> 3) & 1)
+#define SMB_CACHE_CFG_LEVEL(c) (((c) & 7) + 1)
+
+typedef struct smb_port {
+ smb_header_t smbpo_hdr; /* structure header */
+ uint8_t smbpo_iref; /* internal reference designator */
+ uint8_t smbpo_itype; /* internal connector type */
+ uint8_t smbpo_eref; /* external reference designator */
+ uint8_t smbpo_etype; /* external connector type */
+ uint8_t smbpo_ptype; /* port type */
+} smb_port_t;
+
+typedef struct smb_slot {
+ smb_header_t smbsl_hdr; /* structure header */
+ uint8_t smbsl_name; /* reference designation */
+ uint8_t smbsl_type; /* slot type */
+ uint8_t smbsl_width; /* slot data bus width */
+ uint8_t smbsl_usage; /* current usage */
+ uint8_t smbsl_length; /* slot length */
+ uint16_t smbsl_id; /* slot ID */
+ uint8_t smbsl_ch1; /* slot characteristics 1 */
+ uint8_t smbsl_ch2; /* slot characteristics 2 */
+} smb_slot_t;
+
+typedef struct smb_obdev {
+ uint8_t smbob_type; /* encoded type and enable bit */
+ uint8_t smbob_name; /* descriptiong string */
+} smb_obdev_t;
+
+#define SMB_OBT_ENABLED 0x80 /* enable bit within smbob_type */
+
+typedef struct smb_strtab {
+ smb_header_t smbtb_hdr; /* structure header */
+ uint8_t smbtb_count; /* number of strings */
+} smb_strtab_t;
+
+typedef struct smb_lang {
+ smb_header_t smblang_hdr; /* structure header */
+ uint8_t smblang_num; /* number of installed languages */
+ uint8_t smblang_flags; /* flags */
+ uint8_t smblang_resv[15]; /* reserved for future use */
+ uint8_t smblang_cur; /* current language string */
+} smb_lang_t;
+
+typedef struct smb_sel {
+ smb_header_t smbsel_hdr; /* structure header */
+ uint16_t smbsel_len; /* log area length */
+ uint16_t smbsel_hdroff; /* header offset */
+ uint16_t smbsel_dataoff; /* data offset */
+ uint8_t smbsel_method; /* access method */
+ uint8_t smbsel_status; /* status flags */
+ uint32_t smbsel_token; /* change token */
+ uint32_t smbsel_addr; /* access method address */
+ uint8_t smbsel_format; /* header format */
+ uint8_t smbsel_typec; /* number of type descriptors */
+ uint8_t smbsel_typesz; /* size of each type descriptor */
+ uint8_t smbsel_typev[1]; /* array of type descriptors */
+} smb_sel_t;
+
+typedef struct smb_memarray {
+ smb_header_t smbmarr_hdr; /* structure header */
+ uint8_t smbmarr_loc; /* location */
+ uint8_t smbmarr_use; /* use */
+ uint8_t smbmarr_ecc; /* error detect/correct mechanism */
+ uint32_t smbmarr_cap; /* maximum capacity */
+ uint16_t smbmarr_err; /* error handle */
+ uint16_t smbmarr_ndevs; /* number of slots or sockets */
+} smb_memarray_t;
+
+typedef struct smb_memarrmap {
+ smb_header_t smbamap_hdr; /* structure header */
+ uint32_t smbamap_start; /* starting address in kilobytes */
+ uint32_t smbamap_end; /* ending address in kilobytes */
+ uint16_t smbamap_array; /* physical memory array handle */
+ uint8_t smbamap_width; /* partition width */
+} smb_memarrmap_t;
+
+typedef struct smb_memdevice {
+ smb_header_t smbmdev_hdr; /* structure header */
+ uint16_t smbmdev_array; /* array handle */
+ uint16_t smbmdev_error; /* error handle */
+ uint16_t smbmdev_twidth; /* total width */
+ uint16_t smbmdev_dwidth; /* data width */
+ uint16_t smbmdev_size; /* size in either K or MB */
+ uint8_t smbmdev_form; /* form factor */
+ uint8_t smbmdev_set; /* device set */
+ uint8_t smbmdev_dloc; /* device locator */
+ uint8_t smbmdev_bloc; /* bank locator */
+ uint8_t smbmdev_type; /* memory type */
+ uint16_t smbmdev_flags; /* detail flags */
+ uint16_t smbmdev_speed; /* speed in MHz */
+ uint8_t smbmdev_manufacturer; /* manufacturer */
+ uint8_t smbmdev_serial; /* serial number */
+ uint8_t smbmdev_asset; /* asset tag */
+ uint8_t smbmdev_part; /* part number */
+} smb_memdevice_t;
+
+#define SMB_MDS_KBYTES 0x8000 /* size in specified in kilobytes */
+
+typedef struct smb_memdevmap {
+ smb_header_t smbdmap_hdr; /* structure header */
+ uint32_t smbdmap_start; /* starting address in kilobytes */
+ uint32_t smbdmap_end; /* ending address in kilobytes */
+ uint16_t smbdmap_device; /* memory device handle */
+ uint16_t smbdmap_array; /* memory array mapped address handle */
+ uint8_t smbdmap_rpos; /* row position */
+ uint8_t smbdmap_ipos; /* interleave position */
+ uint8_t smbdmap_idepth; /* interleave depth */
+} smb_memdevmap_t;
+
+typedef struct smb_battery {
+ smb_header_t smbbat_hdr; /* structure header */
+ uint8_t smbbat_loc; /* location */
+ uint8_t smbbat_manufacturer; /* manufacturer */
+ uint8_t smbbat_date; /* manufacture date */
+ uint8_t smbbat_serial; /* serial number */
+ uint8_t smbbat_devname; /* device name */
+ uint8_t smbbat_chem; /* device chemistry */
+ uint16_t smbbat_cap; /* design capacity in mW hours */
+ uint16_t smbbat_volt; /* design voltage in mV */
+ uint8_t smbbat_version; /* SBDS version string */
+ uint8_t smbbat_err; /* error percentage */
+ uint16_t smbbat_ssn; /* SBDS serial number */
+ uint16_t smbbat_sdate; /* SBDS manufacture date */
+ uint8_t smbbat_schem; /* SBDS chemistry string */
+ uint8_t smbbat_mult; /* design capacity multiplier */
+ uint32_t smbbat_oemdata; /* OEM-specific data */
+} smb_battery_t;
+
+typedef struct smb_hwsec {
+ smb_header_t smbhs_hdr; /* structure header */
+ uint8_t smbhs_settings; /* settings byte */
+} smb_hwsec_t;
+
+#define SMB_HWS_PWR_PS(x) (((x) & 0xC0) >> 6)
+#define SMB_HWS_KBD_PS(x) (((x) & 0x30) >> 4)
+#define SMB_HWS_ADM_PS(x) (((x) & 0x0C) >> 2)
+#define SMB_HWS_PAN_PS(x) (((x) & 0x03) >> 0)
+
+typedef struct smb_boot {
+ smb_header_t smbbo_hdr; /* structure header */
+ uint8_t smbbo_pad[6]; /* reserved for future use */
+ uint8_t smbbo_status[1]; /* variable-length status buffer */
+} smb_boot_t;
+
+typedef struct smb_ipmi {
+ smb_header_t smbipm_hdr; /* structure header */
+ uint8_t smbipm_type; /* interface type */
+ uint8_t smbipm_spec; /* specification revision */
+ uint8_t smbipm_i2c; /* i2C slave address */
+ uint8_t smbipm_bus; /* NV storage device bus ID */
+ uint64_t smbipm_addr; /* base address */
+ uint8_t smbipm_info; /* base address modifier/intr info */
+ uint8_t smbipm_intr; /* interrupt number */
+} smb_ipmi_t;
+
+#define SMB_IPM_SPEC_MAJOR(x) (((x) & 0xF0) >> 4)
+#define SMB_IPM_SPEC_MINOR(x) ((x) & 0x0F)
+
+#define SMB_IPM_ADDR_IO 1ULL
+
+#define SMB_IPM_INFO_REGS(x) (((x) & 0xC0) >> 6)
+#define SMB_IPM_INFO_LSB(x) (((x) & 0x10) >> 4)
+#define SMB_IPM_INFO_ISPEC(x) (((x) & 0x08) >> 3)
+#define SMB_IPM_INFO_IPOL(x) (((x) & 0x02) >> 1)
+#define SMB_IPM_INFO_IMODE(x) (((x) & 0x01) >> 0)
+
+#define SMB_IPM_REGS_1B 0
+#define SMB_IPM_REGS_4B 1
+#define SMB_IPM_REGS_16B 2
+
+#define SMB_IPM_IPOL_LO 0
+#define SMB_IPM_IPOL_HI 1
+
+#define SMB_IPM_IMODE_EDGE 0
+#define SMB_IPM_IMODE_LEVEL 1
+
+typedef struct smb_powersup {
+ smb_header_t smbpsup_hdr; /* structure header */
+ uint8_t smbpsup_group; /* group id */
+ uint8_t smbpsup_loc; /* location tag */
+ uint8_t smbpsup_devname; /* device name */
+ uint8_t smbpsup_manufacturer; /* manufacturer */
+ uint8_t smbpsup_serial; /* serial number */
+ uint8_t smbpsup_asset; /* asset tag */
+ uint8_t smbpsup_part; /* part number */
+ uint8_t smbpsup_rev; /* revision string */
+ uint16_t smbpsup_max; /* max output in milliwatts */
+ uint16_t smbpsup_char; /* characteristics */
+ uint16_t smbpsup_vprobe; /* voltage probe handle */
+ uint16_t smbpsup_cooldev; /* cooling device handle */
+ uint16_t smbpsup_iprobe; /* current probe handle */
+} smb_powersup_t;
+
+#pragma pack()
+
+typedef struct smb_struct {
+ const smb_header_t *smbst_hdr; /* address of raw structure data */
+ const uchar_t *smbst_str; /* address of string data (if any) */
+ const uchar_t *smbst_end; /* address of 0x0000 ending tag */
+ struct smb_struct *smbst_next; /* next structure in hash chain */
+ uint16_t *smbst_strtab; /* string index -> offset table */
+ uint_t smbst_strtablen; /* length of smbst_strtab */
+} smb_struct_t;
+
+struct smbios_hdl {
+ smbios_entry_t sh_ent; /* structure table entry point */
+ const void *sh_buf; /* structure table buffer */
+ size_t sh_buflen; /* size of structure table buffer */
+ smb_struct_t *sh_structs; /* array of structure descriptors */
+ uint_t sh_nstructs; /* number of active structures */
+ smb_struct_t **sh_hash; /* hash bucket array for descriptors */
+ uint_t sh_hashlen; /* hash bucket array length */
+ int sh_err; /* error code for smbios_errno() */
+ int sh_libvers; /* library client abi version */
+ int sh_smbvers; /* derived underlying format version */
+ uint_t sh_flags; /* miscellaneous flags (see below) */
+};
+
+#define SMB_FL_DEBUG 0x1 /* print debug messages for this hdl */
+#define SMB_FL_BUFALLOC 0x2 /* sh_buf was allocated by library */
+
+#define SMB_BIOS_DEVICE "/dev/xsvc" /* device w/ BIOS physmem */
+#define SMB_SMBIOS_DEVICE "/dev/smbios" /* device w/ SMBIOS image */
+
+#define SMB_RANGE_START 0xF0000 /* start of physical address range */
+#define SMB_RANGE_LIMIT 0xFFFFF /* limit of physical address range */
+
+#define SMB_MAJMIN(M, m) ((((M) & 0xFF) << 16) | ((m) & 0xFF))
+#define SMB_MAJOR(v) (((v) & 0xFF00) >> 8)
+#define SMB_MINOR(v) (((v) & 0x00FF))
+
+#define ESMB_BASE 1000 /* base value for libsmbios errnos */
+
+enum {
+ ESMB_NOTFOUND = ESMB_BASE, /* SMBIOS table not found on system */
+ ESMB_MAPDEV, /* failed to map SMBIOS table */
+ ESMB_NOENT, /* failed to locate structure */
+ ESMB_NOMEM, /* failed to allocate memory */
+ ESMB_NOHDR, /* failed to read SMBIOS header */
+ ESMB_NOSTAB, /* failed to read SMBIOS struct table */
+ ESMB_NOINFO, /* no common info for structure */
+ ESMB_SHORT, /* buffer length doesn't match header */
+ ESMB_CORRUPT, /* buffer struct or len is corrupt */
+ ESMB_VERSION, /* version not supported by library */
+ ESMB_NOTSUP, /* feature not supported by provider */
+ ESMB_HEADER, /* SMBIOS header corrupt or invalid */
+ ESMB_OLD, /* SMBIOS version is too old for us */
+ ESMB_NEW, /* SMBIOS version is too new for us */
+ ESMB_CKSUM, /* SMBIOS header checksum mismatch */
+ ESMB_INVAL, /* invalid function call argument */
+ ESMB_TYPE, /* structure type mismatch */
+ ESMB_UNKNOWN /* unknown error (maximum value tag) */
+};
+
+extern const smb_struct_t *smb_lookup_type(smbios_hdl_t *, uint_t);
+extern const smb_struct_t *smb_lookup_id(smbios_hdl_t *, uint_t);
+extern const char *smb_strptr(const smb_struct_t *, uint_t);
+extern int smb_gteq(smbios_hdl_t *, int);
+
+extern int smb_set_errno(smbios_hdl_t *, int);
+extern smbios_hdl_t *smb_open_error(smbios_hdl_t *, int *, int);
+extern const char *smb_strerror(int);
+
+extern void *smb_alloc(size_t);
+extern void *smb_zalloc(size_t);
+extern void smb_free(void *, size_t);
+
+extern void smb_dprintf(smbios_hdl_t *, const char *, ...);
+
+extern int _smb_debug;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_SMBIOS_IMPL_H */
diff --git a/usr/src/uts/i86pc/Makefile.files b/usr/src/uts/i86pc/Makefile.files
index dad578abdf..d56ec87b3b 100644
--- a/usr/src/uts/i86pc/Makefile.files
+++ b/usr/src/uts/i86pc/Makefile.files
@@ -75,6 +75,12 @@ CORE_OBJS += \
x_call.o
#
+# Add the SMBIOS subsystem object files directly to the list of objects
+# built into unix itself; this is all common code except for smb_dev.c.
+#
+CORE_OBJS += $(SMBIOS_OBJS)
+
+#
# locore.o is special. It must be the first file relocated so that it
# it is relocated just where its name implies.
#
diff --git a/usr/src/uts/i86pc/os/smb_dev.c b/usr/src/uts/i86pc/os/smb_dev.c
new file mode 100644
index 0000000000..db3b2f6962
--- /dev/null
+++ b/usr/src/uts/i86pc/os/smb_dev.c
@@ -0,0 +1,129 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Platform-Specific SMBIOS Subroutines
+ *
+ * The routines in this file form part of <sys/smbios_impl.h> and combine with
+ * the usr/src/common/smbios code to form an in-kernel SMBIOS decoding service.
+ * The SMBIOS entry point is locating by scanning a range of physical memory
+ * assigned to BIOS as described in Section 2 of the DMTF SMBIOS specification.
+ */
+
+#include <sys/smbios_impl.h>
+#include <sys/sysmacros.h>
+#include <sys/errno.h>
+#include <sys/psm.h>
+#include <sys/smp_impldefs.h>
+
+smbios_hdl_t *ksmbios;
+int ksmbios_flags;
+
+smbios_hdl_t *
+smb_open_error(smbios_hdl_t *shp, int *errp, int err)
+{
+ if (shp != NULL)
+ smbios_close(shp);
+
+ if (errp != NULL)
+ *errp = err;
+
+ if (ksmbios == NULL)
+ cmn_err(CE_CONT, "?SMBIOS not loaded (%s)", smbios_errmsg(err));
+
+ return (NULL);
+}
+
+smbios_hdl_t *
+smbios_open(const char *file, int version, int flags, int *errp)
+{
+ smbios_hdl_t *shp = NULL;
+ smbios_entry_t ep;
+ caddr_t stbuf, bios, p, q;
+ size_t bioslen;
+ int err;
+
+ if (file != NULL || (flags & ~SMB_O_MASK))
+ return (smb_open_error(shp, errp, ESMB_INVAL));
+
+ bioslen = SMB_RANGE_LIMIT - SMB_RANGE_START + 1;
+ bios = psm_map_phys(SMB_RANGE_START, bioslen, PSM_PROT_READ);
+
+ if (bios == NULL)
+ return (smb_open_error(shp, errp, ESMB_MAPDEV));
+
+ for (p = bios, q = bios + bioslen; p < q; p += 16) {
+ if (strncmp(p, SMB_ENTRY_EANCHOR, SMB_ENTRY_EANCHORLEN) == 0)
+ break;
+ }
+
+ if (p >= q) {
+ psm_unmap_phys(bios, bioslen);
+ return (smb_open_error(shp, errp, ESMB_NOTFOUND));
+ }
+
+ bcopy(p, &ep, sizeof (smbios_entry_t));
+ psm_unmap_phys(bios, bioslen);
+ bios = psm_map_phys(ep.smbe_staddr, ep.smbe_stlen, PSM_PROT_READ);
+
+ if (bios == NULL)
+ return (smb_open_error(shp, errp, ESMB_MAPDEV));
+
+ stbuf = smb_alloc(ep.smbe_stlen);
+ bcopy(bios, stbuf, ep.smbe_stlen);
+ psm_unmap_phys(bios, ep.smbe_stlen);
+ shp = smbios_bufopen(&ep, stbuf, ep.smbe_stlen, version, flags, &err);
+
+ if (shp == NULL) {
+ smb_free(stbuf, ep.smbe_stlen);
+ return (smb_open_error(shp, errp, err));
+ }
+
+ if (ksmbios == NULL) {
+ cmn_err(CE_CONT, "?SMBIOS v%u.%u loaded (%u bytes)",
+ ep.smbe_major, ep.smbe_minor, ep.smbe_stlen);
+ }
+
+ shp->sh_flags |= SMB_FL_BUFALLOC;
+ return (shp);
+}
+
+/*ARGSUSED*/
+smbios_hdl_t *
+smbios_fdopen(int fd, int version, int flags, int *errp)
+{
+ return (smb_open_error(NULL, errp, ENOTSUP));
+}
+
+/*ARGSUSED*/
+int
+smbios_write(smbios_hdl_t *shp, int fd)
+{
+ return (smb_set_errno(shp, ENOTSUP));
+}
diff --git a/usr/src/uts/i86pc/os/startup.c b/usr/src/uts/i86pc/os/startup.c
index e6ed3f1e03..e94696f210 100644
--- a/usr/src/uts/i86pc/os/startup.c
+++ b/usr/src/uts/i86pc/os/startup.c
@@ -123,8 +123,8 @@
#include <sys/cpc_impl.h>
#include <sys/chip.h>
#include <sys/x86_archext.h>
+#include <sys/smbios.h>
-extern void debug_enter(char *);
extern void progressbar_init(void);
extern void progressbar_start(void);
@@ -1870,8 +1870,6 @@ ulong_t _bdhs34;
void
post_startup(void)
{
- extern void memscrub_init(void);
-
/*
* Set the system wide, processor-specific flags to be passed
* to userland via the aux vector for performance hints and
@@ -1880,20 +1878,20 @@ post_startup(void)
bind_hwcap();
/*
- * Startup memory scrubber.
+ * Load the System Management BIOS into the global ksmbios handle,
+ * if an SMBIOS is present on this system.
*/
- (void) memscrub_init();
+ ksmbios = smbios_open(NULL, SMB_VERSION, ksmbios_flags, NULL);
/*
- * Perform forceloading tasks for /etc/system.
+ * Startup memory scrubber.
*/
- (void) mod_sysctl(SYS_FORCELOAD, NULL);
+ memscrub_init();
/*
- * complete mmu initialization, now that kernel and critical
- * modules have been loaded.
+ * Perform forceloading tasks for /etc/system.
*/
- (void) post_startup_mmu_initialization();
+ (void) mod_sysctl(SYS_FORCELOAD, NULL);
/*
* ON4.0: Force /proc module in until clock interrupt handle fixed
diff --git a/usr/src/uts/i86pc/sys/machsystm.h b/usr/src/uts/i86pc/sys/machsystm.h
index d3f5247bad..e4ffdd5351 100644
--- a/usr/src/uts/i86pc/sys/machsystm.h
+++ b/usr/src/uts/i86pc/sys/machsystm.h
@@ -87,9 +87,9 @@ struct system_hardware {
extern struct system_hardware system_hardware;
extern void get_system_configuration(void);
extern void mmu_init(void);
-extern void post_startup_mmu_initialization(void);
extern int cpuid2nodeid(int);
extern void map_kaddr(caddr_t, pfn_t, int, int);
+extern void memscrub_init(void);
extern unsigned int microdata;
extern int use_mp;
diff --git a/usr/src/uts/i86pc/vm/vm_machdep.c b/usr/src/uts/i86pc/vm/vm_machdep.c
index 18d6266eb6..ef6675fdaf 100644
--- a/usr/src/uts/i86pc/vm/vm_machdep.c
+++ b/usr/src/uts/i86pc/vm/vm_machdep.c
@@ -1948,13 +1948,6 @@ pageout_init(void (*procedure)(), proc_t *pp, pri_t pri)
}
/*
- * any use for this?
- */
-void
-post_startup_mmu_initialization(void)
-{}
-
-/*
* Function for flushing D-cache when performing module relocations
* to an alternate mapping. Unnecessary on Intel / AMD platforms.
*/
diff --git a/usr/src/uts/intel/Makefile.intel b/usr/src/uts/intel/Makefile.intel
index c9125719cc..49d1ab53bb 100644
--- a/usr/src/uts/intel/Makefile.intel
+++ b/usr/src/uts/intel/Makefile.intel
@@ -273,6 +273,7 @@ DRV_KMODS += sctp
DRV_KMODS += sctp6
DRV_KMODS += sd
DRV_KMODS += sgen
+DRV_KMODS += smbios
DRV_KMODS += spdsock
DRV_KMODS += sppp
DRV_KMODS += sppptun
diff --git a/usr/src/uts/intel/os/minor_perm b/usr/src/uts/intel/os/minor_perm
index c28c994485..c4e62dd8e5 100644
--- a/usr/src/uts/intel/os/minor_perm
+++ b/usr/src/uts/intel/os/minor_perm
@@ -112,3 +112,4 @@ cpuid:self 0644 root sys
bmc:bmc 0666 root sys
dld:* 0666 root sys
aggr:* 0666 root sys
+smbios:smbios 0444 root sys
diff --git a/usr/src/uts/intel/os/name_to_major b/usr/src/uts/intel/os/name_to_major
index 29ff7f12fe..7349093cf7 100644
--- a/usr/src/uts/intel/os/name_to_major
+++ b/usr/src/uts/intel/os/name_to_major
@@ -114,4 +114,5 @@ cpuid 176
bmc 177
dld 178
aggr 179
+smbios 180
did 239
diff --git a/usr/src/uts/intel/smbios/Makefile b/usr/src/uts/intel/smbios/Makefile
new file mode 100644
index 0000000000..bc7c770bf5
--- /dev/null
+++ b/usr/src/uts/intel/smbios/Makefile
@@ -0,0 +1,61 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+UTSBASE = ../..
+
+MODULE = smbios
+OBJECTS = $(OBJS_DIR)/smbios.o
+LINTS = $(LINTS_DIR)/smbios.ln
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
+CONF_SRCDIR = $(UTSBASE)/common/io
+
+include $(UTSBASE)/intel/Makefile.intel
+
+ALL_TARGET = $(BINARY) $(SRC_CONFILE)
+LINT_TARGET = $(MODULE).lint
+INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
+
+.KEEP_STATE:
+
+def: $(DEF_DEPS)
+
+all: $(ALL_DEPS)
+
+clean: $(CLEAN_DEPS)
+
+clobber: $(CLOBBER_DEPS)
+
+lint: $(LINT_DEPS)
+
+modlintlib: $(MODLINTLIB_DEPS)
+
+clean.lint: $(CLEAN_LINT_DEPS)
+
+install: $(INSTALL_DEPS)
+
+include $(UTSBASE)/intel/Makefile.targ