84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws/*
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * CDDL HEADER START
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws *
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * The contents of this file are subject to the terms of the
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * Common Development and Distribution License, Version 1.0 only
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * (the "License"). You may not use this file except in compliance
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * with the License.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws *
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * or http://www.opensolaris.org/os/licensing.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * See the License for the specific language governing permissions
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * and limitations under the License.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws *
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * When distributing Covered Code, include this CDDL HEADER in each
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * If applicable, add the following below this CDDL HEADER, with the
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * fields enclosed by brackets "[]" replaced with your own identifying
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * information: Portions Copyright [yyyy] [name of copyright owner]
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws *
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * CDDL HEADER END
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws */
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws/*
e4586ebf2f01666696316c178da243993b1a0c04mws * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * Use is subject to license terms.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws */
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws/*
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * Platform-Specific SMBIOS Subroutines
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws *
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * The routines in this file form part of <sys/smbios_impl.h> and combine with
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * the usr/src/common/smbios code to form an in-kernel SMBIOS decoding service.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * The SMBIOS entry point is locating by scanning a range of physical memory
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * assigned to BIOS as described in Section 2 of the DMTF SMBIOS specification.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws */
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws#include <sys/smbios_impl.h>
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws#include <sys/sysmacros.h>
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws#include <sys/errno.h>
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws#include <sys/psm.h>
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws#include <sys/smp_impldefs.h>
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwssmbios_hdl_t *ksmbios;
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwsint ksmbios_flags;
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwssmbios_hdl_t *
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwssmb_open_error(smbios_hdl_t *shp, int *errp, int err)
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws{
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (shp != NULL)
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws smbios_close(shp);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (errp != NULL)
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws *errp = err;
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (ksmbios == NULL)
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws cmn_err(CE_CONT, "?SMBIOS not loaded (%s)", smbios_errmsg(err));
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws return (NULL);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws}
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwssmbios_hdl_t *
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwssmbios_open(const char *file, int version, int flags, int *errp)
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws{
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws smbios_hdl_t *shp = NULL;
e4586ebf2f01666696316c178da243993b1a0c04mws smbios_entry_t *ep;
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws caddr_t stbuf, bios, p, q;
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws size_t bioslen;
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws int err;
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (file != NULL || (flags & ~SMB_O_MASK))
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws return (smb_open_error(shp, errp, ESMB_INVAL));
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws bioslen = SMB_RANGE_LIMIT - SMB_RANGE_START + 1;
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws bios = psm_map_phys(SMB_RANGE_START, bioslen, PSM_PROT_READ);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (bios == NULL)
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws return (smb_open_error(shp, errp, ESMB_MAPDEV));
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws for (p = bios, q = bios + bioslen; p < q; p += 16) {
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (strncmp(p, SMB_ENTRY_EANCHOR, SMB_ENTRY_EANCHORLEN) == 0)
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws break;
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws }
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (p >= q) {
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws psm_unmap_phys(bios, bioslen);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws return (smb_open_error(shp, errp, ESMB_NOTFOUND));
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws }
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
e4586ebf2f01666696316c178da243993b1a0c04mws ep = smb_alloc(SMB_ENTRY_MAXLEN);
e4586ebf2f01666696316c178da243993b1a0c04mws bcopy(p, ep, sizeof (smbios_entry_t));
e4586ebf2f01666696316c178da243993b1a0c04mws ep->smbe_elen = MIN(ep->smbe_elen, SMB_ENTRY_MAXLEN);
e4586ebf2f01666696316c178da243993b1a0c04mws bcopy(p, ep, ep->smbe_elen);
e4586ebf2f01666696316c178da243993b1a0c04mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws psm_unmap_phys(bios, bioslen);
e4586ebf2f01666696316c178da243993b1a0c04mws bios = psm_map_phys(ep->smbe_staddr, ep->smbe_stlen, PSM_PROT_READ);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
e4586ebf2f01666696316c178da243993b1a0c04mws if (bios == NULL) {
e4586ebf2f01666696316c178da243993b1a0c04mws smb_free(ep, SMB_ENTRY_MAXLEN);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws return (smb_open_error(shp, errp, ESMB_MAPDEV));
e4586ebf2f01666696316c178da243993b1a0c04mws }
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
e4586ebf2f01666696316c178da243993b1a0c04mws stbuf = smb_alloc(ep->smbe_stlen);
e4586ebf2f01666696316c178da243993b1a0c04mws bcopy(bios, stbuf, ep->smbe_stlen);
e4586ebf2f01666696316c178da243993b1a0c04mws psm_unmap_phys(bios, ep->smbe_stlen);
e4586ebf2f01666696316c178da243993b1a0c04mws shp = smbios_bufopen(ep, stbuf, ep->smbe_stlen, version, flags, &err);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (shp == NULL) {
e4586ebf2f01666696316c178da243993b1a0c04mws smb_free(stbuf, ep->smbe_stlen);
e4586ebf2f01666696316c178da243993b1a0c04mws smb_free(ep, SMB_ENTRY_MAXLEN);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws return (smb_open_error(shp, errp, err));
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws }
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (ksmbios == NULL) {
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws cmn_err(CE_CONT, "?SMBIOS v%u.%u loaded (%u bytes)",
e4586ebf2f01666696316c178da243993b1a0c04mws ep->smbe_major, ep->smbe_minor, ep->smbe_stlen);
516627f338a630bcf9806a91aa873bbbae9a2facJonathan Matthew if (shp->sh_flags & SMB_FL_TRUNC)
516627f338a630bcf9806a91aa873bbbae9a2facJonathan Matthew cmn_err(CE_CONT, "?SMBIOS table is truncated");
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws }
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws shp->sh_flags |= SMB_FL_BUFALLOC;
e4586ebf2f01666696316c178da243993b1a0c04mws smb_free(ep, SMB_ENTRY_MAXLEN);
e4586ebf2f01666696316c178da243993b1a0c04mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws return (shp);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws}
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws/*ARGSUSED*/
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwssmbios_hdl_t *
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwssmbios_fdopen(int fd, int version, int flags, int *errp)
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws{
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws return (smb_open_error(NULL, errp, ENOTSUP));
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws}
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws/*ARGSUSED*/
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwsint
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwssmbios_write(smbios_hdl_t *shp, int fd)
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws{
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws return (smb_set_errno(shp, ENOTSUP));
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws}