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