xref: /onnv-gate/usr/src/uts/i86pc/os/smb_dev.c (revision 1222:6c8cd7eac61b)
1437Smws /*
2437Smws  * CDDL HEADER START
3437Smws  *
4437Smws  * The contents of this file are subject to the terms of the
5437Smws  * Common Development and Distribution License, Version 1.0 only
6437Smws  * (the "License").  You may not use this file except in compliance
7437Smws  * with the License.
8437Smws  *
9437Smws  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10437Smws  * or http://www.opensolaris.org/os/licensing.
11437Smws  * See the License for the specific language governing permissions
12437Smws  * and limitations under the License.
13437Smws  *
14437Smws  * When distributing Covered Code, include this CDDL HEADER in each
15437Smws  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16437Smws  * If applicable, add the following below this CDDL HEADER, with the
17437Smws  * fields enclosed by brackets "[]" replaced with your own identifying
18437Smws  * information: Portions Copyright [yyyy] [name of copyright owner]
19437Smws  *
20437Smws  * CDDL HEADER END
21437Smws  */
22437Smws 
23437Smws /*
24*1222Smws  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
25437Smws  * Use is subject to license terms.
26437Smws  */
27437Smws 
28437Smws #pragma ident	"%Z%%M%	%I%	%E% SMI"
29437Smws 
30437Smws /*
31437Smws  * Platform-Specific SMBIOS Subroutines
32437Smws  *
33437Smws  * The routines in this file form part of <sys/smbios_impl.h> and combine with
34437Smws  * the usr/src/common/smbios code to form an in-kernel SMBIOS decoding service.
35437Smws  * The SMBIOS entry point is locating by scanning a range of physical memory
36437Smws  * assigned to BIOS as described in Section 2 of the DMTF SMBIOS specification.
37437Smws  */
38437Smws 
39437Smws #include <sys/smbios_impl.h>
40437Smws #include <sys/sysmacros.h>
41437Smws #include <sys/errno.h>
42437Smws #include <sys/psm.h>
43437Smws #include <sys/smp_impldefs.h>
44437Smws 
45437Smws smbios_hdl_t *ksmbios;
46437Smws int ksmbios_flags;
47437Smws 
48437Smws smbios_hdl_t *
smb_open_error(smbios_hdl_t * shp,int * errp,int err)49437Smws smb_open_error(smbios_hdl_t *shp, int *errp, int err)
50437Smws {
51437Smws 	if (shp != NULL)
52437Smws 		smbios_close(shp);
53437Smws 
54437Smws 	if (errp != NULL)
55437Smws 		*errp = err;
56437Smws 
57437Smws 	if (ksmbios == NULL)
58437Smws 		cmn_err(CE_CONT, "?SMBIOS not loaded (%s)", smbios_errmsg(err));
59437Smws 
60437Smws 	return (NULL);
61437Smws }
62437Smws 
63437Smws smbios_hdl_t *
smbios_open(const char * file,int version,int flags,int * errp)64437Smws smbios_open(const char *file, int version, int flags, int *errp)
65437Smws {
66437Smws 	smbios_hdl_t *shp = NULL;
67*1222Smws 	smbios_entry_t *ep;
68437Smws 	caddr_t stbuf, bios, p, q;
69437Smws 	size_t bioslen;
70437Smws 	int err;
71437Smws 
72437Smws 	if (file != NULL || (flags & ~SMB_O_MASK))
73437Smws 		return (smb_open_error(shp, errp, ESMB_INVAL));
74437Smws 
75437Smws 	bioslen = SMB_RANGE_LIMIT - SMB_RANGE_START + 1;
76437Smws 	bios = psm_map_phys(SMB_RANGE_START, bioslen, PSM_PROT_READ);
77437Smws 
78437Smws 	if (bios == NULL)
79437Smws 		return (smb_open_error(shp, errp, ESMB_MAPDEV));
80437Smws 
81437Smws 	for (p = bios, q = bios + bioslen; p < q; p += 16) {
82437Smws 		if (strncmp(p, SMB_ENTRY_EANCHOR, SMB_ENTRY_EANCHORLEN) == 0)
83437Smws 			break;
84437Smws 	}
85437Smws 
86437Smws 	if (p >= q) {
87437Smws 		psm_unmap_phys(bios, bioslen);
88437Smws 		return (smb_open_error(shp, errp, ESMB_NOTFOUND));
89437Smws 	}
90437Smws 
91*1222Smws 	ep = smb_alloc(SMB_ENTRY_MAXLEN);
92*1222Smws 	bcopy(p, ep, sizeof (smbios_entry_t));
93*1222Smws 	ep->smbe_elen = MIN(ep->smbe_elen, SMB_ENTRY_MAXLEN);
94*1222Smws 	bcopy(p, ep, ep->smbe_elen);
95*1222Smws 
96437Smws 	psm_unmap_phys(bios, bioslen);
97*1222Smws 	bios = psm_map_phys(ep->smbe_staddr, ep->smbe_stlen, PSM_PROT_READ);
98437Smws 
99*1222Smws 	if (bios == NULL) {
100*1222Smws 		smb_free(ep, SMB_ENTRY_MAXLEN);
101437Smws 		return (smb_open_error(shp, errp, ESMB_MAPDEV));
102*1222Smws 	}
103437Smws 
104*1222Smws 	stbuf = smb_alloc(ep->smbe_stlen);
105*1222Smws 	bcopy(bios, stbuf, ep->smbe_stlen);
106*1222Smws 	psm_unmap_phys(bios, ep->smbe_stlen);
107*1222Smws 	shp = smbios_bufopen(ep, stbuf, ep->smbe_stlen, version, flags, &err);
108437Smws 
109437Smws 	if (shp == NULL) {
110*1222Smws 		smb_free(stbuf, ep->smbe_stlen);
111*1222Smws 		smb_free(ep, SMB_ENTRY_MAXLEN);
112437Smws 		return (smb_open_error(shp, errp, err));
113437Smws 	}
114437Smws 
115437Smws 	if (ksmbios == NULL) {
116437Smws 		cmn_err(CE_CONT, "?SMBIOS v%u.%u loaded (%u bytes)",
117*1222Smws 		    ep->smbe_major, ep->smbe_minor, ep->smbe_stlen);
118437Smws 	}
119437Smws 
120437Smws 	shp->sh_flags |= SMB_FL_BUFALLOC;
121*1222Smws 	smb_free(ep, SMB_ENTRY_MAXLEN);
122*1222Smws 
123437Smws 	return (shp);
124437Smws }
125437Smws 
126437Smws /*ARGSUSED*/
127437Smws smbios_hdl_t *
smbios_fdopen(int fd,int version,int flags,int * errp)128437Smws smbios_fdopen(int fd, int version, int flags, int *errp)
129437Smws {
130437Smws 	return (smb_open_error(NULL, errp, ENOTSUP));
131437Smws }
132437Smws 
133437Smws /*ARGSUSED*/
134437Smws int
smbios_write(smbios_hdl_t * shp,int fd)135437Smws smbios_write(smbios_hdl_t *shp, int fd)
136437Smws {
137437Smws 	return (smb_set_errno(shp, ENOTSUP));
138437Smws }
139