cfe_api.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. /*
  2. * Copyright (C) 2000, 2001, 2002 Broadcom Corporation
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. /*
  19. *
  20. * Broadcom Common Firmware Environment (CFE)
  21. *
  22. * This module contains device function stubs (small routines to
  23. * call the standard "iocb" interface entry point to CFE).
  24. * There should be one routine here per iocb function call.
  25. *
  26. * Authors: Mitch Lichtenberg, Chris Demetriou
  27. */
  28. #include <asm/fw/cfe/cfe_api.h>
  29. #include "cfe_api_int.h"
  30. /* Cast from a native pointer to a cfe_xptr_t and back. */
  31. #define XPTR_FROM_NATIVE(n) ((cfe_xptr_t) (intptr_t) (n))
  32. #define NATIVE_FROM_XPTR(x) ((void *) (intptr_t) (x))
  33. int cfe_iocb_dispatch(struct cfe_xiocb *xiocb);
  34. /*
  35. * Declare the dispatch function with args of "intptr_t".
  36. * This makes sure whatever model we're compiling in
  37. * puts the pointers in a single register. For example,
  38. * combining -mlong64 and -mips1 or -mips2 would lead to
  39. * trouble, since the handle and IOCB pointer will be
  40. * passed in two registers each, and CFE expects one.
  41. */
  42. static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb);
  43. static u64 cfe_handle;
  44. int cfe_init(u64 handle, u64 ept)
  45. {
  46. cfe_dispfunc = NATIVE_FROM_XPTR(ept);
  47. cfe_handle = handle;
  48. return 0;
  49. }
  50. int cfe_iocb_dispatch(struct cfe_xiocb * xiocb)
  51. {
  52. if (!cfe_dispfunc)
  53. return -1;
  54. return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb);
  55. }
  56. int cfe_close(int handle)
  57. {
  58. struct cfe_xiocb xiocb;
  59. xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE;
  60. xiocb.xiocb_status = 0;
  61. xiocb.xiocb_handle = handle;
  62. xiocb.xiocb_flags = 0;
  63. xiocb.xiocb_psize = 0;
  64. cfe_iocb_dispatch(&xiocb);
  65. return xiocb.xiocb_status;
  66. }
  67. int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1)
  68. {
  69. struct cfe_xiocb xiocb;
  70. xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
  71. xiocb.xiocb_status = 0;
  72. xiocb.xiocb_handle = 0;
  73. xiocb.xiocb_flags = 0;
  74. xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl);
  75. xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
  76. xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START;
  77. xiocb.plist.xiocb_cpuctl.gp_val = gp;
  78. xiocb.plist.xiocb_cpuctl.sp_val = sp;
  79. xiocb.plist.xiocb_cpuctl.a1_val = a1;
  80. xiocb.plist.xiocb_cpuctl.start_addr = (long) fn;
  81. cfe_iocb_dispatch(&xiocb);
  82. return xiocb.xiocb_status;
  83. }
  84. int cfe_cpu_stop(int cpu)
  85. {
  86. struct cfe_xiocb xiocb;
  87. xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
  88. xiocb.xiocb_status = 0;
  89. xiocb.xiocb_handle = 0;
  90. xiocb.xiocb_flags = 0;
  91. xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl);
  92. xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
  93. xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP;
  94. cfe_iocb_dispatch(&xiocb);
  95. return xiocb.xiocb_status;
  96. }
  97. int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen)
  98. {
  99. struct cfe_xiocb xiocb;
  100. xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
  101. xiocb.xiocb_status = 0;
  102. xiocb.xiocb_handle = 0;
  103. xiocb.xiocb_flags = 0;
  104. xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
  105. xiocb.plist.xiocb_envbuf.enum_idx = idx;
  106. xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
  107. xiocb.plist.xiocb_envbuf.name_length = namelen;
  108. xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val);
  109. xiocb.plist.xiocb_envbuf.val_length = vallen;
  110. cfe_iocb_dispatch(&xiocb);
  111. return xiocb.xiocb_status;
  112. }
  113. int
  114. cfe_enummem(int idx, int flags, u64 *start, u64 *length, u64 *type)
  115. {
  116. struct cfe_xiocb xiocb;
  117. xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM;
  118. xiocb.xiocb_status = 0;
  119. xiocb.xiocb_handle = 0;
  120. xiocb.xiocb_flags = flags;
  121. xiocb.xiocb_psize = sizeof(struct xiocb_meminfo);
  122. xiocb.plist.xiocb_meminfo.mi_idx = idx;
  123. cfe_iocb_dispatch(&xiocb);
  124. if (xiocb.xiocb_status < 0)
  125. return xiocb.xiocb_status;
  126. *start = xiocb.plist.xiocb_meminfo.mi_addr;
  127. *length = xiocb.plist.xiocb_meminfo.mi_size;
  128. *type = xiocb.plist.xiocb_meminfo.mi_type;
  129. return 0;
  130. }
  131. int cfe_exit(int warm, int status)
  132. {
  133. struct cfe_xiocb xiocb;
  134. xiocb.xiocb_fcode = CFE_CMD_FW_RESTART;
  135. xiocb.xiocb_status = 0;
  136. xiocb.xiocb_handle = 0;
  137. xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0;
  138. xiocb.xiocb_psize = sizeof(struct xiocb_exitstat);
  139. xiocb.plist.xiocb_exitstat.status = status;
  140. cfe_iocb_dispatch(&xiocb);
  141. return xiocb.xiocb_status;
  142. }
  143. int cfe_flushcache(int flg)
  144. {
  145. struct cfe_xiocb xiocb;
  146. xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE;
  147. xiocb.xiocb_status = 0;
  148. xiocb.xiocb_handle = 0;
  149. xiocb.xiocb_flags = flg;
  150. xiocb.xiocb_psize = 0;
  151. cfe_iocb_dispatch(&xiocb);
  152. return xiocb.xiocb_status;
  153. }
  154. int cfe_getdevinfo(char *name)
  155. {
  156. struct cfe_xiocb xiocb;
  157. xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO;
  158. xiocb.xiocb_status = 0;
  159. xiocb.xiocb_handle = 0;
  160. xiocb.xiocb_flags = 0;
  161. xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
  162. xiocb.plist.xiocb_buffer.buf_offset = 0;
  163. xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
  164. xiocb.plist.xiocb_buffer.buf_length = strlen(name);
  165. cfe_iocb_dispatch(&xiocb);
  166. if (xiocb.xiocb_status < 0)
  167. return xiocb.xiocb_status;
  168. return xiocb.plist.xiocb_buffer.buf_ioctlcmd;
  169. }
  170. int cfe_getenv(char *name, char *dest, int destlen)
  171. {
  172. struct cfe_xiocb xiocb;
  173. *dest = 0;
  174. xiocb.xiocb_fcode = CFE_CMD_ENV_GET;
  175. xiocb.xiocb_status = 0;
  176. xiocb.xiocb_handle = 0;
  177. xiocb.xiocb_flags = 0;
  178. xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
  179. xiocb.plist.xiocb_envbuf.enum_idx = 0;
  180. xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
  181. xiocb.plist.xiocb_envbuf.name_length = strlen(name);
  182. xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest);
  183. xiocb.plist.xiocb_envbuf.val_length = destlen;
  184. cfe_iocb_dispatch(&xiocb);
  185. return xiocb.xiocb_status;
  186. }
  187. int cfe_getfwinfo(cfe_fwinfo_t * info)
  188. {
  189. struct cfe_xiocb xiocb;
  190. xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO;
  191. xiocb.xiocb_status = 0;
  192. xiocb.xiocb_handle = 0;
  193. xiocb.xiocb_flags = 0;
  194. xiocb.xiocb_psize = sizeof(struct xiocb_fwinfo);
  195. cfe_iocb_dispatch(&xiocb);
  196. if (xiocb.xiocb_status < 0)
  197. return xiocb.xiocb_status;
  198. info->fwi_version = xiocb.plist.xiocb_fwinfo.fwi_version;
  199. info->fwi_totalmem = xiocb.plist.xiocb_fwinfo.fwi_totalmem;
  200. info->fwi_flags = xiocb.plist.xiocb_fwinfo.fwi_flags;
  201. info->fwi_boardid = xiocb.plist.xiocb_fwinfo.fwi_boardid;
  202. info->fwi_bootarea_va = xiocb.plist.xiocb_fwinfo.fwi_bootarea_va;
  203. info->fwi_bootarea_pa = xiocb.plist.xiocb_fwinfo.fwi_bootarea_pa;
  204. info->fwi_bootarea_size =
  205. xiocb.plist.xiocb_fwinfo.fwi_bootarea_size;
  206. #if 0
  207. info->fwi_reserved1 = xiocb.plist.xiocb_fwinfo.fwi_reserved1;
  208. info->fwi_reserved2 = xiocb.plist.xiocb_fwinfo.fwi_reserved2;
  209. info->fwi_reserved3 = xiocb.plist.xiocb_fwinfo.fwi_reserved3;
  210. #endif
  211. return 0;
  212. }
  213. int cfe_getstdhandle(int flg)
  214. {
  215. struct cfe_xiocb xiocb;
  216. xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE;
  217. xiocb.xiocb_status = 0;
  218. xiocb.xiocb_handle = 0;
  219. xiocb.xiocb_flags = flg;
  220. xiocb.xiocb_psize = 0;
  221. cfe_iocb_dispatch(&xiocb);
  222. if (xiocb.xiocb_status < 0)
  223. return xiocb.xiocb_status;
  224. return xiocb.xiocb_handle;
  225. }
  226. int64_t
  227. cfe_getticks(void)
  228. {
  229. struct cfe_xiocb xiocb;
  230. xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME;
  231. xiocb.xiocb_status = 0;
  232. xiocb.xiocb_handle = 0;
  233. xiocb.xiocb_flags = 0;
  234. xiocb.xiocb_psize = sizeof(struct xiocb_time);
  235. xiocb.plist.xiocb_time.ticks = 0;
  236. cfe_iocb_dispatch(&xiocb);
  237. return xiocb.plist.xiocb_time.ticks;
  238. }
  239. int cfe_inpstat(int handle)
  240. {
  241. struct cfe_xiocb xiocb;
  242. xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT;
  243. xiocb.xiocb_status = 0;
  244. xiocb.xiocb_handle = handle;
  245. xiocb.xiocb_flags = 0;
  246. xiocb.xiocb_psize = sizeof(struct xiocb_inpstat);
  247. xiocb.plist.xiocb_inpstat.inp_status = 0;
  248. cfe_iocb_dispatch(&xiocb);
  249. if (xiocb.xiocb_status < 0)
  250. return xiocb.xiocb_status;
  251. return xiocb.plist.xiocb_inpstat.inp_status;
  252. }
  253. int
  254. cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
  255. int length, int *retlen, u64 offset)
  256. {
  257. struct cfe_xiocb xiocb;
  258. xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL;
  259. xiocb.xiocb_status = 0;
  260. xiocb.xiocb_handle = handle;
  261. xiocb.xiocb_flags = 0;
  262. xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
  263. xiocb.plist.xiocb_buffer.buf_offset = offset;
  264. xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum;
  265. xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
  266. xiocb.plist.xiocb_buffer.buf_length = length;
  267. cfe_iocb_dispatch(&xiocb);
  268. if (retlen)
  269. *retlen = xiocb.plist.xiocb_buffer.buf_retlen;
  270. return xiocb.xiocb_status;
  271. }
  272. int cfe_open(char *name)
  273. {
  274. struct cfe_xiocb xiocb;
  275. xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN;
  276. xiocb.xiocb_status = 0;
  277. xiocb.xiocb_handle = 0;
  278. xiocb.xiocb_flags = 0;
  279. xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
  280. xiocb.plist.xiocb_buffer.buf_offset = 0;
  281. xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
  282. xiocb.plist.xiocb_buffer.buf_length = strlen(name);
  283. cfe_iocb_dispatch(&xiocb);
  284. if (xiocb.xiocb_status < 0)
  285. return xiocb.xiocb_status;
  286. return xiocb.xiocb_handle;
  287. }
  288. int cfe_read(int handle, unsigned char *buffer, int length)
  289. {
  290. return cfe_readblk(handle, 0, buffer, length);
  291. }
  292. int cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length)
  293. {
  294. struct cfe_xiocb xiocb;
  295. xiocb.xiocb_fcode = CFE_CMD_DEV_READ;
  296. xiocb.xiocb_status = 0;
  297. xiocb.xiocb_handle = handle;
  298. xiocb.xiocb_flags = 0;
  299. xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
  300. xiocb.plist.xiocb_buffer.buf_offset = offset;
  301. xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
  302. xiocb.plist.xiocb_buffer.buf_length = length;
  303. cfe_iocb_dispatch(&xiocb);
  304. if (xiocb.xiocb_status < 0)
  305. return xiocb.xiocb_status;
  306. return xiocb.plist.xiocb_buffer.buf_retlen;
  307. }
  308. int cfe_setenv(char *name, char *val)
  309. {
  310. struct cfe_xiocb xiocb;
  311. xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
  312. xiocb.xiocb_status = 0;
  313. xiocb.xiocb_handle = 0;
  314. xiocb.xiocb_flags = 0;
  315. xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
  316. xiocb.plist.xiocb_envbuf.enum_idx = 0;
  317. xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
  318. xiocb.plist.xiocb_envbuf.name_length = strlen(name);
  319. xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val);
  320. xiocb.plist.xiocb_envbuf.val_length = strlen(val);
  321. cfe_iocb_dispatch(&xiocb);
  322. return xiocb.xiocb_status;
  323. }
  324. int cfe_write(int handle, const char *buffer, int length)
  325. {
  326. return cfe_writeblk(handle, 0, buffer, length);
  327. }
  328. int cfe_writeblk(int handle, s64 offset, const char *buffer, int length)
  329. {
  330. struct cfe_xiocb xiocb;
  331. xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE;
  332. xiocb.xiocb_status = 0;
  333. xiocb.xiocb_handle = handle;
  334. xiocb.xiocb_flags = 0;
  335. xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
  336. xiocb.plist.xiocb_buffer.buf_offset = offset;
  337. xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
  338. xiocb.plist.xiocb_buffer.buf_length = length;
  339. cfe_iocb_dispatch(&xiocb);
  340. if (xiocb.xiocb_status < 0)
  341. return xiocb.xiocb_status;
  342. return xiocb.plist.xiocb_buffer.buf_retlen;
  343. }