xref: /titanic_51/usr/src/cmd/eeprom/i386/benv_kvm.c (revision 3b133bec939f5230f040960ee1503dadd3dff343)
1ae115bc7Smrj /*
2ae115bc7Smrj  * CDDL HEADER START
3ae115bc7Smrj  *
4ae115bc7Smrj  * The contents of this file are subject to the terms of the
5*3b133becSGangadhar Mylapuram  * Common Development and Distribution License (the "License").
6*3b133becSGangadhar Mylapuram  * You may not use this file except in compliance with the License.
7ae115bc7Smrj  *
8ae115bc7Smrj  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9ae115bc7Smrj  * or http://www.opensolaris.org/os/licensing.
10ae115bc7Smrj  * See the License for the specific language governing permissions
11ae115bc7Smrj  * and limitations under the License.
12ae115bc7Smrj  *
13ae115bc7Smrj  * When distributing Covered Code, include this CDDL HEADER in each
14ae115bc7Smrj  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15ae115bc7Smrj  * If applicable, add the following below this CDDL HEADER, with the
16ae115bc7Smrj  * fields enclosed by brackets "[]" replaced with your own identifying
17ae115bc7Smrj  * information: Portions Copyright [yyyy] [name of copyright owner]
18ae115bc7Smrj  *
19ae115bc7Smrj  * CDDL HEADER END
20ae115bc7Smrj  */
21ae115bc7Smrj /*
22*3b133becSGangadhar Mylapuram  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23ae115bc7Smrj  * Use is subject to license terms.
24ae115bc7Smrj  */
25ae115bc7Smrj 
26ae115bc7Smrj 
27ae115bc7Smrj #include "benv.h"
28ae115bc7Smrj #include <sys/sunddi.h>
29ae115bc7Smrj #include <sys/ddi_impldefs.h>
30ae115bc7Smrj #include <sys/openpromio.h>
31ae115bc7Smrj #include <stdio.h>
32ae115bc7Smrj 
33ae115bc7Smrj static int getpropval(struct openpromio *opp, char *prop);
34ae115bc7Smrj 
35ae115bc7Smrj static char *promdev = "/dev/openprom";
36ae115bc7Smrj static int prom_fd;
37ae115bc7Smrj static char *mfail = "malloc";
38ae115bc7Smrj 
39ae115bc7Smrj /*
40ae115bc7Smrj  * 128 is the size of the largest (currently) property name
41ae115bc7Smrj  * 16384 - MAXPROPSIZE - sizeof (int) is the size of the largest
42ae115bc7Smrj  * (currently) property value that is allowed.
43ae115bc7Smrj  * the sizeof (u_int) is from struct openpromio
44ae115bc7Smrj  */
45ae115bc7Smrj 
46ae115bc7Smrj #define	MAXPROPSIZE	128
47ae115bc7Smrj #define	MAXVALSIZE	(16384 - MAXPROPSIZE - sizeof (u_int))
48ae115bc7Smrj #define	BUFSIZE		(MAXPROPSIZE + MAXVALSIZE + sizeof (u_int))
49ae115bc7Smrj #define	MINVALSIZE	(4 * sizeof (u_long))
50ae115bc7Smrj #define	MINBUFSIZE	(MINVALSIZE + sizeof (u_long))
51ae115bc7Smrj 
52ae115bc7Smrj typedef union {
53ae115bc7Smrj 	char buf[BUFSIZE];
54ae115bc7Smrj 	struct openpromio opp;
55ae115bc7Smrj } Oppbuf;
56ae115bc7Smrj 
57ae115bc7Smrj typedef union {
58ae115bc7Smrj 	char buf[MINVALSIZE + sizeof (u_int)];
59ae115bc7Smrj 	struct openpromio opp;
60ae115bc7Smrj } Oppbuf_small;
61ae115bc7Smrj 
62ae115bc7Smrj static Oppbuf	oppbuf;
63ae115bc7Smrj 
64ae115bc7Smrj static unsigned long
65ae115bc7Smrj next(unsigned long id)
66ae115bc7Smrj {
67ae115bc7Smrj 	Oppbuf_small	oppbuf;
68ae115bc7Smrj 	struct openpromio *opp = &(oppbuf.opp);
69ae115bc7Smrj 	unsigned long *ip = (unsigned long *)(opp->oprom_array);
70ae115bc7Smrj 
71ae115bc7Smrj 	memset(oppbuf.buf, 0, MINBUFSIZE);
72ae115bc7Smrj 	opp->oprom_size = MINVALSIZE;
73ae115bc7Smrj 	*ip = id;
74ae115bc7Smrj 	if (ioctl(prom_fd, OPROMNEXT, opp) < 0)
75ae115bc7Smrj 		return (0);
76ae115bc7Smrj 	return (*(unsigned long *)opp->oprom_array);
77ae115bc7Smrj }
78ae115bc7Smrj 
79ae115bc7Smrj static unsigned long
80ae115bc7Smrj child(unsigned long id)
81ae115bc7Smrj {
82ae115bc7Smrj 	Oppbuf_small	oppbuf;
83ae115bc7Smrj 	struct openpromio *opp = &(oppbuf.opp);
84ae115bc7Smrj 	unsigned long *ip = (unsigned long *)(opp->oprom_array);
85ae115bc7Smrj 
86ae115bc7Smrj 	memset(oppbuf.buf, 0, MINBUFSIZE);
87ae115bc7Smrj 	opp->oprom_size = MINVALSIZE;
88ae115bc7Smrj 	*ip = id;
89ae115bc7Smrj 	if (ioctl(prom_fd, OPROMCHILD, opp) < 0)
90ae115bc7Smrj 		return (0);
91ae115bc7Smrj 	return (*(unsigned long *)opp->oprom_array);
92ae115bc7Smrj }
93ae115bc7Smrj 
94ae115bc7Smrj /*
95ae115bc7Smrj  * Find a node by name from the prom device tree.
96ae115bc7Smrj  * Return the id or 0 if it is not found.
97ae115bc7Smrj  */
98ae115bc7Smrj static unsigned long
99ae115bc7Smrj prom_findnode_byname(unsigned long id, char *name)
100ae115bc7Smrj {
101ae115bc7Smrj 	struct openpromio *opp = &(oppbuf.opp);
102ae115bc7Smrj 	unsigned long nid;
103ae115bc7Smrj 
104ae115bc7Smrj 	if (id == 0)
105ae115bc7Smrj 		return (0);
106ae115bc7Smrj 	if (!getpropval(opp, "name"))
107ae115bc7Smrj 		return (0);
108ae115bc7Smrj 	if (strcmp(opp->oprom_array, name) == 0)
109ae115bc7Smrj 		return (id);
110ae115bc7Smrj 	if (nid = prom_findnode_byname(child(id), name))
111ae115bc7Smrj 		return (nid);
112ae115bc7Smrj 	if (nid = prom_findnode_byname(next(id), name))
113ae115bc7Smrj 		return (nid);
114ae115bc7Smrj 	return (0);
115ae115bc7Smrj }
116ae115bc7Smrj 
117ae115bc7Smrj /*
118ae115bc7Smrj  * Make the current prom node be the rootnode and return its id.
119ae115bc7Smrj  */
120ae115bc7Smrj static unsigned long
121ae115bc7Smrj prom_rootnode()
122ae115bc7Smrj {
123ae115bc7Smrj 	return (next(0));
124ae115bc7Smrj }
125ae115bc7Smrj 
126ae115bc7Smrj static int
127ae115bc7Smrj getpropval(struct openpromio *opp, char *prop)
128ae115bc7Smrj {
129ae115bc7Smrj 	opp->oprom_size = MAXVALSIZE;
130ae115bc7Smrj 
131ae115bc7Smrj 	(void) strlcpy(opp->oprom_array, prop, MAXPROPSIZE);
132ae115bc7Smrj 	if (ioctl(prom_fd, OPROMGETPROP, opp) < 0)
133ae115bc7Smrj 		return (0);
134ae115bc7Smrj 	if (opp->oprom_size == 0)
135ae115bc7Smrj 		return (0);
136ae115bc7Smrj 	return (1);
137ae115bc7Smrj }
138ae115bc7Smrj 
139ae115bc7Smrj static int
140ae115bc7Smrj getnextprop(struct openpromio *opp, char *prop)
141ae115bc7Smrj {
142ae115bc7Smrj 	opp->oprom_size = MAXVALSIZE;
143ae115bc7Smrj 
144ae115bc7Smrj 	(void) strlcpy(opp->oprom_array, prop, MAXPROPSIZE);
145ae115bc7Smrj 	if (ioctl(prom_fd, OPROMNXTPROP, opp) < 0)
146ae115bc7Smrj 		return (0);
147ae115bc7Smrj 	if (opp->oprom_size == 0)
148ae115bc7Smrj 		return (0);
149ae115bc7Smrj 	return (1);
150ae115bc7Smrj }
151ae115bc7Smrj 
152*3b133becSGangadhar Mylapuram char *
153*3b133becSGangadhar Mylapuram getbootcmd(void)
154*3b133becSGangadhar Mylapuram {
155*3b133becSGangadhar Mylapuram 	struct openpromio *opp = &(oppbuf.opp);
156*3b133becSGangadhar Mylapuram 	opp->oprom_size = MAXVALSIZE;
157*3b133becSGangadhar Mylapuram 	if (ioctl(prom_fd, OPROMGETBOOTPATH, opp) < 0)
158*3b133becSGangadhar Mylapuram 		return (NULL);
159*3b133becSGangadhar Mylapuram 	return (opp->oprom_array);
160*3b133becSGangadhar Mylapuram }
161*3b133becSGangadhar Mylapuram 
162ae115bc7Smrj /*
163ae115bc7Smrj  * Get a pointer to the requested property from the current node.
164ae115bc7Smrj  * The property is stored in static storage and the returned pointer
165ae115bc7Smrj  * points into the static storage.  The property length is placed in
166ae115bc7Smrj  * the location pointed to by the third argument.
167ae115bc7Smrj  */
168ae115bc7Smrj static unsigned char *
169ae115bc7Smrj prom_getprop(char *prop, int *lenp)
170ae115bc7Smrj {
171ae115bc7Smrj 	struct openpromio *opp = &(oppbuf.opp);
172ae115bc7Smrj 
173ae115bc7Smrj 	if (!getpropval(opp, prop))
174ae115bc7Smrj 		return (NULL);
175ae115bc7Smrj 	*lenp = opp->oprom_size;
176ae115bc7Smrj 	return ((unsigned char *)opp->oprom_array);
177ae115bc7Smrj }
178ae115bc7Smrj 
179ae115bc7Smrj static unsigned char *
180ae115bc7Smrj prom_nextprop(char *prop)
181ae115bc7Smrj {
182ae115bc7Smrj 	struct openpromio *opp = &(oppbuf.opp);
183ae115bc7Smrj 
184ae115bc7Smrj 	if (!getnextprop(opp, prop))
185ae115bc7Smrj 		return ((unsigned char *)0);
186ae115bc7Smrj 	return ((unsigned char *)opp->oprom_array);
187ae115bc7Smrj }
188ae115bc7Smrj 
189ae115bc7Smrj ddi_prop_t *
190ae115bc7Smrj get_proplist(char *name)
191ae115bc7Smrj {
192ae115bc7Smrj 	ddi_prop_t *plist, *npp, *plast;
193ae115bc7Smrj 	char *curprop, *newprop;
194ae115bc7Smrj 	unsigned char *propval;
195ae115bc7Smrj 	unsigned long id;
196ae115bc7Smrj 
197ae115bc7Smrj 	plist = NULL;
198ae115bc7Smrj 	plast = NULL;
199ae115bc7Smrj 	id = prom_findnode_byname(prom_rootnode(), name);
200ae115bc7Smrj 	if (id == 0)
201ae115bc7Smrj 		return (plist);
202ae115bc7Smrj 	curprop = "";
203ae115bc7Smrj 	while (newprop = (char *)prom_nextprop(curprop)) {
204ae115bc7Smrj 		curprop = strdup(newprop);
205ae115bc7Smrj 		npp = (ddi_prop_t *)malloc(sizeof (ddi_prop_t));
206ae115bc7Smrj 		if (npp == 0)
207ae115bc7Smrj 			exit(_error(PERROR, mfail));
208ae115bc7Smrj 		propval = prom_getprop(curprop, &npp->prop_len);
209ae115bc7Smrj 		npp->prop_name = curprop;
210ae115bc7Smrj 		if (propval != NULL) {
211ae115bc7Smrj 			npp->prop_val = (char *)malloc(npp->prop_len);
212ae115bc7Smrj 			if (npp->prop_val == 0)
213ae115bc7Smrj 				exit(_error(PERROR, mfail));
214ae115bc7Smrj 			memcpy(npp->prop_val, propval, npp->prop_len);
215ae115bc7Smrj 		} else
216ae115bc7Smrj 			npp->prop_val = NULL;
217ae115bc7Smrj 		npp->prop_next = NULL;
218ae115bc7Smrj 		if (plast == NULL) {
219ae115bc7Smrj 			plist = npp;
220ae115bc7Smrj 		} else {
221ae115bc7Smrj 			plast->prop_next = npp;
222ae115bc7Smrj 		}
223ae115bc7Smrj 		plast = npp;
224ae115bc7Smrj 	}
225ae115bc7Smrj 	return (plist);
226ae115bc7Smrj }
227ae115bc7Smrj 
228ae115bc7Smrj caddr_t
229ae115bc7Smrj get_propval(char *name, char *node)
230ae115bc7Smrj {
231ae115bc7Smrj 	ddi_prop_t *prop, *plist;
232ae115bc7Smrj 
233ae115bc7Smrj 	if ((plist = get_proplist(node)) == NULL)
234ae115bc7Smrj 		return (NULL);
235ae115bc7Smrj 
236ae115bc7Smrj 	for (prop = plist; prop != NULL; prop = prop->prop_next)
237ae115bc7Smrj 		if (strcmp(prop->prop_name, name) == 0)
238ae115bc7Smrj 			return (prop->prop_val);
239ae115bc7Smrj 
240ae115bc7Smrj 	return (NULL);
241ae115bc7Smrj }
242ae115bc7Smrj 
243ae115bc7Smrj void
244ae115bc7Smrj get_kbenv(void)
245ae115bc7Smrj {
246ae115bc7Smrj 	if ((prom_fd = open(promdev, O_RDONLY)) < 0) {
247ae115bc7Smrj 		exit(_error(PERROR, "prom open failed"));
248ae115bc7Smrj 	}
249ae115bc7Smrj }
250ae115bc7Smrj 
251ae115bc7Smrj void
252ae115bc7Smrj close_kbenv(void)
253ae115bc7Smrj {
254ae115bc7Smrj 	(void) close(prom_fd);
255ae115bc7Smrj }
256