Blame view

examples/api/glue.c 7.14 KB
500856eb1   Rafal Jaworowski   API for external ...
1
  /*
923aa4812   Rafal Jaworowski   API: Improve glue...
2
   * (C) Copyright 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
500856eb1   Rafal Jaworowski   API for external ...
3
   *
1a4596601   Wolfgang Denk   Add GPL-2.0+ SPDX...
4
   * SPDX-License-Identifier:	GPL-2.0+
500856eb1   Rafal Jaworowski   API for external ...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
   */
  
  #include <common.h>
  #include <linux/types.h>
  #include <api_public.h>
  
  #include "glue.h"
  
  static int valid_sig(struct api_signature *sig)
  {
  	uint32_t checksum;
  	struct api_signature s;
  
  	if (sig == NULL)
  		return 0;
  	/*
  	 * Clear the checksum field (in the local copy) so as to calculate the
  	 * CRC with the same initial contents as at the time when the sig was
  	 * produced
  	 */
  	s = *sig;
  	s.checksum = 0;
  
  	checksum = crc32(0, (unsigned char *)&s, sizeof(struct api_signature));
  
  	if (checksum != sig->checksum)
  		return 0;
  
  	return 1;
  }
  
  /*
   * Searches for the U-Boot API signature
   *
   * returns 1/0 depending on found/not found result
   */
923aa4812   Rafal Jaworowski   API: Improve glue...
41
42
  int api_search_sig(struct api_signature **sig)
  {
500856eb1   Rafal Jaworowski   API for external ...
43
  	unsigned char *sp;
b84d7d8f1   Rafal Jaworowski   API: Use stack po...
44
45
  	uint32_t search_start = 0;
  	uint32_t search_end = 0;
500856eb1   Rafal Jaworowski   API for external ...
46
47
48
  
  	if (sig == NULL)
  		return 0;
b84d7d8f1   Rafal Jaworowski   API: Use stack po...
49
50
  	if (search_hint == 0)
  		search_hint = 255 * 1024 * 1024;
500856eb1   Rafal Jaworowski   API for external ...
51

b84d7d8f1   Rafal Jaworowski   API: Use stack po...
52
53
54
55
56
  	search_start = search_hint & ~0x000fffff;
  	search_end = search_start + API_SEARCH_LEN - API_SIG_MAGLEN;
  
  	sp = (unsigned char *)search_start;
  	while ((sp + API_SIG_MAGLEN) < (unsigned char *)search_end) {
500856eb1   Rafal Jaworowski   API for external ...
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  		if (!memcmp(sp, API_SIG_MAGIC, API_SIG_MAGLEN)) {
  			*sig = (struct api_signature *)sp;
  			if (valid_sig(*sig))
  				return 1;
  		}
  		sp += API_SIG_MAGLEN;
  	}
  
  	*sig = NULL;
  	return 0;
  }
  
  /****************************************
   *
   * console
   *
   ****************************************/
  
  int ub_getc(void)
  {
  	int c;
78757d52c   Stanislav Galabov   Fix FreeBSD loade...
78
  	if (!syscall(API_GETC, NULL, &c))
500856eb1   Rafal Jaworowski   API for external ...
79
80
81
82
83
84
85
86
  		return -1;
  
  	return c;
  }
  
  int ub_tstc(void)
  {
  	int t;
78757d52c   Stanislav Galabov   Fix FreeBSD loade...
87
  	if (!syscall(API_TSTC, NULL, &t))
500856eb1   Rafal Jaworowski   API for external ...
88
89
90
91
92
93
94
  		return -1;
  
  	return t;
  }
  
  void ub_putc(char c)
  {
78757d52c   Stanislav Galabov   Fix FreeBSD loade...
95
  	syscall(API_PUTC, NULL, &c);
500856eb1   Rafal Jaworowski   API for external ...
96
97
98
99
  }
  
  void ub_puts(const char *s)
  {
78757d52c   Stanislav Galabov   Fix FreeBSD loade...
100
  	syscall(API_PUTS, NULL, s);
500856eb1   Rafal Jaworowski   API for external ...
101
102
103
104
105
106
107
108
109
110
111
112
  }
  
  /****************************************
   *
   * system
   *
   ****************************************/
  
  void ub_reset(void)
  {
  	syscall(API_RESET, NULL);
  }
