xref: /illumos-gate/usr/src/uts/i86pc/os/smb_dev.c (revision 355b4669e025ff377602b6fc7caaf30dbc218371)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*
24  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
29 
30 /*
31  * Platform-Specific SMBIOS Subroutines
32  *
33  * The routines in this file form part of <sys/smbios_impl.h> and combine with
34  * the usr/src/common/smbios code to form an in-kernel SMBIOS decoding service.
35  * The SMBIOS entry point is locating by scanning a range of physical memory
36  * assigned to BIOS as described in Section 2 of the DMTF SMBIOS specification.
37  */
38 
39 #include <sys/smbios_impl.h>
40 #include <sys/sysmacros.h>
41 #include <sys/errno.h>
42 #include <sys/psm.h>
43 #include <sys/smp_impldefs.h>
44 
45 smbios_hdl_t *ksmbios;
46 int ksmbios_flags;
47 
48 smbios_hdl_t *
49 smb_open_error(smbios_hdl_t *shp, int *errp, int err)
50 {
51 	if (shp != NULL)
52 		smbios_close(shp);
53 
54 	if (errp != NULL)
55 		*errp = err;
56 
57 	if (ksmbios == NULL)
58 		cmn_err(CE_CONT, "?SMBIOS not loaded (%s)", smbios_errmsg(err));
59 
60 	return (NULL);
61 }
62 
63 smbios_hdl_t *
64 smbios_open(const char *file, int version, int flags, int *errp)
65 {
66 	smbios_hdl_t *shp = NULL;
67 	smbios_entry_t *ep;
68 	caddr_t stbuf, bios, p, q;
69 	size_t bioslen;
70 	int err;
71 
72 	if (file != NULL || (flags & ~SMB_O_MASK))
73 		return (smb_open_error(shp, errp, ESMB_INVAL));
74 
75 	bioslen = SMB_RANGE_LIMIT - SMB_RANGE_START + 1;
76 	bios = psm_map_phys(SMB_RANGE_START, bioslen, PSM_PROT_READ);
77 
78 	if (bios == NULL)
79 		return (smb_open_error(shp, errp, ESMB_MAPDEV));
80 
81 	for (p = bios, q = bios + bioslen; p < q; p += 16) {
82 		if (strncmp(p, SMB_ENTRY_EANCHOR, SMB_ENTRY_EANCHORLEN) == 0)
83 			break;
84 	}
85 
86 	if (p >= q) {
87 		psm_unmap_phys(bios, bioslen);
88 		return (smb_open_error(shp, errp, ESMB_NOTFOUND));
89 	}
90 
91 	ep = smb_alloc(SMB_ENTRY_MAXLEN);
92 	bcopy(p, ep, sizeof (smbios_entry_t));
93 	ep->smbe_elen = MIN(ep->smbe_elen, SMB_ENTRY_MAXLEN);
94 	bcopy(p, ep, ep->smbe_elen);
95 
96 	psm_unmap_phys(bios, bioslen);
97 	bios = psm_map_phys(ep->smbe_staddr, ep->smbe_stlen, PSM_PROT_READ);
98 
99 	if (bios == NULL) {
100 		smb_free(ep, SMB_ENTRY_MAXLEN);
101 		return (smb_open_error(shp, errp, ESMB_MAPDEV));
102 	}
103 
104 	stbuf = smb_alloc(ep->smbe_stlen);
105 	bcopy(bios, stbuf, ep->smbe_stlen);
106 	psm_unmap_phys(bios, ep->smbe_stlen);
107 	shp = smbios_bufopen(ep, stbuf, ep->smbe_stlen, version, flags, &err);
108 
109 	if (shp == NULL) {
110 		smb_free(stbuf, ep->smbe_stlen);
111 		smb_free(ep, SMB_ENTRY_MAXLEN);
112 		return (smb_open_error(shp, errp, err));
113 	}
114 
115 	if (ksmbios == NULL) {
116 		cmn_err(CE_CONT, "?SMBIOS v%u.%u loaded (%u bytes)",
117 		    ep->smbe_major, ep->smbe_minor, ep->smbe_stlen);
118 	}
119 
120 	shp->sh_flags |= SMB_FL_BUFALLOC;
121 	smb_free(ep, SMB_ENTRY_MAXLEN);
122 
123 	return (shp);
124 }
125 
126 /*ARGSUSED*/
127 smbios_hdl_t *
128 smbios_fdopen(int fd, int version, int flags, int *errp)
129 {
130 	return (smb_open_error(NULL, errp, ENOTSUP));
131 }
132 
133 /*ARGSUSED*/
134 int
135 smbios_write(smbios_hdl_t *shp, int fd)
136 {
137 	return (smb_set_errno(shp, ENOTSUP));
138 }
139