source: SVN/rincon/u-boot/api_examples/glue.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 7.1 KB
Line 
1/*
2 * (C) Copyright 2007 Semihalf
3 *
4 * Written by: Rafal Jaworowski <raj@semihalf.com>
5 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 *
24 */
25
26#include <common.h>
27#include <linux/types.h>
28#include <api_public.h>
29
30#include "glue.h"
31
32static int valid_sig(struct api_signature *sig)
33{
34        uint32_t checksum;
35        struct api_signature s;
36
37        if (sig == NULL)
38                return 0;
39        /*
40         * Clear the checksum field (in the local copy) so as to calculate the
41         * CRC with the same initial contents as at the time when the sig was
42         * produced
43         */
44        s = *sig;
45        s.checksum = 0;
46
47        checksum = crc32(0, (unsigned char *)&s, sizeof(struct api_signature));
48
49        if (checksum != sig->checksum)
50                return 0;
51
52        return 1;
53}
54
55/*
56 * Searches for the U-Boot API signature
57 *
58 * returns 1/0 depending on found/not found result
59 */
60int api_search_sig(struct api_signature **sig) {
61
62        unsigned char *sp;
63
64        if (sig == NULL)
65                return 0;
66
67        sp = (unsigned char *)API_SEARCH_START;
68
69        while ((sp + (int)API_SIG_MAGLEN) < (unsigned char *)API_SEARCH_END) {
70                if (!memcmp(sp, API_SIG_MAGIC, API_SIG_MAGLEN)) {
71                        *sig = (struct api_signature *)sp;
72                        if (valid_sig(*sig))
73                                return 1;
74                }
75                sp += API_SIG_MAGLEN;
76        }
77
78        *sig = NULL;
79        return 0;
80}
81
82/****************************************
83 *
84 * console
85 *
86 ****************************************/
87
88int ub_getc(void)
89{
90        int c;
91
92        if (!syscall(API_GETC, NULL, (uint32_t)&c))
93                return -1;
94
95        return c;
96}
97
98int ub_tstc(void)
99{
100        int t;
101
102        if (!syscall(API_TSTC, NULL, (uint32_t)&t))
103                return -1;
104
105        return t;
106}
107
108void ub_putc(char c)
109{
110        syscall(API_PUTC, NULL, (uint32_t)&c);
111}
112
113void ub_puts(const char *s)
114{
115        syscall(API_PUTS, NULL, (uint32_t)s);
116}
117
118/****************************************
119 *
120 * system
121 *
122 ****************************************/
123
124void ub_reset(void)
125{
126        syscall(API_RESET, NULL);
127}
128
129#define MR_MAX 5
130static struct mem_region mr[MR_MAX];
131static struct sys_info si;
132
133struct sys_info * ub_get_sys_info(void)
134{
135        int err = 0;
136
137        memset(&si, 0, sizeof(struct sys_info));
138        si.mr = mr;
139        si.mr_no = MR_MAX;
140        memset(&mr, 0, sizeof(mr));
141
142        if (!syscall(API_GET_SYS_INFO, &err, (u_int32_t)&si))
143                return NULL;
144
145        return ((err) ? NULL : &si);
146}
147
148/****************************************
149 *
150 * timing
151 *
152 ****************************************/
153
154void ub_udelay(unsigned long usec)
155{
156        syscall(API_UDELAY, NULL, &usec);
157}
158
159unsigned long ub_get_timer(unsigned long base)
160{
161        unsigned long cur;
162
163        if (!syscall(API_GET_TIMER, NULL, &cur, &base))
164                return 0;
165
166        return cur;
167}
168
169
170/****************************************************************************
171 *
172 * devices
173 *
174 * Devices are identified by handles: numbers 0, 1, 2, ..., MAX_DEVS-1
175 *
176 ***************************************************************************/
177
178#define MAX_DEVS 6
179
180static struct device_info devices[MAX_DEVS];
181
182struct device_info * ub_dev_get(int i)
183{
184        return ((i < 0 || i >= MAX_DEVS) ? NULL : &devices[i]);
185}
186
187/*
188 * Enumerates the devices: fills out device_info elements in the devices[]
189 * array.
190 *
191 * returns:             number of devices found
192 */
193int ub_dev_enum(void)
194{
195        struct device_info *di;
196        int n = 0;
197
198        memset(&devices, 0, sizeof(struct device_info) * MAX_DEVS);
199        di = &devices[0];
200
201        if (!syscall(API_DEV_ENUM, NULL, di))
202                return 0;
203
204        while (di->cookie != NULL) {
205
206                if (++n >= MAX_DEVS)
207                        break;
208
209                /* take another device_info */
210                di++;
211
212                /* pass on the previous cookie */
213                di->cookie = devices[n - 1].cookie;
214
215                if (!syscall(API_DEV_ENUM, NULL, di))
216                        return 0;
217        }
218
219        return n;
220}
221
222/*
223 * handle:      0-based id of the device
224 *
225 * returns:     0 when OK, err otherwise
226 */
227int ub_dev_open(int handle)
228{
229        struct device_info *di;
230        int err = 0;
231
232        if (handle < 0 || handle >= MAX_DEVS)
233                return API_EINVAL;
234
235        di = &devices[handle];
236
237        if (!syscall(API_DEV_OPEN, &err, di))
238                return -1;
239
240        return err;
241}
242
243int ub_dev_close(int handle)
244{
245        struct device_info *di;
246
247        if (handle < 0 || handle >= MAX_DEVS)
248                return API_EINVAL;
249
250        di = &devices[handle];
251        if (!syscall(API_DEV_CLOSE, NULL, di))
252                return -1;
253
254        return 0;
255}
256
257/*
258 *
259 * Validates device for read/write, it has to:
260 *
261 * - have sane handle
262 * - be opened
263 *
264 * returns:     0/1 accordingly
265 */
266static int dev_valid(int handle)
267{
268        if (handle < 0 || handle >= MAX_DEVS)
269                return 0;
270
271        if (devices[handle].state != DEV_STA_OPEN)
272                return 0;
273
274        return 1;
275}
276
277static int dev_stor_valid(int handle)
278{
279        if (!dev_valid(handle))
280                return 0;
281
282        if (!(devices[handle].type & DEV_TYP_STOR))
283                return 0;
284
285        return 1;
286}
287
288int ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start)
289{
290        struct device_info *di;
291        lbasize_t act_len;
292        int err = 0;
293
294        if (!dev_stor_valid(handle))
295                return API_ENODEV;
296
297        di = &devices[handle];
298        if (!syscall(API_DEV_READ, &err, di, buf, &len, &start, &act_len))
299                return -1;
300
301        if (err)
302                return err;
303
304        if (act_len != len)
305                return API_EIO;
306
307        return 0;
308}
309
310static int dev_net_valid(int handle)
311{
312        if (!dev_valid(handle))
313                return 0;
314
315        if (devices[handle].type != DEV_TYP_NET)
316                return 0;
317
318        return 1;
319}
320
321int ub_dev_recv(int handle, void *buf, int len)
322{
323        struct device_info *di;
324        int err = 0, act_len;
325
326        if (!dev_net_valid(handle))
327                return API_ENODEV;
328
329        di = &devices[handle];
330        if (!syscall(API_DEV_READ, &err, di, buf, &len, &act_len))
331                return -1;
332
333        if (err)
334                return -1;
335
336        return act_len;
337}
338
339int ub_dev_send(int handle, void *buf, int len)
340{
341        struct device_info *di;
342        int err = 0;
343
344        if (!dev_net_valid(handle))
345                return API_ENODEV;
346
347        di = &devices[handle];
348        if (!syscall(API_DEV_WRITE, &err, di, buf, &len))
349                return -1;
350
351        return err;
352}
353
354/****************************************
355 *
356 * env vars
357 *
358 ****************************************/
359
360char * ub_env_get(const char *name)
361{
362        char *value;
363
364        if (!syscall(API_ENV_GET, NULL, (uint32_t)name, (uint32_t)&value))
365                return NULL;
366
367        return value;
368}
369
370void ub_env_set(const char *name, char *value)
371{
372        syscall(API_ENV_SET, NULL, (uint32_t)name, (uint32_t)value);
373}
374
375
376static char env_name[256];
377
378const char * ub_env_enum(const char *last)
379{
380        const char *env, *str;
381        int i;
382
383        env = NULL;
384
385        /*
386         * It's OK to pass only the name piece as last (and not the whole
387         * 'name=val' string), since the API_ENUM_ENV call uses envmatch()
388         * internally, which handles such case
389         */
390        if (!syscall(API_ENV_ENUM, NULL, (uint32_t)last, (uint32_t)&env))
391                return NULL;
392
393        if (!env)
394                /* no more env. variables to enumerate */
395                return NULL;
396
397        /* next enumerated env var */
398        memset(env_name, 0, 256);
399        for (i = 0, str = env; *str != '=' && *str != '\0';)
400                env_name[i++] = *str++;
401
402        env_name[i] = '\0';
403
404        return env_name;
405}
Note: See TracBrowser for help on using the repository browser.