923aa4812   Rafal Jaworowski   API: Improve glue...
113
  static struct mem_region mr[UB_MAX_MR];
500856eb1   Rafal Jaworowski   API for external ...
114
115
116
117
118
119
120
121
  static struct sys_info si;
  
  struct sys_info * ub_get_sys_info(void)
  {
  	int err = 0;
  
  	memset(&si, 0, sizeof(struct sys_info));
  	si.mr = mr;
923aa4812   Rafal Jaworowski   API: Improve glue...
122
  	si.mr_no = UB_MAX_MR;
500856eb1   Rafal Jaworowski   API for external ...
123
  	memset(&mr, 0, sizeof(mr));
78757d52c   Stanislav Galabov   Fix FreeBSD loade...
124
  	if (!syscall(API_GET_SYS_INFO, &err, &si))
500856eb1   Rafal Jaworowski   API for external ...
125
126
127
128
129
130
131
132
133
134
  		return NULL;
  
  	return ((err) ? NULL : &si);
  }
  
  /****************************************
   *
   * timing
   *
   ****************************************/
d3a6532cb   Wolfgang Denk   Coding Style clea...
135

500856eb1   Rafal Jaworowski   API for external ...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  void ub_udelay(unsigned long usec)
  {
  	syscall(API_UDELAY, NULL, &usec);
  }
  
  unsigned long ub_get_timer(unsigned long base)
  {
  	unsigned long cur;
  
  	if (!syscall(API_GET_TIMER, NULL, &cur, &base))
  		return 0;
  
  	return cur;
  }
  
  
  /****************************************************************************
   *
   * devices
   *
923aa4812   Rafal Jaworowski   API: Improve glue...
156
   * Devices are identified by handles: numbers 0, 1, 2, ..., UB_MAX_DEV-1
500856eb1   Rafal Jaworowski   API for external ...
157
158
   *
   ***************************************************************************/
923aa4812   Rafal Jaworowski   API: Improve glue...
159
  static struct device_info devices[UB_MAX_DEV];
