Blame view

examples/api/glue.c 7.04 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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
  		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;
  
  	if (!syscall(API_GETC, NULL, (uint32_t)&c))
  		return -1;
  
  	return c;
  }
  
  int ub_tstc(void)
  {
  	int t;
  
  	if (!syscall(API_TSTC, NULL, (uint32_t)&t))
  		return -1;
  
  	return t;
  }
  
  void ub_putc(char c)
  {
  	syscall(API_PUTC, NULL, (uint32_t)&c);
  }
  
  void ub_puts(const char *s)
  {
  	syscall(API_PUTS, NULL, (uint32_t)s);
  }
  
  /****************************************
   *
   * system
   *
   ****************************************/
  
  void ub_reset(void)
  {
  	syscall(API_RESET, NULL);
  }
923aa4812   Rafal Jaworowski   API: Improve glue...
115
  static struct mem_region mr[UB_MAX_MR];
500856eb1   Rafal Jaworowski   API for external ...
116
117
118
119
120
121
122
123
  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...
124
  	si.mr_no = UB_MAX_MR;
500856eb1   Rafal Jaworowski   API for external ...
125
126
127
128
129
130
131
132
133
134
135
136
137
  	memset(&mr, 0, sizeof(mr));
  
  	if (!syscall(API_GET_SYS_INFO, &err, (u_int32_t)&si))
  		return NULL;
  
  	return ((err) ? NULL : &si);
  }
  
  /****************************************
   *
   * timing
   *
   ****************************************/
d3a6532cb   Wolfgang Denk   Coding Style clea...
138

500856eb1   Rafal Jaworowski   API for external ...
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  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...
159
   * Devices are identified by handles: numbers 0, 1, 2, ..., UB_MAX_DEV-1
500856eb1   Rafal Jaworowski   API for external ...
160
161
   *
   ***************************************************************************/
923aa4812   Rafal Jaworowski   API: Improve glue...
162
  static struct device_info devices[UB_MAX_DEV];
500856eb1   Rafal Jaworowski   API for external ...
163
164
165
  
  struct device_info * ub_dev_get(int i)
  {
923aa4812   Rafal Jaworowski   API: Improve glue...
166
  	return ((i < 0 || i >= UB_MAX_DEV) ? NULL : &devices[i]);
500856eb1   Rafal Jaworowski   API for external ...
167
168
169
170
171
172
173
174
175
176
177
178
  }
  
  /*
   * 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...
179
  	memset(&devices, 0, sizeof(struct device_info) * UB_MAX_DEV);
500856eb1   Rafal Jaworowski   API for external ...
180
181
182
183
184
185
  	di = &devices[0];
  
  	if (!syscall(API_DEV_ENUM, NULL, di))
  		return 0;
  
  	while (di->cookie != NULL) {
923aa4812   Rafal Jaworowski   API: Improve glue...
186
  		if (++n >= UB_MAX_DEV)
500856eb1   Rafal Jaworowski   API for external ...
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
  			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...
211
  	if (handle < 0 || handle >= UB_MAX_DEV)
500856eb1   Rafal Jaworowski   API for external ...
212
213
214
215
216
217
218
219
220
221
222
223
224
  		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...
225
  	if (handle < 0 || handle >= UB_MAX_DEV)
500856eb1   Rafal Jaworowski   API for external ...
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
  		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...
246
  	if (handle < 0 || handle >= UB_MAX_DEV)
500856eb1   Rafal Jaworowski   API for external ...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
  		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...
265
266
  int ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start,
  		lbasize_t *rlen)
500856eb1   Rafal Jaworowski   API for external ...
267
268
269
270
271
272
273
274
275
276
  {
  	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...
277
  		return API_ESYSC;
500856eb1   Rafal Jaworowski   API for external ...
278

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

923aa4812   Rafal Jaworowski   API: Improve glue...
282
  	return err;
500856eb1   Rafal Jaworowski   API for external ...
283
284
285
286
287
288
289
290
291
292
293
294
  }
  
  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...
295
  int ub_dev_recv(int handle, void *buf, int len, int *rlen)
500856eb1   Rafal Jaworowski   API for external ...
296
297
298
299
300
301
302
303
304
  {
  	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...
305
  		return API_ESYSC;
500856eb1   Rafal Jaworowski   API for external ...
306

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

923aa4812   Rafal Jaworowski   API: Improve glue...
310
  	 return (err);
500856eb1   Rafal Jaworowski   API for external ...
311
312
313
314
315
316
317
318
319
320
321
322
  }
  
  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...
323
  		return API_ESYSC;
500856eb1   Rafal Jaworowski   API for external ...
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
  
  	return err;
  }
  
  /****************************************
   *
   * env vars
   *
   ****************************************/
  
  char * ub_env_get(const char *name)
  {
  	char *value;
  
  	if (!syscall(API_ENV_GET, NULL, (uint32_t)name, (uint32_t)&value))
  		return NULL;
  
  	return value;
  }
  
  void ub_env_set(const char *name, char *value)
  {
  	syscall(API_ENV_SET, NULL, (uint32_t)name, (uint32_t)value);
  }
500856eb1   Rafal Jaworowski   API for external ...
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
  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
  	 */
  	if (!syscall(API_ENV_ENUM, NULL, (uint32_t)last, (uint32_t)&env))
  		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...
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
  
  /****************************************
   *
   * display
   *
   ****************************************/
  
  int ub_display_get_info(int type, struct display_info *di)
  {
  	int err = 0;
  
  	if (!syscall(API_DISPLAY_GET_INFO, &err, (uint32_t)type, (uint32_t)di))
  		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);
  }