blob: 4fc451a83d1905a9f50faf0d767ce75ed8a19ca7 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Rafal Jaworowskia19be782008-01-09 19:39:36 +01002/*
3 * (C) Copyright 2007 Semihalf
4 *
5 * Written by: Rafal Jaworowski <raj@semihalf.com>
Rafal Jaworowskia19be782008-01-09 19:39:36 +01006 */
7
8#include <config.h>
Rafal Jaworowskia19be782008-01-09 19:39:36 +01009#include <command.h>
10#include <common.h>
Simon Glass313112a2019-08-01 09:46:46 -060011#include <env.h>
Rafal Jaworowskia19be782008-01-09 19:39:36 +010012#include <malloc.h>
Simon Glass9d1f6192019-08-02 09:44:25 -060013#include <env_internal.h>
Rafal Jaworowskia19be782008-01-09 19:39:36 +010014#include <linux/types.h>
15#include <api_public.h>
Simon Glass48b6c6b2019-11-14 12:57:16 -070016#include <u-boot/crc.h>
Rafal Jaworowskia19be782008-01-09 19:39:36 +010017
18#include "api_private.h"
19
20#define DEBUG
21#undef DEBUG
22
Rafal Jaworowskia19be782008-01-09 19:39:36 +010023/*****************************************************************************
24 *
25 * This is the API core.
26 *
27 * API_ functions are part of U-Boot code and constitute the lowest level
28 * calls:
29 *
30 * - they know what values they need as arguments
31 * - their direct return value pertains to the API_ "shell" itself (0 on
32 * success, some error code otherwise)
33 * - if the call returns a value it is buried within arguments
34 *
35 ****************************************************************************/
36
37#ifdef DEBUG
38#define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt, ##args); } while (0)
39#else
40#define debugf(fmt, args...)
41#endif
42
43typedef int (*cfp_t)(va_list argp);
44
45static int calls_no;
46
47/*
48 * pseudo signature:
49 *
50 * int API_getc(int *c)
51 */
52static int API_getc(va_list ap)
53{
54 int *c;
55
Stanislav Galabov10c7a572016-02-17 15:23:31 +020056 if ((c = (int *)va_arg(ap, uintptr_t)) == NULL)
Rafal Jaworowskia19be782008-01-09 19:39:36 +010057 return API_EINVAL;
58
59 *c = getc();
60 return 0;
61}
62
63/*
64 * pseudo signature:
65 *
66 * int API_tstc(int *c)
67 */
68static int API_tstc(va_list ap)
69{
70 int *t;
71
Stanislav Galabov10c7a572016-02-17 15:23:31 +020072 if ((t = (int *)va_arg(ap, uintptr_t)) == NULL)
Rafal Jaworowskia19be782008-01-09 19:39:36 +010073 return API_EINVAL;
74
75 *t = tstc();
76 return 0;
77}
78
79/*
80 * pseudo signature:
81 *
82 * int API_putc(char *ch)
83 */
84static int API_putc(va_list ap)
85{
86 char *c;
87
Stanislav Galabov10c7a572016-02-17 15:23:31 +020088 if ((c = (char *)va_arg(ap, uintptr_t)) == NULL)
Rafal Jaworowskia19be782008-01-09 19:39:36 +010089 return API_EINVAL;
90
91 putc(*c);
92 return 0;
93}
94
95/*
96 * pseudo signature:
97 *
98 * int API_puts(char **s)
99 */
100static int API_puts(va_list ap)
101{
102 char *s;
103
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200104 if ((s = (char *)va_arg(ap, uintptr_t)) == NULL)
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100105 return API_EINVAL;
106
107 puts(s);
108 return 0;
109}
110
111/*
112 * pseudo signature:
113 *
114 * int API_reset(void)
115 */
116static int API_reset(va_list ap)
117{
118 do_reset(NULL, 0, 0, NULL);
119
120 /* NOT REACHED */
121 return 0;
122}
123
124/*
125 * pseudo signature:
126 *
127 * int API_get_sys_info(struct sys_info *si)
128 *
129 * fill out the sys_info struct containing selected parameters about the
130 * machine
131 */
132static int API_get_sys_info(va_list ap)
133{
134 struct sys_info *si;
135
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200136 si = (struct sys_info *)va_arg(ap, uintptr_t);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100137 if (si == NULL)
138 return API_ENOMEM;
139
140 return (platform_sys_info(si)) ? 0 : API_ENODEV;
141}
142
143/*
144 * pseudo signature:
145 *
146 * int API_udelay(unsigned long *udelay)
147 */
148static int API_udelay(va_list ap)
149{
150 unsigned long *d;
151
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200152 if ((d = (unsigned long *)va_arg(ap, unsigned long)) == NULL)
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100153 return API_EINVAL;
154
155 udelay(*d);
156 return 0;
157}
158
159/*
160 * pseudo signature:
161 *
162 * int API_get_timer(unsigned long *current, unsigned long *base)
163 */
164static int API_get_timer(va_list ap)
165{
166 unsigned long *base, *cur;
167
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200168 cur = (unsigned long *)va_arg(ap, unsigned long);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100169 if (cur == NULL)
170 return API_EINVAL;
171
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200172 base = (unsigned long *)va_arg(ap, unsigned long);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100173 if (base == NULL)
174 return API_EINVAL;
175
176 *cur = get_timer(*base);
177 return 0;
178}
179
180
181/*****************************************************************************
182 *
183 * pseudo signature:
184 *
185 * int API_dev_enum(struct device_info *)
186 *
187 *
188 * cookies uniqely identify the previously enumerated device instance and
189 * provide a hint for what to inspect in current enum iteration:
190 *
191 * - net: &eth_device struct address from list pointed to by eth_devices
192 *
Simon Glasse3394752016-02-29 15:25:34 -0700193 * - storage: struct blk_desc struct address from &ide_dev_desc[n],
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100194 * &scsi_dev_desc[n] and similar tables
195 *
196 ****************************************************************************/
197
198static int API_dev_enum(va_list ap)
199{
200 struct device_info *di;
201
202 /* arg is ptr to the device_info struct we are going to fill out */
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200203 di = (struct device_info *)va_arg(ap, uintptr_t);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100204 if (di == NULL)
205 return API_EINVAL;
206
207 if (di->cookie == NULL) {
208 /* start over - clean up enumeration */
209 dev_enum_reset(); /* XXX shouldn't the name contain 'stor'? */
210 debugf("RESTART ENUM\n");
Wolfgang Denk545b06a2008-01-10 00:55:14 +0100211
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100212 /* net device enumeration first */
213 if (dev_enum_net(di))
214 return 0;
215 }
216
217 /*
218 * The hidden assumption is there can only be one active network
219 * device and it is identified upon enumeration (re)start, so there's
220 * no point in trying to find network devices in other cases than the
221 * (re)start and hence the 'next' device can only be storage
222 */
223 if (!dev_enum_storage(di))
224 /* make sure we mark there are no more devices */
225 di->cookie = NULL;
226
227 return 0;
228}
229
230
231static int API_dev_open(va_list ap)
232{
233 struct device_info *di;
234 int err = 0;
235
236 /* arg is ptr to the device_info struct */
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200237 di = (struct device_info *)va_arg(ap, uintptr_t);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100238 if (di == NULL)
239 return API_EINVAL;
240
241 /* Allow only one consumer of the device at a time */
242 if (di->state == DEV_STA_OPEN)
243 return API_EBUSY;
244
245 if (di->cookie == NULL)
246 return API_ENODEV;
247
248 if (di->type & DEV_TYP_STOR)
249 err = dev_open_stor(di->cookie);
250
251 else if (di->type & DEV_TYP_NET)
252 err = dev_open_net(di->cookie);
253 else
254 err = API_ENODEV;
255
256 if (!err)
257 di->state = DEV_STA_OPEN;
258
259 return err;
260}
261
262
263static int API_dev_close(va_list ap)
264{
265 struct device_info *di;
266 int err = 0;
267
268 /* arg is ptr to the device_info struct */
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200269 di = (struct device_info *)va_arg(ap, uintptr_t);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100270 if (di == NULL)
271 return API_EINVAL;
272
273 if (di->state == DEV_STA_CLOSED)
274 return 0;
275
276 if (di->cookie == NULL)
277 return API_ENODEV;
278
279 if (di->type & DEV_TYP_STOR)
280 err = dev_close_stor(di->cookie);
281
282 else if (di->type & DEV_TYP_NET)
283 err = dev_close_net(di->cookie);
284 else
285 /*
286 * In case of unknown device we cannot change its state, so
287 * only return error code
288 */
289 err = API_ENODEV;
290
291 if (!err)
292 di->state = DEV_STA_CLOSED;
293
294 return err;
295}
296
297
298/*
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100299 * pseudo signature:
300 *
301 * int API_dev_write(
302 * struct device_info *di,
303 * void *buf,
Cristian Ciocaltea29f2ace2019-01-12 02:03:15 +0200304 * int *len,
305 * unsigned long *start
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100306 * )
307 *
308 * buf: ptr to buffer from where to get the data to send
309 *
Cristian Ciocaltea29f2ace2019-01-12 02:03:15 +0200310 * len: ptr to length to be read
311 * - network: len of packet to be sent (in bytes)
312 * - storage: # of blocks to write (can vary in size depending on define)
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100313 *
Cristian Ciocaltea29f2ace2019-01-12 02:03:15 +0200314 * start: ptr to start block (only used for storage devices, ignored for
315 * network)
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100316 */
317static int API_dev_write(va_list ap)
318{
319 struct device_info *di;
320 void *buf;
Cristian Ciocaltea29f2ace2019-01-12 02:03:15 +0200321 lbasize_t *len_stor, act_len_stor;
322 lbastart_t *start;
323 int *len_net;
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100324 int err = 0;
325
326 /* 1. arg is ptr to the device_info struct */
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200327 di = (struct device_info *)va_arg(ap, uintptr_t);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100328 if (di == NULL)
329 return API_EINVAL;
330
331 /* XXX should we check if device is open? i.e. the ->state ? */
332
333 if (di->cookie == NULL)
334 return API_ENODEV;
335
336 /* 2. arg is ptr to buffer from where to get data to write */
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200337 buf = (void *)va_arg(ap, uintptr_t);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100338 if (buf == NULL)
339 return API_EINVAL;
340
Cristian Ciocaltea29f2ace2019-01-12 02:03:15 +0200341 if (di->type & DEV_TYP_STOR) {
342 /* 3. arg - ptr to var with # of blocks to write */
343 len_stor = (lbasize_t *)va_arg(ap, uintptr_t);
344 if (!len_stor)
345 return API_EINVAL;
346 if (*len_stor <= 0)
347 return API_EINVAL;
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100348
Cristian Ciocaltea29f2ace2019-01-12 02:03:15 +0200349 /* 4. arg - ptr to var with start block */
350 start = (lbastart_t *)va_arg(ap, uintptr_t);
351
352 act_len_stor = dev_write_stor(di->cookie, buf, *len_stor, *start);
353 if (act_len_stor != *len_stor) {
354 debugf("write @ %llu: done %llu out of %llu blocks",
355 (uint64_t)blk, (uint64_t)act_len_stor,
356 (uint64_t)len_stor);
357 return API_EIO;
358 }
359
360 } else if (di->type & DEV_TYP_NET) {
361 /* 3. arg points to the var with length of packet to write */
362 len_net = (int *)va_arg(ap, uintptr_t);
363 if (!len_net)
364 return API_EINVAL;
365 if (*len_net <= 0)
366 return API_EINVAL;
367
368 err = dev_write_net(di->cookie, buf, *len_net);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100369
Cristian Ciocaltea29f2ace2019-01-12 02:03:15 +0200370 } else
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100371 err = API_ENODEV;
372
373 return err;
374}
375
376
377/*
378 * pseudo signature:
379 *
380 * int API_dev_read(
381 * struct device_info *di,
382 * void *buf,
383 * size_t *len,
384 * unsigned long *start
385 * size_t *act_len
386 * )
387 *
388 * buf: ptr to buffer where to put the read data
389 *
390 * len: ptr to length to be read
391 * - network: len of packet to read (in bytes)
392 * - storage: # of blocks to read (can vary in size depending on define)
393 *
394 * start: ptr to start block (only used for storage devices, ignored for
395 * network)
396 *
397 * act_len: ptr to where to put the len actually read
398 */
399static int API_dev_read(va_list ap)
400{
401 struct device_info *di;
402 void *buf;
403 lbasize_t *len_stor, *act_len_stor;
404 lbastart_t *start;
405 int *len_net, *act_len_net;
406
407 /* 1. arg is ptr to the device_info struct */
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200408 di = (struct device_info *)va_arg(ap, uintptr_t);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100409 if (di == NULL)
410 return API_EINVAL;
411
412 /* XXX should we check if device is open? i.e. the ->state ? */
413
414 if (di->cookie == NULL)
415 return API_ENODEV;
416
417 /* 2. arg is ptr to buffer from where to put the read data */
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200418 buf = (void *)va_arg(ap, uintptr_t);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100419 if (buf == NULL)
420 return API_EINVAL;
421
422 if (di->type & DEV_TYP_STOR) {
423 /* 3. arg - ptr to var with # of blocks to read */
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200424 len_stor = (lbasize_t *)va_arg(ap, uintptr_t);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100425 if (!len_stor)
426 return API_EINVAL;
427 if (*len_stor <= 0)
428 return API_EINVAL;
429
430 /* 4. arg - ptr to var with start block */
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200431 start = (lbastart_t *)va_arg(ap, uintptr_t);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100432
433 /* 5. arg - ptr to var where to put the len actually read */
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200434 act_len_stor = (lbasize_t *)va_arg(ap, uintptr_t);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100435 if (!act_len_stor)
436 return API_EINVAL;
437
438 *act_len_stor = dev_read_stor(di->cookie, buf, *len_stor, *start);
439
440 } else if (di->type & DEV_TYP_NET) {
441
442 /* 3. arg points to the var with length of packet to read */
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200443 len_net = (int *)va_arg(ap, uintptr_t);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100444 if (!len_net)
445 return API_EINVAL;
446 if (*len_net <= 0)
447 return API_EINVAL;
448
449 /* 4. - ptr to var where to put the len actually read */
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200450 act_len_net = (int *)va_arg(ap, uintptr_t);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100451 if (!act_len_net)
452 return API_EINVAL;
453
454 *act_len_net = dev_read_net(di->cookie, buf, *len_net);
455
456 } else
457 return API_ENODEV;
458
459 return 0;
460}
461
462
463/*
464 * pseudo signature:
465 *
466 * int API_env_get(const char *name, char **value)
467 *
468 * name: ptr to name of env var
469 */
470static int API_env_get(va_list ap)
471{
472 char *name, **value;
473
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200474 if ((name = (char *)va_arg(ap, uintptr_t)) == NULL)
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100475 return API_EINVAL;
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200476 if ((value = (char **)va_arg(ap, uintptr_t)) == NULL)
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100477 return API_EINVAL;
478
Simon Glass64b723f2017-08-03 12:22:12 -0600479 *value = env_get(name);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100480
481 return 0;
482}
483
484/*
485 * pseudo signature:
486 *
487 * int API_env_set(const char *name, const char *value)
488 *
489 * name: ptr to name of env var
490 *
491 * value: ptr to value to be set
492 */
493static int API_env_set(va_list ap)
494{
495 char *name, *value;
496
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200497 if ((name = (char *)va_arg(ap, uintptr_t)) == NULL)
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100498 return API_EINVAL;
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200499 if ((value = (char *)va_arg(ap, uintptr_t)) == NULL)
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100500 return API_EINVAL;
501
Simon Glass6a38e412017-08-03 12:22:09 -0600502 env_set(name, value);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100503
504 return 0;
505}
506
507/*
508 * pseudo signature:
509 *
510 * int API_env_enum(const char *last, char **next)
511 *
512 * last: ptr to name of env var found in last iteration
513 */
514static int API_env_enum(va_list ap)
515{
Emmanuel Vadotc4971b92016-12-26 18:57:56 +0100516 int i, buflen;
517 char *last, **next, *s;
Simon Glass1a236862019-08-02 09:44:18 -0600518 struct env_entry *match, search;
Emmanuel Vadotc4971b92016-12-26 18:57:56 +0100519 static char *var;
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100520
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200521 last = (char *)va_arg(ap, unsigned long);
Wolfgang Denk545b06a2008-01-10 00:55:14 +0100522
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200523 if ((next = (char **)va_arg(ap, uintptr_t)) == NULL)
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100524 return API_EINVAL;
525
Emmanuel Vadotc4971b92016-12-26 18:57:56 +0100526 if (last == NULL) {
527 var = NULL;
528 i = 0;
529 } else {
530 var = strdup(last);
531 s = strchr(var, '=');
532 if (s != NULL)
533 *s = 0;
534 search.key = var;
Simon Glass63a2f572019-08-01 09:47:09 -0600535 i = hsearch_r(search, ENV_FIND, &match, &env_htab, 0);
Emmanuel Vadotc4971b92016-12-26 18:57:56 +0100536 if (i == 0) {
537 i = API_EINVAL;
538 goto done;
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100539 }
540 }
541
Emmanuel Vadotc4971b92016-12-26 18:57:56 +0100542 /* match the next entry after i */
543 i = hmatch_r("", i, &match, &env_htab);
544 if (i == 0)
545 goto done;
546 buflen = strlen(match->key) + strlen(match->data) + 2;
547 var = realloc(var, buflen);
548 snprintf(var, buflen, "%s=%s", match->key, match->data);
549 *next = var;
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100550 return 0;
Emmanuel Vadotc4971b92016-12-26 18:57:56 +0100551
552done:
553 free(var);
554 var = NULL;
555 *next = NULL;
556 return i;
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100557}
558
Che-Liang Chiou0d460412011-10-20 23:04:22 +0000559/*
560 * pseudo signature:
561 *
562 * int API_display_get_info(int type, struct display_info *di)
563 */
564static int API_display_get_info(va_list ap)
565{
566 int type;
567 struct display_info *di;
568
569 type = va_arg(ap, int);
570 di = va_arg(ap, struct display_info *);
571
572 return display_get_info(type, di);
573}
574
575/*
576 * pseudo signature:
577 *
578 * int API_display_draw_bitmap(ulong bitmap, int x, int y)
579 */
580static int API_display_draw_bitmap(va_list ap)
581{
582 ulong bitmap;
583 int x, y;
584
585 bitmap = va_arg(ap, ulong);
586 x = va_arg(ap, int);
587 y = va_arg(ap, int);
588
589 return display_draw_bitmap(bitmap, x, y);
590}
591
592/*
593 * pseudo signature:
594 *
595 * void API_display_clear(void)
596 */
597static int API_display_clear(va_list ap)
598{
599 display_clear();
600 return 0;
601}
602
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100603static cfp_t calls_table[API_MAXCALL] = { NULL, };
604
605/*
606 * The main syscall entry point - this is not reentrant, only one call is
607 * serviced until finished.
608 *
609 * e.g. syscall(1, int *, u_int32_t, u_int32_t, u_int32_t, u_int32_t);
Wolfgang Denk545b06a2008-01-10 00:55:14 +0100610 *
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100611 * call: syscall number
612 *
613 * retval: points to the return value placeholder, this is the place the
614 * syscall puts its return value, if NULL the caller does not
615 * expect a return value
616 *
617 * ... syscall arguments (variable number)
618 *
619 * returns: 0 if the call not found, 1 if serviced
620 */
621int syscall(int call, int *retval, ...)
622{
623 va_list ap;
624 int rv;
625
Jean-Christophe PLAGNIOL-VILLARDffaed162008-05-11 23:13:57 +0200626 if (call < 0 || call >= calls_no) {
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100627 debugf("invalid call #%d\n", call);
628 return 0;
629 }
630
631 if (calls_table[call] == NULL) {
632 debugf("syscall #%d does not have a handler\n", call);
633 return 0;
634 }
635
636 va_start(ap, retval);
637 rv = calls_table[call](ap);
638 if (retval != NULL)
639 *retval = rv;
640
641 return 1;
642}
643
644void api_init(void)
645{
xypron.glpk@gmx.de0a23a732017-07-30 19:54:37 +0200646 struct api_signature *sig;
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100647
648 /* TODO put this into linker set one day... */
649 calls_table[API_RSVD] = NULL;
650 calls_table[API_GETC] = &API_getc;
651 calls_table[API_PUTC] = &API_putc;
652 calls_table[API_TSTC] = &API_tstc;
653 calls_table[API_PUTS] = &API_puts;
654 calls_table[API_RESET] = &API_reset;
655 calls_table[API_GET_SYS_INFO] = &API_get_sys_info;
656 calls_table[API_UDELAY] = &API_udelay;
657 calls_table[API_GET_TIMER] = &API_get_timer;
658 calls_table[API_DEV_ENUM] = &API_dev_enum;
659 calls_table[API_DEV_OPEN] = &API_dev_open;
660 calls_table[API_DEV_CLOSE] = &API_dev_close;
661 calls_table[API_DEV_READ] = &API_dev_read;
662 calls_table[API_DEV_WRITE] = &API_dev_write;
663 calls_table[API_ENV_GET] = &API_env_get;
664 calls_table[API_ENV_SET] = &API_env_set;
665 calls_table[API_ENV_ENUM] = &API_env_enum;
Che-Liang Chiou0d460412011-10-20 23:04:22 +0000666 calls_table[API_DISPLAY_GET_INFO] = &API_display_get_info;
667 calls_table[API_DISPLAY_DRAW_BITMAP] = &API_display_draw_bitmap;
668 calls_table[API_DISPLAY_CLEAR] = &API_display_clear;
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100669 calls_no = API_MAXCALL;
670
671 debugf("API initialized with %d calls\n", calls_no);
672
673 dev_stor_init();
674
675 /*
676 * Produce the signature so the API consumers can find it
677 */
678 sig = malloc(sizeof(struct api_signature));
679 if (sig == NULL) {
680 printf("API: could not allocate memory for the signature!\n");
681 return;
682 }
683
Simon Glass4d949a22017-08-03 12:22:10 -0600684 env_set_hex("api_address", (unsigned long)sig);
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200685 debugf("API sig @ 0x%lX\n", (unsigned long)sig);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100686 memcpy(sig->magic, API_SIG_MAGIC, 8);
687 sig->version = API_SIG_VERSION;
688 sig->syscall = &syscall;
689 sig->checksum = 0;
690 sig->checksum = crc32(0, (unsigned char *)sig,
691 sizeof(struct api_signature));
Stanislav Galabov10c7a572016-02-17 15:23:31 +0200692 debugf("syscall entry: 0x%lX\n", (unsigned long)sig->syscall);
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100693}
694
695void platform_set_mr(struct sys_info *si, unsigned long start, unsigned long size,
696 int flags)
697{
698 int i;
699
700 if (!si->mr || !size || (flags == 0))
701 return;
Wolfgang Denk545b06a2008-01-10 00:55:14 +0100702
Rafal Jaworowskia19be782008-01-09 19:39:36 +0100703 /* find free slot */
704 for (i = 0; i < si->mr_no; i++)
705 if (si->mr[i].flags == 0) {
706 /* insert new mem region */
707 si->mr[i].start = start;
708 si->mr[i].size = size;
709 si->mr[i].flags = flags;
710 return;
711 }
712}