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