500856eb1   Rafal Jaworowski   API for external ...
160
161
162
  
  struct device_info * ub_dev_get(int i)
  {
923aa4812   Rafal Jaworowski   API: Improve glue...
163
  	return ((i < 0 || i >= UB_MAX_DEV) ? NULL : &devices[i]);
500856eb1   Rafal Jaworowski   API for external ...
164
165
166
167
168
169
170
171
172
173
174
175
  }
  
  /*
   * Enumerates the devices: fills out device_info elements in the devices[]
   * array.
   *
   * returns:		number of devices found
   */
  int ub_dev_enum(void)
  {
  	struct device_info *di;
  	int n = 0;
923aa4812   Rafal Jaworowski   API: Improve glue...
176
  	memset(&devices, 0, sizeof(struct device_info) * UB_MAX_DEV);
500856eb1   Rafal Jaworowski   API for external ...
177
178
179
180
181
182
  	di = &devices[0];
  
  	if (!syscall(API_DEV_ENUM, NULL, di))
  		return 0;
  
  	while (di->cookie != NULL) {
923aa4812   Rafal Jaworowski   API: Improve glue...
183
  		if (++n >= UB_MAX_DEV)
500856eb1   Rafal Jaworowski   API for external ...
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
  			break;
  
  		/* take another device_info */
  		di++;
  
  		/* pass on the previous cookie */
  		di->cookie = devices[n - 1].cookie;
  
  		if (!syscall(API_DEV_ENUM, NULL, di))
  			return 0;
  	}
  
  	return n;
  }
  
  /*
   * handle:	0-based id of the device
   *
   * returns:	0 when OK, err otherwise
   */
  int ub_dev_open(int handle)
  {
  	struct device_info *di;
  	int err = 0;
923aa4812   Rafal Jaworowski   API: Improve glue...
208
  	if (handle < 0 || handle >= UB_MAX_DEV)
500856eb1   Rafal Jaworowski   API for external ...
209
210
211
212
213
214
215
216
217
218
219
220
221
  		return API_EINVAL;
  
  	di = &devices[handle];
  
  	if (!syscall(API_DEV_OPEN, &err, di))
  		return -1;
  
  	return err;
  }
  
  int ub_dev_close(int handle)
  {
  	struct device_info *di;
923aa4812   Rafal Jaworowski   API: Improve glue...
222
  	if (handle < 0 || handle >= UB_MAX_DEV)
500856eb1   Rafal Jaworowski   API for external ...
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
  		return API_EINVAL;
  
  	di = &devices[handle];
  	if (!syscall(API_DEV_CLOSE, NULL, di))
  		return -1;
  
  	return 0;
  }
  
  /*
   *
   * Validates device for read/write, it has to:
   *
   * - have sane handle
   * - be opened
   *
   * returns:	0/1 accordingly
   */
  static int dev_valid(int handle)
  {
923aa4812   Rafal Jaworowski   API: Improve glue...
243
  	if (handle < 0 || handle >= UB_MAX_DEV)
500856eb1   Rafal Jaworowski   API for external ...
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
  		return 0;
  
  	if (devices[handle].state != DEV_STA_OPEN)
  		return 0;
  
  	return 1;
  }
  
  static int dev_stor_valid(int handle)
  {
  	if (!dev_valid(handle))
  		return 0;
  
  	if (!(devices[handle].type & DEV_TYP_STOR))
  		return 0;
  
  	return 1;
  }
923aa4812   Rafal Jaworowski   API: Improve glue...
262
263
  int ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start,
  		lbasize_t *rlen)
500856eb1   Rafal Jaworowski   API for external ...
264
265
266
267
268
269
270
271
272
273
  {
  	struct device_info *di;
  	lbasize_t act_len;
  	int err = 0;
  
  	if (!dev_stor_valid(handle))
  		return API_ENODEV;
  
  	di = &devices[handle];
  	if (!syscall(API_DEV_READ, &err, di, buf, &len, &start, &act_len))
923aa4812   Rafal Jaworowski   API: Improve glue...
274
  		return API_ESYSC;
500856eb1   Rafal Jaworowski   API for external ...
275

923aa4812   Rafal Jaworowski   API: Improve glue...
276
277
  	if (!err && rlen)
  		*rlen = act_len;
500856eb1   Rafal Jaworowski   API for external ...
278

923aa4812   Rafal Jaworowski   API: Improve glue...
279
  	return err;
500856eb1   Rafal Jaworowski   API for external ...
280
281
282
283
284
285
286
287
288
289
290
291
  }
  
  static int dev_net_valid(int handle)
  {
  	if (!dev_valid(handle))
  		return 0;
  
  	if (devices[handle].type != DEV_TYP_NET)
  		return 0;
  
  	return 1;
  }
923aa4812   Rafal Jaworowski   API: Improve glue...
292
  int ub_dev_recv(int handle, void *buf, int len, int *rlen)
