ieee1275.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. /* of.c - Access the Open Firmware client interface. */
  2. /*
  3. * GRUB -- GRand Unified Bootloader
  4. * Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
  5. *
  6. * GRUB is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * GRUB is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <grub/ieee1275/ieee1275.h>
  20. #include <grub/types.h>
  21. #include <grub/misc.h>
  22. #define IEEE1275_PHANDLE_INVALID ((grub_ieee1275_cell_t) -1)
  23. #define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_cell_t) 0)
  24. #define IEEE1275_CELL_INVALID ((grub_ieee1275_cell_t) -1)
  25. int
  26. grub_ieee1275_finddevice (const char *name, grub_ieee1275_phandle_t *phandlep)
  27. {
  28. struct find_device_args
  29. {
  30. struct grub_ieee1275_common_hdr common;
  31. grub_ieee1275_cell_t device;
  32. grub_ieee1275_cell_t phandle;
  33. }
  34. args;
  35. INIT_IEEE1275_COMMON (&args.common, "finddevice", 1, 1);
  36. args.device = (grub_ieee1275_cell_t) name;
  37. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  38. return -1;
  39. *phandlep = args.phandle;
  40. if (args.phandle == IEEE1275_PHANDLE_INVALID)
  41. return -1;
  42. return 0;
  43. }
  44. int
  45. grub_ieee1275_get_property (grub_ieee1275_phandle_t phandle,
  46. const char *property, void *buf,
  47. grub_size_t size, grub_ssize_t *actual)
  48. {
  49. struct get_property_args
  50. {
  51. struct grub_ieee1275_common_hdr common;
  52. grub_ieee1275_cell_t phandle;
  53. grub_ieee1275_cell_t prop;
  54. grub_ieee1275_cell_t buf;
  55. grub_ieee1275_cell_t buflen;
  56. grub_ieee1275_cell_t size;
  57. }
  58. args;
  59. INIT_IEEE1275_COMMON (&args.common, "getprop", 4, 1);
  60. args.phandle = phandle;
  61. args.prop = (grub_ieee1275_cell_t) property;
  62. args.buf = (grub_ieee1275_cell_t) buf;
  63. args.buflen = (grub_ieee1275_cell_t) size;
  64. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  65. return -1;
  66. if (actual)
  67. *actual = (grub_ssize_t) args.size;
  68. if (args.size == IEEE1275_CELL_INVALID)
  69. return -1;
  70. return 0;
  71. }
  72. int
  73. grub_ieee1275_get_integer_property (grub_ieee1275_phandle_t phandle,
  74. const char *property, grub_uint32_t *buf,
  75. grub_size_t size, grub_ssize_t *actual)
  76. {
  77. int ret;
  78. ret = grub_ieee1275_get_property (phandle, property, (void *) buf, size, actual);
  79. #ifndef GRUB_CPU_WORDS_BIGENDIAN
  80. /* Integer properties are always in big endian. */
  81. if (ret == 0)
  82. {
  83. unsigned int i;
  84. size /= sizeof (grub_uint32_t);
  85. for (i = 0; i < size; i++)
  86. buf[i] = grub_be_to_cpu32 (buf[i]);
  87. }
  88. #endif
  89. return ret;
  90. }
  91. int
  92. grub_ieee1275_next_property (grub_ieee1275_phandle_t phandle, char *prev_prop,
  93. char *prop)
  94. {
  95. struct get_property_args
  96. {
  97. struct grub_ieee1275_common_hdr common;
  98. grub_ieee1275_cell_t phandle;
  99. grub_ieee1275_cell_t prev_prop;
  100. grub_ieee1275_cell_t next_prop;
  101. grub_ieee1275_cell_t flags;
  102. }
  103. args;
  104. INIT_IEEE1275_COMMON (&args.common, "nextprop", 3, 1);
  105. args.phandle = phandle;
  106. args.prev_prop = (grub_ieee1275_cell_t) prev_prop;
  107. args.next_prop = (grub_ieee1275_cell_t) prop;
  108. args.flags = (grub_ieee1275_cell_t) -1;
  109. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  110. return -1;
  111. return (int) args.flags;
  112. }
  113. int
  114. grub_ieee1275_get_property_length (grub_ieee1275_phandle_t phandle,
  115. const char *prop, grub_ssize_t *length)
  116. {
  117. struct get_property_args
  118. {
  119. struct grub_ieee1275_common_hdr common;
  120. grub_ieee1275_cell_t phandle;
  121. grub_ieee1275_cell_t prop;
  122. grub_ieee1275_cell_t length;
  123. }
  124. args;
  125. INIT_IEEE1275_COMMON (&args.common, "getproplen", 2, 1);
  126. args.phandle = phandle;
  127. args.prop = (grub_ieee1275_cell_t) prop;
  128. args.length = (grub_ieee1275_cell_t) -1;
  129. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  130. return -1;
  131. *length = args.length;
  132. if (args.length == IEEE1275_CELL_INVALID)
  133. return -1;
  134. return 0;
  135. }
  136. int
  137. grub_ieee1275_instance_to_package (grub_ieee1275_ihandle_t ihandle,
  138. grub_ieee1275_phandle_t *phandlep)
  139. {
  140. struct instance_to_package_args
  141. {
  142. struct grub_ieee1275_common_hdr common;
  143. grub_ieee1275_cell_t ihandle;
  144. grub_ieee1275_cell_t phandle;
  145. }
  146. args;
  147. INIT_IEEE1275_COMMON (&args.common, "instance-to-package", 1, 1);
  148. args.ihandle = ihandle;
  149. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  150. return -1;
  151. *phandlep = args.phandle;
  152. if (args.phandle == IEEE1275_PHANDLE_INVALID)
  153. return -1;
  154. return 0;
  155. }
  156. int
  157. grub_ieee1275_package_to_path (grub_ieee1275_phandle_t phandle,
  158. char *path, grub_size_t len,
  159. grub_ssize_t *actual)
  160. {
  161. struct instance_to_package_args
  162. {
  163. struct grub_ieee1275_common_hdr common;
  164. grub_ieee1275_cell_t phandle;
  165. grub_ieee1275_cell_t buf;
  166. grub_ieee1275_cell_t buflen;
  167. grub_ieee1275_cell_t actual;
  168. }
  169. args;
  170. INIT_IEEE1275_COMMON (&args.common, "package-to-path", 3, 1);
  171. args.phandle = phandle;
  172. args.buf = (grub_ieee1275_cell_t) path;
  173. args.buflen = (grub_ieee1275_cell_t) len;
  174. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  175. return -1;
  176. if (actual)
  177. *actual = args.actual;
  178. if (args.actual == IEEE1275_CELL_INVALID)
  179. return -1;
  180. return 0;
  181. }
  182. int
  183. grub_ieee1275_instance_to_path (grub_ieee1275_ihandle_t ihandle,
  184. char *path, grub_size_t len,
  185. grub_ssize_t *actual)
  186. {
  187. struct instance_to_path_args
  188. {
  189. struct grub_ieee1275_common_hdr common;
  190. grub_ieee1275_cell_t ihandle;
  191. grub_ieee1275_cell_t buf;
  192. grub_ieee1275_cell_t buflen;
  193. grub_ieee1275_cell_t actual;
  194. }
  195. args;
  196. INIT_IEEE1275_COMMON (&args.common, "instance-to-path", 3, 1);
  197. args.ihandle = ihandle;
  198. args.buf = (grub_ieee1275_cell_t) path;
  199. args.buflen = (grub_ieee1275_cell_t) len;
  200. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  201. return -1;
  202. if (actual)
  203. *actual = args.actual;
  204. if (args.actual == IEEE1275_CELL_INVALID)
  205. return -1;
  206. return 0;
  207. }
  208. int
  209. grub_ieee1275_write (grub_ieee1275_ihandle_t ihandle, const void *buffer,
  210. grub_size_t len, grub_ssize_t *actualp)
  211. {
  212. struct write_args
  213. {
  214. struct grub_ieee1275_common_hdr common;
  215. grub_ieee1275_cell_t ihandle;
  216. grub_ieee1275_cell_t buf;
  217. grub_ieee1275_cell_t len;
  218. grub_ieee1275_cell_t actual;
  219. }
  220. args;
  221. INIT_IEEE1275_COMMON (&args.common, "write", 3, 1);
  222. args.ihandle = ihandle;
  223. args.buf = (grub_ieee1275_cell_t) buffer;
  224. args.len = (grub_ieee1275_cell_t) len;
  225. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  226. return -1;
  227. if (actualp)
  228. *actualp = args.actual;
  229. return 0;
  230. }
  231. int
  232. grub_ieee1275_read (grub_ieee1275_ihandle_t ihandle, void *buffer,
  233. grub_size_t len, grub_ssize_t *actualp)
  234. {
  235. struct write_args
  236. {
  237. struct grub_ieee1275_common_hdr common;
  238. grub_ieee1275_cell_t ihandle;
  239. grub_ieee1275_cell_t buf;
  240. grub_ieee1275_cell_t len;
  241. grub_ieee1275_cell_t actual;
  242. }
  243. args;
  244. INIT_IEEE1275_COMMON (&args.common, "read", 3, 1);
  245. args.ihandle = ihandle;
  246. args.buf = (grub_ieee1275_cell_t) buffer;
  247. args.len = (grub_ieee1275_cell_t) len;
  248. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  249. return -1;
  250. if (actualp)
  251. *actualp = args.actual;
  252. return 0;
  253. }
  254. int
  255. grub_ieee1275_seek (grub_ieee1275_ihandle_t ihandle, grub_disk_addr_t pos,
  256. grub_ssize_t *result)
  257. {
  258. struct write_args
  259. {
  260. struct grub_ieee1275_common_hdr common;
  261. grub_ieee1275_cell_t ihandle;
  262. grub_ieee1275_cell_t pos_hi;
  263. grub_ieee1275_cell_t pos_lo;
  264. grub_ieee1275_cell_t result;
  265. }
  266. args;
  267. INIT_IEEE1275_COMMON (&args.common, "seek", 3, 1);
  268. args.ihandle = ihandle;
  269. /* To prevent stupid gcc warning. */
  270. #if GRUB_IEEE1275_CELL_SIZEOF >= 8
  271. args.pos_hi = 0;
  272. args.pos_lo = pos;
  273. #else
  274. args.pos_hi = (grub_ieee1275_cell_t) (pos >> (8 * GRUB_IEEE1275_CELL_SIZEOF));
  275. args.pos_lo = (grub_ieee1275_cell_t)
  276. (pos & ((1ULL << (8 * GRUB_IEEE1275_CELL_SIZEOF)) - 1));
  277. #endif
  278. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  279. return -1;
  280. if (result)
  281. *result = args.result;
  282. return 0;
  283. }
  284. int
  285. grub_ieee1275_peer (grub_ieee1275_phandle_t node,
  286. grub_ieee1275_phandle_t *result)
  287. {
  288. struct peer_args
  289. {
  290. struct grub_ieee1275_common_hdr common;
  291. grub_ieee1275_cell_t node;
  292. grub_ieee1275_cell_t result;
  293. }
  294. args;
  295. INIT_IEEE1275_COMMON (&args.common, "peer", 1, 1);
  296. args.node = node;
  297. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  298. return -1;
  299. *result = args.result;
  300. if (args.result == 0)
  301. return -1;
  302. return 0;
  303. }
  304. int
  305. grub_ieee1275_child (grub_ieee1275_phandle_t node,
  306. grub_ieee1275_phandle_t *result)
  307. {
  308. struct child_args
  309. {
  310. struct grub_ieee1275_common_hdr common;
  311. grub_ieee1275_cell_t node;
  312. grub_ieee1275_cell_t result;
  313. }
  314. args;
  315. INIT_IEEE1275_COMMON (&args.common, "child", 1, 1);
  316. args.node = node;
  317. args.result = IEEE1275_PHANDLE_INVALID;
  318. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  319. return -1;
  320. *result = args.result;
  321. if (args.result == 0)
  322. return -1;
  323. return 0;
  324. }
  325. int
  326. grub_ieee1275_parent (grub_ieee1275_phandle_t node,
  327. grub_ieee1275_phandle_t *result)
  328. {
  329. struct parent_args
  330. {
  331. struct grub_ieee1275_common_hdr common;
  332. grub_ieee1275_cell_t node;
  333. grub_ieee1275_cell_t result;
  334. }
  335. args;
  336. INIT_IEEE1275_COMMON (&args.common, "parent", 1, 1);
  337. args.node = node;
  338. args.result = IEEE1275_PHANDLE_INVALID;
  339. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  340. return -1;
  341. *result = args.result;
  342. return 0;
  343. }
  344. int
  345. grub_ieee1275_interpret (const char *command, grub_ieee1275_cell_t *catch)
  346. {
  347. struct enter_args
  348. {
  349. struct grub_ieee1275_common_hdr common;
  350. grub_ieee1275_cell_t command;
  351. grub_ieee1275_cell_t catch;
  352. }
  353. args;
  354. INIT_IEEE1275_COMMON (&args.common, "interpret", 1, 1);
  355. args.command = (grub_ieee1275_cell_t) command;
  356. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  357. return -1;
  358. if (catch)
  359. *catch = args.catch;
  360. return 0;
  361. }
  362. int
  363. grub_ieee1275_enter (void)
  364. {
  365. struct enter_args
  366. {
  367. struct grub_ieee1275_common_hdr common;
  368. }
  369. args;
  370. INIT_IEEE1275_COMMON (&args.common, "enter", 0, 0);
  371. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  372. return -1;
  373. return 0;
  374. }
  375. void
  376. grub_ieee1275_exit (void)
  377. {
  378. struct exit_args
  379. {
  380. struct grub_ieee1275_common_hdr common;
  381. }
  382. args;
  383. INIT_IEEE1275_COMMON (&args.common, "exit", 0, 0);
  384. IEEE1275_CALL_ENTRY_FN (&args);
  385. for (;;) ;
  386. }
  387. int
  388. grub_ieee1275_open (const char *path, grub_ieee1275_ihandle_t *result)
  389. {
  390. struct open_args
  391. {
  392. struct grub_ieee1275_common_hdr common;
  393. grub_ieee1275_cell_t path;
  394. grub_ieee1275_cell_t result;
  395. }
  396. args;
  397. INIT_IEEE1275_COMMON (&args.common, "open", 1, 1);
  398. args.path = (grub_ieee1275_cell_t) path;
  399. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  400. return -1;
  401. *result = args.result;
  402. if (args.result == IEEE1275_IHANDLE_INVALID)
  403. return -1;
  404. return 0;
  405. }
  406. int
  407. grub_ieee1275_close (grub_ieee1275_ihandle_t ihandle)
  408. {
  409. struct close_args
  410. {
  411. struct grub_ieee1275_common_hdr common;
  412. grub_ieee1275_cell_t ihandle;
  413. }
  414. args;
  415. INIT_IEEE1275_COMMON (&args.common, "close", 1, 0);
  416. args.ihandle = ihandle;
  417. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  418. return -1;
  419. return 0;
  420. }
  421. int
  422. grub_ieee1275_decode_unit4 (grub_ieee1275_ihandle_t ihandle,
  423. void *addr, grub_size_t size,
  424. grub_uint32_t *phy_lo, grub_uint32_t *phy_hi,
  425. grub_uint32_t *lun_lo, grub_uint32_t *lun_hi)
  426. {
  427. struct decode_args
  428. {
  429. struct grub_ieee1275_common_hdr common;
  430. grub_ieee1275_cell_t method;
  431. grub_ieee1275_cell_t ihandle;
  432. grub_ieee1275_cell_t size;
  433. grub_ieee1275_cell_t addr;
  434. grub_ieee1275_cell_t catch_result;
  435. grub_ieee1275_cell_t tgt_h;
  436. grub_ieee1275_cell_t tgt_l;
  437. grub_ieee1275_cell_t lun_h;
  438. grub_ieee1275_cell_t lun_l;
  439. }
  440. args;
  441. INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 5);
  442. args.method = (grub_ieee1275_cell_t) "decode-unit";
  443. args.ihandle = ihandle;
  444. args.size = size;
  445. args.addr = (grub_ieee1275_cell_t) addr;
  446. args.catch_result = 1;
  447. if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result))
  448. {
  449. grub_error (GRUB_ERR_OUT_OF_RANGE, "decode-unit failed\n");
  450. return -1;
  451. }
  452. *phy_lo = args.tgt_l;
  453. *phy_hi = args.tgt_h;
  454. *lun_lo = args.lun_l;
  455. *lun_hi = args.lun_h;
  456. return 0;
  457. }
  458. char *
  459. grub_ieee1275_encode_uint4 (grub_ieee1275_ihandle_t ihandle,
  460. grub_uint32_t phy_lo, grub_uint32_t phy_hi,
  461. grub_uint32_t lun_lo, grub_uint32_t lun_hi,
  462. grub_size_t *size)
  463. {
  464. char *addr;
  465. struct encode_args
  466. {
  467. struct grub_ieee1275_common_hdr common;
  468. grub_ieee1275_cell_t method;
  469. grub_ieee1275_cell_t ihandle;
  470. grub_ieee1275_cell_t tgt_h;
  471. grub_ieee1275_cell_t tgt_l;
  472. grub_ieee1275_cell_t lun_h;
  473. grub_ieee1275_cell_t lun_l;
  474. grub_ieee1275_cell_t catch_result;
  475. grub_ieee1275_cell_t size;
  476. grub_ieee1275_cell_t addr;
  477. }
  478. args;
  479. INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 3);
  480. args.method = (grub_ieee1275_cell_t) "encode-unit";
  481. args.ihandle = ihandle;
  482. args.tgt_l = phy_lo;
  483. args.tgt_h = phy_hi;
  484. args.lun_l = lun_lo;
  485. args.lun_h = lun_hi;
  486. args.catch_result = 1;
  487. if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result))
  488. {
  489. grub_error (GRUB_ERR_OUT_OF_RANGE, "encode-unit failed\n");
  490. return 0;
  491. }
  492. addr = (void *)args.addr;
  493. *size = args.size;
  494. addr = grub_strdup ((char *)args.addr);
  495. return addr;
  496. }
  497. int
  498. grub_ieee1275_claim (grub_addr_t addr, grub_size_t size, unsigned int align,
  499. grub_addr_t *result)
  500. {
  501. struct claim_args
  502. {
  503. struct grub_ieee1275_common_hdr common;
  504. grub_ieee1275_cell_t addr;
  505. grub_ieee1275_cell_t size;
  506. grub_ieee1275_cell_t align;
  507. grub_ieee1275_cell_t base;
  508. }
  509. args;
  510. INIT_IEEE1275_COMMON (&args.common, "claim", 3, 1);
  511. args.addr = (grub_ieee1275_cell_t) addr;
  512. args.size = (grub_ieee1275_cell_t) size;
  513. args.align = (grub_ieee1275_cell_t) align;
  514. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  515. return -1;
  516. if (result)
  517. *result = args.base;
  518. if (args.base == IEEE1275_CELL_INVALID)
  519. return -1;
  520. grub_dprintf ("mmap", "CLAIMED: 0x%" PRIxGRUB_IEEE1275_CELL_T " (%"
  521. PRIuGRUB_IEEE1275_CELL_T " MiB) size: %" PRIuGRUB_SIZE " MiB\n",
  522. args.base, args.base >> 20, ALIGN_UP (size, 1 << 20) >> 20);
  523. return 0;
  524. }
  525. int
  526. grub_ieee1275_release (grub_addr_t addr, grub_size_t size)
  527. {
  528. struct release_args
  529. {
  530. struct grub_ieee1275_common_hdr common;
  531. grub_ieee1275_cell_t addr;
  532. grub_ieee1275_cell_t size;
  533. }
  534. args;
  535. INIT_IEEE1275_COMMON (&args.common, "release", 2, 0);
  536. args.addr = addr;
  537. args.size = size;
  538. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  539. return -1;
  540. return 0;
  541. }
  542. int
  543. grub_ieee1275_set_property (grub_ieee1275_phandle_t phandle,
  544. const char *propname, const void *buf,
  545. grub_size_t size, grub_ssize_t *actual)
  546. {
  547. struct set_property_args
  548. {
  549. struct grub_ieee1275_common_hdr common;
  550. grub_ieee1275_cell_t phandle;
  551. grub_ieee1275_cell_t propname;
  552. grub_ieee1275_cell_t buf;
  553. grub_ieee1275_cell_t size;
  554. grub_ieee1275_cell_t actual;
  555. }
  556. args;
  557. INIT_IEEE1275_COMMON (&args.common, "setprop", 4, 1);
  558. args.size = (grub_ieee1275_cell_t) size;
  559. args.buf = (grub_ieee1275_cell_t) buf;
  560. args.propname = (grub_ieee1275_cell_t) propname;
  561. args.phandle = (grub_ieee1275_cell_t) phandle;
  562. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  563. return -1;
  564. *actual = args.actual;
  565. if ((args.actual == IEEE1275_CELL_INVALID) || (args.actual != args.size))
  566. return -1;
  567. return 0;
  568. }
  569. int
  570. grub_ieee1275_set_color (grub_ieee1275_ihandle_t ihandle,
  571. int index, int r, int g, int b)
  572. {
  573. struct set_color_args
  574. {
  575. struct grub_ieee1275_common_hdr common;
  576. grub_ieee1275_cell_t method;
  577. grub_ieee1275_cell_t ihandle;
  578. grub_ieee1275_cell_t index;
  579. grub_ieee1275_cell_t b;
  580. grub_ieee1275_cell_t g;
  581. grub_ieee1275_cell_t r;
  582. grub_ieee1275_cell_t catch_result;
  583. }
  584. args;
  585. INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1);
  586. args.method = (grub_ieee1275_cell_t) "color!";
  587. args.ihandle = ihandle;
  588. args.index = index;
  589. args.r = r;
  590. args.g = g;
  591. args.b = b;
  592. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  593. return -1;
  594. return args.catch_result;
  595. }
  596. int
  597. grub_ieee1275_milliseconds (grub_uint32_t *msecs)
  598. {
  599. struct milliseconds_args
  600. {
  601. struct grub_ieee1275_common_hdr common;
  602. grub_ieee1275_cell_t msecs;
  603. }
  604. args;
  605. INIT_IEEE1275_COMMON (&args.common, "milliseconds", 0, 1);
  606. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  607. return -1;
  608. *msecs = args.msecs;
  609. return 0;
  610. }
  611. int
  612. grub_ieee1275_set_address (grub_ieee1275_ihandle_t ihandle,
  613. grub_uint32_t target, grub_uint32_t lun)
  614. {
  615. struct set_address
  616. {
  617. struct grub_ieee1275_common_hdr common;
  618. grub_ieee1275_cell_t method;
  619. grub_ieee1275_cell_t ihandle;
  620. grub_ieee1275_cell_t tgt;
  621. grub_ieee1275_cell_t lun;
  622. grub_ieee1275_cell_t catch_result;
  623. }
  624. args;
  625. INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 1);
  626. /*
  627. * IEEE 1275-1994 Standard for Boot (Initialization Configuration)
  628. * Firmware: Core Requirements and Practices
  629. * E.3.2.2 Bus-specific methods for bus nodes
  630. *
  631. * A package implementing the scsi-2 device type shall implement the
  632. * following bus-specific method:
  633. *
  634. * set-address ( unit# target# -- )
  635. * Sets the SCSI target number (0x0..0xf) and unit number (0..7) to which
  636. * subsequent commands apply.
  637. */
  638. args.method = (grub_ieee1275_cell_t) "set-address";
  639. args.ihandle = ihandle;
  640. args.tgt = target;
  641. args.lun = lun;
  642. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  643. return -1;
  644. return args.catch_result;
  645. }
  646. int
  647. grub_ieee1275_no_data_command (grub_ieee1275_ihandle_t ihandle,
  648. const void *cmd_addr, grub_ssize_t *result)
  649. {
  650. struct set_address
  651. {
  652. struct grub_ieee1275_common_hdr common;
  653. grub_ieee1275_cell_t method;
  654. grub_ieee1275_cell_t ihandle;
  655. grub_ieee1275_cell_t cmd_addr;
  656. grub_ieee1275_cell_t error;
  657. grub_ieee1275_cell_t catch_result;
  658. }
  659. args;
  660. INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2);
  661. /*
  662. * IEEE 1275-1994 Standard for Boot (Initialization Configuration)
  663. * Firmware: Core Requirements and Practices
  664. *
  665. * E.3.2.2 Bus-specific methods for bus nodes
  666. *
  667. * A package implementing the scsi-2 device type shall implement the
  668. * following bus-specific method:
  669. *
  670. * no-data-command ( cmd-addr -- error? )
  671. * Executes a simple SCSI command, automatically retrying under
  672. * certain conditions. cmd-addr is the address of a 6-byte command buffer
  673. * containing an SCSI command that does not have a data transfer phase.
  674. * Executes the command, retrying indefinitely with the same retry criteria
  675. * as retry-command.
  676. *
  677. * error? is nonzero if an error occurred, zero otherwise.
  678. * NOTE no-data-command is a convenience function. It provides
  679. * no capabilities that are not present in retry-command, but for
  680. * those commands that meet its restrictions, it is easier to use.
  681. */
  682. args.method = (grub_ieee1275_cell_t) "no-data-command";
  683. args.ihandle = ihandle;
  684. args.cmd_addr = (grub_ieee1275_cell_t) cmd_addr;
  685. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  686. return -1;
  687. if (result)
  688. *result = args.error;
  689. return args.catch_result;
  690. }
  691. int
  692. grub_ieee1275_get_block_size (grub_ieee1275_ihandle_t ihandle)
  693. {
  694. struct size_args_ieee1275
  695. {
  696. struct grub_ieee1275_common_hdr common;
  697. grub_ieee1275_cell_t method;
  698. grub_ieee1275_cell_t ihandle;
  699. grub_ieee1275_cell_t result;
  700. grub_ieee1275_cell_t size;
  701. } args;
  702. INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2);
  703. args.method = (grub_ieee1275_cell_t) "block-size";
  704. args.ihandle = ihandle;
  705. args.result = 1;
  706. if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result))
  707. return 0;
  708. return args.size;
  709. }