diff options
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 |