glue.c revision 182732
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 182732 2008-09-03 17:48:41Z 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);
150176481Smarcel	spend = sp + 0x00100000 - 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
219176348Smarcel
220177152Sobrien#define	MR_MAX 5
221176348Smarcelstatic struct mem_region mr[MR_MAX];
222176348Smarcelstatic struct sys_info si;
223176348Smarcel
224177152Sobrienstruct sys_info *
225177152Sobrienub_get_sys_info(void)
226176348Smarcel{
227176348Smarcel	int err = 0;
228177152Sobrien
229176348Smarcel	memset(&si, 0, sizeof(struct sys_info));
230176348Smarcel	si.mr = mr;
231176348Smarcel	si.mr_no = MR_MAX;
232176348Smarcel	memset(&mr, 0, sizeof(mr));
233177152Sobrien
234176348Smarcel	if (!syscall(API_GET_SYS_INFO, &err, (u_int32_t)&si))
235177108Sraj		return (NULL);
236176348Smarcel
237176348Smarcel	return ((err) ? NULL : &si);
238176348Smarcel}
239176348Smarcel
240176348Smarcel
241176348Smarcel/****************************************
242176348Smarcel *
243176348Smarcel * timing
244176348Smarcel *
245176348Smarcel ****************************************/
246177108Sraj
247177152Sobrienvoid
248177152Sobrienub_udelay(unsigned long usec)
249176348Smarcel{
250177108Sraj
251176348Smarcel	syscall(API_UDELAY, NULL, &usec);
252176348Smarcel}
253176348Smarcel
254177152Sobrienunsigned long
255177152Sobrienub_get_timer(unsigned long base)
256176348Smarcel{
257176348Smarcel	unsigned long cur;
258177152Sobrien
259176348Smarcel	if (!syscall(API_GET_TIMER, NULL, &cur, &base))
260177108Sraj		return (0);
261176348Smarcel
262177108Sraj	return (cur);
263176348Smarcel}
264176348Smarcel
265176348Smarcel
266176348Smarcel/****************************************************************************
267176348Smarcel *
268176348Smarcel * devices
269176348Smarcel *
270176348Smarcel * Devices are identified by handles: numbers 0, 1, 2, ..., MAX_DEVS-1
271176348Smarcel *
272176348Smarcel ***************************************************************************/
273176348Smarcel
274177152Sobrien#define	MAX_DEVS 6
275176348Smarcel
276176348Smarcelstatic struct device_info devices[MAX_DEVS];
277176348Smarcel
278177152Sobrienstruct device_info *
279177152Sobrienub_dev_get(int i)
280176348Smarcel{
281177152Sobrien
282176348Smarcel	return ((i < 0 || i >= MAX_DEVS) ? NULL : &devices[i]);
283176348Smarcel}
284176348Smarcel
285176348Smarcel/*
286176348Smarcel * Enumerates the devices: fills out device_info elements in the devices[]
287176348Smarcel * array.
288176348Smarcel *
289176348Smarcel * returns:		number of devices found
290176348Smarcel */
291177152Sobrienint
292177152Sobrienub_dev_enum(void)
293176348Smarcel{
294176348Smarcel	struct device_info *di;
295176348Smarcel	int n = 0;
296176348Smarcel
297176348Smarcel	memset(&devices, 0, sizeof(struct device_info) * MAX_DEVS);
298176348Smarcel	di = &devices[0];
299176348Smarcel
300176348Smarcel	if (!syscall(API_DEV_ENUM, NULL, di))
301177108Sraj		return (0);
302176348Smarcel
303176348Smarcel	while (di->cookie != NULL) {
304176348Smarcel
305176348Smarcel		if (++n >= MAX_DEVS)
306176348Smarcel			break;
307176348Smarcel
308176348Smarcel		/* take another device_info */
309176348Smarcel		di++;
310176348Smarcel
311176348Smarcel		/* pass on the previous cookie */
312176348Smarcel		di->cookie = devices[n - 1].cookie;
313176348Smarcel
314176348Smarcel		if (!syscall(API_DEV_ENUM, NULL, di))
315182732Sraj			return (0);
316177108Sraj	}
317176348Smarcel
318177108Sraj	return (n);
319176348Smarcel}
320176348Smarcel
321176348Smarcel
322176348Smarcel/*
323176348Smarcel * handle:	0-based id of the device
324176348Smarcel *
325176348Smarcel * returns:	0 when OK, err otherwise
326176348Smarcel */
327177152Sobrienint
328177152Sobrienub_dev_open(int handle)
329176348Smarcel{
330176348Smarcel	struct device_info *di;
331176348Smarcel	int err = 0;
332176348Smarcel
333176348Smarcel	if (handle < 0 || handle >= MAX_DEVS)
334177108Sraj		return (API_EINVAL);
335176348Smarcel
336176348Smarcel	di = &devices[handle];
337176348Smarcel	if (!syscall(API_DEV_OPEN, &err, di))
338177108Sraj		return (-1);
339176348Smarcel
340177108Sraj	return (err);
341176348Smarcel}
342176348Smarcel
343177152Sobrienint
344177152Sobrienub_dev_close(int handle)
345176348Smarcel{
346176348Smarcel	struct device_info *di;
347176348Smarcel
348176348Smarcel	if (handle < 0 || handle >= MAX_DEVS)
349177108Sraj		return (API_EINVAL);
350176348Smarcel
351176348Smarcel	di = &devices[handle];
352176348Smarcel	if (!syscall(API_DEV_CLOSE, NULL, di))
353177108Sraj		return (-1);
354176348Smarcel
355177108Sraj	return (0);
356176348Smarcel}
357176348Smarcel
358176348Smarcel/*
359176348Smarcel * Validates device for read/write, it has to:
360176348Smarcel *
361176348Smarcel * - have sane handle
362176348Smarcel * - be opened
363176348Smarcel *
364176348Smarcel * returns:	0/1 accordingly
365176348Smarcel */
366177152Sobrienstatic int
367177152Sobriendev_valid(int handle)
368176348Smarcel{
369177108Sraj
370176348Smarcel	if (handle < 0 || handle >= MAX_DEVS)
371177108Sraj		return (0);
372176348Smarcel
373176348Smarcel	if (devices[handle].state != DEV_STA_OPEN)
374177108Sraj		return (0);
375176348Smarcel
376177108Sraj	return (1);
377176348Smarcel}
378176348Smarcel
379177152Sobrienstatic int
380177152Sobriendev_stor_valid(int handle)
381176348Smarcel{
382177108Sraj
383176348Smarcel	if (!dev_valid(handle))
384177108Sraj		return (0);
385176348Smarcel
386176348Smarcel	if (!(devices[handle].type & DEV_TYP_STOR))
387177108Sraj		return (0);
388176348Smarcel
389177108Sraj	return (1);
390176348Smarcel}
391176348Smarcel
392177152Sobrienint
393177152Sobrienub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start)
394176348Smarcel{
395176348Smarcel	struct device_info *di;
396176348Smarcel	lbasize_t act_len;
397176348Smarcel	int err = 0;
398176348Smarcel
399176348Smarcel	if (!dev_stor_valid(handle))
400177108Sraj		return (API_ENODEV);
401176348Smarcel
402176348Smarcel	di = &devices[handle];
403176348Smarcel	if (!syscall(API_DEV_READ, &err, di, buf, &len, &start, &act_len))
404177108Sraj		return (-1);
405176348Smarcel
406177108Sraj	if (err)
407177108Sraj		return (err);
408176348Smarcel
409176348Smarcel	if (act_len != len)
410177108Sraj		return (API_EIO);
411176348Smarcel
412177108Sraj	return (0);
413176348Smarcel}
414176348Smarcel
415177152Sobrienstatic int
416177152Sobriendev_net_valid(int handle)
417176348Smarcel{
418177108Sraj
419176348Smarcel	if (!dev_valid(handle))
420177108Sraj		return (0);
421176348Smarcel
422176348Smarcel	if (devices[handle].type != DEV_TYP_NET)
423177108Sraj		return (0);
424176348Smarcel
425177108Sraj	return (1);
426176348Smarcel}
427176348Smarcel
428177152Sobrienint
429177152Sobrienub_dev_recv(int handle, void *buf, int len)
430176348Smarcel{
431176348Smarcel	struct device_info *di;
432176348Smarcel	int err = 0, act_len;
433176348Smarcel
434176348Smarcel	if (!dev_net_valid(handle))
435177108Sraj		return (API_ENODEV);
436176348Smarcel
437176348Smarcel	di = &devices[handle];
438176348Smarcel	if (!syscall(API_DEV_READ, &err, di, buf, &len, &act_len))
439177108Sraj		return (-1);
440176348Smarcel
441176348Smarcel	if (err)
442177108Sraj		return (-1);
443176348Smarcel
444177108Sraj	return (act_len);
445176348Smarcel}
446176348Smarcel
447177152Sobrienint
448177152Sobrienub_dev_send(int handle, void *buf, int len)
449176348Smarcel{
450176348Smarcel	struct device_info *di;
451176348Smarcel	int err = 0;
452176348Smarcel
453176348Smarcel	if (!dev_net_valid(handle))
454177108Sraj		return (API_ENODEV);
455176348Smarcel
456176348Smarcel	di = &devices[handle];
457176348Smarcel	if (!syscall(API_DEV_WRITE, &err, di, buf, &len))
458177108Sraj		return (-1);
459176348Smarcel
460177108Sraj	return (err);
461176348Smarcel}
462176348Smarcel
463182732Srajstatic char *
464182732Srajub_stor_type(int type)
465182732Sraj{
466182732Sraj
467182732Sraj	if (type & DT_STOR_IDE)
468182732Sraj		return ("IDE");
469182732Sraj
470182732Sraj	if (type & DT_STOR_SCSI)
471182732Sraj		return ("SCSI");
472182732Sraj
473182732Sraj	if (type & DT_STOR_USB)
474182732Sraj		return ("USB");
475182732Sraj
476182732Sraj	if (type & DT_STOR_MMC);
477182732Sraj		return ("MMC");
478182732Sraj
479182732Sraj	return ("Unknown");
480182732Sraj}
481182732Sraj
482182732Srajchar *
483182732Srajub_mem_type(int flags)
484182732Sraj{
485182732Sraj
486182732Sraj	switch(flags & 0x000F) {
487182732Sraj	case MR_ATTR_FLASH:
488182732Sraj		return ("FLASH");
489182732Sraj	case MR_ATTR_DRAM:
490182732Sraj		return ("DRAM");
491182732Sraj	case MR_ATTR_SRAM:
492182732Sraj		return ("SRAM");
493182732Sraj	default:
494182732Sraj		return ("Unknown");
495182732Sraj	}
496182732Sraj}
497182732Sraj
498182732Srajvoid
499182732Srajub_dump_di(int handle)
500182732Sraj{
501182732Sraj	struct device_info *di = ub_dev_get(handle);
502182732Sraj	int i;
503182732Sraj
504182732Sraj	printf("device info (%d):\n", handle);
505182732Sraj	printf("  cookie\t= 0x%08x\n", (uint32_t)di->cookie);
506182732Sraj	printf("  type\t\t= 0x%08x\n", di->type);
507182732Sraj
508182732Sraj	if (di->type == DEV_TYP_NET) {
509182732Sraj		printf("  hwaddr\t= ");
510182732Sraj		for (i = 0; i < 6; i++)
511182732Sraj			printf("%02x ", di->di_net.hwaddr[i]);
512182732Sraj
513182732Sraj		printf("\n");
514182732Sraj
515182732Sraj	} else if (di->type & DEV_TYP_STOR) {
516182732Sraj		printf("  type\t\t= %s\n", ub_stor_type(di->type));
517182732Sraj		printf("  blk size\t\t= %ld\n", di->di_stor.block_size);
518182732Sraj		printf("  blk count\t\t= %ld\n", di->di_stor.block_count);
519182732Sraj	}
520182732Sraj}
521182732Sraj
522182732Srajvoid
523182732Srajub_dump_si(struct sys_info *si)
524182732Sraj{
525182732Sraj	int i;
526182732Sraj
527182732Sraj	printf("sys info:\n");
528182732Sraj	printf("  clkbus\t= %ld MHz\n", si->clk_bus / 1000 / 1000);
529182732Sraj	printf("  clkcpu\t= %ld MHz\n", si->clk_cpu / 1000 / 1000);
530182732Sraj	printf("  bar\t\t= 0x%08lx\n", si->bar);
531182732Sraj
532182732Sraj	printf("---\n");
533182732Sraj	for (i = 0; i < si->mr_no; i++) {
534182732Sraj		if (si->mr[i].flags == 0)
535182732Sraj			break;
536182732Sraj
537182732Sraj		printf("  start\t= 0x%08lx\n", si->mr[i].start);
538182732Sraj		printf("  size\t= 0x%08lx\n", si->mr[i].size);
539182732Sraj		printf("  type\t= %s\n", ub_mem_type(si->mr[i].flags));
540182732Sraj		printf("---\n");
541182732Sraj	}
542182732Sraj}
543182732Sraj
544176348Smarcel/****************************************
545176348Smarcel *
546176348Smarcel * env vars
547176348Smarcel *
548176348Smarcel ****************************************/
549176348Smarcel
550177152Sobrienchar *
551177152Sobrienub_env_get(const char *name)
552176348Smarcel{
553176348Smarcel	char *value;
554176348Smarcel
555176348Smarcel	if (!syscall(API_ENV_GET, NULL, (uint32_t)name, (uint32_t)&value))
556177108Sraj		return (NULL);
557176348Smarcel
558177108Sraj	return (value);
559176348Smarcel}
560176348Smarcel
561177152Sobrienvoid
562177152Sobrienub_env_set(const char *name, char *value)
563176348Smarcel{
564177108Sraj
565176348Smarcel	syscall(API_ENV_SET, NULL, (uint32_t)name, (uint32_t)value);
566176348Smarcel}
567176348Smarcel
568176348Smarcel
569176348Smarcelstatic char env_name[256];
570176348Smarcel
571177152Sobrienconst char *
572177152Sobrienub_env_enum(const char *last)
573176348Smarcel{
574176348Smarcel	const char *env, *str;
575176348Smarcel	int i;
576176348Smarcel
577176348Smarcel	env = NULL;
578176348Smarcel
579176348Smarcel	/*
580176348Smarcel	 * It's OK to pass only the name piece as last (and not the whole
581176348Smarcel	 * 'name=val' string), since the API_ENUM_ENV call uses envmatch()
582176348Smarcel	 * internally, which handles such case
583176348Smarcel	 */
584176348Smarcel	if (!syscall(API_ENV_ENUM, NULL, (uint32_t)last, (uint32_t)&env))
585177108Sraj		return (NULL);
586176348Smarcel
587176348Smarcel	if (!env)
588176348Smarcel		/* no more env. variables to enumerate */
589177108Sraj		return (NULL);
590176348Smarcel#if 0
591176348Smarcel	if (last && strncmp(env, last, strlen(last)) == 0);
592176348Smarcel		/* error, trying to enumerate non existing env. variable */
593176348Smarcel		return NULL;
594176348Smarcel#endif
595176348Smarcel
596176348Smarcel	/* next enumerated env var */
597176348Smarcel	memset(env_name, 0, 256);
598176348Smarcel	for (i = 0, str = env; *str != '=' && *str != '\0';)
599176348Smarcel		env_name[i++] = *str++;
600176348Smarcel
601176348Smarcel	env_name[i] = '\0';
602176348Smarcel
603177108Sraj	return (env_name);
604176348Smarcel}
605