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