summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd')
-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
12 files changed, 1560 insertions, 105 deletions
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);
+}