1
/* of.c - Access the Open Firmware client interface. */
3
* GRUB -- GRand Unified Bootloader
4
* Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
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.
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.
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/>.
20
#include <grub/ieee1275/ieee1275.h>
21
#include <grub/types.h>
23
#define IEEE1275_PHANDLE_INVALID ((grub_ieee1275_cell_t) -1)
24
#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_cell_t) 0)
25
#define IEEE1275_CELL_INVALID ((grub_ieee1275_cell_t) -1)
30
grub_ieee1275_finddevice (char *name, grub_ieee1275_phandle_t *phandlep)
32
struct find_device_args
34
struct grub_ieee1275_common_hdr common;
35
grub_ieee1275_cell_t device;
36
grub_ieee1275_cell_t phandle;
40
INIT_IEEE1275_COMMON (&args.common, "finddevice", 1, 1);
41
args.device = (grub_ieee1275_cell_t) name;
43
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
45
*phandlep = args.phandle;
46
if (args.phandle == IEEE1275_PHANDLE_INVALID)
52
grub_ieee1275_get_property (grub_ieee1275_phandle_t phandle,
53
const char *property, void *buf,
54
grub_size_t size, grub_ssize_t *actual)
56
struct get_property_args
58
struct grub_ieee1275_common_hdr common;
59
grub_ieee1275_cell_t phandle;
60
grub_ieee1275_cell_t prop;
61
grub_ieee1275_cell_t buf;
62
grub_ieee1275_cell_t buflen;
63
grub_ieee1275_cell_t size;
67
INIT_IEEE1275_COMMON (&args.common, "getprop", 4, 1);
68
args.phandle = phandle;
69
args.prop = (grub_ieee1275_cell_t) property;
70
args.buf = (grub_ieee1275_cell_t) buf;
71
args.buflen = (grub_ieee1275_cell_t) size;
73
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
76
*actual = (grub_ssize_t) args.size;
77
if (args.size == IEEE1275_CELL_INVALID)
83
grub_ieee1275_get_integer_property (grub_ieee1275_phandle_t phandle,
84
const char *property, grub_uint32_t *buf,
85
grub_size_t size, grub_ssize_t *actual)
88
ret = grub_ieee1275_get_property (phandle, property, (void *) buf, size, actual);
89
#ifndef GRUB_CPU_WORDS_BIGENDIAN
90
/* Integer properties are always in big endian. */
94
size /= sizeof (grub_uint32_t);
95
for (i = 0; i < size; i++)
96
buf[i] = grub_be_to_cpu32 (buf[i]);
103
grub_ieee1275_next_property (grub_ieee1275_phandle_t phandle, char *prev_prop,
106
struct get_property_args
108
struct grub_ieee1275_common_hdr common;
109
grub_ieee1275_cell_t phandle;
110
grub_ieee1275_cell_t prev_prop;
111
grub_ieee1275_cell_t next_prop;
112
grub_ieee1275_cell_t flags;
116
INIT_IEEE1275_COMMON (&args.common, "nextprop", 3, 1);
117
args.phandle = phandle;
118
args.prev_prop = (grub_ieee1275_cell_t) prev_prop;
119
args.next_prop = (grub_ieee1275_cell_t) prop;
120
args.flags = (grub_ieee1275_cell_t) -1;
122
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
124
return (int) args.flags;
128
grub_ieee1275_get_property_length (grub_ieee1275_phandle_t phandle,
129
const char *prop, grub_ssize_t *length)
131
struct get_property_args
133
struct grub_ieee1275_common_hdr common;
134
grub_ieee1275_cell_t phandle;
135
grub_ieee1275_cell_t prop;
136
grub_ieee1275_cell_t length;
140
INIT_IEEE1275_COMMON (&args.common, "getproplen", 2, 1);
141
args.phandle = phandle;
142
args.prop = (grub_ieee1275_cell_t) prop;
143
args.length = (grub_ieee1275_cell_t) -1;
145
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
147
*length = args.length;
148
if (args.length == IEEE1275_CELL_INVALID)
154
grub_ieee1275_instance_to_package (grub_ieee1275_ihandle_t ihandle,
155
grub_ieee1275_phandle_t *phandlep)
157
struct instance_to_package_args
159
struct grub_ieee1275_common_hdr common;
160
grub_ieee1275_cell_t ihandle;
161
grub_ieee1275_cell_t phandle;
165
INIT_IEEE1275_COMMON (&args.common, "instance-to-package", 1, 1);
166
args.ihandle = ihandle;
168
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
170
*phandlep = args.phandle;
171
if (args.phandle == IEEE1275_PHANDLE_INVALID)
177
grub_ieee1275_package_to_path (grub_ieee1275_phandle_t phandle,
178
char *path, grub_size_t len,
179
grub_ssize_t *actual)
181
struct instance_to_package_args
183
struct grub_ieee1275_common_hdr common;
184
grub_ieee1275_cell_t phandle;
185
grub_ieee1275_cell_t buf;
186
grub_ieee1275_cell_t buflen;
187
grub_ieee1275_cell_t actual;
191
INIT_IEEE1275_COMMON (&args.common, "package-to-path", 3, 1);
192
args.phandle = phandle;
193
args.buf = (grub_ieee1275_cell_t) path;
194
args.buflen = (grub_ieee1275_cell_t) len;
196
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
199
*actual = args.actual;
200
if (args.actual == IEEE1275_CELL_INVALID)
206
grub_ieee1275_instance_to_path (grub_ieee1275_ihandle_t ihandle,
207
char *path, grub_size_t len,
208
grub_ssize_t *actual)
210
struct instance_to_path_args
212
struct grub_ieee1275_common_hdr common;
213
grub_ieee1275_cell_t ihandle;
214
grub_ieee1275_cell_t buf;
215
grub_ieee1275_cell_t buflen;
216
grub_ieee1275_cell_t actual;
220
INIT_IEEE1275_COMMON (&args.common, "instance-to-path", 3, 1);
221
args.ihandle = ihandle;
222
args.buf = (grub_ieee1275_cell_t) path;
223
args.buflen = (grub_ieee1275_cell_t) len;
225
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
228
*actual = args.actual;
229
if (args.actual == IEEE1275_CELL_INVALID)
235
grub_ieee1275_write (grub_ieee1275_ihandle_t ihandle, void *buffer,
236
grub_size_t len, grub_ssize_t *actualp)
240
struct grub_ieee1275_common_hdr common;
241
grub_ieee1275_cell_t ihandle;
242
grub_ieee1275_cell_t buf;
243
grub_ieee1275_cell_t len;
244
grub_ieee1275_cell_t actual;
248
INIT_IEEE1275_COMMON (&args.common, "write", 3, 1);
249
args.ihandle = ihandle;
250
args.buf = (grub_ieee1275_cell_t) buffer;
251
args.len = (grub_ieee1275_cell_t) len;
253
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
256
*actualp = args.actual;
261
grub_ieee1275_read (grub_ieee1275_ihandle_t ihandle, void *buffer,
262
grub_size_t len, grub_ssize_t *actualp)
266
struct grub_ieee1275_common_hdr common;
267
grub_ieee1275_cell_t ihandle;
268
grub_ieee1275_cell_t buf;
269
grub_ieee1275_cell_t len;
270
grub_ieee1275_cell_t actual;
274
INIT_IEEE1275_COMMON (&args.common, "read", 3, 1);
275
args.ihandle = ihandle;
276
args.buf = (grub_ieee1275_cell_t) buffer;
277
args.len = (grub_ieee1275_cell_t) len;
279
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
282
*actualp = args.actual;
287
grub_ieee1275_seek (grub_ieee1275_ihandle_t ihandle, grub_disk_addr_t pos,
288
grub_ssize_t *result)
292
struct grub_ieee1275_common_hdr common;
293
grub_ieee1275_cell_t ihandle;
294
grub_ieee1275_cell_t pos_hi;
295
grub_ieee1275_cell_t pos_lo;
296
grub_ieee1275_cell_t result;
300
INIT_IEEE1275_COMMON (&args.common, "seek", 3, 1);
301
args.ihandle = ihandle;
302
/* To prevent stupid gcc warning. */
303
#if GRUB_IEEE1275_CELL_SIZEOF >= 8
307
args.pos_hi = (grub_ieee1275_cell_t) (pos >> (8 * GRUB_IEEE1275_CELL_SIZEOF));
308
args.pos_lo = (grub_ieee1275_cell_t)
309
(pos & ((1ULL << (8 * GRUB_IEEE1275_CELL_SIZEOF)) - 1));
312
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
316
*result = args.result;
321
grub_ieee1275_peer (grub_ieee1275_phandle_t node,
322
grub_ieee1275_phandle_t *result)
326
struct grub_ieee1275_common_hdr common;
327
grub_ieee1275_cell_t node;
328
grub_ieee1275_cell_t result;
332
INIT_IEEE1275_COMMON (&args.common, "peer", 1, 1);
335
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
337
*result = args.result;
338
if (args.result == 0)
344
grub_ieee1275_child (grub_ieee1275_phandle_t node,
345
grub_ieee1275_phandle_t *result)
349
struct grub_ieee1275_common_hdr common;
350
grub_ieee1275_cell_t node;
351
grub_ieee1275_cell_t result;
355
INIT_IEEE1275_COMMON (&args.common, "child", 1, 1);
357
args.result = IEEE1275_PHANDLE_INVALID;
359
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
361
*result = args.result;
362
if (args.result == 0)
368
grub_ieee1275_parent (grub_ieee1275_phandle_t node,
369
grub_ieee1275_phandle_t *result)
373
struct grub_ieee1275_common_hdr common;
374
grub_ieee1275_cell_t node;
375
grub_ieee1275_cell_t result;
379
INIT_IEEE1275_COMMON (&args.common, "parent", 1, 1);
381
args.result = IEEE1275_PHANDLE_INVALID;
383
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
385
*result = args.result;
390
grub_ieee1275_interpret (const char *command, grub_ieee1275_cell_t *catch)
394
struct grub_ieee1275_common_hdr common;
395
grub_ieee1275_cell_t command;
396
grub_ieee1275_cell_t catch;
400
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
403
INIT_IEEE1275_COMMON (&args.common, "interpret", 1, 1);
404
args.command = (grub_ieee1275_cell_t) command;
406
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
414
grub_ieee1275_enter (void)
418
struct grub_ieee1275_common_hdr common;
422
INIT_IEEE1275_COMMON (&args.common, "enter", 0, 0);
424
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
430
grub_ieee1275_exit (void)
434
struct grub_ieee1275_common_hdr common;
438
INIT_IEEE1275_COMMON (&args.common, "exit", 0, 0);
440
IEEE1275_CALL_ENTRY_FN (&args);
445
grub_ieee1275_open (const char *path, grub_ieee1275_ihandle_t *result)
449
struct grub_ieee1275_common_hdr common;
450
grub_ieee1275_cell_t path;
451
grub_ieee1275_cell_t result;
455
INIT_IEEE1275_COMMON (&args.common, "open", 1, 1);
456
args.path = (grub_ieee1275_cell_t) path;
458
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
460
*result = args.result;
461
if (args.result == IEEE1275_IHANDLE_INVALID)
467
grub_ieee1275_close (grub_ieee1275_ihandle_t ihandle)
471
struct grub_ieee1275_common_hdr common;
472
grub_ieee1275_cell_t ihandle;
476
INIT_IEEE1275_COMMON (&args.common, "close", 1, 0);
477
args.ihandle = ihandle;
479
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
486
grub_ieee1275_claim (grub_addr_t addr, grub_size_t size, unsigned int align,
491
struct grub_ieee1275_common_hdr common;
492
grub_ieee1275_cell_t addr;
493
grub_ieee1275_cell_t size;
494
grub_ieee1275_cell_t align;
495
grub_ieee1275_cell_t base;
499
INIT_IEEE1275_COMMON (&args.common, "claim", 3, 1);
500
args.addr = (grub_ieee1275_cell_t) addr;
501
args.size = (grub_ieee1275_cell_t) size;
502
args.align = (grub_ieee1275_cell_t) align;
504
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
508
if (args.base == IEEE1275_CELL_INVALID)
514
grub_ieee1275_release (grub_addr_t addr, grub_size_t size)
518
struct grub_ieee1275_common_hdr common;
519
grub_ieee1275_cell_t addr;
520
grub_ieee1275_cell_t size;
524
INIT_IEEE1275_COMMON (&args.common, "release", 2, 0);
528
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
534
grub_ieee1275_set_property (grub_ieee1275_phandle_t phandle,
535
const char *propname, void *buf,
536
grub_size_t size, grub_ssize_t *actual)
538
struct set_property_args
540
struct grub_ieee1275_common_hdr common;
541
grub_ieee1275_cell_t phandle;
542
grub_ieee1275_cell_t propname;
543
grub_ieee1275_cell_t buf;
544
grub_ieee1275_cell_t size;
545
grub_ieee1275_cell_t actual;
549
INIT_IEEE1275_COMMON (&args.common, "setprop", 4, 1);
550
args.size = (grub_ieee1275_cell_t) size;
551
args.buf = (grub_ieee1275_cell_t) buf;
552
args.propname = (grub_ieee1275_cell_t) propname;
553
args.phandle = (grub_ieee1275_cell_t) phandle;
555
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
557
*actual = args.actual;
558
if ((args.actual == IEEE1275_CELL_INVALID) || (args.actual != args.size))
564
grub_ieee1275_set_color (grub_ieee1275_ihandle_t ihandle,
565
int index, int r, int g, int b)
567
struct set_color_args
569
struct grub_ieee1275_common_hdr common;
570
grub_ieee1275_cell_t method;
571
grub_ieee1275_cell_t ihandle;
572
grub_ieee1275_cell_t index;
573
grub_ieee1275_cell_t b;
574
grub_ieee1275_cell_t g;
575
grub_ieee1275_cell_t r;
576
grub_ieee1275_cell_t catch_result;
580
INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1);
581
args.method = (grub_ieee1275_cell_t) "color!";
582
args.ihandle = ihandle;
588
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
590
return args.catch_result;
594
grub_ieee1275_milliseconds (grub_uint32_t *msecs)
596
struct milliseconds_args
598
struct grub_ieee1275_common_hdr common;
599
grub_ieee1275_cell_t msecs;
603
INIT_IEEE1275_COMMON (&args.common, "milliseconds", 0, 1);
605
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)