glue.c 7.1 KB

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