500856eb1   Rafal Jaworowski   API for external ...
293
294
295
296
297
298
299
300
301
  {
  	struct device_info *di;
  	int err = 0, act_len;
  
  	if (!dev_net_valid(handle))
  		return API_ENODEV;
  
  	di = &devices[handle];
  	if (!syscall(API_DEV_READ, &err, di, buf, &len, &act_len))
923aa4812   Rafal Jaworowski   API: Improve glue...
302
  		return API_ESYSC;
500856eb1   Rafal Jaworowski   API for external ...
303

923aa4812   Rafal Jaworowski   API: Improve glue...
304
305
  	if (!err && rlen)
  		*rlen = act_len;
500856eb1   Rafal Jaworowski   API for external ...
306

923aa4812   Rafal Jaworowski   API: Improve glue...
307
  	 return (err);
500856eb1   Rafal Jaworowski   API for external ...
308
309
310
311
312
313
314
315
316
317
318
319
  }
  
  int ub_dev_send(int handle, void *buf, int len)
  {
  	struct device_info *di;
  	int err = 0;
  
  	if (!dev_net_valid(handle))
  		return API_ENODEV;
  
  	di = &devices[handle];
  	if (!syscall(API_DEV_WRITE, &err, di, buf, &len))
923aa4812   Rafal Jaworowski   API: Improve glue...
320
  		return API_ESYSC;
500856eb1   Rafal Jaworowski   API for external ...
321
322
323
324
325
326
327
328
329
330
331
332
333
  
  	return err;
  }
  
  /****************************************
   *
   * env vars
   *
   ****************************************/
  
  char * ub_env_get(const char *name)
  {
  	char *value;
78757d52c   Stanislav Galabov   Fix FreeBSD loade...
334
  	if (!syscall(API_ENV_GET, NULL, name, &value))
500856eb1   Rafal Jaworowski   API for external ...
335
336
337
338
339
340
341
  		return NULL;
  
  	return value;
  }
  
  void ub_env_set(const char *name, char *value)
  {
78757d52c   Stanislav Galabov   Fix FreeBSD loade...
342
  	syscall(API_ENV_SET, NULL, name, value);
500856eb1   Rafal Jaworowski   API for external ...
343
  }
500856eb1   Rafal Jaworowski   API for external ...
344
345
346
347
348
349
350
351
352
353
354
355
356
357
  static char env_name[256];
  
  const char * ub_env_enum(const char *last)
  {
  	const char *env, *str;
  	int i;
  
  	env = NULL;
  
  	/*
  	 * It's OK to pass only the name piece as last (and not the whole
  	 * 'name=val' string), since the API_ENUM_ENV call uses envmatch()
  	 * internally, which handles such case
  	 */
78757d52c   Stanislav Galabov   Fix FreeBSD loade...
358
  	if (!syscall(API_ENV_ENUM, NULL, last, &env))
500856eb1   Rafal Jaworowski   API for external ...
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
  		return NULL;
  
  	if (!env)
  		/* no more env. variables to enumerate */
  		return NULL;
  
  	/* next enumerated env var */
  	memset(env_name, 0, 256);
  	for (i = 0, str = env; *str != '=' && *str != '\0';)
  		env_name[i++] = *str++;
  
  	env_name[i] = '\0';
  
  	return env_name;
  }
a2a5729fc   Che-Liang Chiou   api: export LCD d...
374
375
376
377
378
379
380
381
382
383
  
  /****************************************
   *
   * display
   *
   ****************************************/
  
  int ub_display_get_info(int type, struct display_info *di)
  {
  	int err = 0;
78757d52c   Stanislav Galabov   Fix FreeBSD loade...
384
  	if (!syscall(API_DISPLAY_GET_INFO, &err, type, di))
a2a5729fc   Che-Liang Chiou   api: export LCD d...
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
  		return API_ESYSC;
  
  	return err;
  }
  
  int ub_display_draw_bitmap(ulong bitmap, int x, int y)
  {
  	int err = 0;
  
  	if (!syscall(API_DISPLAY_DRAW_BITMAP, &err, bitmap, x, y))
  		return API_ESYSC;
  
  	return err;
  }
  
  void ub_display_clear(void)
  {
  	syscall(API_DISPLAY_CLEAR, NULL);
  }
7e3e20560   Rob Clark   examples: add fal...
404
405
406
407
408
409
410
411
412
413
414
415
  
  __weak void *memcpy(void *dest, const void *src, size_t size)
  {
  	unsigned char *dptr = dest;
  	const unsigned char *ptr = src;
  	const unsigned char *end = src + size;
  
  	while (ptr < end)
  		*dptr++ = *ptr++;
  
  	return dest;
  }