glue.c revision 183878
1176348Smarcel/*-
2182732Sraj * Copyright (c) 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
3176348Smarcel * All rights reserved.
4176348Smarcel *
5176348Smarcel * Redistribution and use in source and binary forms, with or without
6176348Smarcel * modification, are permitted provided that the following conditions
7176348Smarcel * are met:
8176348Smarcel * 1. Redistributions of source code must retain the above copyright
9176348Smarcel *    notice, this list of conditions and the following disclaimer.
10176348Smarcel * 2. Redistributions in binary form must reproduce the above copyright
11176348Smarcel *    notice, this list of conditions and the following disclaimer in the
12176348Smarcel *    documentation and/or other materials provided with the distribution.
13176348Smarcel *
14176348Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15176348Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16176348Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17176348Smarcel * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18176348Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19176348Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20176348Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21176348Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22176348Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23176348Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24176348Smarcel * SUCH DAMAGE.
25176348Smarcel */
26176348Smarcel
27176348Smarcel#include <sys/cdefs.h>
28176348Smarcel__FBSDID("$FreeBSD: head/sys/boot/uboot/lib/glue.c 183878 2008-10-14 10:11:14Z raj $");
29176348Smarcel
30176348Smarcel#include <stand.h>
31176348Smarcel#include "api_public.h"
32176481Smarcel#include "glue.h"
33176348Smarcel
34176481Smarcel#define DEBUG
35176348Smarcel#undef DEBUG
36176348Smarcel
37176348Smarcel#ifdef DEBUG
38177152Sobrien#define	debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0)
39176348Smarcel#else
40177152Sobrien#define	debugf(fmt, args...)
41176348Smarcel#endif
42176348Smarcel
43176481Smarcel/* Some random address used by U-Boot. */
44182732Srajextern long uboot_address;
45176348Smarcel
46176348Smarcel/* crc32 stuff stolen from lib/libdisk/write_ia64_disk.c */
47176348Smarcelstatic uint32_t crc32_tab[] = {
48176348Smarcel	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
49176348Smarcel	0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
50176348Smarcel	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
51176348Smarcel	0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
52176348Smarcel	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
53176348Smarcel	0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
54176348Smarcel	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
55176348Smarcel	0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
56176348Smarcel	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
57176348Smarcel	0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
58176348Smarcel	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
59176348Smarcel	0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
60176348Smarcel	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
61176348Smarcel	0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
62176348Smarcel	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
63176348Smarcel	0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
64176348Smarcel	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
65176348Smarcel	0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
66176348Smarcel	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
67176348Smarcel	0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
68176348Smarcel	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
69176348Smarcel	0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
70176348Smarcel	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
71176348Smarcel	0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
72176348Smarcel	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
73176348Smarcel	0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
74176348Smarcel	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
75176348Smarcel	0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
76176348Smarcel	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
77176348Smarcel	0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
78176348Smarcel	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
79176348Smarcel	0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
80176348Smarcel	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
81176348Smarcel	0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
82176348Smarcel	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
83176348Smarcel	0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
84176348Smarcel	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
85176348Smarcel	0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
86176348Smarcel	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
87176348Smarcel	0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
88176348Smarcel	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
89176348Smarcel	0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
90176348Smarcel	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
91176348Smarcel};
92176348Smarcel
93176348Smarcelstatic uint32_t
94176348Smarcelcrc32(const void *buf, size_t size)
95176348Smarcel{
96176348Smarcel	const uint8_t *p;
97176348Smarcel	uint32_t crc;
98176348Smarcel
99176348Smarcel	p = buf;
100176348Smarcel	crc = ~0U;
101176348Smarcel
102176348Smarcel	while (size--)
103176348Smarcel		crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
104176348Smarcel
105176348Smarcel	return (crc ^ ~0U);
106176348Smarcel}
107176348Smarcel
108176348Smarcel
109177152Sobrienstatic int
110177152Sobrienvalid_sig(struct api_signature *sig)
111176348Smarcel{
112176348Smarcel	uint32_t checksum;
113176348Smarcel	struct api_signature s;
114176348Smarcel
115176348Smarcel	if (sig == NULL)
116177108Sraj		return (0);
117176348Smarcel	/*
118176348Smarcel	 * Clear the checksum field (in the local copy) so as to calculate the
119176348Smarcel	 * CRC with the same initial contents as at the time when the sig was
120176348Smarcel	 * produced
121176348Smarcel	 */
122176348Smarcel	s = *sig;
123176348Smarcel	s.checksum = 0;
124176348Smarcel
125176348Smarcel	checksum = crc32((void *)&s, sizeof(struct api_signature));
126176348Smarcel
127176348Smarcel	if (checksum != sig->checksum)
128177108Sraj		return (0);
129176348Smarcel
130177108Sraj	return (1);
131176348Smarcel}
132176348Smarcel
133176348Smarcel/*
134176348Smarcel * Searches for the U-Boot API signature
135176348Smarcel *
136176348Smarcel * returns 1/0 depending on found/not found result
137176348Smarcel */
138177152Sobrienint
139177152Sobrienapi_search_sig(struct api_signature **sig)
140177152Sobrien{
141176481Smarcel	unsigned char *sp, *spend;
142176348Smarcel
143176348Smarcel	if (sig == NULL)
144177108Sraj		return (0);
145176348Smarcel
146176481Smarcel	if (uboot_address == 0)
147176481Smarcel		uboot_address = 255 * 1024 * 1024;
148176348Smarcel
149176481Smarcel	sp = (void *)(uboot_address & ~0x000fffff);
150183878Sraj	spend = sp + 0x00300000 - API_SIG_MAGLEN;
151176481Smarcel	while (sp < spend) {
152176348Smarcel		if (!bcmp(sp, API_SIG_MAGIC, API_SIG_MAGLEN)) {
153176348Smarcel			*sig = (struct api_signature *)sp;
154176348Smarcel			if (valid_sig(*sig))
155177108Sraj				return (1);
156176348Smarcel		}
157176348Smarcel		sp += API_SIG_MAGLEN;
158176348Smarcel	}
159176348Smarcel
160176348Smarcel	*sig = NULL;
161177108Sraj	return (0);
162176348Smarcel}
163176348Smarcel
164176348Smarcel/****************************************
165176348Smarcel *
166176348Smarcel * console
167176348Smarcel *
168176348Smarcel ****************************************/
169176348Smarcel
170177152Sobrienint
171177152Sobrienub_getc(void)
172176348Smarcel{
173176348Smarcel	int c;
174176348Smarcel
175176348Smarcel	if (!syscall(API_GETC, NULL, (uint32_t)&c))
176177108Sraj		return (-1);
177177108Sraj
178182732Sraj	return (c);
179176348Smarcel}
180176348Smarcel
181177152Sobrienint
182177152Sobrienub_tstc(void)
183176348Smarcel{
184176348Smarcel	int t;
185176348Smarcel
186176348Smarcel	if (!syscall(API_TSTC, NULL, (uint32_t)&t))
187177108Sraj		return (-1);
188176348Smarcel
189182732Sraj	return (t);
190176348Smarcel}
191176348Smarcel
192177152Sobrienvoid
193177152Sobrienub_putc(char c)
194176348Smarcel{
195177152Sobrien
196176348Smarcel	syscall(API_PUTC, NULL, (uint32_t)&c);
197176348Smarcel}
198176348Smarcel
199177152Sobrienvoid
200177152Sobrienub_puts(const char *s)
201176348Smarcel{
202177152Sobrien
203176348Smarcel	syscall(API_PUTS, NULL, (uint32_t)s);
204176348Smarcel}
205176348Smarcel
206176348Smarcel/****************************************
207176348Smarcel *
208176348Smarcel * system
209176348Smarcel *
210176348Smarcel ****************************************/
211176348Smarcel
212177152Sobrienvoid
213177152Sobrienub_reset(void)
214176348Smarcel{
215177152Sobrien
216176348Smarcel	syscall(API_RESET, NULL);
217176348Smarcel}
218176348Smarcel
219183598Srajstatic struct mem_region mr[UB_MAX_MR];
220176348Smarcelstatic struct sys_info si;
221176348Smarcel
222177152Sobrienstruct sys_info *
223177152Sobrienub_get_sys_info(void)
224176348Smarcel{
225176348Smarcel	int err = 0;
226177152Sobrien
227176348Smarcel	memset(&si, 0, sizeof(struct sys_info));
228176348Smarcel	si.mr = mr;
229183598Sraj	si.mr_no = UB_MAX_MR;
230176348Smarcel	memset(&mr, 0, sizeof(mr));
231177152Sobrien
232176348Smarcel	if (!syscall(API_GET_SYS_INFO, &err, (u_int32_t)&si))
233177108Sraj		return (NULL);
234176348Smarcel
235176348Smarcel	return ((err) ? NULL : &si);
236176348Smarcel}
237176348Smarcel
238176348Smarcel
239176348Smarcel/****************************************
240176348Smarcel *
241176348Smarcel * timing
242176348Smarcel *
243176348Smarcel ****************************************/
244177108Sraj
245177152Sobrienvoid
246177152Sobrienub_udelay(unsigned long usec)
247176348Smarcel{
248177108Sraj
249176348Smarcel	syscall(API_UDELAY, NULL, &usec);
250176348Smarcel}
251176348Smarcel
252177152Sobrienunsigned long
253177152Sobrienub_get_timer(unsigned long base)
254176348Smarcel{
255176348Smarcel	unsigned long cur;
256177152Sobrien
257176348Smarcel	if (!syscall(API_GET_TIMER, NULL, &cur, &base))
258177108Sraj		return (0);
259176348Smarcel
260177108Sraj	return (cur);
261176348Smarcel}
262176348Smarcel
263176348Smarcel
264176348Smarcel/****************************************************************************
265176348Smarcel *
266176348Smarcel * devices
267176348Smarcel *
268183598Sraj * Devices are identified by handles: numbers 0, 1, 2, ..., UB_MAX_DEV-1
269176348Smarcel *
270176348Smarcel ***************************************************************************/
271176348Smarcel
272183598Srajstatic struct device_info devices[UB_MAX_DEV];
273176348Smarcel
274177152Sobrienstruct device_info *
275177152Sobrienub_dev_get(int i)
276176348Smarcel{
277177152Sobrien
278183598Sraj	return ((i < 0 || i >= UB_MAX_DEV) ? NULL : &devices[i]);
279176348Smarcel}
280176348Smarcel
281176348Smarcel/*
282176348Smarcel * Enumerates the devices: fills out device_info elements in the devices[]
283176348Smarcel * array.
284176348Smarcel *
285176348Smarcel * returns:		number of devices found
286176348Smarcel */
287177152Sobrienint
288177152Sobrienub_dev_enum(void)
289176348Smarcel{
290176348Smarcel	struct device_info *di;
291176348Smarcel	int n = 0;
292176348Smarcel
293183598Sraj	memset(&devices, 0, sizeof(struct device_info) * UB_MAX_DEV);
294176348Smarcel	di = &devices[0];
295176348Smarcel
296176348Smarcel	if (!syscall(API_DEV_ENUM, NULL, di))
297177108Sraj		return (0);
298176348Smarcel
299176348Smarcel	while (di->cookie != NULL) {
300176348Smarcel
301183598Sraj		if (++n >= UB_MAX_DEV)
302176348Smarcel			break;
303176348Smarcel
304176348Smarcel		/* take another device_info */
305176348Smarcel		di++;
306176348Smarcel
307176348Smarcel		/* pass on the previous cookie */
308176348Smarcel		di->cookie = devices[n - 1].cookie;
309176348Smarcel
310176348Smarcel		if (!syscall(API_DEV_ENUM, NULL, di))
311182732Sraj			return (0);
312177108Sraj	}
313176348Smarcel
314177108Sraj	return (n);
315176348Smarcel}
316176348Smarcel
317176348Smarcel
318176348Smarcel/*
319176348Smarcel * handle:	0-based id of the device
320176348Smarcel *
321176348Smarcel * returns:	0 when OK, err otherwise
322176348Smarcel */
323177152Sobrienint
324177152Sobrienub_dev_open(int handle)
325176348Smarcel{
326176348Smarcel	struct device_info *di;
327176348Smarcel	int err = 0;
328176348Smarcel
329183598Sraj	if (handle < 0 || handle >= UB_MAX_DEV)
330177108Sraj		return (API_EINVAL);
331176348Smarcel
332176348Smarcel	di = &devices[handle];
333176348Smarcel	if (!syscall(API_DEV_OPEN, &err, di))
334177108Sraj		return (-1);
335176348Smarcel
336177108Sraj	return (err);
337176348Smarcel}
338176348Smarcel
339177152Sobrienint
340177152Sobrienub_dev_close(int handle)
341176348Smarcel{
342176348Smarcel	struct device_info *di;
343176348Smarcel
344183598Sraj	if (handle < 0 || handle >= UB_MAX_DEV)
345177108Sraj		return (API_EINVAL);
346176348Smarcel
347176348Smarcel	di = &devices[handle];
348176348Smarcel	if (!syscall(API_DEV_CLOSE, NULL, di))
349177108Sraj		return (-1);
350176348Smarcel
351177108Sraj	return (0);
352176348Smarcel}
353176348Smarcel
354176348Smarcel/*
355176348Smarcel * Validates device for read/write, it has to:
356176348Smarcel *
357176348Smarcel * - have sane handle
358176348Smarcel * - be opened
359176348Smarcel *
360176348Smarcel * returns:	0/1 accordingly
361176348Smarcel */
362177152Sobrienstatic int
363177152Sobriendev_valid(int handle)
364176348Smarcel{
365177108Sraj
366183598Sraj	if (handle < 0 || handle >= UB_MAX_DEV)
367177108Sraj		return (0);
368176348Smarcel
369176348Smarcel	if (devices[handle].state != DEV_STA_OPEN)
370177108Sraj		return (0);
371176348Smarcel
372177108Sraj	return (1);
373176348Smarcel}
374176348Smarcel
375177152Sobrienstatic int
376177152Sobriendev_stor_valid(int handle)
377176348Smarcel{
378177108Sraj
379176348Smarcel	if (!dev_valid(handle))
380177108Sraj		return (0);
381176348Smarcel
382176348Smarcel	if (!(devices[handle].type & DEV_TYP_STOR))
383177108Sraj		return (0);
384176348Smarcel
385177108Sraj	return (1);
386176348Smarcel}
387176348Smarcel
388177152Sobrienint
389183598Srajub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start,
390183598Sraj    lbasize_t *rlen)
391176348Smarcel{
392176348Smarcel	struct device_info *di;
393176348Smarcel	lbasize_t act_len;
394176348Smarcel	int err = 0;
395176348Smarcel
396176348Smarcel	if (!dev_stor_valid(handle))
397177108Sraj		return (API_ENODEV);
398176348Smarcel
399176348Smarcel	di = &devices[handle];
400176348Smarcel	if (!syscall(API_DEV_READ, &err, di, buf, &len, &start, &act_len))
401183598Sraj		return (API_ESYSC);
402176348Smarcel
403183598Sraj	if (!err && rlen)
404183598Sraj		*rlen = act_len;
405176348Smarcel
406183598Sraj	return (err);
407176348Smarcel}
408176348Smarcel
409177152Sobrienstatic int
410177152Sobriendev_net_valid(int handle)
411176348Smarcel{
412177108Sraj
413176348Smarcel	if (!dev_valid(handle))
414177108Sraj		return (0);
415176348Smarcel
416176348Smarcel	if (devices[handle].type != DEV_TYP_NET)
417177108Sraj		return (0);
418176348Smarcel
419177108Sraj	return (1);
420176348Smarcel}
421176348Smarcel
422177152Sobrienint
423183598Srajub_dev_recv(int handle, void *buf, int len, int *rlen)
424176348Smarcel{
425176348Smarcel	struct device_info *di;
426176348Smarcel	int err = 0, act_len;
427176348Smarcel
428176348Smarcel	if (!dev_net_valid(handle))
429177108Sraj		return (API_ENODEV);
430176348Smarcel
431176348Smarcel	di = &devices[handle];
432176348Smarcel	if (!syscall(API_DEV_READ, &err, di, buf, &len, &act_len))
433183598Sraj		return (API_ESYSC);
434176348Smarcel
435183598Sraj	if (!err)
436183598Sraj		*rlen = act_len;
437176348Smarcel
438183598Sraj	return (err);
439176348Smarcel}
440176348Smarcel
441177152Sobrienint
442177152Sobrienub_dev_send(int handle, void *buf, int len)
443176348Smarcel{
444176348Smarcel	struct device_info *di;
445176348Smarcel	int err = 0;
446176348Smarcel
447176348Smarcel	if (!dev_net_valid(handle))
448177108Sraj		return (API_ENODEV);
449176348Smarcel
450176348Smarcel	di = &devices[handle];
451176348Smarcel	if (!syscall(API_DEV_WRITE, &err, di, buf, &len))
452183598Sraj		return (API_ESYSC);
453176348Smarcel
454177108Sraj	return (err);
455176348Smarcel}
456176348Smarcel
457182732Srajstatic char *
458182732Srajub_stor_type(int type)
459182732Sraj{
460182732Sraj
461182732Sraj	if (type & DT_STOR_IDE)
462182732Sraj		return ("IDE");
463182732Sraj
464182732Sraj	if (type & DT_STOR_SCSI)
465182732Sraj		return ("SCSI");
466182732Sraj
467182732Sraj	if (type & DT_STOR_USB)
468182732Sraj		return ("USB");
469182732Sraj
470182732Sraj	if (type & DT_STOR_MMC);
471182732Sraj		return ("MMC");
472182732Sraj
473182732Sraj	return ("Unknown");
474182732Sraj}
475182732Sraj
476182732Srajchar *
477182732Srajub_mem_type(int flags)
478182732Sraj{
479182732Sraj
480183599Sraj	switch (flags & 0x000F) {
481182732Sraj	case MR_ATTR_FLASH:
482182732Sraj		return ("FLASH");
483182732Sraj	case MR_ATTR_DRAM:
484182732Sraj		return ("DRAM");
485182732Sraj	case MR_ATTR_SRAM:
486182732Sraj		return ("SRAM");
487182732Sraj	default:
488182732Sraj		return ("Unknown");
489182732Sraj	}
490182732Sraj}
491182732Sraj
492182732Srajvoid
493182732Srajub_dump_di(int handle)
494182732Sraj{
495182732Sraj	struct device_info *di = ub_dev_get(handle);
496182732Sraj	int i;
497182732Sraj
498182732Sraj	printf("device info (%d):\n", handle);
499182732Sraj	printf("  cookie\t= 0x%08x\n", (uint32_t)di->cookie);
500182732Sraj	printf("  type\t\t= 0x%08x\n", di->type);
501182732Sraj
502182732Sraj	if (di->type == DEV_TYP_NET) {
503182732Sraj		printf("  hwaddr\t= ");
504182732Sraj		for (i = 0; i < 6; i++)
505182732Sraj			printf("%02x ", di->di_net.hwaddr[i]);
506182732Sraj
507182732Sraj		printf("\n");
508182732Sraj
509182732Sraj	} else if (di->type & DEV_TYP_STOR) {
510182732Sraj		printf("  type\t\t= %s\n", ub_stor_type(di->type));
511182732Sraj		printf("  blk size\t\t= %ld\n", di->di_stor.block_size);
512182732Sraj		printf("  blk count\t\t= %ld\n", di->di_stor.block_count);
513182732Sraj	}
514182732Sraj}
515182732Sraj
516182732Srajvoid
517182732Srajub_dump_si(struct sys_info *si)
518182732Sraj{
519182732Sraj	int i;
520182732Sraj
521182732Sraj	printf("sys info:\n");
522182732Sraj	printf("  clkbus\t= %ld MHz\n", si->clk_bus / 1000 / 1000);
523182732Sraj	printf("  clkcpu\t= %ld MHz\n", si->clk_cpu / 1000 / 1000);
524182732Sraj	printf("  bar\t\t= 0x%08lx\n", si->bar);
525182732Sraj
526182732Sraj	printf("---\n");
527182732Sraj	for (i = 0; i < si->mr_no; i++) {
528182732Sraj		if (si->mr[i].flags == 0)
529182732Sraj			break;
530182732Sraj
531182732Sraj		printf("  start\t= 0x%08lx\n", si->mr[i].start);
532182732Sraj		printf("  size\t= 0x%08lx\n", si->mr[i].size);
533182732Sraj		printf("  type\t= %s\n", ub_mem_type(si->mr[i].flags));
534182732Sraj		printf("---\n");
535182732Sraj	}
536182732Sraj}
537182732Sraj
538176348Smarcel/****************************************
539176348Smarcel *
540176348Smarcel * env vars
541176348Smarcel *
542176348Smarcel ****************************************/
543176348Smarcel
544177152Sobrienchar *
545177152Sobrienub_env_get(const char *name)
546176348Smarcel{
547176348Smarcel	char *value;
548176348Smarcel
549176348Smarcel	if (!syscall(API_ENV_GET, NULL, (uint32_t)name, (uint32_t)&value))
550177108Sraj		return (NULL);
551176348Smarcel
552177108Sraj	return (value);
553176348Smarcel}
554176348Smarcel
555177152Sobrienvoid
556177152Sobrienub_env_set(const char *name, char *value)
557176348Smarcel{
558177108Sraj
559176348Smarcel	syscall(API_ENV_SET, NULL, (uint32_t)name, (uint32_t)value);
560176348Smarcel}
561176348Smarcel
562176348Smarcel
563176348Smarcelstatic char env_name[256];
564176348Smarcel
565177152Sobrienconst char *
566177152Sobrienub_env_enum(const char *last)
567176348Smarcel{
568176348Smarcel	const char *env, *str;
569176348Smarcel	int i;
570176348Smarcel
571176348Smarcel	env = NULL;
572176348Smarcel
573176348Smarcel	/*
574176348Smarcel	 * It's OK to pass only the name piece as last (and not the whole
575176348Smarcel	 * 'name=val' string), since the API_ENUM_ENV call uses envmatch()
576176348Smarcel	 * internally, which handles such case
577176348Smarcel	 */
578176348Smarcel	if (!syscall(API_ENV_ENUM, NULL, (uint32_t)last, (uint32_t)&env))
579177108Sraj		return (NULL);
580176348Smarcel
581176348Smarcel	if (!env)
582176348Smarcel		/* no more env. variables to enumerate */
583177108Sraj		return (NULL);
584176348Smarcel#if 0
585176348Smarcel	if (last && strncmp(env, last, strlen(last)) == 0);
586176348Smarcel		/* error, trying to enumerate non existing env. variable */
587176348Smarcel		return NULL;
588176348Smarcel#endif
589176348Smarcel
590176348Smarcel	/* next enumerated env var */
591176348Smarcel	memset(env_name, 0, 256);
592176348Smarcel	for (i = 0, str = env; *str != '=' && *str != '\0';)
593176348Smarcel		env_name[i++] = *str++;
594176348Smarcel
595176348Smarcel	env_name[i] = '\0';
596176348Smarcel
597177108Sraj	return (env_name);
598176348Smarcel}
599