xref: /freebsd/stand/uboot/glue.c (revision 7c43148a974877188a930e4078a164f83da8e652)
1*9dc70af8SWarner Losh /*-
2*9dc70af8SWarner Losh  * Copyright (c) 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
3*9dc70af8SWarner Losh  * All rights reserved.
4*9dc70af8SWarner Losh  *
5*9dc70af8SWarner Losh  * Redistribution and use in source and binary forms, with or without
6*9dc70af8SWarner Losh  * modification, are permitted provided that the following conditions
7*9dc70af8SWarner Losh  * are met:
8*9dc70af8SWarner Losh  * 1. Redistributions of source code must retain the above copyright
9*9dc70af8SWarner Losh  *    notice, this list of conditions and the following disclaimer.
10*9dc70af8SWarner Losh  * 2. Redistributions in binary form must reproduce the above copyright
11*9dc70af8SWarner Losh  *    notice, this list of conditions and the following disclaimer in the
12*9dc70af8SWarner Losh  *    documentation and/or other materials provided with the distribution.
13*9dc70af8SWarner Losh  *
14*9dc70af8SWarner Losh  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*9dc70af8SWarner Losh  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*9dc70af8SWarner Losh  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*9dc70af8SWarner Losh  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*9dc70af8SWarner Losh  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*9dc70af8SWarner Losh  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*9dc70af8SWarner Losh  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*9dc70af8SWarner Losh  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*9dc70af8SWarner Losh  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*9dc70af8SWarner Losh  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*9dc70af8SWarner Losh  * SUCH DAMAGE.
25*9dc70af8SWarner Losh  */
26*9dc70af8SWarner Losh 
27*9dc70af8SWarner Losh #include <sys/types.h>
28*9dc70af8SWarner Losh 
29*9dc70af8SWarner Losh #include <zlib.h>
30*9dc70af8SWarner Losh #include <stand.h>
31*9dc70af8SWarner Losh #include "api_public.h"
32*9dc70af8SWarner Losh #include "glue.h"
33*9dc70af8SWarner Losh 
34*9dc70af8SWarner Losh #ifdef DEBUG
35*9dc70af8SWarner Losh #define	debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0)
36*9dc70af8SWarner Losh #else
37*9dc70af8SWarner Losh #define	debugf(fmt, args...)
38*9dc70af8SWarner Losh #endif
39*9dc70af8SWarner Losh 
40*9dc70af8SWarner Losh /* Some random address used by U-Boot. */
41*9dc70af8SWarner Losh extern long uboot_address;
42*9dc70af8SWarner Losh 
43*9dc70af8SWarner Losh static int
valid_sig(struct api_signature * sig)44*9dc70af8SWarner Losh valid_sig(struct api_signature *sig)
45*9dc70af8SWarner Losh {
46*9dc70af8SWarner Losh 	uint32_t checksum;
47*9dc70af8SWarner Losh 	struct api_signature s;
48*9dc70af8SWarner Losh 
49*9dc70af8SWarner Losh 	if (sig == NULL)
50*9dc70af8SWarner Losh 		return (0);
51*9dc70af8SWarner Losh 	/*
52*9dc70af8SWarner Losh 	 * Clear the checksum field (in the local copy) so as to calculate the
53*9dc70af8SWarner Losh 	 * CRC with the same initial contents as at the time when the sig was
54*9dc70af8SWarner Losh 	 * produced
55*9dc70af8SWarner Losh 	 */
56*9dc70af8SWarner Losh 	s = *sig;
57*9dc70af8SWarner Losh 	s.checksum = crc32(0, Z_NULL, 0);
58*9dc70af8SWarner Losh 
59*9dc70af8SWarner Losh 	checksum = crc32(s.checksum, (void *)&s, sizeof(struct api_signature));
60*9dc70af8SWarner Losh 
61*9dc70af8SWarner Losh 	if (checksum != sig->checksum)
62*9dc70af8SWarner Losh 		return (0);
63*9dc70af8SWarner Losh 
64*9dc70af8SWarner Losh 	return (1);
65*9dc70af8SWarner Losh }
66*9dc70af8SWarner Losh 
67*9dc70af8SWarner Losh /*
68*9dc70af8SWarner Losh  * Checks to see if API signature's address was given to us as a command line
69*9dc70af8SWarner Losh  * argument by U-Boot.
70*9dc70af8SWarner Losh  *
71*9dc70af8SWarner Losh  * returns 1/0 depending on found/not found result
72*9dc70af8SWarner Losh  */
73*9dc70af8SWarner Losh int
api_parse_cmdline_sig(int argc,char ** argv,struct api_signature ** sig)74*9dc70af8SWarner Losh api_parse_cmdline_sig(int argc, char **argv, struct api_signature **sig)
75*9dc70af8SWarner Losh {
76*9dc70af8SWarner Losh 	unsigned long api_address;
77*9dc70af8SWarner Losh 	int c;
78*9dc70af8SWarner Losh 
79*9dc70af8SWarner Losh 	api_address = 0;
80*9dc70af8SWarner Losh 	opterr = 0;
81*9dc70af8SWarner Losh 	optreset = 1;
82*9dc70af8SWarner Losh 	optind = 1;
83*9dc70af8SWarner Losh 
84*9dc70af8SWarner Losh 	while ((c = getopt (argc, argv, "a:")) != -1)
85*9dc70af8SWarner Losh 		switch (c) {
86*9dc70af8SWarner Losh 		case 'a':
87*9dc70af8SWarner Losh 			api_address = strtoul(optarg, NULL, 16);
88*9dc70af8SWarner Losh 			break;
89*9dc70af8SWarner Losh 		default:
90*9dc70af8SWarner Losh 			break;
91*9dc70af8SWarner Losh 		}
92*9dc70af8SWarner Losh 
93*9dc70af8SWarner Losh 	if (api_address != 0) {
94*9dc70af8SWarner Losh 		*sig = (struct api_signature *)api_address;
95*9dc70af8SWarner Losh 		if (valid_sig(*sig))
96*9dc70af8SWarner Losh 			return (1);
97*9dc70af8SWarner Losh 	}
98*9dc70af8SWarner Losh 
99*9dc70af8SWarner Losh 	return (0);
100*9dc70af8SWarner Losh }
101*9dc70af8SWarner Losh 
102*9dc70af8SWarner Losh /*
103*9dc70af8SWarner Losh  * Searches for the U-Boot API signature
104*9dc70af8SWarner Losh  *
105*9dc70af8SWarner Losh  * returns 1/0 depending on found/not found result
106*9dc70af8SWarner Losh  */
107*9dc70af8SWarner Losh int
api_search_sig(struct api_signature ** sig)108*9dc70af8SWarner Losh api_search_sig(struct api_signature **sig)
109*9dc70af8SWarner Losh {
110*9dc70af8SWarner Losh 	unsigned char *sp, *spend;
111*9dc70af8SWarner Losh 
112*9dc70af8SWarner Losh 	if (sig == NULL)
113*9dc70af8SWarner Losh 		return (0);
114*9dc70af8SWarner Losh 
115*9dc70af8SWarner Losh 	if (uboot_address == 0)
116*9dc70af8SWarner Losh 		uboot_address = 255 * 1024 * 1024;
117*9dc70af8SWarner Losh 
118*9dc70af8SWarner Losh 	sp = (void *)(uboot_address & API_SIG_SEARCH_MASK);
119*9dc70af8SWarner Losh 	spend = sp + API_SIG_SEARCH_LEN - API_SIG_MAGLEN;
120*9dc70af8SWarner Losh 
121*9dc70af8SWarner Losh 	while (sp < spend) {
122*9dc70af8SWarner Losh 		if (!bcmp(sp, API_SIG_MAGIC, API_SIG_MAGLEN)) {
123*9dc70af8SWarner Losh 			*sig = (struct api_signature *)sp;
124*9dc70af8SWarner Losh 			if (valid_sig(*sig))
125*9dc70af8SWarner Losh 				return (1);
126*9dc70af8SWarner Losh 		}
127*9dc70af8SWarner Losh 		sp += API_SIG_MAGLEN;
128*9dc70af8SWarner Losh 	}
129*9dc70af8SWarner Losh 
130*9dc70af8SWarner Losh 	*sig = NULL;
131*9dc70af8SWarner Losh 	return (0);
132*9dc70af8SWarner Losh }
133*9dc70af8SWarner Losh 
134*9dc70af8SWarner Losh /****************************************
135*9dc70af8SWarner Losh  *
136*9dc70af8SWarner Losh  * console
137*9dc70af8SWarner Losh  *
138*9dc70af8SWarner Losh  ****************************************/
139*9dc70af8SWarner Losh 
140*9dc70af8SWarner Losh int
ub_getc(void)141*9dc70af8SWarner Losh ub_getc(void)
142*9dc70af8SWarner Losh {
143*9dc70af8SWarner Losh 	int c;
144*9dc70af8SWarner Losh 
145*9dc70af8SWarner Losh 	if (!syscall(API_GETC, NULL, &c))
146*9dc70af8SWarner Losh 		return (-1);
147*9dc70af8SWarner Losh 
148*9dc70af8SWarner Losh 	return (c);
149*9dc70af8SWarner Losh }
150*9dc70af8SWarner Losh 
151*9dc70af8SWarner Losh int
ub_tstc(void)152*9dc70af8SWarner Losh ub_tstc(void)
153*9dc70af8SWarner Losh {
154*9dc70af8SWarner Losh 	int t;
155*9dc70af8SWarner Losh 
156*9dc70af8SWarner Losh 	if (!syscall(API_TSTC, NULL, &t))
157*9dc70af8SWarner Losh 		return (-1);
158*9dc70af8SWarner Losh 
159*9dc70af8SWarner Losh 	return (t);
160*9dc70af8SWarner Losh }
161*9dc70af8SWarner Losh 
162*9dc70af8SWarner Losh void
ub_putc(const char c)163*9dc70af8SWarner Losh ub_putc(const char c)
164*9dc70af8SWarner Losh {
165*9dc70af8SWarner Losh 
166*9dc70af8SWarner Losh 	syscall(API_PUTC, NULL, &c);
167*9dc70af8SWarner Losh }
168*9dc70af8SWarner Losh 
169*9dc70af8SWarner Losh void
ub_puts(const char * s)170*9dc70af8SWarner Losh ub_puts(const char *s)
171*9dc70af8SWarner Losh {
172*9dc70af8SWarner Losh 
173*9dc70af8SWarner Losh 	syscall(API_PUTS, NULL, s);
174*9dc70af8SWarner Losh }
175*9dc70af8SWarner Losh 
176*9dc70af8SWarner Losh /****************************************
177*9dc70af8SWarner Losh  *
178*9dc70af8SWarner Losh  * system
179*9dc70af8SWarner Losh  *
180*9dc70af8SWarner Losh  ****************************************/
181*9dc70af8SWarner Losh 
182*9dc70af8SWarner Losh void
ub_reset(void)183*9dc70af8SWarner Losh ub_reset(void)
184*9dc70af8SWarner Losh {
185*9dc70af8SWarner Losh 
186*9dc70af8SWarner Losh 	syscall(API_RESET, NULL);
187*9dc70af8SWarner Losh 	while (1);	/* fallback if API_RESET failed */
188*9dc70af8SWarner Losh 	__unreachable();
189*9dc70af8SWarner Losh }
190*9dc70af8SWarner Losh 
191*9dc70af8SWarner Losh static struct mem_region mr[UB_MAX_MR];
192*9dc70af8SWarner Losh static struct sys_info si;
193*9dc70af8SWarner Losh 
194*9dc70af8SWarner Losh struct sys_info *
ub_get_sys_info(void)195*9dc70af8SWarner Losh ub_get_sys_info(void)
196*9dc70af8SWarner Losh {
197*9dc70af8SWarner Losh 	int err = 0;
198*9dc70af8SWarner Losh 
199*9dc70af8SWarner Losh 	memset(&si, 0, sizeof(struct sys_info));
200*9dc70af8SWarner Losh 	si.mr = mr;
201*9dc70af8SWarner Losh 	si.mr_no = UB_MAX_MR;
202*9dc70af8SWarner Losh 	memset(&mr, 0, sizeof(mr));
203*9dc70af8SWarner Losh 
204*9dc70af8SWarner Losh 	if (!syscall(API_GET_SYS_INFO, &err, &si))
205*9dc70af8SWarner Losh 		return (NULL);
206*9dc70af8SWarner Losh 
207*9dc70af8SWarner Losh 	return ((err) ? NULL : &si);
208*9dc70af8SWarner Losh }
209*9dc70af8SWarner Losh 
210*9dc70af8SWarner Losh /****************************************
211*9dc70af8SWarner Losh  *
212*9dc70af8SWarner Losh  * timing
213*9dc70af8SWarner Losh  *
214*9dc70af8SWarner Losh  ****************************************/
215*9dc70af8SWarner Losh 
216*9dc70af8SWarner Losh void
ub_udelay(unsigned long usec)217*9dc70af8SWarner Losh ub_udelay(unsigned long usec)
218*9dc70af8SWarner Losh {
219*9dc70af8SWarner Losh 
220*9dc70af8SWarner Losh 	syscall(API_UDELAY, NULL, &usec);
221*9dc70af8SWarner Losh }
222*9dc70af8SWarner Losh 
223*9dc70af8SWarner Losh unsigned long
ub_get_timer(unsigned long base)224*9dc70af8SWarner Losh ub_get_timer(unsigned long base)
225*9dc70af8SWarner Losh {
226*9dc70af8SWarner Losh 	unsigned long cur;
227*9dc70af8SWarner Losh 
228*9dc70af8SWarner Losh 	if (!syscall(API_GET_TIMER, NULL, &cur, &base))
229*9dc70af8SWarner Losh 		return (0);
230*9dc70af8SWarner Losh 
231*9dc70af8SWarner Losh 	return (cur);
232*9dc70af8SWarner Losh }
233*9dc70af8SWarner Losh 
234*9dc70af8SWarner Losh /****************************************************************************
235*9dc70af8SWarner Losh  *
236*9dc70af8SWarner Losh  * devices
237*9dc70af8SWarner Losh  *
238*9dc70af8SWarner Losh  * Devices are identified by handles: numbers 0, 1, 2, ..., UB_MAX_DEV-1
239*9dc70af8SWarner Losh  *
240*9dc70af8SWarner Losh  ***************************************************************************/
241*9dc70af8SWarner Losh 
242*9dc70af8SWarner Losh static struct device_info devices[UB_MAX_DEV];
243*9dc70af8SWarner Losh 
244*9dc70af8SWarner Losh struct device_info *
ub_dev_get(int i)245*9dc70af8SWarner Losh ub_dev_get(int i)
246*9dc70af8SWarner Losh {
247*9dc70af8SWarner Losh 
248*9dc70af8SWarner Losh 	return ((i < 0 || i >= UB_MAX_DEV) ? NULL : &devices[i]);
249*9dc70af8SWarner Losh }
250*9dc70af8SWarner Losh 
251*9dc70af8SWarner Losh /*
252*9dc70af8SWarner Losh  * Enumerates the devices: fills out device_info elements in the devices[]
253*9dc70af8SWarner Losh  * array.
254*9dc70af8SWarner Losh  *
255*9dc70af8SWarner Losh  * returns:		number of devices found
256*9dc70af8SWarner Losh  */
257*9dc70af8SWarner Losh int
ub_dev_enum(void)258*9dc70af8SWarner Losh ub_dev_enum(void)
259*9dc70af8SWarner Losh {
260*9dc70af8SWarner Losh 	struct device_info *di;
261*9dc70af8SWarner Losh 	int n = 0;
262*9dc70af8SWarner Losh 
263*9dc70af8SWarner Losh 	memset(&devices, 0, sizeof(struct device_info) * UB_MAX_DEV);
264*9dc70af8SWarner Losh 	di = &devices[0];
265*9dc70af8SWarner Losh 
266*9dc70af8SWarner Losh 	if (!syscall(API_DEV_ENUM, NULL, di))
267*9dc70af8SWarner Losh 		return (0);
268*9dc70af8SWarner Losh 
269*9dc70af8SWarner Losh 	while (di->cookie != NULL) {
270*9dc70af8SWarner Losh 
271*9dc70af8SWarner Losh 		if (++n >= UB_MAX_DEV)
272*9dc70af8SWarner Losh 			break;
273*9dc70af8SWarner Losh 
274*9dc70af8SWarner Losh 		/* take another device_info */
275*9dc70af8SWarner Losh 		di++;
276*9dc70af8SWarner Losh 
277*9dc70af8SWarner Losh 		/* pass on the previous cookie */
278*9dc70af8SWarner Losh 		di->cookie = devices[n - 1].cookie;
279*9dc70af8SWarner Losh 
280*9dc70af8SWarner Losh 		if (!syscall(API_DEV_ENUM, NULL, di))
281*9dc70af8SWarner Losh 			return (0);
282*9dc70af8SWarner Losh 	}
283*9dc70af8SWarner Losh 
284*9dc70af8SWarner Losh 	return (n);
285*9dc70af8SWarner Losh }
286*9dc70af8SWarner Losh 
287*9dc70af8SWarner Losh /*
288*9dc70af8SWarner Losh  * handle:	0-based id of the device
289*9dc70af8SWarner Losh  *
290*9dc70af8SWarner Losh  * returns:	0 when OK, err otherwise
291*9dc70af8SWarner Losh  */
292*9dc70af8SWarner Losh int
ub_dev_open(int handle)293*9dc70af8SWarner Losh ub_dev_open(int handle)
294*9dc70af8SWarner Losh {
295*9dc70af8SWarner Losh 	struct device_info *di;
296*9dc70af8SWarner Losh 	int err = 0;
297*9dc70af8SWarner Losh 
298*9dc70af8SWarner Losh 	if (handle < 0 || handle >= UB_MAX_DEV)
299*9dc70af8SWarner Losh 		return (API_EINVAL);
300*9dc70af8SWarner Losh 
301*9dc70af8SWarner Losh 	di = &devices[handle];
302*9dc70af8SWarner Losh 	if (!syscall(API_DEV_OPEN, &err, di))
303*9dc70af8SWarner Losh 		return (-1);
304*9dc70af8SWarner Losh 
305*9dc70af8SWarner Losh 	return (err);
306*9dc70af8SWarner Losh }
307*9dc70af8SWarner Losh 
308*9dc70af8SWarner Losh int
ub_dev_close(int handle)309*9dc70af8SWarner Losh ub_dev_close(int handle)
310*9dc70af8SWarner Losh {
311*9dc70af8SWarner Losh 	struct device_info *di;
312*9dc70af8SWarner Losh 
313*9dc70af8SWarner Losh 	if (handle < 0 || handle >= UB_MAX_DEV)
314*9dc70af8SWarner Losh 		return (API_EINVAL);
315*9dc70af8SWarner Losh 
316*9dc70af8SWarner Losh 	di = &devices[handle];
317*9dc70af8SWarner Losh 	if (!syscall(API_DEV_CLOSE, NULL, di))
318*9dc70af8SWarner Losh 		return (-1);
319*9dc70af8SWarner Losh 
320*9dc70af8SWarner Losh 	return (0);
321*9dc70af8SWarner Losh }
322*9dc70af8SWarner Losh 
323*9dc70af8SWarner Losh /*
324*9dc70af8SWarner Losh  * Validates device for read/write, it has to:
325*9dc70af8SWarner Losh  *
326*9dc70af8SWarner Losh  * - have sane handle
327*9dc70af8SWarner Losh  * - be opened
328*9dc70af8SWarner Losh  *
329*9dc70af8SWarner Losh  * returns:	0/1 accordingly
330*9dc70af8SWarner Losh  */
331*9dc70af8SWarner Losh static int
dev_valid(int handle)332*9dc70af8SWarner Losh dev_valid(int handle)
333*9dc70af8SWarner Losh {
334*9dc70af8SWarner Losh 
335*9dc70af8SWarner Losh 	if (handle < 0 || handle >= UB_MAX_DEV)
336*9dc70af8SWarner Losh 		return (0);
337*9dc70af8SWarner Losh 
338*9dc70af8SWarner Losh 	if (devices[handle].state != DEV_STA_OPEN)
339*9dc70af8SWarner Losh 		return (0);
340*9dc70af8SWarner Losh 
341*9dc70af8SWarner Losh 	return (1);
342*9dc70af8SWarner Losh }
343*9dc70af8SWarner Losh 
344*9dc70af8SWarner Losh static int
dev_stor_valid(int handle)345*9dc70af8SWarner Losh dev_stor_valid(int handle)
346*9dc70af8SWarner Losh {
347*9dc70af8SWarner Losh 
348*9dc70af8SWarner Losh 	if (!dev_valid(handle))
349*9dc70af8SWarner Losh 		return (0);
350*9dc70af8SWarner Losh 
351*9dc70af8SWarner Losh 	if (!(devices[handle].type & DEV_TYP_STOR))
352*9dc70af8SWarner Losh 		return (0);
353*9dc70af8SWarner Losh 
354*9dc70af8SWarner Losh 	return (1);
355*9dc70af8SWarner Losh }
356*9dc70af8SWarner Losh 
357*9dc70af8SWarner Losh int
ub_dev_read(int handle,void * buf,lbasize_t len,lbastart_t start,lbasize_t * rlen)358*9dc70af8SWarner Losh ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start,
359*9dc70af8SWarner Losh     lbasize_t *rlen)
360*9dc70af8SWarner Losh {
361*9dc70af8SWarner Losh 	struct device_info *di;
362*9dc70af8SWarner Losh 	lbasize_t act_len;
363*9dc70af8SWarner Losh 	int err = 0;
364*9dc70af8SWarner Losh 
365*9dc70af8SWarner Losh 	if (!dev_stor_valid(handle))
366*9dc70af8SWarner Losh 		return (API_ENODEV);
367*9dc70af8SWarner Losh 
368*9dc70af8SWarner Losh 	di = &devices[handle];
369*9dc70af8SWarner Losh 	if (!syscall(API_DEV_READ, &err, di, buf, &len, &start, &act_len))
370*9dc70af8SWarner Losh 		return (API_ESYSC);
371*9dc70af8SWarner Losh 
372*9dc70af8SWarner Losh 	if (!err && rlen)
373*9dc70af8SWarner Losh 		*rlen = act_len;
374*9dc70af8SWarner Losh 
375*9dc70af8SWarner Losh 	return (err);
376*9dc70af8SWarner Losh }
377*9dc70af8SWarner Losh 
378*9dc70af8SWarner Losh static int
dev_net_valid(int handle)379*9dc70af8SWarner Losh dev_net_valid(int handle)
380*9dc70af8SWarner Losh {
381*9dc70af8SWarner Losh 
382*9dc70af8SWarner Losh 	if (!dev_valid(handle))
383*9dc70af8SWarner Losh 		return (0);
384*9dc70af8SWarner Losh 
385*9dc70af8SWarner Losh 	if (devices[handle].type != DEV_TYP_NET)
386*9dc70af8SWarner Losh 		return (0);
387*9dc70af8SWarner Losh 
388*9dc70af8SWarner Losh 	return (1);
389*9dc70af8SWarner Losh }
390*9dc70af8SWarner Losh 
391*9dc70af8SWarner Losh int
ub_dev_recv(int handle,void * buf,int len,int * rlen)392*9dc70af8SWarner Losh ub_dev_recv(int handle, void *buf, int len, int *rlen)
393*9dc70af8SWarner Losh {
394*9dc70af8SWarner Losh 	struct device_info *di;
395*9dc70af8SWarner Losh 	int err = 0, act_len;
396*9dc70af8SWarner Losh 
397*9dc70af8SWarner Losh 	if (!dev_net_valid(handle))
398*9dc70af8SWarner Losh 		return (API_ENODEV);
399*9dc70af8SWarner Losh 
400*9dc70af8SWarner Losh 	di = &devices[handle];
401*9dc70af8SWarner Losh 	if (!syscall(API_DEV_READ, &err, di, buf, &len, &act_len))
402*9dc70af8SWarner Losh 		return (API_ESYSC);
403*9dc70af8SWarner Losh 
404*9dc70af8SWarner Losh 	if (!err)
405*9dc70af8SWarner Losh 		*rlen = act_len;
406*9dc70af8SWarner Losh 
407*9dc70af8SWarner Losh 	return (err);
408*9dc70af8SWarner Losh }
409*9dc70af8SWarner Losh 
410*9dc70af8SWarner Losh int
ub_dev_send(int handle,void * buf,int len)411*9dc70af8SWarner Losh ub_dev_send(int handle, void *buf, int len)
412*9dc70af8SWarner Losh {
413*9dc70af8SWarner Losh 	struct device_info *di;
414*9dc70af8SWarner Losh 	int err = 0;
415*9dc70af8SWarner Losh 
416*9dc70af8SWarner Losh 	if (!dev_net_valid(handle))
417*9dc70af8SWarner Losh 		return (API_ENODEV);
418*9dc70af8SWarner Losh 
419*9dc70af8SWarner Losh 	di = &devices[handle];
420*9dc70af8SWarner Losh 	if (!syscall(API_DEV_WRITE, &err, di, buf, &len))
421*9dc70af8SWarner Losh 		return (API_ESYSC);
422*9dc70af8SWarner Losh 
423*9dc70af8SWarner Losh 	return (err);
424*9dc70af8SWarner Losh }
425*9dc70af8SWarner Losh 
426*9dc70af8SWarner Losh char *
ub_stor_type(int type)427*9dc70af8SWarner Losh ub_stor_type(int type)
428*9dc70af8SWarner Losh {
429*9dc70af8SWarner Losh 
430*9dc70af8SWarner Losh 	if (type & DT_STOR_IDE)
431*9dc70af8SWarner Losh 		return ("IDE");
432*9dc70af8SWarner Losh 
433*9dc70af8SWarner Losh 	if (type & DT_STOR_SCSI)
434*9dc70af8SWarner Losh 		return ("SCSI");
435*9dc70af8SWarner Losh 
436*9dc70af8SWarner Losh 	if (type & DT_STOR_USB)
437*9dc70af8SWarner Losh 		return ("USB");
438*9dc70af8SWarner Losh 
439*9dc70af8SWarner Losh 	if (type & DT_STOR_MMC)
440*9dc70af8SWarner Losh 		return ("MMC");
441*9dc70af8SWarner Losh 
442*9dc70af8SWarner Losh 	if (type & DT_STOR_SATA)
443*9dc70af8SWarner Losh 		return ("SATA");
444*9dc70af8SWarner Losh 
445*9dc70af8SWarner Losh 	return ("Unknown");
446*9dc70af8SWarner Losh }
447*9dc70af8SWarner Losh 
448*9dc70af8SWarner Losh char *
ub_mem_type(int flags)449*9dc70af8SWarner Losh ub_mem_type(int flags)
450*9dc70af8SWarner Losh {
451*9dc70af8SWarner Losh 
452*9dc70af8SWarner Losh 	switch (flags & 0x000F) {
453*9dc70af8SWarner Losh 	case MR_ATTR_FLASH:
454*9dc70af8SWarner Losh 		return ("FLASH");
455*9dc70af8SWarner Losh 	case MR_ATTR_DRAM:
456*9dc70af8SWarner Losh 		return ("DRAM");
457*9dc70af8SWarner Losh 	case MR_ATTR_SRAM:
458*9dc70af8SWarner Losh 		return ("SRAM");
459*9dc70af8SWarner Losh 	default:
460*9dc70af8SWarner Losh 		return ("Unknown");
461*9dc70af8SWarner Losh 	}
462*9dc70af8SWarner Losh }
463*9dc70af8SWarner Losh 
464*9dc70af8SWarner Losh void
ub_dump_di(int handle)465*9dc70af8SWarner Losh ub_dump_di(int handle)
466*9dc70af8SWarner Losh {
467*9dc70af8SWarner Losh 	struct device_info *di = ub_dev_get(handle);
468*9dc70af8SWarner Losh 	int i;
469*9dc70af8SWarner Losh 
470*9dc70af8SWarner Losh 	printf("device info (%d):\n", handle);
471*9dc70af8SWarner Losh 	printf("  cookie\t= %p\n", di->cookie);
472*9dc70af8SWarner Losh 	printf("  type\t\t= 0x%08x\n", di->type);
473*9dc70af8SWarner Losh 
474*9dc70af8SWarner Losh 	if (di->type == DEV_TYP_NET) {
475*9dc70af8SWarner Losh 		printf("  hwaddr\t= ");
476*9dc70af8SWarner Losh 		for (i = 0; i < 6; i++)
477*9dc70af8SWarner Losh 			printf("%02x ", di->di_net.hwaddr[i]);
478*9dc70af8SWarner Losh 
479*9dc70af8SWarner Losh 		printf("\n");
480*9dc70af8SWarner Losh 
481*9dc70af8SWarner Losh 	} else if (di->type & DEV_TYP_STOR) {
482*9dc70af8SWarner Losh 		printf("  type\t\t= %s\n", ub_stor_type(di->type));
483*9dc70af8SWarner Losh 		printf("  blk size\t\t= %ld\n", di->di_stor.block_size);
484*9dc70af8SWarner Losh 		printf("  blk count\t\t= %ld\n", di->di_stor.block_count);
485*9dc70af8SWarner Losh 	}
486*9dc70af8SWarner Losh }
487*9dc70af8SWarner Losh 
488*9dc70af8SWarner Losh void
ub_dump_si(struct sys_info * si)489*9dc70af8SWarner Losh ub_dump_si(struct sys_info *si)
490*9dc70af8SWarner Losh {
491*9dc70af8SWarner Losh 	int i;
492*9dc70af8SWarner Losh 
493*9dc70af8SWarner Losh 	printf("sys info:\n");
494*9dc70af8SWarner Losh 	printf("  clkbus\t= %ld MHz\n", si->clk_bus / 1000 / 1000);
495*9dc70af8SWarner Losh 	printf("  clkcpu\t= %ld MHz\n", si->clk_cpu / 1000 / 1000);
496*9dc70af8SWarner Losh 	printf("  bar\t\t= 0x%08lx\n", si->bar);
497*9dc70af8SWarner Losh 
498*9dc70af8SWarner Losh 	printf("---\n");
499*9dc70af8SWarner Losh 	for (i = 0; i < si->mr_no; i++) {
500*9dc70af8SWarner Losh 		if (si->mr[i].flags == 0)
501*9dc70af8SWarner Losh 			break;
502*9dc70af8SWarner Losh 
503*9dc70af8SWarner Losh 		printf("  start\t= 0x%08lx\n", si->mr[i].start);
504*9dc70af8SWarner Losh 		printf("  size\t= 0x%08lx\n", si->mr[i].size);
505*9dc70af8SWarner Losh 		printf("  type\t= %s\n", ub_mem_type(si->mr[i].flags));
506*9dc70af8SWarner Losh 		printf("---\n");
507*9dc70af8SWarner Losh 	}
508*9dc70af8SWarner Losh }
509*9dc70af8SWarner Losh 
510*9dc70af8SWarner Losh /****************************************
511*9dc70af8SWarner Losh  *
512*9dc70af8SWarner Losh  * env vars
513*9dc70af8SWarner Losh  *
514*9dc70af8SWarner Losh  ****************************************/
515*9dc70af8SWarner Losh 
516*9dc70af8SWarner Losh char *
ub_env_get(const char * name)517*9dc70af8SWarner Losh ub_env_get(const char *name)
518*9dc70af8SWarner Losh {
519*9dc70af8SWarner Losh 	char *value;
520*9dc70af8SWarner Losh 
521*9dc70af8SWarner Losh 	if (!syscall(API_ENV_GET, NULL, name, &value))
522*9dc70af8SWarner Losh 		return (NULL);
523*9dc70af8SWarner Losh 
524*9dc70af8SWarner Losh 	return (value);
525*9dc70af8SWarner Losh }
526*9dc70af8SWarner Losh 
527*9dc70af8SWarner Losh void
ub_env_set(const char * name,char * value)528*9dc70af8SWarner Losh ub_env_set(const char *name, char *value)
529*9dc70af8SWarner Losh {
530*9dc70af8SWarner Losh 
531*9dc70af8SWarner Losh 	syscall(API_ENV_SET, NULL, name, value);
532*9dc70af8SWarner Losh }
533*9dc70af8SWarner Losh 
534*9dc70af8SWarner Losh static char env_name[256];
535*9dc70af8SWarner Losh 
536*9dc70af8SWarner Losh const char *
ub_env_enum(const char * last)537*9dc70af8SWarner Losh ub_env_enum(const char *last)
538*9dc70af8SWarner Losh {
539*9dc70af8SWarner Losh 	const char *env, *str;
540*9dc70af8SWarner Losh 	int i;
541*9dc70af8SWarner Losh 
542*9dc70af8SWarner Losh 	/*
543*9dc70af8SWarner Losh 	 * It's OK to pass only the name piece as last (and not the whole
544*9dc70af8SWarner Losh 	 * 'name=val' string), since the API_ENUM_ENV call uses envmatch()
545*9dc70af8SWarner Losh 	 * internally, which handles such case
546*9dc70af8SWarner Losh 	 */
547*9dc70af8SWarner Losh 	env = NULL;
548*9dc70af8SWarner Losh 	if (!syscall(API_ENV_ENUM, NULL, last, &env))
549*9dc70af8SWarner Losh 		return (NULL);
550*9dc70af8SWarner Losh 
551*9dc70af8SWarner Losh 	if (env == NULL || last == env)
552*9dc70af8SWarner Losh 		/* no more env. variables to enumerate */
553*9dc70af8SWarner Losh 		return (NULL);
554*9dc70af8SWarner Losh 
555*9dc70af8SWarner Losh 	/* next enumerated env var */
556*9dc70af8SWarner Losh 	memset(env_name, 0, 256);
557*9dc70af8SWarner Losh 	for (i = 0, str = env; *str != '=' && *str != '\0';)
558*9dc70af8SWarner Losh 		env_name[i++] = *str++;
559*9dc70af8SWarner Losh 
560*9dc70af8SWarner Losh 	env_name[i] = '\0';
561*9dc70af8SWarner Losh 
562*9dc70af8SWarner Losh 	return (env_name);
563*9dc70af8SWarner Losh }
564