PageRenderTime 61ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/examples/api/glue.c

https://bitbucket.org/kasimling/u-boot
C | 435 lines | 242 code | 100 blank | 93 comment | 55 complexity | 18981ccab9443223f361d6a98d33fe54 MD5 | raw file
  1. /*
  2. * (C) Copyright 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
  3. *
  4. * See file CREDITS for list of people who contributed to this
  5. * project.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20. * MA 02111-1307 USA
  21. *
  22. */
  23. #include <common.h>
  24. #include <linux/types.h>
  25. #include <api_public.h>
  26. #include "glue.h"
  27. static int valid_sig(struct api_signature *sig)
  28. {
  29. uint32_t checksum;
  30. struct api_signature s;
  31. if (sig == NULL)
  32. return 0;
  33. /*
  34. * Clear the checksum field (in the local copy) so as to calculate the
  35. * CRC with the same initial contents as at the time when the sig was
  36. * produced
  37. */
  38. s = *sig;
  39. s.checksum = 0;
  40. checksum = crc32(0, (unsigned char *)&s, sizeof(struct api_signature));
  41. if (checksum != sig->checksum)
  42. return 0;
  43. return 1;
  44. }
  45. /*
  46. * Searches for the U-Boot API signature
  47. *
  48. * returns 1/0 depending on found/not found result
  49. */
  50. int api_search_sig(struct api_signature **sig)
  51. {
  52. unsigned char *sp;
  53. uint32_t search_start = 0;
  54. uint32_t search_end = 0;
  55. if (sig == NULL)
  56. return 0;
  57. if (search_hint == 0)
  58. search_hint = 255 * 1024 * 1024;
  59. search_start = search_hint & ~0x000fffff;
  60. search_end = search_start + API_SEARCH_LEN - API_SIG_MAGLEN;
  61. sp = (unsigned char *)search_start;
  62. while ((sp + API_SIG_MAGLEN) < (unsigned char *)search_end) {
  63. if (!memcmp(sp, API_SIG_MAGIC, API_SIG_MAGLEN)) {
  64. *sig = (struct api_signature *)sp;
  65. if (valid_sig(*sig))
  66. return 1;
  67. }
  68. sp += API_SIG_MAGLEN;
  69. }
  70. *sig = NULL;
  71. return 0;
  72. }
  73. /****************************************
  74. *
  75. * console
  76. *
  77. ****************************************/
  78. int ub_getc(void)
  79. {
  80. int c;
  81. if (!syscall(API_GETC, NULL, (uint32_t)&c))
  82. return -1;
  83. return c;
  84. }
  85. int ub_tstc(void)
  86. {
  87. int t;
  88. if (!syscall(API_TSTC, NULL, (uint32_t)&t))
  89. return -1;
  90. return t;
  91. }
  92. void ub_putc(char c)
  93. {
  94. syscall(API_PUTC, NULL, (uint32_t)&c);
  95. }
  96. void ub_puts(const char *s)
  97. {
  98. syscall(API_PUTS, NULL, (uint32_t)s);
  99. }
  100. /****************************************
  101. *
  102. * system
  103. *
  104. ****************************************/
  105. void ub_reset(void)
  106. {
  107. syscall(API_RESET, NULL);
  108. }
  109. static struct mem_region mr[UB_MAX_MR];
  110. static struct sys_info si;
  111. struct sys_info * ub_get_sys_info(void)
  112. {
  113. int err = 0;
  114. memset(&si, 0, sizeof(struct sys_info));
  115. si.mr = mr;
  116. si.mr_no = UB_MAX_MR;
  117. memset(&mr, 0, sizeof(mr));
  118. if (!syscall(API_GET_SYS_INFO, &err, (u_int32_t)&si))
  119. return NULL;
  120. return ((err) ? NULL : &si);
  121. }
  122. /****************************************
  123. *
  124. * timing
  125. *
  126. ****************************************/
  127. void ub_udelay(unsigned long usec)
  128. {
  129. syscall(API_UDELAY, NULL, &usec);
  130. }
  131. unsigned long ub_get_timer(unsigned long base)
  132. {
  133. unsigned long cur;
  134. if (!syscall(API_GET_TIMER, NULL, &cur, &base))
  135. return 0;
  136. return cur;
  137. }
  138. /****************************************************************************
  139. *
  140. * devices
  141. *
  142. * Devices are identified by handles: numbers 0, 1, 2, ..., UB_MAX_DEV-1
  143. *
  144. ***************************************************************************/
  145. static struct device_info devices[UB_MAX_DEV];
  146. struct device_info * ub_dev_get(int i)
  147. {
  148. return ((i < 0 || i >= UB_MAX_DEV) ? NULL : &devices[i]);
  149. }
  150. /*
  151. * Enumerates the devices: fills out device_info elements in the devices[]
  152. * array.
  153. *
  154. * returns: number of devices found
  155. */
  156. int ub_dev_enum(void)
  157. {
  158. struct device_info *di;
  159. int n = 0;
  160. memset(&devices, 0, sizeof(struct device_info) * UB_MAX_DEV);
  161. di = &devices[0];
  162. if (!syscall(API_DEV_ENUM, NULL, di))
  163. return 0;
  164. while (di->cookie != NULL) {
  165. if (++n >= UB_MAX_DEV)
  166. break;
  167. /* take another device_info */
  168. di++;
  169. /* pass on the previous cookie */
  170. di->cookie = devices[n - 1].cookie;
  171. if (!syscall(API_DEV_ENUM, NULL, di))
  172. return 0;
  173. }
  174. return n;
  175. }
  176. /*
  177. * handle: 0-based id of the device
  178. *
  179. * returns: 0 when OK, err otherwise
  180. */
  181. int ub_dev_open(int handle)
  182. {
  183. struct device_info *di;
  184. int err = 0;
  185. if (handle < 0 || handle >= UB_MAX_DEV)
  186. return API_EINVAL;
  187. di = &devices[handle];
  188. if (!syscall(API_DEV_OPEN, &err, di))
  189. return -1;
  190. return err;
  191. }
  192. int ub_dev_close(int handle)
  193. {
  194. struct device_info *di;
  195. if (handle < 0 || handle >= UB_MAX_DEV)
  196. return API_EINVAL;
  197. di = &devices[handle];
  198. if (!syscall(API_DEV_CLOSE, NULL, di))
  199. return -1;
  200. return 0;
  201. }
  202. /*
  203. *
  204. * Validates device for read/write, it has to:
  205. *
  206. * - have sane handle
  207. * - be opened
  208. *
  209. * returns: 0/1 accordingly
  210. */
  211. static int dev_valid(int handle)
  212. {
  213. if (handle < 0 || handle >= UB_MAX_DEV)
  214. return 0;
  215. if (devices[handle].state != DEV_STA_OPEN)
  216. return 0;
  217. return 1;
  218. }
  219. static int dev_stor_valid(int handle)
  220. {
  221. if (!dev_valid(handle))
  222. return 0;
  223. if (!(devices[handle].type & DEV_TYP_STOR))
  224. return 0;
  225. return 1;
  226. }
  227. int ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start,
  228. lbasize_t *rlen)
  229. {
  230. struct device_info *di;
  231. lbasize_t act_len;
  232. int err = 0;
  233. if (!dev_stor_valid(handle))
  234. return API_ENODEV;
  235. di = &devices[handle];
  236. if (!syscall(API_DEV_READ, &err, di, buf, &len, &start, &act_len))
  237. return API_ESYSC;
  238. if (!err && rlen)
  239. *rlen = act_len;
  240. return err;
  241. }
  242. static int dev_net_valid(int handle)
  243. {
  244. if (!dev_valid(handle))
  245. return 0;
  246. if (devices[handle].type != DEV_TYP_NET)
  247. return 0;
  248. return 1;
  249. }
  250. int ub_dev_recv(int handle, void *buf, int len, int *rlen)
  251. {
  252. struct device_info *di;
  253. int err = 0, act_len;
  254. if (!dev_net_valid(handle))
  255. return API_ENODEV;
  256. di = &devices[handle];
  257. if (!syscall(API_DEV_READ, &err, di, buf, &len, &act_len))
  258. return API_ESYSC;
  259. if (!err && rlen)
  260. *rlen = act_len;
  261. return (err);
  262. }
  263. int ub_dev_send(int handle, void *buf, int len)
  264. {
  265. struct device_info *di;
  266. int err = 0;
  267. if (!dev_net_valid(handle))
  268. return API_ENODEV;
  269. di = &devices[handle];
  270. if (!syscall(API_DEV_WRITE, &err, di, buf, &len))
  271. return API_ESYSC;
  272. return err;
  273. }
  274. /****************************************
  275. *
  276. * env vars
  277. *
  278. ****************************************/
  279. char * ub_env_get(const char *name)
  280. {
  281. char *value;
  282. if (!syscall(API_ENV_GET, NULL, (uint32_t)name, (uint32_t)&value))
  283. return NULL;
  284. return value;
  285. }
  286. void ub_env_set(const char *name, char *value)
  287. {
  288. syscall(API_ENV_SET, NULL, (uint32_t)name, (uint32_t)value);
  289. }
  290. static char env_name[256];
  291. const char * ub_env_enum(const char *last)
  292. {
  293. const char *env, *str;
  294. int i;
  295. env = NULL;
  296. /*
  297. * It's OK to pass only the name piece as last (and not the whole
  298. * 'name=val' string), since the API_ENUM_ENV call uses envmatch()
  299. * internally, which handles such case
  300. */
  301. if (!syscall(API_ENV_ENUM, NULL, (uint32_t)last, (uint32_t)&env))
  302. return NULL;
  303. if (!env)
  304. /* no more env. variables to enumerate */
  305. return NULL;
  306. /* next enumerated env var */
  307. memset(env_name, 0, 256);
  308. for (i = 0, str = env; *str != '=' && *str != '\0';)
  309. env_name[i++] = *str++;
  310. env_name[i] = '\0';
  311. return env_name;
  312. }
  313. /****************************************
  314. *
  315. * display
  316. *
  317. ****************************************/
  318. int ub_display_get_info(int type, struct display_info *di)
  319. {
  320. int err = 0;
  321. if (!syscall(API_DISPLAY_GET_INFO, &err, (uint32_t)type, (uint32_t)di))
  322. return API_ESYSC;
  323. return err;
  324. }
  325. int ub_display_draw_bitmap(ulong bitmap, int x, int y)
  326. {
  327. int err = 0;
  328. if (!syscall(API_DISPLAY_DRAW_BITMAP, &err, bitmap, x, y))
  329. return API_ESYSC;
  330. return err;
  331. }
  332. void ub_display_clear(void)
  333. {
  334. syscall(API_DISPLAY_CLEAR, NULL);
  335. }