19dc70af8SWarner Losh /*-
29dc70af8SWarner Losh * Copyright (c) 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
39dc70af8SWarner Losh * All rights reserved.
49dc70af8SWarner Losh *
59dc70af8SWarner Losh * Redistribution and use in source and binary forms, with or without
69dc70af8SWarner Losh * modification, are permitted provided that the following conditions
79dc70af8SWarner Losh * are met:
89dc70af8SWarner Losh * 1. Redistributions of source code must retain the above copyright
99dc70af8SWarner Losh * notice, this list of conditions and the following disclaimer.
109dc70af8SWarner Losh * 2. Redistributions in binary form must reproduce the above copyright
119dc70af8SWarner Losh * notice, this list of conditions and the following disclaimer in the
129dc70af8SWarner Losh * documentation and/or other materials provided with the distribution.
139dc70af8SWarner Losh *
149dc70af8SWarner Losh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
159dc70af8SWarner Losh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
169dc70af8SWarner Losh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
179dc70af8SWarner Losh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
189dc70af8SWarner Losh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
199dc70af8SWarner Losh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
209dc70af8SWarner Losh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
219dc70af8SWarner Losh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
229dc70af8SWarner Losh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
239dc70af8SWarner Losh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
249dc70af8SWarner Losh * SUCH DAMAGE.
259dc70af8SWarner Losh */
269dc70af8SWarner Losh
279dc70af8SWarner Losh #include <sys/types.h>
289dc70af8SWarner Losh
299dc70af8SWarner Losh #include <zlib.h>
309dc70af8SWarner Losh #include <stand.h>
319dc70af8SWarner Losh #include "api_public.h"
329dc70af8SWarner Losh #include "glue.h"
339dc70af8SWarner Losh
349dc70af8SWarner Losh #ifdef DEBUG
359dc70af8SWarner Losh #define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0)
369dc70af8SWarner Losh #else
379dc70af8SWarner Losh #define debugf(fmt, args...)
389dc70af8SWarner Losh #endif
399dc70af8SWarner Losh
409dc70af8SWarner Losh /* Some random address used by U-Boot. */
419dc70af8SWarner Losh extern long uboot_address;
429dc70af8SWarner Losh
439dc70af8SWarner Losh static int
valid_sig(struct api_signature * sig)449dc70af8SWarner Losh valid_sig(struct api_signature *sig)
459dc70af8SWarner Losh {
469dc70af8SWarner Losh uint32_t checksum;
479dc70af8SWarner Losh struct api_signature s;
489dc70af8SWarner Losh
499dc70af8SWarner Losh if (sig == NULL)
509dc70af8SWarner Losh return (0);
519dc70af8SWarner Losh /*
529dc70af8SWarner Losh * Clear the checksum field (in the local copy) so as to calculate the
539dc70af8SWarner Losh * CRC with the same initial contents as at the time when the sig was
549dc70af8SWarner Losh * produced
559dc70af8SWarner Losh */
569dc70af8SWarner Losh s = *sig;
579dc70af8SWarner Losh s.checksum = crc32(0, Z_NULL, 0);
589dc70af8SWarner Losh
599dc70af8SWarner Losh checksum = crc32(s.checksum, (void *)&s, sizeof(struct api_signature));
609dc70af8SWarner Losh
619dc70af8SWarner Losh if (checksum != sig->checksum)
629dc70af8SWarner Losh return (0);
639dc70af8SWarner Losh
649dc70af8SWarner Losh return (1);
659dc70af8SWarner Losh }
669dc70af8SWarner Losh
679dc70af8SWarner Losh /*
689dc70af8SWarner Losh * Checks to see if API signature's address was given to us as a command line
699dc70af8SWarner Losh * argument by U-Boot.
709dc70af8SWarner Losh *
719dc70af8SWarner Losh * returns 1/0 depending on found/not found result
729dc70af8SWarner Losh */
739dc70af8SWarner Losh int
api_parse_cmdline_sig(int argc,char ** argv,struct api_signature ** sig)749dc70af8SWarner Losh api_parse_cmdline_sig(int argc, char **argv, struct api_signature **sig)
759dc70af8SWarner Losh {
769dc70af8SWarner Losh unsigned long api_address;
779dc70af8SWarner Losh int c;
789dc70af8SWarner Losh
799dc70af8SWarner Losh api_address = 0;
809dc70af8SWarner Losh opterr = 0;
819dc70af8SWarner Losh optreset = 1;
829dc70af8SWarner Losh optind = 1;
839dc70af8SWarner Losh
849dc70af8SWarner Losh while ((c = getopt (argc, argv, "a:")) != -1)
859dc70af8SWarner Losh switch (c) {
869dc70af8SWarner Losh case 'a':
879dc70af8SWarner Losh api_address = strtoul(optarg, NULL, 16);
889dc70af8SWarner Losh break;
899dc70af8SWarner Losh default:
909dc70af8SWarner Losh break;
919dc70af8SWarner Losh }
929dc70af8SWarner Losh
939dc70af8SWarner Losh if (api_address != 0) {
949dc70af8SWarner Losh *sig = (struct api_signature *)api_address;
959dc70af8SWarner Losh if (valid_sig(*sig))
969dc70af8SWarner Losh return (1);
979dc70af8SWarner Losh }
989dc70af8SWarner Losh
999dc70af8SWarner Losh return (0);
1009dc70af8SWarner Losh }
1019dc70af8SWarner Losh
1029dc70af8SWarner Losh /*
1039dc70af8SWarner Losh * Searches for the U-Boot API signature
1049dc70af8SWarner Losh *
1059dc70af8SWarner Losh * returns 1/0 depending on found/not found result
1069dc70af8SWarner Losh */
1079dc70af8SWarner Losh int
api_search_sig(struct api_signature ** sig)1089dc70af8SWarner Losh api_search_sig(struct api_signature **sig)
1099dc70af8SWarner Losh {
1109dc70af8SWarner Losh unsigned char *sp, *spend;
1119dc70af8SWarner Losh
1129dc70af8SWarner Losh if (sig == NULL)
1139dc70af8SWarner Losh return (0);
1149dc70af8SWarner Losh
1159dc70af8SWarner Losh if (uboot_address == 0)
1169dc70af8SWarner Losh uboot_address = 255 * 1024 * 1024;
1179dc70af8SWarner Losh
1189dc70af8SWarner Losh sp = (void *)(uboot_address & API_SIG_SEARCH_MASK);
1199dc70af8SWarner Losh spend = sp + API_SIG_SEARCH_LEN - API_SIG_MAGLEN;
1209dc70af8SWarner Losh
1219dc70af8SWarner Losh while (sp < spend) {
1229dc70af8SWarner Losh if (!bcmp(sp, API_SIG_MAGIC, API_SIG_MAGLEN)) {
1239dc70af8SWarner Losh *sig = (struct api_signature *)sp;
1249dc70af8SWarner Losh if (valid_sig(*sig))
1259dc70af8SWarner Losh return (1);
1269dc70af8SWarner Losh }
1279dc70af8SWarner Losh sp += API_SIG_MAGLEN;
1289dc70af8SWarner Losh }
1299dc70af8SWarner Losh
1309dc70af8SWarner Losh *sig = NULL;
1319dc70af8SWarner Losh return (0);
1329dc70af8SWarner Losh }
1339dc70af8SWarner Losh
1349dc70af8SWarner Losh /****************************************
1359dc70af8SWarner Losh *
1369dc70af8SWarner Losh * console
1379dc70af8SWarner Losh *
1389dc70af8SWarner Losh ****************************************/
1399dc70af8SWarner Losh
1409dc70af8SWarner Losh int
ub_getc(void)1419dc70af8SWarner Losh ub_getc(void)
1429dc70af8SWarner Losh {
1439dc70af8SWarner Losh int c;
1449dc70af8SWarner Losh
1459dc70af8SWarner Losh if (!syscall(API_GETC, NULL, &c))
1469dc70af8SWarner Losh return (-1);
1479dc70af8SWarner Losh
1489dc70af8SWarner Losh return (c);
1499dc70af8SWarner Losh }
1509dc70af8SWarner Losh
1519dc70af8SWarner Losh int
ub_tstc(void)1529dc70af8SWarner Losh ub_tstc(void)
1539dc70af8SWarner Losh {
1549dc70af8SWarner Losh int t;
1559dc70af8SWarner Losh
1569dc70af8SWarner Losh if (!syscall(API_TSTC, NULL, &t))
1579dc70af8SWarner Losh return (-1);
1589dc70af8SWarner Losh
1599dc70af8SWarner Losh return (t);
1609dc70af8SWarner Losh }
1619dc70af8SWarner Losh
1629dc70af8SWarner Losh void
ub_putc(const char c)1639dc70af8SWarner Losh ub_putc(const char c)
1649dc70af8SWarner Losh {
1659dc70af8SWarner Losh
1669dc70af8SWarner Losh syscall(API_PUTC, NULL, &c);
1679dc70af8SWarner Losh }
1689dc70af8SWarner Losh
1699dc70af8SWarner Losh void
ub_puts(const char * s)1709dc70af8SWarner Losh ub_puts(const char *s)
1719dc70af8SWarner Losh {
1729dc70af8SWarner Losh
1739dc70af8SWarner Losh syscall(API_PUTS, NULL, s);
1749dc70af8SWarner Losh }
1759dc70af8SWarner Losh
1769dc70af8SWarner Losh /****************************************
1779dc70af8SWarner Losh *
1789dc70af8SWarner Losh * system
1799dc70af8SWarner Losh *
1809dc70af8SWarner Losh ****************************************/
1819dc70af8SWarner Losh
1829dc70af8SWarner Losh void
ub_reset(void)1839dc70af8SWarner Losh ub_reset(void)
1849dc70af8SWarner Losh {
1859dc70af8SWarner Losh
1869dc70af8SWarner Losh syscall(API_RESET, NULL);
1879dc70af8SWarner Losh while (1); /* fallback if API_RESET failed */
1889dc70af8SWarner Losh __unreachable();
1899dc70af8SWarner Losh }
1909dc70af8SWarner Losh
1919dc70af8SWarner Losh static struct mem_region mr[UB_MAX_MR];
1929dc70af8SWarner Losh static struct sys_info si;
1939dc70af8SWarner Losh
1949dc70af8SWarner Losh struct sys_info *
ub_get_sys_info(void)1959dc70af8SWarner Losh ub_get_sys_info(void)
1969dc70af8SWarner Losh {
1979dc70af8SWarner Losh int err = 0;
1989dc70af8SWarner Losh
1999dc70af8SWarner Losh memset(&si, 0, sizeof(struct sys_info));
2009dc70af8SWarner Losh si.mr = mr;
2019dc70af8SWarner Losh si.mr_no = UB_MAX_MR;
2029dc70af8SWarner Losh memset(&mr, 0, sizeof(mr));
2039dc70af8SWarner Losh
2049dc70af8SWarner Losh if (!syscall(API_GET_SYS_INFO, &err, &si))
2059dc70af8SWarner Losh return (NULL);
2069dc70af8SWarner Losh
2079dc70af8SWarner Losh return ((err) ? NULL : &si);
2089dc70af8SWarner Losh }
2099dc70af8SWarner Losh
2109dc70af8SWarner Losh /****************************************
2119dc70af8SWarner Losh *
2129dc70af8SWarner Losh * timing
2139dc70af8SWarner Losh *
2149dc70af8SWarner Losh ****************************************/
2159dc70af8SWarner Losh
2169dc70af8SWarner Losh void
ub_udelay(unsigned long usec)2179dc70af8SWarner Losh ub_udelay(unsigned long usec)
2189dc70af8SWarner Losh {
2199dc70af8SWarner Losh
2209dc70af8SWarner Losh syscall(API_UDELAY, NULL, &usec);
2219dc70af8SWarner Losh }
2229dc70af8SWarner Losh
2239dc70af8SWarner Losh unsigned long
ub_get_timer(unsigned long base)2249dc70af8SWarner Losh ub_get_timer(unsigned long base)
2259dc70af8SWarner Losh {
2269dc70af8SWarner Losh unsigned long cur;
2279dc70af8SWarner Losh
2289dc70af8SWarner Losh if (!syscall(API_GET_TIMER, NULL, &cur, &base))
2299dc70af8SWarner Losh return (0);
2309dc70af8SWarner Losh
2319dc70af8SWarner Losh return (cur);
2329dc70af8SWarner Losh }
2339dc70af8SWarner Losh
2349dc70af8SWarner Losh /****************************************************************************
2359dc70af8SWarner Losh *
2369dc70af8SWarner Losh * devices
2379dc70af8SWarner Losh *
2389dc70af8SWarner Losh * Devices are identified by handles: numbers 0, 1, 2, ..., UB_MAX_DEV-1
2399dc70af8SWarner Losh *
2409dc70af8SWarner Losh ***************************************************************************/
2419dc70af8SWarner Losh
2429dc70af8SWarner Losh static struct device_info devices[UB_MAX_DEV];
2439dc70af8SWarner Losh
2449dc70af8SWarner Losh struct device_info *
ub_dev_get(int i)2459dc70af8SWarner Losh ub_dev_get(int i)
2469dc70af8SWarner Losh {
2479dc70af8SWarner Losh
2489dc70af8SWarner Losh return ((i < 0 || i >= UB_MAX_DEV) ? NULL : &devices[i]);
2499dc70af8SWarner Losh }
2509dc70af8SWarner Losh
2519dc70af8SWarner Losh /*
2529dc70af8SWarner Losh * Enumerates the devices: fills out device_info elements in the devices[]
2539dc70af8SWarner Losh * array.
2549dc70af8SWarner Losh *
2559dc70af8SWarner Losh * returns: number of devices found
2569dc70af8SWarner Losh */
2579dc70af8SWarner Losh int
ub_dev_enum(void)2589dc70af8SWarner Losh ub_dev_enum(void)
2599dc70af8SWarner Losh {
2609dc70af8SWarner Losh struct device_info *di;
2619dc70af8SWarner Losh int n = 0;
2629dc70af8SWarner Losh
2639dc70af8SWarner Losh memset(&devices, 0, sizeof(struct device_info) * UB_MAX_DEV);
2649dc70af8SWarner Losh di = &devices[0];
2659dc70af8SWarner Losh
2669dc70af8SWarner Losh if (!syscall(API_DEV_ENUM, NULL, di))
2679dc70af8SWarner Losh return (0);
2689dc70af8SWarner Losh
2699dc70af8SWarner Losh while (di->cookie != NULL) {
2709dc70af8SWarner Losh
2719dc70af8SWarner Losh if (++n >= UB_MAX_DEV)
2729dc70af8SWarner Losh break;
2739dc70af8SWarner Losh
2749dc70af8SWarner Losh /* take another device_info */
2759dc70af8SWarner Losh di++;
2769dc70af8SWarner Losh
2779dc70af8SWarner Losh /* pass on the previous cookie */
2789dc70af8SWarner Losh di->cookie = devices[n - 1].cookie;
2799dc70af8SWarner Losh
2809dc70af8SWarner Losh if (!syscall(API_DEV_ENUM, NULL, di))
2819dc70af8SWarner Losh return (0);
2829dc70af8SWarner Losh }
2839dc70af8SWarner Losh
2849dc70af8SWarner Losh return (n);
2859dc70af8SWarner Losh }
2869dc70af8SWarner Losh
2879dc70af8SWarner Losh /*
2889dc70af8SWarner Losh * handle: 0-based id of the device
2899dc70af8SWarner Losh *
2909dc70af8SWarner Losh * returns: 0 when OK, err otherwise
2919dc70af8SWarner Losh */
2929dc70af8SWarner Losh int
ub_dev_open(int handle)2939dc70af8SWarner Losh ub_dev_open(int handle)
2949dc70af8SWarner Losh {
2959dc70af8SWarner Losh struct device_info *di;
2969dc70af8SWarner Losh int err = 0;
2979dc70af8SWarner Losh
2989dc70af8SWarner Losh if (handle < 0 || handle >= UB_MAX_DEV)
2999dc70af8SWarner Losh return (API_EINVAL);
3009dc70af8SWarner Losh
3019dc70af8SWarner Losh di = &devices[handle];
3029dc70af8SWarner Losh if (!syscall(API_DEV_OPEN, &err, di))
3039dc70af8SWarner Losh return (-1);
3049dc70af8SWarner Losh
3059dc70af8SWarner Losh return (err);
3069dc70af8SWarner Losh }
3079dc70af8SWarner Losh
3089dc70af8SWarner Losh int
ub_dev_close(int handle)3099dc70af8SWarner Losh ub_dev_close(int handle)
3109dc70af8SWarner Losh {
3119dc70af8SWarner Losh struct device_info *di;
3129dc70af8SWarner Losh
3139dc70af8SWarner Losh if (handle < 0 || handle >= UB_MAX_DEV)
3149dc70af8SWarner Losh return (API_EINVAL);
3159dc70af8SWarner Losh
3169dc70af8SWarner Losh di = &devices[handle];
3179dc70af8SWarner Losh if (!syscall(API_DEV_CLOSE, NULL, di))
3189dc70af8SWarner Losh return (-1);
3199dc70af8SWarner Losh
3209dc70af8SWarner Losh return (0);
3219dc70af8SWarner Losh }
3229dc70af8SWarner Losh
3239dc70af8SWarner Losh /*
3249dc70af8SWarner Losh * Validates device for read/write, it has to:
3259dc70af8SWarner Losh *
3269dc70af8SWarner Losh * - have sane handle
3279dc70af8SWarner Losh * - be opened
3289dc70af8SWarner Losh *
3299dc70af8SWarner Losh * returns: 0/1 accordingly
3309dc70af8SWarner Losh */
3319dc70af8SWarner Losh static int
dev_valid(int handle)3329dc70af8SWarner Losh dev_valid(int handle)
3339dc70af8SWarner Losh {
3349dc70af8SWarner Losh
3359dc70af8SWarner Losh if (handle < 0 || handle >= UB_MAX_DEV)
3369dc70af8SWarner Losh return (0);
3379dc70af8SWarner Losh
3389dc70af8SWarner Losh if (devices[handle].state != DEV_STA_OPEN)
3399dc70af8SWarner Losh return (0);
3409dc70af8SWarner Losh
3419dc70af8SWarner Losh return (1);
3429dc70af8SWarner Losh }
3439dc70af8SWarner Losh
3449dc70af8SWarner Losh static int
dev_stor_valid(int handle)3459dc70af8SWarner Losh dev_stor_valid(int handle)
3469dc70af8SWarner Losh {
3479dc70af8SWarner Losh
3489dc70af8SWarner Losh if (!dev_valid(handle))
3499dc70af8SWarner Losh return (0);
3509dc70af8SWarner Losh
3519dc70af8SWarner Losh if (!(devices[handle].type & DEV_TYP_STOR))
3529dc70af8SWarner Losh return (0);
3539dc70af8SWarner Losh
3549dc70af8SWarner Losh return (1);
3559dc70af8SWarner Losh }
3569dc70af8SWarner Losh
3579dc70af8SWarner Losh int
ub_dev_read(int handle,void * buf,lbasize_t len,lbastart_t start,lbasize_t * rlen)3589dc70af8SWarner Losh ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start,
3599dc70af8SWarner Losh lbasize_t *rlen)
3609dc70af8SWarner Losh {
3619dc70af8SWarner Losh struct device_info *di;
3629dc70af8SWarner Losh lbasize_t act_len;
3639dc70af8SWarner Losh int err = 0;
3649dc70af8SWarner Losh
3659dc70af8SWarner Losh if (!dev_stor_valid(handle))
3669dc70af8SWarner Losh return (API_ENODEV);
3679dc70af8SWarner Losh
3689dc70af8SWarner Losh di = &devices[handle];
3699dc70af8SWarner Losh if (!syscall(API_DEV_READ, &err, di, buf, &len, &start, &act_len))
3709dc70af8SWarner Losh return (API_ESYSC);
3719dc70af8SWarner Losh
3729dc70af8SWarner Losh if (!err && rlen)
3739dc70af8SWarner Losh *rlen = act_len;
3749dc70af8SWarner Losh
3759dc70af8SWarner Losh return (err);
3769dc70af8SWarner Losh }
3779dc70af8SWarner Losh
3789dc70af8SWarner Losh static int
dev_net_valid(int handle)3799dc70af8SWarner Losh dev_net_valid(int handle)
3809dc70af8SWarner Losh {
3819dc70af8SWarner Losh
3829dc70af8SWarner Losh if (!dev_valid(handle))
3839dc70af8SWarner Losh return (0);
3849dc70af8SWarner Losh
3859dc70af8SWarner Losh if (devices[handle].type != DEV_TYP_NET)
3869dc70af8SWarner Losh return (0);
3879dc70af8SWarner Losh
3889dc70af8SWarner Losh return (1);
3899dc70af8SWarner Losh }
3909dc70af8SWarner Losh
3919dc70af8SWarner Losh int
ub_dev_recv(int handle,void * buf,int len,int * rlen)3929dc70af8SWarner Losh ub_dev_recv(int handle, void *buf, int len, int *rlen)
3939dc70af8SWarner Losh {
3949dc70af8SWarner Losh struct device_info *di;
3959dc70af8SWarner Losh int err = 0, act_len;
3969dc70af8SWarner Losh
3979dc70af8SWarner Losh if (!dev_net_valid(handle))
3989dc70af8SWarner Losh return (API_ENODEV);
3999dc70af8SWarner Losh
4009dc70af8SWarner Losh di = &devices[handle];
4019dc70af8SWarner Losh if (!syscall(API_DEV_READ, &err, di, buf, &len, &act_len))
4029dc70af8SWarner Losh return (API_ESYSC);
4039dc70af8SWarner Losh
4049dc70af8SWarner Losh if (!err)
4059dc70af8SWarner Losh *rlen = act_len;
4069dc70af8SWarner Losh
4079dc70af8SWarner Losh return (err);
4089dc70af8SWarner Losh }
4099dc70af8SWarner Losh
4109dc70af8SWarner Losh int
ub_dev_send(int handle,void * buf,int len)4119dc70af8SWarner Losh ub_dev_send(int handle, void *buf, int len)
4129dc70af8SWarner Losh {
4139dc70af8SWarner Losh struct device_info *di;
4149dc70af8SWarner Losh int err = 0;
4159dc70af8SWarner Losh
4169dc70af8SWarner Losh if (!dev_net_valid(handle))
4179dc70af8SWarner Losh return (API_ENODEV);
4189dc70af8SWarner Losh
4199dc70af8SWarner Losh di = &devices[handle];
4209dc70af8SWarner Losh if (!syscall(API_DEV_WRITE, &err, di, buf, &len))
4219dc70af8SWarner Losh return (API_ESYSC);
4229dc70af8SWarner Losh
4239dc70af8SWarner Losh return (err);
4249dc70af8SWarner Losh }
4259dc70af8SWarner Losh
4269dc70af8SWarner Losh char *
ub_stor_type(int type)4279dc70af8SWarner Losh ub_stor_type(int type)
4289dc70af8SWarner Losh {
4299dc70af8SWarner Losh
4309dc70af8SWarner Losh if (type & DT_STOR_IDE)
4319dc70af8SWarner Losh return ("IDE");
4329dc70af8SWarner Losh
4339dc70af8SWarner Losh if (type & DT_STOR_SCSI)
4349dc70af8SWarner Losh return ("SCSI");
4359dc70af8SWarner Losh
4369dc70af8SWarner Losh if (type & DT_STOR_USB)
4379dc70af8SWarner Losh return ("USB");
4389dc70af8SWarner Losh
4399dc70af8SWarner Losh if (type & DT_STOR_MMC)
4409dc70af8SWarner Losh return ("MMC");
4419dc70af8SWarner Losh
4429dc70af8SWarner Losh if (type & DT_STOR_SATA)
4439dc70af8SWarner Losh return ("SATA");
4449dc70af8SWarner Losh
4459dc70af8SWarner Losh return ("Unknown");
4469dc70af8SWarner Losh }
4479dc70af8SWarner Losh
4489dc70af8SWarner Losh char *
ub_mem_type(int flags)4499dc70af8SWarner Losh ub_mem_type(int flags)
4509dc70af8SWarner Losh {
4519dc70af8SWarner Losh
4529dc70af8SWarner Losh switch (flags & 0x000F) {
4539dc70af8SWarner Losh case MR_ATTR_FLASH:
4549dc70af8SWarner Losh return ("FLASH");
4559dc70af8SWarner Losh case MR_ATTR_DRAM:
4569dc70af8SWarner Losh return ("DRAM");
4579dc70af8SWarner Losh case MR_ATTR_SRAM:
4589dc70af8SWarner Losh return ("SRAM");
4599dc70af8SWarner Losh default:
4609dc70af8SWarner Losh return ("Unknown");
4619dc70af8SWarner Losh }
4629dc70af8SWarner Losh }
4639dc70af8SWarner Losh
4649dc70af8SWarner Losh void
ub_dump_di(int handle)4659dc70af8SWarner Losh ub_dump_di(int handle)
4669dc70af8SWarner Losh {
4679dc70af8SWarner Losh struct device_info *di = ub_dev_get(handle);
4689dc70af8SWarner Losh int i;
4699dc70af8SWarner Losh
4709dc70af8SWarner Losh printf("device info (%d):\n", handle);
4719dc70af8SWarner Losh printf(" cookie\t= %p\n", di->cookie);
4729dc70af8SWarner Losh printf(" type\t\t= 0x%08x\n", di->type);
4739dc70af8SWarner Losh
4749dc70af8SWarner Losh if (di->type == DEV_TYP_NET) {
4759dc70af8SWarner Losh printf(" hwaddr\t= ");
4769dc70af8SWarner Losh for (i = 0; i < 6; i++)
4779dc70af8SWarner Losh printf("%02x ", di->di_net.hwaddr[i]);
4789dc70af8SWarner Losh
4799dc70af8SWarner Losh printf("\n");
4809dc70af8SWarner Losh
4819dc70af8SWarner Losh } else if (di->type & DEV_TYP_STOR) {
4829dc70af8SWarner Losh printf(" type\t\t= %s\n", ub_stor_type(di->type));
4839dc70af8SWarner Losh printf(" blk size\t\t= %ld\n", di->di_stor.block_size);
4849dc70af8SWarner Losh printf(" blk count\t\t= %ld\n", di->di_stor.block_count);
4859dc70af8SWarner Losh }
4869dc70af8SWarner Losh }
4879dc70af8SWarner Losh
4889dc70af8SWarner Losh void
ub_dump_si(struct sys_info * si)4899dc70af8SWarner Losh ub_dump_si(struct sys_info *si)
4909dc70af8SWarner Losh {
4919dc70af8SWarner Losh int i;
4929dc70af8SWarner Losh
4939dc70af8SWarner Losh printf("sys info:\n");
4949dc70af8SWarner Losh printf(" clkbus\t= %ld MHz\n", si->clk_bus / 1000 / 1000);
4959dc70af8SWarner Losh printf(" clkcpu\t= %ld MHz\n", si->clk_cpu / 1000 / 1000);
4969dc70af8SWarner Losh printf(" bar\t\t= 0x%08lx\n", si->bar);
4979dc70af8SWarner Losh
4989dc70af8SWarner Losh printf("---\n");
4999dc70af8SWarner Losh for (i = 0; i < si->mr_no; i++) {
5009dc70af8SWarner Losh if (si->mr[i].flags == 0)
5019dc70af8SWarner Losh break;
5029dc70af8SWarner Losh
5039dc70af8SWarner Losh printf(" start\t= 0x%08lx\n", si->mr[i].start);
5049dc70af8SWarner Losh printf(" size\t= 0x%08lx\n", si->mr[i].size);
5059dc70af8SWarner Losh printf(" type\t= %s\n", ub_mem_type(si->mr[i].flags));
5069dc70af8SWarner Losh printf("---\n");
5079dc70af8SWarner Losh }
5089dc70af8SWarner Losh }
5099dc70af8SWarner Losh
5109dc70af8SWarner Losh /****************************************
5119dc70af8SWarner Losh *
5129dc70af8SWarner Losh * env vars
5139dc70af8SWarner Losh *
5149dc70af8SWarner Losh ****************************************/
5159dc70af8SWarner Losh
5169dc70af8SWarner Losh char *
ub_env_get(const char * name)5179dc70af8SWarner Losh ub_env_get(const char *name)
5189dc70af8SWarner Losh {
5199dc70af8SWarner Losh char *value;
5209dc70af8SWarner Losh
5219dc70af8SWarner Losh if (!syscall(API_ENV_GET, NULL, name, &value))
5229dc70af8SWarner Losh return (NULL);
5239dc70af8SWarner Losh
5249dc70af8SWarner Losh return (value);
5259dc70af8SWarner Losh }
5269dc70af8SWarner Losh
5279dc70af8SWarner Losh void
ub_env_set(const char * name,char * value)5289dc70af8SWarner Losh ub_env_set(const char *name, char *value)
5299dc70af8SWarner Losh {
5309dc70af8SWarner Losh
5319dc70af8SWarner Losh syscall(API_ENV_SET, NULL, name, value);
5329dc70af8SWarner Losh }
5339dc70af8SWarner Losh
5349dc70af8SWarner Losh static char env_name[256];
5359dc70af8SWarner Losh
5369dc70af8SWarner Losh const char *
ub_env_enum(const char * last)5379dc70af8SWarner Losh ub_env_enum(const char *last)
5389dc70af8SWarner Losh {
5399dc70af8SWarner Losh const char *env, *str;
5409dc70af8SWarner Losh int i;
5419dc70af8SWarner Losh
5429dc70af8SWarner Losh /*
5439dc70af8SWarner Losh * It's OK to pass only the name piece as last (and not the whole
5449dc70af8SWarner Losh * 'name=val' string), since the API_ENUM_ENV call uses envmatch()
5459dc70af8SWarner Losh * internally, which handles such case
5469dc70af8SWarner Losh */
5479dc70af8SWarner Losh env = NULL;
5489dc70af8SWarner Losh if (!syscall(API_ENV_ENUM, NULL, last, &env))
5499dc70af8SWarner Losh return (NULL);
5509dc70af8SWarner Losh
5519dc70af8SWarner Losh if (env == NULL || last == env)
5529dc70af8SWarner Losh /* no more env. variables to enumerate */
5539dc70af8SWarner Losh return (NULL);
5549dc70af8SWarner Losh
5559dc70af8SWarner Losh /* next enumerated env var */
5569dc70af8SWarner Losh memset(env_name, 0, 256);
5579dc70af8SWarner Losh for (i = 0, str = env; *str != '=' && *str != '\0';)
5589dc70af8SWarner Losh env_name[i++] = *str++;
5599dc70af8SWarner Losh
5609dc70af8SWarner Losh env_name[i] = '\0';
5619dc70af8SWarner Losh
5629dc70af8SWarner Losh return (env_name);
5639dc70af8SWarner Losh }
564