summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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