1
/* Open firmware emulation.
3
* This is really simplistic. The first goal is to implement all stuff
4
* needed to boot Linux. Then, I'll try Darwin.
5
* Note that this emulation run in the host environment.
6
* There is no Forth interpreter, so standard bootloader cannot be launched.
7
* In the future, it will be nice to get a complete OpenFirmware implementation
8
* so that OSes can be launched exactly the way they are in the real world...
10
* Copyright (c) 2003-2005 Jocelyn Mayer
12
* This program is free software; you can redistribute it and/or
13
* modify it under the terms of the GNU General Public License V2
14
* as published by the Free Software Foundation
16
* This program is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
21
* You should have received a copy of the GNU General Public License
22
* along with this program; if not, write to the Free Software
23
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32
#if defined (DEBUG_OF)
33
#define OF_DPRINTF(fmt, args...) \
34
do { dprintf("%s: " fmt, __func__ , ##args); } while (0)
36
#define OF_DPRINTF(fmt, args...) \
43
typedef struct OF_transl_t OF_transl_t;
51
typedef struct OF_env_t OF_env_t;
53
uint32_t *stackp; /* Stack pointer */
54
uint32_t *stackb; /* Stack base */
55
uint32_t *funcp; /* Function stack pointer */
56
uint32_t *funcb; /* Function stack base */
59
typedef struct OF_bustyp_t OF_bustyp_t;
65
typedef struct pci_address_t pci_address_t;
66
struct pci_address_t {
72
typedef struct pci_reg_prop_t pci_reg_prop_t;
73
struct pci_reg_prop_t {
79
typedef struct pci_range_t pci_range_t;
87
/*****************************************************************************/
88
__attribute__ (( section (".OpenFirmware") ))
89
static void OF_lds (uint8_t *dst, const void *address)
94
for (p = address; *p != '\0'; p++) {
98
OF_DPRINTF("Loaded string %s\n", dst);
101
__attribute__ (( section (".OpenFirmware") ))
102
static void OF_sts (void *address, const uint8_t *src)
105
uint8_t *p = address;
107
OF_DPRINTF("Store string %s\n", src);
108
for (_s = src; *_s != '\0'; _s++) {
114
#define OF_DUMP_STRING(env, buffer) \
116
unsigned char tmp[OF_NAMELEN_MAX]; \
117
OF_lds(tmp, buffer); \
118
OF_DPRINTF("[%s]\n", tmp); \
121
/*****************************************************************************/
122
/* Forth like environmnent */
123
#define OF_CHECK_NBARGS(env, nb) \
126
nb_args = stackd_depth((env)); \
127
if (nb_args != (nb)) { \
128
printf("%s: Bad number of arguments (%d - %d)\n", \
129
__func__, nb_args, (nb)); \
131
popd_all((env), nb_args); \
137
#define OF_STACK_SIZE 0x1000
138
#define OF_FSTACK_SIZE 0x100
139
__attribute__ (( section (".OpenFirmware_vars") ))
140
uint8_t OF_stack[OF_STACK_SIZE];
141
__attribute__ (( section (".OpenFirmware_vars") ))
142
uint8_t OF_fstack[OF_FSTACK_SIZE];
144
typedef void (*OF_cb_t)(OF_env_t *OF_env);
146
static inline void _push (uint32_t **stackp, uint32_t data)
148
// OF_DPRINTF("%p 0x%0x\n", *stackp, data);
153
static inline uint32_t _pop (uint32_t **stackp)
156
// OF_DPRINTF("%p 0x%0x\n", *stackp, **stackp);
160
static inline void _pop_all (uint32_t **stackp, int nb)
164
for (i = 0; i < nb; i++)
168
static inline int _stack_depth (uint32_t *stackp, uint32_t *basep)
170
return basep - stackp;
173
static inline void pushd (OF_env_t *OF_env, uint32_t data)
175
_push(&OF_env->stackp, data);
178
static inline uint32_t popd (OF_env_t *OF_env)
180
return _pop(&OF_env->stackp);
183
static inline void popd_all (OF_env_t *OF_env, int nb)
185
_pop_all(&OF_env->stackp, nb);
188
static inline int stackd_depth (OF_env_t *OF_env)
190
return _stack_depth(OF_env->stackp, OF_env->stackb);
193
static inline void pushf (OF_env_t *OF_env, OF_cb_t *func)
195
_push(&OF_env->funcp, (uint32_t)func);
198
static inline OF_cb_t *popf (OF_env_t *OF_env)
200
return (OF_cb_t *)_pop(&OF_env->funcp);
203
static inline void popf_all (OF_env_t *OF_env, int nb)
205
_pop_all(&OF_env->funcp, nb);
208
static inline int stackf_depth (OF_env_t *OF_env)
210
return _stack_depth(OF_env->funcp, OF_env->funcb);
213
static inline void OF_env_init (OF_env_t *OF_env)
215
OF_env->stackb = (uint32_t *)(OF_stack + OF_STACK_SIZE - 4);
216
OF_env->stackp = OF_env->stackb;
217
OF_env->funcb = (uint32_t *)(OF_fstack + OF_FSTACK_SIZE - 4);
218
OF_env->funcp = OF_env->funcb;
222
__attribute__ (( section (".OpenFirmware") ))
223
static void C_to_Forth (OF_env_t *env, void *p, OF_cb_t *cb)
227
uint32_t i, n_args, n_rets, tmp;
229
// OF_DPRINTF("enter\n");
230
/* Fill argument structure */
236
// OF_DPRINTF("n_args=%d n_rets=%d\n", n_args, n_rets);
238
for (i = 0; i < n_args; i++)
241
while (stackf_depth(env) != 0) {
242
// OF_DPRINTF("func stack: %p %p\n", env->funcb, env->funcp);
244
// OF_DPRINTF("Next func: %p %d\n", cb, stackf_depth(env));
247
// OF_DPRINTF("Back to C: n_args=%d n_rets=%d\n", n_args, n_rets);
248
/* Copy returned values */
249
for (i = 0; stackd_depth(env) != 0; i++) {
251
// OF_DPRINTF("Store 0x%0x (%d)\n", tmp, tmp);
254
for (; i < n_rets; i++)
256
OF_CHECK_NBARGS(env, 0);
257
// OF_DPRINTF("done\n");
260
/*****************************************************************************/
261
/* Memory pool (will be needed when it'll become native) */
263
#define OF_INTBITS_LEN 128
264
#define OF_INTPOOL_LEN (OF_INTBITS_LEN * 8)
265
__attribute__ (( section (".OpenFirmware_vars") ))
266
static uint32_t OF_int_pool[OF_INTPOOL_LEN];
267
__attribute__ (( section (".OpenFirmware_vars") ))
268
static uint8_t OF_int_bits[OF_INTBITS_LEN];
270
__attribute__ (( section (".OpenFirmware") ))
271
static uint32_t *OF_int_alloc (unused OF_env_t *env)
276
for (i = 0; i < OF_INTBITS_LEN; i++) {
277
tmp = OF_int_bits[i];
280
for (j = 0; j < 7; j++) {
281
if ((tmp & 1) == 0) {
282
OF_int_bits[i] |= 1 << j;
283
return &OF_int_pool[(i << 3) | j];
288
printf("ALERT: unable to \"allocate\" new integer\n");
293
__attribute__ (( section (".OpenFirmware") ))
294
static void OF_int_free (unused OF_env_t *env,
299
i = area - OF_int_pool;
302
OF_int_bits[i] &= ~(1 << j);
305
__attribute__ (( section (".OpenFirmware") ))
306
static void OF_free (unused OF_env_t *env, void *area)
310
/* Check if it's in our int pool */
312
if (check >= OF_int_pool && check < (OF_int_pool + OF_INTPOOL_LEN)) {
313
OF_int_free(env, check);
322
/*****************************************************************************/
323
/* Internal structures */
324
/* Property value types */
325
typedef struct OF_node_t OF_node_t;
326
typedef struct OF_prop_t OF_prop_t;
327
typedef struct OF_method_t OF_method_t;
328
typedef struct OF_inst_t OF_inst_t;
330
#define OF_ADDRESS_NONE ((uint32_t)(-1))
336
/* Link to next node at the same level */
338
/* Link to children, if any */
339
OF_node_t *children, *child_last;
342
/* The following ones belong to the package */
350
OF_prop_t *properties, *prop_last, *prop_name, *prop_address;
352
OF_method_t *methods, *method_last;
358
OF_inst_t *instances, *inst_last;
363
/* Link to next property */
365
/* The node it belongs to */
368
const unsigned char *name;
369
/* property value len */
371
/* property value buffer */
373
/* Property change callback */
374
void (*cb)(OF_env_t *OF_env, OF_prop_t *prop, const void *data, int len);
379
OF_METHOD_INTERNAL = 0,
384
/* Link to next method */
386
/* The package it belongs to */
390
/* Method function pointer */
394
/* Package instance */
396
/* Link to next instance of the same package */
398
/* Link to the parent instance */
400
/* The package it belongs to */
402
/* Instance identifier */
409
typedef struct OF_regprop_t OF_regprop_t;
410
struct OF_regprop_t {
416
typedef struct OF_range_t OF_range_t;
423
/* Open firmware tree */
424
#define OF_MAX_PACKAGE 256
425
/* nodes and packages */
426
__attribute__ (( section (".OpenFirmware_vars") ))
427
static OF_node_t *OF_node_root;
428
__attribute__ (( section (".OpenFirmware_vars") ))
429
static uint16_t OF_pack_last_id = 0;
430
__attribute__ (( section (".OpenFirmware_vars") ))
431
static uint16_t inst_last_id = 0;
432
/* To speed up lookup by id, we get a package table */
433
__attribute__ (( section (".OpenFirmware_vars") ))
434
static OF_node_t *OF_packages[OF_MAX_PACKAGE];
435
__attribute__ (( section (".OpenFirmware_vars") ))
436
static OF_node_t *OF_pack_active;
438
static OF_prop_t *OF_prop_string_new (OF_env_t *env, OF_node_t *node,
439
const unsigned char *name,
440
const unsigned char *string);
441
static OF_prop_t *OF_prop_int_new (OF_env_t *env, OF_node_t *node,
442
const unsigned char *name, uint32_t value);
443
static OF_prop_t *OF_property_get (OF_env_t *env, OF_node_t *node,
444
const unsigned char *name);
445
static uint16_t OF_pack_handle (OF_env_t *env, OF_node_t *node);
447
__attribute__ (( section (".OpenFirmware_vars") ))
448
static uint8_t *RTAS_memory;
450
/*****************************************************************************/
451
/* Node management */
452
/* Insert a new node */
453
__attribute__ (( section (".OpenFirmware") ))
454
static uint16_t OF_pack_new_id (unused OF_env_t *env, OF_node_t *node)
458
for (cur_id = OF_pack_last_id + 1; cur_id != OF_pack_last_id; cur_id++) {
459
if (cur_id == (uint16_t)(OF_MAX_PACKAGE))
461
if (OF_packages[cur_id] == NULL) {
462
OF_packages[cur_id] = node;
463
OF_pack_last_id = cur_id;
468
return (uint16_t)(-1);
471
static OF_node_t *OF_node_create (OF_env_t *env, OF_node_t *parent,
472
const unsigned char *name, uint32_t address)
476
OF_DPRINTF("New node: %s\n", name);
477
new = malloc(sizeof(OF_node_t));
479
ERROR("%s can't alloc new node '%s'\n", __func__, name);
482
memset(new, 0, sizeof(OF_node_t));
483
new->parent = parent;
486
new->prop_name = OF_prop_string_new(env, new, "name", name);
487
if (new->prop_name == NULL) {
489
ERROR("%s can't alloc new node '%s' name\n", __func__, name);
492
new->prop_address = OF_prop_int_new(env, new, "unit-address", address);
493
if (new->prop_address == NULL) {
494
free(new->prop_name->value);
495
free(new->prop_name);
497
ERROR("%s can't alloc new node '%s' address\n", __func__, name);
500
/* Link it in parent tree */
501
if (parent != NULL) {
503
if (parent->children == NULL) {
504
parent->children = new;
506
parent->child_last->next = new;
508
parent->child_last = new;
510
/* This is a bug and should never happen, but for root node */
511
if (strcmp(name, "device-tree") != 0)
512
ERROR("WARNING: parent of '%s' is NULL!\n", name);
514
// OF_DPRINTF("New node: %s get id\n", name);
519
__attribute__ (( section (".OpenFirmware") ))
520
static OF_node_t *OF_node_new (OF_env_t *env, OF_node_t *parent,
521
const unsigned char *name, uint32_t address)
525
new = OF_node_create(env, parent, name, address);
528
new->pack_id = OF_pack_new_id(env, new);
529
// OF_DPRINTF("New node: %s id=0x%0x\n", name, new->pack_id);
530
OF_pack_active = new;
535
static inline OF_node_t *OF_node_parent (unused OF_env_t *env, OF_node_t *node)
540
/* Look for a node, given its name */
541
__attribute__ (( section (".OpenFirmware") ))
542
static OF_node_t *OF_node_get_child (OF_env_t *env, OF_node_t *parent,
543
const unsigned char *name,
546
unsigned char tname[OF_NAMELEN_MAX];
547
OF_node_t *parse, *tmp;
548
OF_prop_t *prop_name, *prop_address;
552
if (parent == OF_node_root) {
553
OF_DPRINTF("Look for node [%s]\n", name);
556
memcpy(tname, name, len + 1);
557
for (i = len; i > 0; i--) {
558
if (tname[i - 1] == ',') {
564
for (parse = parent->children; parse != NULL; parse = parse->next) {
565
prop_name = parse->prop_name;
566
prop_address = parse->prop_address;
567
if (prop_address == NULL)
570
addr_valp = (void *)prop_address->value;
572
OF_DPRINTF("node [%s] <=> [%s]\n", prop_name->value, tname);
574
if (prop_name != NULL && strncmp(prop_name->value, tname, len) == 0 &&
575
(prop_name->value[len] == '\0') &&
576
(address == OF_ADDRESS_NONE || addr_valp == NULL ||
577
address == *addr_valp)) {
582
OF_DPRINTF("look in children [%s]\n", prop_name->value);
584
tmp = OF_node_get_child(env, parse, tname, address);
588
OF_DPRINTF("didn't find in children [%s]\n", prop_name->value);
591
if (parent == OF_node_root) {
592
OF_DPRINTF("node [%s] not found\n", name);
598
__attribute__ (( section (".OpenFirmware") ))
599
static OF_node_t *OF_node_get (OF_env_t *env, const unsigned char *name)
601
unsigned char tname[OF_NAMELEN_MAX];
602
unsigned char *addrp;
605
if (strcmp(name, "device_tree") == 0)
609
addrp = strchr(tname, '@');
611
address = OF_ADDRESS_NONE;
614
address = strtol(addrp, NULL, 16);
618
return OF_node_get_child(env, OF_node_root, name, address);
622
__attribute__ (( section (".OpenFirmware") ))
623
static void OF_node_put (unused OF_env_t *env, OF_node_t *node)
625
if (--node->refcount < 0)
629
/*****************************************************************************/
630
/* Packages tree walk */
631
__attribute__ (( section (".OpenFirmware") ))
632
static uint16_t OF_pack_handle (unused OF_env_t *env, OF_node_t *node)
637
return node->pack_id;
640
__attribute__ (( section (".OpenFirmware") ))
641
static OF_node_t *OF_pack_find_by_name (OF_env_t *env, OF_node_t *base,
642
const unsigned char *name)
644
unsigned char tmp[OF_NAMELEN_MAX], *addrp;
645
const unsigned char *sl, *st;
647
OF_prop_t *prop_name, *prop_address;
648
uint32_t address, *addr_valp;
651
OF_DPRINTF("Path [%s] in '%s'\n", name, base->prop_name->value);
657
/* Should never happen */
658
OF_DPRINTF("Done\n");
661
sl = strchr(st, '/');
667
memcpy(tmp, st, len);
669
addrp = strchr(tmp, '@');
671
address = OF_ADDRESS_NONE;
675
address = strtol(addrp, NULL, 16);
677
OF_DPRINTF("Look for [%s] '%s' %08x\n", tmp, sl, address);
678
for (parse = base->children; parse != NULL; parse = parse->next) {
679
prop_name = parse->prop_name;
680
prop_address = parse->prop_address;
681
if (prop_address == NULL)
684
addr_valp = (void *)prop_address->value;
686
OF_DPRINTF("Check [%s]\n", prop_name->value);
688
if (prop_name == NULL) {
689
printf("ERROR: missing address in node, parent: '%s'\n",
690
base->prop_name->value);
693
if (strncmp(prop_name->value, tmp, len) == 0 &&
694
prop_name->value[len] == '\0' &&
695
(address == OF_ADDRESS_NONE || addr_valp == NULL ||
696
address == *addr_valp)) {
697
OF_pack_active = parse;
699
OF_DPRINTF("Done\n");
702
OF_DPRINTF("Recurse: '%s'\n", sl + 1);
703
return OF_pack_find_by_name(env, parse, sl + 1);
706
OF_DPRINTF("Didn't found [%s]\n", tmp);
711
__attribute__ (( section (".OpenFirmware") ))
712
static OF_node_t *OF_pack_find (unused OF_env_t *env, uint16_t phandle)
714
if (phandle > OF_MAX_PACKAGE)
716
if (OF_packages[phandle] == NULL) {
717
OF_DPRINTF("No package %0x\n", phandle);
719
OF_DPRINTF("return package: %0x %p [%s]\n", phandle,
720
OF_packages[phandle],
721
OF_packages[phandle]->prop_name->value);
724
return OF_packages[phandle];
727
__attribute__ (( section (".OpenFirmware") ))
728
static OF_node_t *OF_pack_next (OF_env_t *env, uint16_t phandle)
732
for (node = OF_pack_find(env, phandle); node != NULL; node = node->next) {
733
if (OF_pack_handle(env, node) != phandle)
737
OF_DPRINTF("found node %p [%s]\n", node, node->prop_name->value);
743
__attribute__ (( section (".OpenFirmware") ))
744
static OF_node_t *OF_pack_child (OF_env_t *env, uint16_t phandle)
748
node = OF_pack_find(env, phandle);
750
ERROR("%s didn't find pack %04x\n", __func__, phandle);
753
node = node->children;
755
OF_DPRINTF("found node %p [%s]\n", node, node->prop_name->value);
761
__attribute__ (( section (".OpenFirmware") ))
762
static OF_node_t *OF_pack_parent (OF_env_t *env, uint16_t phandle)
766
node = OF_pack_find(env, phandle);
768
ERROR("%s didn't find pack %04x\n", __func__, phandle);
771
node = OF_node_parent(env, node);
773
OF_DPRINTF("found node %p [%s]\n", node, node->prop_name->value);
779
/*****************************************************************************/
780
/* Package properties management */
781
/* Insert a new property */
782
__attribute__ (( section (".OpenFirmware") ))
783
static OF_prop_t *OF_property_new (unused OF_env_t *env, OF_node_t *node,
784
const unsigned char *name,
785
const void *data, int len)
792
_prop = OF_property_get(env, node, name);
794
printf("Property '%s' already present !\n", name);
799
/* Allocate a new property */
800
prop = malloc(sizeof(OF_prop_t));
802
ERROR("%s cannot allocate property '%s'\n", __func__, name);
805
memset(prop, 0, sizeof(OF_prop_t));
806
prop->name = strdup(name);
807
if (prop->name == NULL) {
809
ERROR("%s cannot allocate property '%s' name\n", __func__, name);
813
if (data != NULL && len > 0) {
814
prop->value = malloc(len);
815
if (prop->value == NULL) {
817
ERROR("%s cannot allocate property '%s' value\n", __func__, name);
821
memcpy(prop->value, data, len);
823
OF_DPRINTF("New property [%s] '%s'\n\t%p %p %d %p\n", name, prop->name, prop->name, data, len, prop->value);
826
if (node->properties == NULL)
827
node->properties = prop;
829
node->prop_last->next = prop;
830
node->prop_last = prop;
835
/* Find a property given its name */
836
__attribute__ (( section (".OpenFirmware") ))
837
static OF_prop_t *OF_property_get (unused OF_env_t *env, OF_node_t *node,
838
const unsigned char *name)
843
OF_DPRINTF("Look for property [%s] in 0x%0x '%s'\n", name,
844
node->pack_id, node->prop_name->value);
849
for (prop = node->properties; prop != NULL; prop = prop->next) {
851
OF_DPRINTF("property [%s] <=> [%s]\n", prop->name, name);
853
if (strcmp(prop->name, name) == 0) {
858
OF_DPRINTF("property [%s] not found in 0x%08x '%s'\n", name,
859
node->pack_id, node->prop_name->value);
865
/* Change a property */
866
__attribute__ (( section (".OpenFirmware") ))
867
static OF_prop_t *OF_property_set (OF_env_t *env, OF_node_t *node,
868
const unsigned char *name,
869
const void *data, int len)
876
prop = OF_property_get(env, node, name);
878
OF_DPRINTF("change property [%s]\n", name);
880
if (tmp == NULL && len != 0) {
881
ERROR("%s cannot set property '%s'\n", __func__, name);
887
memcpy(prop->value, data, len);
888
if (prop->cb != NULL) {
889
(*prop->cb)(env, prop, data, len);
892
OF_DPRINTF("new property [%s]\n", name);
893
prop = OF_property_new(env, node, name, data, len);
899
__attribute__ (( section (".OpenFirmware") ))
900
static int OF_property_len (OF_env_t *env, OF_node_t *node,
901
const unsigned char *name)
905
prop = OF_property_get(env, node, name);
912
__attribute__ (( section (".OpenFirmware") ))
913
static unsigned char *hex2buf (unsigned char *buf, uint32_t value, int fill)
922
for (; value != 0; pos--) {
931
for (; pos != -1; pos--) {
939
__attribute__ (( section (".OpenFirmware") ))
940
static int OF_property_copy (OF_env_t *env, void *buffer, int maxlen,
941
OF_node_t *node, const unsigned char *name)
943
unsigned char tmp[OF_PROPLEN_MAX];
947
prop = OF_property_get(env, node, name);
949
ERROR("%s cannot get property '%s' for %s\n", __func__, name,
950
node->prop_name->value);
953
len = prop->vlen > maxlen ? maxlen : prop->vlen;
954
if (prop->value != NULL) {
957
hex2buf(tmp + 2, *((uint32_t *)prop->value), 1);
961
OF_DPRINTF("copy property [%s] len=%d to %p len=%d\n",
962
name, prop->vlen, buffer, maxlen);
963
if (strcmp(name, "name") == 0) {
964
OF_DPRINTF("=> '%s'\n", prop->value);
966
memcpy(buffer, prop->value, len);
967
// OF_DPRINTF("done\n");
972
__attribute__ (( section (".OpenFirmware") ))
973
static OF_prop_t *OF_property_next (OF_env_t *env, OF_node_t *node,
974
const unsigned char *name)
976
OF_prop_t *prop, *next;
978
if (name == NULL || *name == '\0') {
979
next = node->properties;
981
prop = OF_property_get(env, node, name);
983
OF_DPRINTF("Property [%s] not found\n", name);
987
/* Skip address if not set */
988
if (next == node->prop_address &&
989
*((uint32_t *)next->value) == OF_ADDRESS_NONE)
994
OF_DPRINTF("Found property %p\n", next);
1000
/* Simplified helpers */
1001
__attribute__ (( section (".OpenFirmware") ))
1002
static OF_prop_t *OF_prop_string_new (OF_env_t *env, OF_node_t *node,
1003
const unsigned char *name,
1004
const unsigned char *string)
1009
prop = OF_property_get(env, node, name);
1011
printf("Property '%s' already present !\n", name);
1016
return OF_property_new(env, node, name,
1017
string, strlen(string) + 1);
1020
/* convert '\1' char to '\0' */
1021
static OF_prop_t *OF_prop_string_new1 (OF_env_t *env, OF_node_t *node,
1022
const unsigned char *name,
1023
const unsigned char *string)
1029
if (strchr(string, '\1') == NULL) {
1030
return OF_prop_string_new(env, node, name, string);
1032
len = strlen(string) + 1;
1036
memcpy(str, string, len);
1037
for(i = 0; i < len; i++)
1040
ret = OF_property_new(env, node, name,
1047
__attribute__ (( section (".OpenFirmware") ))
1048
static OF_prop_t *OF_prop_int_new (OF_env_t *env, OF_node_t *node,
1049
const unsigned char *name, uint32_t value)
1054
prop = OF_property_get(env, node, name);
1056
printf("Property '%s' already present !\n", name);
1061
return OF_property_new(env, node, name, &value, sizeof(uint32_t));
1064
__attribute__ (( section (".OpenFirmware") ))
1065
static OF_prop_t *OF_prop_string_set (OF_env_t *env, OF_node_t *node,
1066
const unsigned char *name,
1067
const unsigned char *string)
1069
const unsigned char *tmp;
1071
tmp = strdup(string);
1073
ERROR("%s cannot duplicate property '%s'\n", __func__, name);
1077
return OF_property_set(env, node, name, tmp, strlen(string) + 1);
1080
__attribute__ (( section (".OpenFirmware") ))
1081
static OF_prop_t *OF_prop_int_set (OF_env_t *env, OF_node_t *node,
1082
const unsigned char *name, uint32_t value)
1084
return OF_property_set(env, node, name, &value, sizeof(uint32_t));
1087
__attribute__ (( section (".OpenFirmware") ))
1089
static OF_prop_t *OF_set_compatibility (OF_env_t *env, OF_node_t *node,
1090
const unsigned char *compat)
1092
return OF_prop_string_new(env, node, "compatible", compat);
1095
__attribute__ (( section (".OpenFirmware") ))
1096
static inline void OF_property_set_cb (unused OF_env_t *OF_env,
1098
void (*cb)(OF_env_t *OF_env,
1100
const void *data, int len))
1105
/*****************************************************************************/
1106
/* Packages methods management */
1107
__attribute__ (( section (".OpenFirmware") ))
1108
static OF_method_t *OF_method_new (unused OF_env_t *env, OF_node_t *node,
1109
const unsigned char *name, OF_cb_t cb)
1113
new = malloc(sizeof(OF_method_t));
1115
ERROR("%s cannot allocate method '%s'\n", __func__, name);
1118
memset(new, 0, sizeof(OF_method_t));
1120
new->name = strdup(name);
1121
if (new->name == NULL) {
1123
ERROR("%s cannot allocate method '%s' name\n", __func__, name);
1126
OF_DPRINTF("new method name %p %s\n", new, new->name);
1130
if (node->method_last == NULL)
1131
node->methods = new;
1133
node->method_last->next = new;
1134
node->method_last = new;
1139
__attribute__ (( section (".OpenFirmware") ))
1140
static OF_method_t *OF_method_get (unused OF_env_t *env, OF_node_t *node,
1141
const unsigned char *name)
1146
OF_DPRINTF("No method in NULL package !\n");
1150
OF_DPRINTF("Look for method %s in package %0x\n",
1151
name, node->pack_id);
1153
for (parse = node->methods; parse != NULL; parse = parse->next) {
1155
OF_DPRINTF("check %p %p\n", parse, parse->name);
1156
OF_DPRINTF("name=%s\n", parse->name);
1158
if (strcmp(parse->name, name) == 0)
1165
/*****************************************************************************/
1166
/* Packages instances management */
1167
__attribute__ (( section (".OpenFirmware") ))
1168
static uint16_t OF_inst_new_id (unused OF_env_t *env, OF_node_t *node)
1170
OF_inst_t *tmp_inst;
1174
OF_DPRINTF("[%s] %d\n", node->prop_name->value,
1177
for (cur_id = inst_last_id + 1;
1178
cur_id != inst_last_id; cur_id++) {
1179
if (cur_id == (uint16_t)(OF_MAX_PACKAGE))
1181
for (tmp_inst = node->instances; tmp_inst != NULL;
1182
tmp_inst = tmp_inst->next) {
1183
if (tmp_inst->inst_id == cur_id)
1186
inst_last_id = cur_id;
1188
OF_DPRINTF("0x%0x\n", cur_id);
1192
OF_DPRINTF("no ID found\n");
1194
return (uint16_t)(-1);
1197
/* Create a new package's instance */
1198
__attribute__ (( section (".OpenFirmware") ))
1199
static OF_inst_t *OF_instance_new (OF_env_t *env, OF_node_t *node)
1201
OF_inst_t *new, *parent;
1204
/* TODO: recurse to root... */
1205
new = malloc(sizeof(OF_inst_t));
1207
ERROR("%s cannot allocate instance of '%s'\n", __func__,
1208
node->prop_name->value);
1211
memset(new, 0, sizeof(OF_inst_t));
1212
if (OF_node_parent(env, node) != NULL) {
1213
parent = OF_instance_new(env, OF_node_parent(env, node));
1214
if (parent == NULL) {
1216
ERROR("%s cannot allocate instance of '%s' parent\n", __func__,
1217
node->prop_name->value);
1220
new->parent = parent;
1224
new_id = OF_inst_new_id(env, node);
1225
if (new_id == (uint16_t)(-1)) {
1229
new->inst_id = new_id;
1233
if (node->inst_last == NULL)
1234
node->instances = new;
1236
node->inst_last->next = new;
1237
node->inst_last = new;
1242
__attribute__ (( section (".OpenFirmware") ))
1243
static uint32_t OF_instance_get_id (unused OF_env_t *env, OF_inst_t *instance)
1245
OF_DPRINTF("p: %0x i: %0x\n", instance->node->pack_id, instance->inst_id);
1246
return (instance->node->pack_id << 16) | instance->inst_id;
1249
__attribute__ (( section (".OpenFirmware") ))
1250
static OF_inst_t *OF_inst_find (OF_env_t *env, uint32_t ihandle)
1254
uint16_t phandle = ihandle >> 16;
1257
OF_DPRINTF("p: %0x i: %0x\n", phandle, ihandle);
1258
if (ihandle > OF_MAX_PACKAGE)
1260
node = OF_pack_find(env, phandle);
1263
for (parse = node->instances; parse != NULL; parse = parse->next) {
1264
if (parse->inst_id == ihandle)
1272
__attribute__ (( section (".OpenFirmware") ))
1273
static OF_inst_t *OF_inst_get_child (OF_env_t *env, OF_node_t *parent,
1274
const uint32_t handle)
1276
OF_node_t *parse, *tmp;
1278
for (parse = parent->children; parse != NULL; parse = parse->next) {
1279
if (parse->pack_id == (handle >> 16)) {
1282
tmp = OF_inst_get_child(env, parse, handle);
1290
__attribute__ (( section (".OpenFirmware") ))
1291
static OF_inst_t *OF_inst_get (OF_env_t *env, const unsigned char *name)
1293
return _OF_node_get(env, &OF_node_root);
1299
__attribute__ (( section (".OpenFirmware") ))
1300
int get_node_name (OF_env_t *env, unsigned char *name,
1301
int len, OF_node_t *node)
1306
/* Set up manufacturer name */
1310
if (OF_node_parent(env, node) == NULL ||
1311
node->manufct != OF_node_parent(env, node)->manufct) {
1312
tmp = strlen(node->manufct);
1313
if ((tmp + 2) > len)
1315
memcpy(name, node->manufct, tmp);
1317
} else if (len < 2) {
1324
/* Set up device model */
1325
tmp = strlen(node->name);
1326
if ((tmp + 2) > len)
1328
memcpy(name, node->model, tmp);
1333
/* Set up unit address */
1334
tmp = strlen(node->address);
1335
if ((tmp + 2) > len)
1337
memcpy(name, node->address, tmp);
1342
for (i = 0; node->arguments[i] != NULL; i++) {
1345
tmp = strlen(node->arguments[i]);
1346
if ((tmp + 2) > len)
1348
memcpy(name, node->arguments[i], tmp);
1359
__attribute__ (( section (".OpenFirmware") ))
1360
static int OF_pack_get_path (OF_env_t *env, unsigned char *name,
1361
int len, OF_node_t *node)
1363
OF_prop_t *prop_name, *prop_address;
1367
/* Recurse until we reach the root node */
1368
OF_DPRINTF("look for [%s]\n", node->prop_name->value);
1369
if (OF_node_parent(env, node) == NULL) {
1374
tmp = OF_pack_get_path(env, name, len, OF_node_parent(env, node));
1376
prop_name = node->prop_name;
1377
prop_address = node->prop_address;
1379
OF_DPRINTF("Found [%s]\n", prop_name->value);
1381
if ((len - tmp) < 2) {
1382
OF_DPRINTF("Buffer too short (%d 2)\n", len - tmp);
1385
if (prop_name == NULL) {
1386
printf("No name in node !\n");
1389
nlen = strlen(prop_name->value);
1391
OF_DPRINTF("got '%s' for '%s' parent (%d %d)\n",
1392
name, prop_name->value, tmp, nlen);
1394
if (name[tmp - 1] != '/') {
1398
address = *((uint32_t *)prop_address->value);
1399
if (address != OF_ADDRESS_NONE) {
1400
if ((len - tmp - nlen) < 10) {
1401
OF_DPRINTF("Buffer too short (%d %d)\n", len - tmp, nlen + 10);
1405
if ((len - tmp - nlen) < 1) {
1406
OF_DPRINTF("Buffer too short (%d %d)\n", len - tmp, nlen + 1);
1410
memcpy(name + tmp, prop_name->value, nlen);
1411
if (address != OF_ADDRESS_NONE) {
1412
OF_DPRINTF("Add address 0x%08x\n", address);
1413
sprintf(name + tmp + nlen, "@%x", address);
1414
nlen += strlen(name + tmp + nlen);
1416
OF_DPRINTF("No address....\n");
1419
name[tmp + nlen] = '\0';
1420
OF_DPRINTF("stored [%d]\n", tmp + nlen);
1421
OF_DUMP_STRING(env, name);
1423
OF_DPRINTF("name '%s' => '%s' %d\n",
1424
node->properties->value, name, tmp + nlen);
1430
__attribute__ (( section (".OpenFirmware") ))
1431
static int OF_inst_get_path (OF_env_t *env, unsigned char *name,
1432
int len, OF_inst_t *inst)
1434
return OF_pack_get_path(env, name, len, inst->node);
1437
/*****************************************************************************/
1438
/* Open firmware C interface */
1439
static void OF_serial_write (OF_env_t *OF_env);
1440
static void OF_serial_read (OF_env_t *OF_env);
1441
static void OF_mmu_translate (OF_env_t *OF_env);
1442
static void OF_mmu_map (OF_env_t *OF_env);
1443
static void RTAS_instantiate (OF_env_t *RTAS_env);
1445
static OF_env_t *OF_env_main;
1447
/* Init standard OF structures */
1448
__attribute__ (( section (".OpenFirmware") ))
1452
"PowerMac3,1\0MacRISC\0Power Macintosh\0";
1453
"PowerMac1,2\0MacRISC\0Power Macintosh\0";
1454
"AAPL,PowerMac G3\0PowerMac G3\0MacRISC\0Power Macintosh\0";
1455
"AAPL,PowerMac3,0\0MacRISC\0Power Macintosh\0";
1456
"AAPL,Gossamer\0MacRISC\0Power Macintosh\0";
1459
OF_node_t *als, *opt, *chs, *pks;
1463
OF_DPRINTF("start\n");
1464
OF_env_main = malloc(sizeof(OF_env_t));
1465
if (OF_env_main == NULL) {
1466
ERROR("%s cannot allocate main OF env\n", __func__);
1469
// memset(OF_env_main, 0, sizeof(OF_env_t));
1470
OF_env = OF_env_main;
1471
// OF_env_init(OF_env);
1473
OF_DPRINTF("start\n");
1474
/* Set up standard IEEE 1275 nodes */
1475
/* "/device-tree" */
1476
OF_node_root = OF_node_new(OF_env, NULL, "device-tree", OF_ADDRESS_NONE);
1477
if (OF_node_root == NULL) {
1478
ERROR("Cannot create 'device-tree'\n");
1481
OF_prop_string_new(OF_env, OF_node_root, "device_type", "bootrom");
1482
if (arch == ARCH_HEATHROW) {
1483
const unsigned char compat_str[] =
1484
"PowerMac1,1\0MacRISC\0Power Macintosh";
1485
OF_property_new(OF_env, OF_node_root, "compatible",
1486
compat_str, sizeof(compat_str));
1487
OF_prop_string_new(OF_env, OF_node_root,
1488
"model", "Power Macintosh");
1490
const unsigned char compat_str[] =
1491
"PowerMac3,1\0MacRISC\0Power Macintosh";
1492
OF_property_new(OF_env, OF_node_root, "compatible",
1493
compat_str, sizeof(compat_str));
1494
OF_prop_string_new(OF_env, OF_node_root,
1495
"model", "PowerMac3,1");
1498
OF_prop_string_new(OF_env, OF_node_root, "copyright", copyright);
1500
OF_prop_string_new(OF_env, OF_node_root, "copyright",
1501
"Copyright 1983-1999 Apple Computer, Inc. All Rights Reserved");
1503
OF_prop_string_new(OF_env, OF_node_root, "system-id", "42");
1504
OF_prop_int_new(OF_env, OF_node_root, "#address-cells", 1);
1505
OF_prop_int_new(OF_env, OF_node_root, "#size-cells", 1);
1506
OF_prop_int_new(OF_env, OF_node_root, "clock-frequency", 0x05F03E4D);
1507
/* "/aliases" node */
1508
als = OF_node_new(OF_env, OF_node_root, "aliases", OF_ADDRESS_NONE);
1510
ERROR("Cannot create 'aliases'\n");
1513
/* "/chosen" node */
1514
chs = OF_node_new(OF_env, OF_node_root, "chosen", OF_ADDRESS_NONE);
1516
ERROR("Cannot create 'choosen'\n");
1519
/* "/packages" node */
1520
pks = OF_node_new(OF_env, OF_node_root, "packages", OF_ADDRESS_NONE);
1522
ERROR("Cannot create 'packages'\n");
1528
cpus = OF_node_new(OF_env, OF_node_root, "cpus", OF_ADDRESS_NONE);
1530
ERROR("Cannot create 'cpus'\n");
1533
OF_prop_int_new(OF_env, cpus, "#address-cells", 1);
1534
OF_prop_int_new(OF_env, cpus, "#size-cells", 0);
1535
OF_node_put(OF_env, cpus);
1537
/* "/memory@0" node */
1540
mem = OF_node_new(OF_env, OF_node_root, "memory", 0);
1542
ERROR("Cannot create 'memory'\n");
1545
OF_prop_string_new(OF_env, mem, "device_type", "memory");
1546
OF_prop_int_new(OF_env, chs, "memory", OF_pack_handle(OF_env, mem));
1547
OF_node_put(OF_env, mem);
1549
/* "/openprom" node */
1552
opp = OF_node_new(OF_env, OF_node_root, "openprom", OF_ADDRESS_NONE);
1554
ERROR("Cannot create 'openprom'\n");
1557
OF_prop_string_new(OF_env, opp, "device_type", "BootROM");
1558
OF_prop_string_new(OF_env, opp, "model", "OpenFirmware 3");
1559
OF_prop_int_new(OF_env, opp, "boot-syntax", 0x0001);
1560
OF_property_new(OF_env, opp, "relative-addressing", NULL, 0);
1561
OF_property_new(OF_env, opp, "supports-bootinfo", NULL, 0);
1562
OF_prop_string_new(OF_env, opp, "built-on", stringify(BUILD_DATE));
1563
OF_prop_string_new(OF_env, als, "rom", "/openprom");
1564
OF_node_put(OF_env, opp);
1566
/* "/options" node */
1567
opt = OF_node_new(OF_env, OF_node_root, "options", OF_ADDRESS_NONE);
1569
ERROR("Cannot create 'options'\n");
1572
OF_prop_string_new(OF_env, opt, "little-endian?", "false");
1573
OF_prop_string_new(OF_env, opt, "real-mode?", "false");
1574
// Will play with this...
1575
OF_prop_string_new(OF_env, opt, "security-mode", "none");
1576
/* "/rom@ff800000" node */
1579
OF_node_t *rom, *brom;
1581
rom = OF_node_new(OF_env, OF_node_root, "rom", 0xff800000);
1583
ERROR("Cannot create 'rom'\n");
1586
regs.address = 0xFF800000;
1587
regs.size = 0x00000000;
1588
OF_property_new(OF_env, rom, "reg", ®s, sizeof(OF_regprop_t));
1589
range.virt = 0xFF800000;
1590
range.phys = 0xFF800000;
1591
range.size = 0x00800000;
1592
OF_property_new(OF_env, rom, "ranges", &range, sizeof(OF_range_t));
1593
OF_prop_int_new(OF_env, rom, "#address-cells", 1);
1595
/* "/rom/boot-rom@fff00000" node */
1596
brom = OF_node_new(OF_env, rom, "boot-rom", 0xfff00000);
1598
ERROR("Cannot create 'boot-rom'\n");
1601
regs.address = 0xFFF00000;
1602
regs.size = 0x00100000;
1603
OF_property_new(OF_env, brom, "reg", ®s, sizeof(OF_regprop_t));
1604
OF_prop_string_new(OF_env, brom, "write-characteristic", "flash");
1605
OF_prop_string_new(OF_env, brom, "BootROM-build-date",
1606
stringify(BUILD_DATE) " at " stringify(BUILD_TIME));
1607
OF_prop_string_new(OF_env, brom, "BootROM-version", BIOS_VERSION);
1608
OF_prop_string_new(OF_env, brom, "copyright", copyright);
1609
OF_prop_string_new(OF_env, brom, "model", BIOS_str);
1610
OF_prop_int_new(OF_env, brom, "result", 0);
1613
/* Hack taken 'as-is' from PearPC */
1614
unsigned char info[] = {
1615
0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
1616
0x00, 0x01, 0x12, 0xf2, 0x19, 0x99, 0x08, 0x19,
1617
0x94, 0x4e, 0x73, 0x27, 0xff, 0xf0, 0x80, 0x00,
1618
0x00, 0x07, 0x80, 0x01, 0x00, 0x01, 0x12, 0xf2,
1619
0x19, 0x99, 0x08, 0x19, 0xd7, 0xf3, 0xfc, 0x17,
1620
0xff, 0xf8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02,
1621
0x00, 0x01, 0x12, 0xf2, 0x19, 0x99, 0x08, 0x19,
1622
0xbb, 0x10, 0xfc, 0x17,
1624
OF_property_new(OF_env, brom, "info", info, sizeof(info));
1627
OF_node_put(OF_env, brom);
1628
OF_node_put(OF_env, rom);
1631
/* From here, hardcoded hacks to get a Mac-like machine */
1632
/* XXX: Core99 does not seem to like this NVRAM tree */
1633
/* "/nvram@fff04000" node */
1638
nvr = OF_node_new(OF_env, OF_node_root, "nvram", 0xfff04000);
1640
ERROR("Cannot create 'nvram'\n");
1643
OF_prop_string_new(OF_env, nvr, "device_type", "nvram");
1644
/* XXX: use real NVRAM size instead */
1645
OF_prop_int_new(OF_env, nvr, "#bytes", 0x2000);
1646
OF_prop_string_new(OF_env, nvr, "compatible", "nvram,flash");
1647
regs.address = 0xFFF04000;
1648
regs.size = 0x00004000; /* Strange, isn't it ? */
1649
OF_property_new(OF_env, nvr, "reg", ®s, sizeof(regs));
1650
OF_prop_int_new(OF_env, chs, "nvram", OF_pack_handle(OF_env, nvr));
1651
OF_node_put(OF_env, nvr);
1654
/* "/pseudo-hid" : hid emulation as Apple does */
1658
hid = OF_node_new(OF_env, OF_node_root,
1659
"pseudo-hid", OF_ADDRESS_NONE);
1661
ERROR("Cannot create 'pseudo-hid'\n");
1665
/* "keyboard" node */
1668
kbd = OF_node_new(OF_env, hid, "keyboard", OF_ADDRESS_NONE);
1670
ERROR("Cannot create 'keyboard'\n");
1673
OF_prop_string_new(OF_env, kbd, "device_type", "keyboard");
1674
OF_node_put(OF_env, kbd);
1679
mouse = OF_node_new(OF_env, hid, "mouse", OF_ADDRESS_NONE);
1680
if (mouse == NULL) {
1681
ERROR("Cannot create 'mouse'\n");
1684
OF_prop_string_new(OF_env, mouse, "device_type", "mouse");
1685
OF_node_put(OF_env, mouse);
1687
/* "eject-key" node */
1690
ejk = OF_node_new(OF_env, hid, "eject-key", OF_ADDRESS_NONE);
1692
ERROR("Cannot create 'eject-key'\n");
1695
OF_prop_string_new(OF_env, ejk, "device_type", "eject-key");
1696
OF_node_put(OF_env, ejk);
1698
OF_node_put(OF_env, hid);
1700
if (arch == ARCH_MAC99) {
1704
unin = OF_node_new(OF_env, OF_node_root,
1705
"uni-n", 0xf8000000);
1707
ERROR("Cannot create 'uni-n'\n");
1710
OF_prop_string_new(OF_env, unin, "device-type", "memory-controller");
1711
OF_prop_string_new(OF_env, unin, "model", "AAPL,UniNorth");
1712
OF_prop_string_new(OF_env, unin, "compatible", "uni-north");
1713
regs.address = 0xf8000000;
1714
regs.size = 0x01000000;
1715
OF_property_new(OF_env, unin, "reg", ®s, sizeof(regs));
1716
OF_prop_int_new(OF_env, unin, "#address-cells", 1);
1717
OF_prop_int_new(OF_env, unin, "#size-cells", 1);
1718
OF_prop_int_new(OF_env, unin, "device-rev", 3);
1719
OF_node_put(OF_env, unin);
1722
#if 1 /* This is mandatory for claim to work
1723
* but I don't know where it should really be (in cpu ?)
1729
mmu = OF_node_new(OF_env, OF_node_root, "mmu", OF_ADDRESS_NONE);
1731
ERROR("Cannot create 'mmu'\n");
1734
inst = OF_instance_new(OF_env, mmu);
1736
OF_node_put(OF_env, mmu);
1737
ERROR("Cannot create 'mmu' instance\n");
1740
OF_prop_int_new(OF_env, chs, "mmu",
1741
OF_instance_get_id(OF_env, inst));
1742
OF_method_new(OF_env, mmu, "translate", &OF_mmu_translate);
1743
OF_method_new(OF_env, mmu, "map", &OF_mmu_map);
1744
OF_node_put(OF_env, mmu);
1748
/* "/options/boot-args" node */
1750
// const unsigned char *args = "-v rootdev cdrom";
1751
//const unsigned char *args = "-v io=0xffffffff";
1752
const unsigned char *args = "-v";
1753
/* Ask MacOS X to print debug messages */
1754
// OF_prop_string_new(OF_env, chs, "machargs", args);
1755
// OF_prop_string_new(OF_env, opt, "boot-command", args);
1756
OF_prop_string_new(OF_env, opt, "boot-args", args);
1760
OF_node_put(OF_env, opt);
1761
OF_node_put(OF_env, pks);
1762
OF_node_put(OF_env, chs);
1763
OF_node_put(OF_env, als);
1764
OF_node_put(OF_env, OF_node_root);
1765
OF_DPRINTF("done\n");
1771
#if 0 // For now, static values are used
1772
__attribute__ (( section (".OpenFirmware") ))
1773
int OF_register_mb (const unsigned char *model, const unsigned char **compats)
1779
OF_env = OF_env_main;
1780
OF_DPRINTF("start\n");
1781
root = OF_node_get(OF_env, "device_tree");
1783
ERROR("Cannot get 'device-tree'\n");
1786
OF_DPRINTF("add model\n");
1787
OF_prop_string_new(OF_env, OF_node_root, "model", model);
1788
for (i = 0; i < 1 && compats[i] != NULL; i++) {
1789
OF_DPRINTF("add compats %s\n", compats[i]);
1790
OF_set_compatibility(OF_env, OF_node_root, compats[i]);
1792
/* we don't implement neither "l2-cache" nor "cache" nodes */
1793
OF_node_put(OF_env, root);
1794
OF_DPRINTF("done\n");
1801
__attribute__ (( section (".OpenFirmware") ))
1802
int OF_register_cpu (const unsigned char *name, int num, uint32_t pvr,
1803
uint32_t min_freq, uint32_t max_freq, uint32_t bus_freq,
1804
uint32_t tb_freq, uint32_t reset_io)
1806
unsigned char tmp[OF_NAMELEN_MAX];
1808
OF_node_t *cpus, *cpu, *l2c, *chs, *als;
1810
OF_env = OF_env_main;
1811
OF_DPRINTF("start\n");
1812
cpus = OF_node_get(OF_env, "cpus");
1814
ERROR("Cannot get 'cpus'\n");
1817
cpu = OF_node_new(OF_env, cpus, name, OF_ADDRESS_NONE);
1819
OF_node_put(OF_env, cpus);
1820
ERROR("Cannot create cpu '%s'\n", name);
1823
OF_prop_string_new(OF_env, cpu, "device_type", "cpu");
1824
OF_prop_int_new(OF_env, cpu, "#address-cells", 0x00000001);
1825
OF_prop_int_new(OF_env, cpu, "#size-cells", 0x00000000);
1826
OF_prop_int_new(OF_env, cpu, "reg", num);
1827
OF_prop_int_new(OF_env, cpu, "cpu-version", pvr);
1828
OF_prop_int_new(OF_env, cpu, "clock-frequency", max_freq);
1829
OF_prop_int_new(OF_env, cpu, "timebase-frequency", tb_freq);
1830
OF_prop_int_new(OF_env, cpu, "bus-frequency", bus_freq);
1831
OF_prop_int_new(OF_env, cpu, "min-clock-frequency", min_freq);
1832
OF_prop_int_new(OF_env, cpu, "max-clock-frequency", max_freq);
1833
OF_prop_int_new(OF_env, cpu, "tlb-size", 0x80);
1834
OF_prop_int_new(OF_env, cpu, "tlb-sets", 0x40);
1835
OF_prop_int_new(OF_env, cpu, "i-tlb-size", 0x40);
1836
OF_prop_int_new(OF_env, cpu, "i-tlb-sets", 0x20);
1837
OF_prop_int_new(OF_env, cpu, "i-cache-size", 0x8000);
1838
OF_prop_int_new(OF_env, cpu, "i-cache-sets", 0x80);
1839
OF_prop_int_new(OF_env, cpu, "i-cache-bloc-size", 0x20);
1840
OF_prop_int_new(OF_env, cpu, "i-cache-line-size", 0x20);
1841
OF_prop_int_new(OF_env, cpu, "d-tlb-size", 0x40);
1842
OF_prop_int_new(OF_env, cpu, "d-tlb-sets", 0x20);
1843
OF_prop_int_new(OF_env, cpu, "d-cache-size", 0x8000);
1844
OF_prop_int_new(OF_env, cpu, "d-cache-sets", 0x80);
1845
OF_prop_int_new(OF_env, cpu, "d-cache-bloc-size", 0x20);
1846
OF_prop_int_new(OF_env, cpu, "d-cache-line-size", 0x20);
1847
OF_prop_int_new(OF_env, cpu, "reservation-granule-size", 0x20);
1848
OF_prop_int_new(OF_env, cpus, "soft-reset", reset_io);
1849
OF_prop_string_new(OF_env, cpus, "graphics", "");
1850
OF_prop_string_new(OF_env, cpus, "performance-monitor", "");
1851
OF_prop_string_new(OF_env, cpus, "data-streams", "");
1852
OF_prop_string_new(OF_env, cpu, "state", "running");
1853
/* We don't implement:
1854
* "dynamic-powerstep" & "reduced-clock-frequency"
1858
l2c = OF_node_new(OF_env, cpu, "l2cache", OF_ADDRESS_NONE);
1860
ERROR("Cannot create 'l2cache'\n");
1863
OF_prop_string_new(OF_env, l2c, "device_type", "cache");
1864
OF_prop_int_new(OF_env, l2c, "i-cache-size", 0x100000);
1865
OF_prop_int_new(OF_env, l2c, "i-cache-sets", 0x2000);
1866
OF_prop_int_new(OF_env, l2c, "i-cache-line-size", 0x40);
1867
OF_prop_int_new(OF_env, l2c, "d-cache-size", 0x100000);
1868
OF_prop_int_new(OF_env, l2c, "d-cache-sets", 0x2000);
1869
OF_prop_int_new(OF_env, l2c, "d-cache-line-size", 0x40);
1870
/* Register it in the cpu node */
1871
OF_prop_int_new(OF_env, cpu, "l2-cache", OF_pack_handle(OF_env, l2c));
1872
OF_node_put(OF_env, l2c);
1873
/* Set it in "/chosen" and "/aliases" */
1875
OF_pack_get_path(OF_env, tmp, 512, cpu);
1876
chs = OF_node_get(OF_env, "chosen");
1878
OF_node_put(OF_env, cpus);
1879
ERROR("Cannot get 'chosen'\n");
1882
OF_prop_int_new(OF_env, chs, "cpu", OF_pack_handle(OF_env, cpu));
1883
OF_node_put(OF_env, chs);
1884
als = OF_node_get(OF_env, "aliases");
1886
OF_node_put(OF_env, cpus);
1887
ERROR("Cannot get 'aliases'\n");
1890
OF_prop_string_new(OF_env, als, "cpu", tmp);
1891
OF_node_put(OF_env, als);
1893
OF_node_put(OF_env, cpu);
1894
OF_node_put(OF_env, cpus);
1895
OF_DPRINTF("done\n");
1900
__attribute__ (( section (".OpenFirmware") ))
1901
int OF_register_translations (int nb, OF_transl_t *translations)
1904
OF_node_t *cpus, *cpu;
1908
OF_env = OF_env_main;
1909
OF_DPRINTF("start\n");
1910
cpus = OF_node_get(OF_env, "cpus");
1912
OF_node_put(OF_env, cpus);
1913
ERROR("Cannot get 'cpus'\n");
1916
cpu = cpus->children;
1917
new = malloc(nb * sizeof(OF_transl_t));
1919
ERROR("Cannot create new translation\n");
1922
for (i = 0; i < nb; i++) {
1923
new->virt = translations[i].virt;
1924
new->size = translations[i].size;
1925
new->phys = translations[i].phys;
1926
new->mode = translations[i].mode;
1927
OF_DPRINTF("%d\n", i);
1929
OF_property_new(OF_env, cpu, "translations",
1930
new, nb * sizeof(OF_transl_t));
1931
OF_node_put(OF_env, cpus);
1932
OF_DPRINTF("done\n");
1938
typedef struct OF_mem_t OF_mem_t;
1944
#define OF_MAX_MEMRANGES 16
1945
/* First entry is the whole known memory space */
1946
static OF_mem_t OF_mem_ranges[OF_MAX_MEMRANGES + 1];
1948
__attribute__ (( section (".OpenFirmware") ))
1949
int OF_register_memory (uint32_t memsize, unused uint32_t bios_size)
1953
OF_regprop_t regs[4];
1956
OF_env = OF_env_main;
1957
OF_DPRINTF("find node\n");
1958
mem = OF_node_get(OF_env, "memory");
1960
ERROR("Cannot get 'memory'\n");
1963
OF_DPRINTF("Memory package: %04x\n", OF_pack_handle(OF_env, mem));
1964
regs[0].address = 0x00000000;
1965
regs[0].size = memsize;
1966
regs[1].address = 0x00000000;
1967
regs[1].size = 0x00000000;
1968
regs[2].address = 0x00000000;
1969
regs[2].size = 0x00000000;
1970
regs[3].address = 0x00000000;
1971
regs[3].size = 0x00000000;
1972
OF_property_new(OF_env, mem, "reg", regs, 4 * sizeof(OF_regprop_t));
1975
regs[0].address = 0x00000000;
1976
regs[0].size = 0x05800000;
1977
regs[1].address = 0x06000000;
1978
regs[1].size = memsize - 0x06000000;
1979
regs[2].address = 0x00000000;
1980
regs[2].size = 0x00000000;
1981
OF_property_new(OF_env, mem, "available",
1982
regs, 3 * sizeof(OF_regprop_t));
1984
regs[0].address = 0x06000000;
1985
regs[0].size = memsize - 0x06000000;
1986
regs[1].address = 0x00000000;
1987
regs[1].size = 0x00000000;
1988
OF_property_new(OF_env, mem, "available",
1989
regs, 2 * sizeof(OF_regprop_t));
1992
OF_node_put(OF_env, mem);
1996
mmu = OF_node_get(OF_env, "mmu");
1998
ERROR("Cannot get 'mmu'\n");
2001
regs[0].address = 0x00000000;
2002
regs[0].size = memsize;
2003
OF_property_new(OF_env, mmu, "reg", regs, sizeof(OF_regprop_t));
2004
regs[0].address = 0x00000000;
2005
regs[0].size = 0x05800000;
2006
regs[1].address = 0x06000000;
2007
regs[1].size = memsize - 0x06000000;
2008
regs[2].address = 0x00000000;
2009
regs[2].size = 0x00000000;
2010
OF_property_new(OF_env, mmu, "available",
2011
regs, 3 * sizeof(OF_regprop_t));
2012
OF_node_put(OF_env, mmu);
2015
/* Also update the claim areas */
2016
OF_mem_ranges[0].start = 0x00000000;
2017
OF_mem_ranges[0].size = memsize;
2018
OF_mem_ranges[1].start = 0x58000000;
2019
OF_mem_ranges[1].size = 0x08000000;
2020
for (i = 2; i < OF_MAX_MEMRANGES + 1; i++) {
2021
OF_mem_ranges[i].start = -1;
2022
OF_mem_ranges[i].size = -1;
2024
OF_DPRINTF("done\n");
2029
/* Linux kernel command line */
2030
__attribute__ (( section (".OpenFirmware") ))
2031
int OF_register_bootargs (const unsigned char *bootargs)
2036
OF_env = OF_env_main;
2037
if (bootargs == NULL)
2039
chs = OF_node_get(OF_env, "chosen");
2041
ERROR("Cannot get 'chosen'\n");
2044
OF_prop_string_set(OF_env, chs, "bootargs", bootargs);
2045
// OF_prop_string_set(OF_env, OF_node_root, "bootargs", "");
2046
OF_node_put(OF_env, chs);
2051
__attribute__ (( section (".OpenFirmware") ))
2052
static void *OF_pci_device_new (OF_env_t *OF_env, OF_node_t *parent,
2053
pci_dev_t *dev, uint32_t address,
2054
uint16_t rev, uint32_t ccode,
2055
uint16_t min_grant, uint16_t max_latency)
2059
dprintf("register '%s' '%s' '%s' '%s' 0x%08x in '%s' 0x%08x\n",
2060
dev->name, dev->type, dev->compat, dev->model, address,
2061
parent->prop_name->value, *(uint32_t *)parent->prop_address->value);
2062
node = OF_node_new(OF_env, parent, dev->name, address);
2065
OF_prop_int_new(OF_env, node, "vendor-id", dev->vendor);
2066
OF_prop_int_new(OF_env, node, "device-id", dev->product);
2067
OF_prop_int_new(OF_env, node, "revision-id", rev);
2068
OF_prop_int_new(OF_env, node, "class-code", ccode);
2069
OF_prop_int_new(OF_env, node, "min-grant", min_grant);
2070
OF_prop_int_new(OF_env, node, "max-latency", max_latency);
2071
if (dev->type != NULL)
2072
OF_prop_string_new1(OF_env, node, "device_type", dev->type);
2073
if (dev->compat != NULL)
2074
OF_prop_string_new1(OF_env, node, "compatible", dev->compat);
2075
if (dev->model != NULL)
2076
OF_prop_string_new1(OF_env, node, "model", dev->model);
2077
if (dev->acells != 0)
2078
OF_prop_int_new(OF_env, node, "#address-cells", dev->acells);
2079
if (dev->scells != 0)
2080
OF_prop_int_new(OF_env, node, "#size-cells", dev->scells);
2081
if (dev->icells != 0)
2082
OF_prop_int_new(OF_env, node, "#interrupt-cells", dev->icells);
2083
dprintf("Done %p %p\n", parent, node);
2088
__attribute__ (( section (".OpenFirmware") ))
2089
void *OF_register_pci_host (pci_dev_t *dev, uint16_t rev, uint32_t ccode,
2090
uint32_t cfg_base, uint32_t cfg_len,
2091
uint32_t mem_base, uint32_t mem_len,
2092
uint32_t io_base, uint32_t io_len,
2093
uint32_t rbase, uint32_t rlen,
2094
uint16_t min_grant, uint16_t max_latency)
2097
pci_range_t ranges[3];
2098
OF_regprop_t regs[1];
2099
OF_node_t *pci_host, *als;
2101
unsigned char buffer[OF_NAMELEN_MAX];
2103
OF_env = OF_env_main;
2104
dprintf("register PCI host '%s' '%s' '%s' '%s'\n",
2105
dev->name, dev->type, dev->compat, dev->model);
2106
pci_host = OF_pci_device_new(OF_env, OF_node_root, dev, cfg_base,
2107
rev, ccode, min_grant, max_latency);
2108
if (pci_host == NULL) {
2109
ERROR("Cannot create pci host\n");
2113
als = OF_node_get(OF_env, "aliases");
2115
ERROR("Cannot get 'aliases'\n");
2118
sprintf(buffer, "/%s", dev->name);
2119
OF_prop_string_set(OF_env, als, "pci", buffer);
2120
OF_node_put(OF_env, als);
2123
regs[0].address = cfg_base;
2124
regs[0].size = cfg_len;
2125
OF_property_new(OF_env, pci_host, "reg", regs, sizeof(OF_regprop_t));
2127
if (rbase != 0x00000000) {
2128
ranges[nranges].addr.hi = 0x02000000;
2129
ranges[nranges].addr.mid = 0x00000000;
2130
ranges[nranges].addr.lo = rbase;
2131
ranges[nranges].phys = rbase;
2132
ranges[nranges].size_hi = 0x00000000;
2133
ranges[nranges].size_lo = rlen;
2136
if (io_base != 0x00000000) {
2137
ranges[nranges].addr.hi = 0x01000000;
2138
ranges[nranges].addr.mid = 0x00000000;
2139
ranges[nranges].addr.lo = 0x00000000;
2140
ranges[nranges].phys = io_base;
2141
ranges[nranges].size_hi = 0x00000000;
2142
ranges[nranges].size_lo = io_len;
2145
if (mem_base != 0x00000000) {
2146
ranges[nranges].addr.hi = 0x02000000;
2147
ranges[nranges].addr.mid = 0x00000000;
2148
ranges[nranges].addr.lo = mem_base;
2149
ranges[nranges].phys = mem_base;
2150
ranges[nranges].size_hi = 0x00000000;
2151
ranges[nranges].size_lo = mem_len;
2154
OF_property_new(OF_env, pci_host, "ranges", ranges,
2155
nranges * sizeof(pci_range_t));
2160
__attribute__ (( section (".OpenFirmware") ))
2161
void *OF_register_pci_bridge (void *parent, pci_dev_t *dev,
2162
uint32_t cfg_base, uint32_t cfg_len,
2163
uint8_t devfn, uint8_t rev, uint32_t ccode,
2164
uint16_t min_grant, uint16_t max_latency)
2167
OF_regprop_t regs[1];
2168
OF_node_t *pci_bridge;
2170
OF_env = OF_env_main;
2171
OF_DPRINTF("register '%s' %08x '%s' '%s' '%s'\n",
2172
dev->name, devfn >> 3, dev->type, dev->compat, dev->model);
2173
dprintf("register PCI bridge '%s' %08x '%s' '%s' '%s'\n",
2174
dev->name, devfn >> 3, dev->type, dev->compat, dev->model);
2175
pci_bridge = OF_pci_device_new(OF_env, parent, dev, devfn >> 3,
2176
rev, ccode, min_grant, max_latency);
2177
if (pci_bridge == NULL) {
2178
ERROR("Cannot create pci bridge\n");
2181
regs[0].address = cfg_base;
2182
regs[0].size = cfg_len;
2183
OF_property_new(OF_env, pci_bridge, "reg", regs, sizeof(OF_regprop_t));
2188
__attribute__ (( section (".OpenFirmware") ))
2189
void *OF_register_pci_device (void *parent, pci_dev_t *dev,
2190
uint8_t devfn, uint8_t rev, uint32_t ccode,
2191
uint16_t min_grant, uint16_t max_latency)
2196
OF_env = OF_env_main;
2197
OF_DPRINTF("register '%s' %08x '%s' '%s' '%s'\n",
2198
dev->name, devfn >> 3, dev->type, dev->compat, dev->model);
2199
dprintf("register pci device '%s' %08x '%s' '%s' '%s'\n",
2200
dev->name, devfn >> 3, dev->type, dev->compat, dev->model);
2201
pci_dev = OF_pci_device_new(OF_env, parent, dev, devfn >> 3,
2202
rev, ccode, min_grant, max_latency);
2207
/* XXX: suppress that, used for interrupt map init */
2208
OF_node_t *pci_host_node;
2209
uint32_t pci_host_interrupt_map[7 * 32];
2210
int pci_host_interrupt_map_len = 0;
2212
void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses)
2215
OF_regprop_t regs[1];
2217
OF_env = OF_env_main;
2218
regs[0].address = first_bus;
2219
regs[0].size = nb_busses;
2220
OF_property_new(OF_env, dev, "bus-range", regs, sizeof(OF_regprop_t));
2221
pci_host_node = dev;
2224
void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn,
2225
uint32_t *regions, uint32_t *sizes,
2229
pci_reg_prop_t pregs[6], rregs[6];
2233
OF_env = OF_env_main;
2234
/* XXX: only useful for VGA card in fact */
2235
if (regions[0] != 0x00000000)
2236
OF_prop_int_set(OF_env, dev, "address", regions[0] & ~0x0000000F);
2237
for (i = 0, j = 0, k = 0; i < 6; i++) {
2238
if (regions[i] != 0x00000000 && sizes[i] != 0x00000000) {
2239
/* Generate "reg" property
2241
if (regions[i] & 1) {
2243
rregs[j].addr.hi = 0x01000000;
2245
} else if (regions[i] & 4) {
2246
/* 64 bits address space */
2247
rregs[j].addr.hi = 0x83000000;
2250
} else if ((regions[i] & 0xF) == 0x00) { /* ? */
2251
/* Configuration space */
2252
rregs[j].addr.hi = 0x00000000;
2256
/* 32 bits address space */
2257
rregs[j].addr.hi = 0x82000000;
2260
/* Set bus number */
2261
rregs[j].addr.hi |= bus << 16;
2262
/* Set device/function */
2263
rregs[j].addr.hi |= devfn << 8;
2266
rregs[j].addr.hi |= 0x10 + (i * sizeof(uint32_t)); /* ? */
2269
rregs[j].addr.mid = 0x00000000;
2270
rregs[j].addr.lo = regions[i] & ~mask;
2272
rregs[j].size_hi = 0x00000000;
2273
rregs[j].size_lo = sizes[i];
2275
if ((rregs[j].addr.hi & 0x03000000) != 0x00000000)
2278
/* No assigned address for configuration space */
2279
pregs[k].addr.hi = rregs[j].addr.hi; /* ? */
2280
pregs[k].addr.mid = rregs[j].addr.mid;
2281
pregs[k].addr.lo = rregs[j].addr.lo; /* ? */
2282
pregs[k].size_hi = rregs[j].size_hi;
2283
pregs[k].size_lo = rregs[j].size_lo;
2290
OF_property_new(OF_env, dev, "reg",
2291
rregs, j * sizeof(pci_reg_prop_t));
2293
OF_property_new(OF_env, dev, "reg", NULL, 0);
2296
OF_property_new(OF_env, dev, "assigned-addresses",
2297
pregs, k * sizeof(pci_reg_prop_t));
2299
OF_property_new(OF_env, dev, "assigned-addresses", NULL, 0);
2301
if (irq_line >= 0) {
2303
OF_prop_int_new(OF_env, dev, "interrupts", 1);
2304
i = pci_host_interrupt_map_len;
2305
pci_host_interrupt_map[i++] = (devfn << 8) & 0xf800;
2306
pci_host_interrupt_map[i++] = 0;
2307
pci_host_interrupt_map[i++] = 0;
2308
pci_host_interrupt_map[i++] = 0;
2309
pci_host_interrupt_map[i++] = 0; /* pic handle will be patched later */
2310
pci_host_interrupt_map[i++] = irq_line;
2311
if (arch != ARCH_HEATHROW) {
2312
pci_host_interrupt_map[i++] = 1;
2314
pci_host_interrupt_map_len = i;
2318
OF_prop_t *prop_name = ((OF_node_t *)dev)->prop_name;
2321
dprintf("PCI device '%s' %d %d %d reg properties:\n",
2322
prop_name->value, bus, devfn >> 3, devfn & 7);
2323
for (i = 0; i < j; i++) {
2324
dprintf(" addr: %08x %08x %08x size: %08x %08x\n",
2325
rregs[i].addr.hi, rregs[i].addr.mid, rregs[i].addr.lo,
2326
rregs[i].size_hi, rregs[i].size_lo);
2329
dprintf("PCI device '%s' %d %d %d has no reg properties:\n",
2330
prop_name->value, bus, devfn >> 3, devfn & 7);
2333
dprintf("PCI device '%s' %d %d %d "
2334
"assigned addresses properties:\n",
2335
prop_name->value, bus, devfn >> 3, devfn & 7);
2336
for (i = 0; i < j; i++) {
2337
dprintf(" addr: %08x %08x %08x size: %08x %08x\n",
2338
pregs[i].addr.hi, pregs[i].addr.mid, pregs[i].addr.lo,
2339
pregs[i].size_hi, pregs[i].size_lo);
2342
dprintf("PCI device '%s' %d %d %d has no "
2343
"assigned addresses properties:\n",
2344
prop_name->value, bus, devfn >> 3, devfn & 7);
2350
__attribute__ (( section (".OpenFirmware") ))
2351
int OF_register_bus (const unsigned char *name, uint32_t address,
2352
const unsigned char *type)
2354
unsigned char buffer[OF_NAMELEN_MAX];
2356
OF_node_t *bus, *als;
2358
OF_env = OF_env_main;
2359
als = OF_node_get(OF_env, "aliases");
2361
ERROR("Cannot get 'aliases'\n");
2364
bus = OF_node_new(OF_env, OF_node_root, name, address);
2366
OF_node_put(OF_env, als);
2367
ERROR("Cannot create bus '%s'\n", name);
2370
OF_prop_string_set(OF_env, bus, "type", type);
2371
sprintf(buffer, "/%s", name);
2372
OF_prop_string_set(OF_env, als, name, buffer);
2373
/* For ISA, should add DMA ranges */
2374
OF_node_put(OF_env, bus);
2375
OF_node_put(OF_env, als);
2380
// We will need to register stdin & stdout via the serial port
2381
__attribute__ (( section (".OpenFirmware") ))
2382
int OF_register_serial (const unsigned char *bus, const unsigned char *name,
2383
uint32_t io_base, unused int irq)
2385
unsigned char tmp[OF_NAMELEN_MAX];
2387
OF_node_t *busn, *srl, *als;
2389
OF_env = OF_env_main;
2390
als = OF_node_get(OF_env, "aliases");
2392
ERROR("Cannot get 'aliases'\n");
2395
busn = OF_node_get(OF_env, bus);
2396
srl = OF_node_new(OF_env, busn, name, io_base);
2398
OF_node_put(OF_env, als);
2399
ERROR("Cannot create serial '%s'\n", name);
2402
OF_prop_string_set(OF_env, srl, "device_type", "serial");
2403
OF_prop_string_set(OF_env, srl, "compatible", "pnpPNP,501");
2406
OF_pack_get_path(OF_env, tmp, 512, srl);
2407
OF_prop_string_new(OF_env, als, "com1", tmp);
2410
OF_pack_get_path(OF_env, tmp, 512, srl);
2411
OF_prop_string_new(OF_env, als, "com2", tmp);
2416
/* register read/write methods and create an instance of the package */
2417
OF_method_new(OF_env, srl, "write", &OF_serial_write);
2418
OF_method_new(OF_env, srl, "read", &OF_serial_read);
2419
OF_node_put(OF_env, srl);
2420
OF_node_put(OF_env, busn);
2421
OF_node_put(OF_env, als);
2426
/* We will also need /isa/rtc */
2428
__attribute__ (( section (".OpenFirmware") ))
2429
int OF_register_stdio (const unsigned char *dev_in,
2430
const unsigned char *dev_out)
2433
OF_node_t *chs, *ndev_in, *ndev_out, *kbd;
2434
OF_inst_t *in_inst, *out_inst;
2436
OF_env = OF_env_main;
2437
chs = OF_node_get(OF_env, "chosen");
2439
ERROR("Cannot get 'chosen'\n");
2442
ndev_in = OF_node_get(OF_env, dev_in);
2443
ndev_out = OF_node_get(OF_env, dev_out);
2444
in_inst = OF_instance_new(OF_env, ndev_in);
2445
if (in_inst == NULL) {
2446
OF_node_put(OF_env, ndev_out);
2447
OF_node_put(OF_env, ndev_in);
2448
OF_node_put(OF_env, chs);
2449
ERROR("Cannot create in_inst\n");
2452
out_inst = OF_instance_new(OF_env, ndev_out);
2453
if (out_inst == NULL) {
2454
OF_node_put(OF_env, ndev_out);
2455
OF_node_put(OF_env, ndev_in);
2456
OF_node_put(OF_env, chs);
2457
ERROR("Cannot create out_inst\n");
2460
OF_prop_int_set(OF_env, chs, "stdin",
2461
OF_instance_get_id(OF_env, in_inst));
2462
OF_prop_int_set(OF_env, chs, "stdout",
2463
OF_instance_get_id(OF_env, out_inst));
2464
kbd = OF_node_new(OF_env, ndev_in, "keyboard", OF_ADDRESS_NONE);
2466
OF_node_put(OF_env, ndev_out);
2467
OF_node_put(OF_env, ndev_in);
2468
OF_node_put(OF_env, chs);
2469
ERROR("Cannot create 'keyboard' for stdio\n");
2472
OF_prop_string_new(OF_env, kbd, "device_type", "keyboard");
2473
OF_node_put(OF_env, kbd);
2474
OF_DPRINTF("stdin h: 0x%0x out : 0x%0x\n",
2475
OF_instance_get_id(OF_env, in_inst),
2476
OF_instance_get_id(OF_env, out_inst));
2477
OF_node_put(OF_env, ndev_out);
2478
OF_node_put(OF_env, ndev_in);
2479
OF_node_put(OF_env, chs);
2484
static void keylargo_ata(OF_node_t *mio, uint32_t base_address,
2485
uint32_t base, int irq1, int irq2,
2486
uint16_t pic_phandle)
2488
OF_env_t *OF_env = OF_env_main;
2490
OF_regprop_t regs[2];
2492
ata = OF_node_new(OF_env, mio, "ata-4", base);
2494
ERROR("Cannot create 'ata-4'\n");
2497
OF_prop_string_new(OF_env, ata, "device_type", "ata");
2499
OF_prop_string_new(OF_env, ata, "compatible", "key2largo-ata");
2500
OF_prop_string_new(OF_env, ata, "model", "ata-4");
2501
OF_prop_string_new(OF_env, ata, "cable-type", "80-conductor");
2503
OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata");
2504
OF_prop_string_new(OF_env, ata, "model", "ata-4");
2506
OF_prop_int_new(OF_env, ata, "#address-cells", 1);
2507
OF_prop_int_new(OF_env, ata, "#size-cells", 0);
2508
regs[0].address = base;
2509
regs[0].size = 0x00001000;
2510
#if 0 // HACK: Don't set up DMA registers
2511
regs[1].address = 0x00008A00;
2512
regs[1].size = 0x00001000;
2513
OF_property_new(OF_env, ata, "reg",
2514
regs, 2 * sizeof(OF_regprop_t));
2516
OF_property_new(OF_env, ata, "reg",
2517
regs, sizeof(OF_regprop_t));
2519
OF_prop_int_new(OF_env, ata, "interrupt-parent", pic_phandle);
2520
regs[0].address = irq1;
2521
regs[0].size = 0x00000001;
2522
regs[1].address = irq2;
2523
regs[1].size = 0x00000000;
2524
OF_property_new(OF_env, ata, "interrupts",
2525
regs, 2 * sizeof(OF_regprop_t));
2526
if (base == 0x1f000)
2527
ide_pci_pmac_register(base_address + base, 0x00000000, ata);
2529
ide_pci_pmac_register(0x00000000, base_address + base, ata);
2532
void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
2535
unsigned char tmp[OF_NAMELEN_MAX];
2537
pci_reg_prop_t pregs[2];
2538
OF_node_t *mio, *chs, *als;
2539
uint16_t pic_phandle;
2543
OF_DPRINTF("mac-io: %p\n", dev);
2544
OF_env = OF_env_main;
2545
chs = OF_node_get(OF_env, "chosen");
2547
ERROR("Cannot get 'chosen'\n");
2550
als = OF_node_get(OF_env, "aliases");
2552
OF_node_put(OF_env, als);
2553
ERROR("Cannot get 'aliases'\n");
2556
/* Mac-IO is mandatory for OSX to boot */
2558
mio->private_data = private_data;
2559
pregs[0].addr.hi = 0x00000000;
2560
pregs[0].addr.mid = 0x00000000;
2561
pregs[0].addr.lo = 0x00000000;
2562
pregs[0].size_hi = base_address;
2563
pregs[0].size_lo = size;
2564
mio_reg = OF_property_get(OF_env, mio, "reg");
2565
if (mio_reg && mio_reg->vlen >= 5 * 4) {
2566
pregs[0].addr.mid = ((pci_reg_prop_t *)mio_reg->value)->addr.hi;
2568
OF_property_new(OF_env, mio, "ranges",
2569
&pregs, sizeof(pci_reg_prop_t));
2571
pregs[0].addr.hi = 0x82013810;
2572
pregs[0].addr.mid = 0x00000000;
2573
pregs[0].addr.lo = 0x80800000;
2574
pregs[0].size_hi = 0x00000000;
2575
pregs[0].size_lo = 0x00080000;
2576
OF_property_new(OF_env, mio, "assigned-addresses",
2577
&pregs, sizeof(pci_reg_prop_t));
2580
if (arch == ARCH_HEATHROW) {
2584
const char compat_str[] = "heathrow\0mac-risc";
2586
mpic = OF_node_new(OF_env, mio, "interrupt-controller", 0x10);
2588
ERROR("Cannot create 'mpic'\n");
2591
OF_prop_string_new(OF_env, mpic, "device_type", "interrupt-controller");
2592
OF_property_new(OF_env, mpic, "compatible", compat_str, sizeof(compat_str));
2593
OF_prop_int_new(OF_env, mpic, "#interrupt-cells", 1);
2594
regs.address = 0x10;
2596
OF_property_new(OF_env, mpic, "reg",
2597
®s, sizeof(regs));
2598
OF_property_new(OF_env, mpic, "interrupt-controller", NULL, 0);
2599
pic_phandle = OF_pack_handle(OF_env, mpic);
2600
OF_prop_int_new(OF_env, chs, "interrupt-controller", pic_phandle);
2601
OF_node_put(OF_env, mpic);
2605
OF_regprop_t regs[4];
2607
mpic = OF_node_new(OF_env, mio, "interrupt-controller", 0x40000);
2609
ERROR("Cannot create 'mpic'\n");
2612
OF_prop_string_new(OF_env, mpic, "device_type", "open-pic");
2613
OF_prop_string_new(OF_env, mpic, "compatible", "chrp,open-pic");
2614
OF_property_new(OF_env, mpic, "interrupt-controller", NULL, 0);
2615
OF_property_new(OF_env, mpic, "built-in", NULL, 0);
2616
OF_prop_int_new(OF_env, mpic, "clock-frequency", 0x003F7A00);
2617
OF_prop_int_new(OF_env, mpic, "#address-cells", 0);
2618
OF_prop_int_new(OF_env, mpic, "#interrupt-cells", 2);
2619
memset(regs, 0, 4 * sizeof(OF_regprop_t));
2620
regs[0].address = 0x00040000;
2621
regs[0].size = 0x00040000;
2622
OF_property_new(OF_env, mpic, "reg",
2623
®s, 1 * sizeof(OF_regprop_t));
2624
pic_phandle = OF_pack_handle(OF_env, mpic);
2625
OF_prop_int_new(OF_env, chs, "interrupt-controller", pic_phandle);
2626
OF_node_put(OF_env, mpic);
2630
/* patch pci host table */
2631
/* XXX: do it after the PCI init */
2636
for(i = 0; i < pci_host_interrupt_map_len; i += rec_len)
2637
pci_host_interrupt_map[i + 4] = pic_phandle;
2639
dprintf("interrupt-map:\n");
2640
for(i = 0; i < pci_host_interrupt_map_len; i++) {
2641
dprintf(" %08x", pci_host_interrupt_map[i]);
2642
if ((i % rec_len) == (rec_len - 1))
2647
OF_property_new(OF_env, pci_host_node, "interrupt-map",
2648
pci_host_interrupt_map,
2649
pci_host_interrupt_map_len * sizeof(uint32_t));
2654
OF_property_new(OF_env, pci_host_node, "interrupt-map-mask",
2655
tab, 4 * sizeof(uint32_t));
2658
/* escc is useful to get MacOS X debug messages */
2660
OF_regprop_t regs[8];
2662
OF_node_t *scc, *chann;
2663
scc = OF_node_new(OF_env, mio, "escc", 0x13000);
2665
ERROR("Cannot create 'escc'\n");
2668
OF_prop_string_new(OF_env, scc, "device_type", "escc");
2669
OF_prop_string_new(OF_env, scc, "compatible", "chrp,es0");
2670
OF_property_new(OF_env, scc, "built-in", NULL, 0);
2671
OF_prop_int_new(OF_env, scc, "#address-cells", 1);
2672
memset(regs, 0, 8 * sizeof(OF_regprop_t));
2673
regs[0].address = 0x00013000;
2674
regs[0].size = 0x00001000;
2675
regs[1].address = 0x00008400;
2676
regs[1].size = 0x00000100;
2677
regs[2].address = 0x00008500;
2678
regs[2].size = 0x00000100;
2679
regs[3].address = 0x00008600;
2680
regs[3].size = 0x00000100;
2681
regs[4].address = 0x00008700;
2682
regs[4].size = 0x00000100;
2683
OF_property_new(OF_env, scc, "reg",
2684
regs, 5 * sizeof(OF_regprop_t));
2685
OF_property_new(OF_env, scc, "ranges", NULL, 0);
2686
/* Set up two channels */
2687
chann = OF_node_new(OF_env, scc, "ch-a", 0x13020);
2688
if (chann == NULL) {
2689
ERROR("Cannot create 'ch-a'\n");
2692
OF_prop_string_new(OF_env, chann, "device_type", "serial");
2693
OF_prop_string_new(OF_env, chann, "compatible", "chrp,es2");
2694
OF_property_new(OF_env, chann, "built-in", NULL, 0);
2695
OF_prop_int_new(OF_env, chann, "slot-names", 0);
2696
OF_prop_int_new(OF_env, chann, "interrupt-parent", pic_phandle);
2697
memset(regs, 0, 8 * sizeof(OF_regprop_t));
2698
regs[0].address = 0x00013020;
2699
regs[0].size = 0x00000001;
2700
regs[1].address = 0x00013030;
2701
regs[1].size = 0x00000001;
2702
regs[2].address = 0x00013050;
2703
regs[2].size = 0x00000001;
2704
regs[3].address = 0x00008400;
2705
regs[3].size = 0x00000100;
2706
regs[4].address = 0x00008500;
2707
regs[4].size = 0x00000100;
2708
OF_property_new(OF_env, chann, "reg",
2709
regs, 5 * sizeof(OF_regprop_t));
2710
/* XXX: tofix: those are regprops */
2717
OF_property_new(OF_env, chann, "interrupts",
2718
irqs, 6 * sizeof(uint32_t));
2719
OF_node_put(OF_env, chann);
2720
chann = OF_node_new(OF_env, scc, "ch-b", 0x13000);
2721
if (chann == NULL) {
2722
ERROR("Cannot create 'ch-b'\n");
2725
OF_prop_string_new(OF_env, chann, "device_type", "serial");
2726
OF_prop_string_new(OF_env, chann, "compatible", "chrp,es3");
2727
OF_property_new(OF_env, chann, "built-in", NULL, 0);
2728
OF_prop_int_new(OF_env, chann, "slot-names", 0);
2729
OF_prop_int_new(OF_env, chann, "interrupt-parent", pic_phandle);
2730
memset(regs, 0, 8 * sizeof(OF_regprop_t));
2731
regs[0].address = 0x00013000;
2732
regs[0].size = 0x00000001;
2733
regs[1].address = 0x00013010;
2734
regs[1].size = 0x00000001;
2735
regs[2].address = 0x00013040;
2736
regs[2].size = 0x00000001;
2737
regs[3].address = 0x00008600;
2738
regs[3].size = 0x00000100;
2739
regs[4].address = 0x00008700;
2740
regs[4].size = 0x00000100;
2741
OF_property_new(OF_env, chann, "reg",
2742
regs, 5 * sizeof(OF_regprop_t));
2743
/* XXX: tofix: those are regprops */
2750
OF_property_new(OF_env, chann, "interrupts",
2751
irqs, 6 * sizeof(uint32_t));
2752
OF_node_put(OF_env, chann);
2753
OF_node_put(OF_env, scc);
2754
/* MacOS likes escc-legacy */
2755
scc = OF_node_new(OF_env, mio, "escc-legacy", 0x12000);
2757
ERROR("Cannot create 'escc-legacy'\n");
2760
OF_prop_string_new(OF_env, scc, "device_type", "escc-legacy");
2761
OF_prop_string_new(OF_env, scc, "compatible", "chrp,es1");
2762
OF_property_new(OF_env, scc, "built-in", NULL, 0);
2763
OF_prop_int_new(OF_env, scc, "#address-cells", 1);
2764
memset(regs, 0, 8 * sizeof(OF_regprop_t));
2765
regs[0].address = 0x00012000;
2766
regs[0].size = 0x00001000;
2767
regs[1].address = 0x00008400;
2768
regs[1].size = 0x00000100;
2769
regs[2].address = 0x00008500;
2770
regs[2].size = 0x00000100;
2771
regs[3].address = 0x00008600;
2772
regs[3].size = 0x00000100;
2773
regs[4].address = 0x00008700;
2774
regs[4].size = 0x00000100;
2775
OF_property_new(OF_env, scc, "reg",
2776
regs, 8 * sizeof(OF_regprop_t));
2777
OF_property_new(OF_env, scc, "ranges", NULL, 0);
2778
/* Set up two channels */
2779
chann = OF_node_new(OF_env, scc, "ch-a", 0x12004);
2780
if (chann == NULL) {
2781
ERROR("Cannot create 'ch-a'\n");
2784
OF_prop_string_new(OF_env, chann, "device_type", "serial");
2785
OF_prop_string_new(OF_env, chann, "compatible", "chrp,es4");
2786
OF_property_new(OF_env, chann, "built-in", NULL, 0);
2787
OF_prop_int_new(OF_env, chann, "interrupt-parent", pic_phandle);
2788
memset(regs, 0, 8 * sizeof(OF_regprop_t));
2789
regs[0].address = 0x00012004;
2790
regs[0].size = 0x00000001;
2791
regs[1].address = 0x00012006;
2792
regs[1].size = 0x00000001;
2793
regs[2].address = 0x0001200A;
2794
regs[2].size = 0x00000001;
2795
regs[3].address = 0x00008400;
2796
regs[3].size = 0x00000100;
2797
regs[4].address = 0x00008500;
2798
regs[4].size = 0x00000100;
2799
OF_property_new(OF_env, chann, "reg",
2800
regs, 8 * sizeof(OF_regprop_t));
2801
/* XXX: tofix: those are regprops */
2808
OF_property_new(OF_env, chann, "interrupts",
2809
irqs, 6 * sizeof(uint32_t));
2810
OF_node_put(OF_env, chann);
2811
chann = OF_node_new(OF_env, scc, "ch-b", 0x12000);
2812
if (chann == NULL) {
2813
ERROR("Cannot create 'ch-b'\n");
2816
OF_prop_string_new(OF_env, chann, "device_type", "serial");
2817
OF_prop_string_new(OF_env, chann, "compatible", "chrp,es5");
2818
OF_property_new(OF_env, chann, "built-in", NULL, 0);
2819
OF_prop_int_new(OF_env, chann, "interrupt-parent", pic_phandle);
2820
memset(regs, 0, 8 * sizeof(OF_regprop_t));
2821
regs[0].address = 0x00012000;
2822
regs[0].size = 0x00000001;
2823
regs[1].address = 0x00012002;
2824
regs[1].size = 0x00000001;
2825
regs[2].address = 0x00012008;
2826
regs[2].size = 0x00000001;
2827
regs[3].address = 0x00008600;
2828
regs[3].size = 0x00000100;
2829
regs[4].address = 0x00008700;
2830
regs[4].size = 0x00000100;
2831
OF_property_new(OF_env, chann, "reg",
2832
regs, 8 * sizeof(OF_regprop_t));
2833
/* XXX: tofix: those are regprops */
2840
OF_property_new(OF_env, chann, "interrupts",
2841
irqs, 6 * sizeof(uint32_t));
2842
OF_node_put(OF_env, chann);
2843
OF_node_put(OF_env, scc);
2846
/* Keylargo IDE controller: need some work (DMA problem ?) */
2847
if (arch == ARCH_MAC99) {
2848
keylargo_ata(mio, base_address, 0x1f000, 0x13, 0xb, pic_phandle);
2849
keylargo_ata(mio, base_address, 0x20000, 0x14, 0xb, pic_phandle);
2855
OF_regprop_t regs[1];
2856
tmr = OF_node_new(OF_env, mio, "timer", 0x15000);
2858
ERROR("Cannot create 'timer'\n");
2861
OF_prop_string_new(OF_env, tmr, "device_type", "timer");
2862
OF_prop_string_new(OF_env, tmr, "compatible", "keylargo-timer");
2863
OF_prop_int_new(OF_env, tmr, "clock-frequency", 0x01194000);
2864
regs[0].address = 0x00015000;
2865
regs[0].size = 0x00001000;
2866
OF_property_new(OF_env, tmr, "reg", regs, sizeof(OF_regprop_t));
2867
OF_prop_int_new(OF_env, tmr, "interrupt-parent", pic_phandle);
2868
regs[0].address = 0x00000020;
2869
regs[0].size = 0x00000001;
2870
OF_property_new(OF_env, tmr, "interrupts",
2871
regs, sizeof(OF_regprop_t));
2872
OF_node_put(OF_env, tmr);
2877
/* Controls adb, RTC and power-mgt (forget it !) */
2878
OF_node_t *via, *adb;
2879
OF_regprop_t regs[1];
2880
#if 0 // THIS IS A HACK AND IS COMPLETELY ABSURD !
2881
// (but needed has Qemu doesn't emulate via-pmu).
2882
via = OF_node_new(OF_env, mio, "via-pmu", 0x16000);
2884
ERROR("Cannot create 'via-pmu'\n");
2887
OF_prop_string_new(OF_env, via, "device_type", "via-pmu");
2888
OF_prop_string_new(OF_env, via, "compatible", "pmu");
2890
via = OF_node_new(OF_env, mio, "via-cuda", 0x16000);
2892
ERROR("Cannot create 'via-cuda'\n");
2895
OF_prop_string_new(OF_env, via, "device_type", "via-cuda");
2896
OF_prop_string_new(OF_env, via, "compatible", "cuda");
2898
regs[0].address = 0x00016000;
2899
regs[0].size = 0x00002000;
2900
OF_property_new(OF_env, via, "reg", regs, sizeof(OF_regprop_t));
2901
OF_prop_int_new(OF_env, via, "interrupt-parent", pic_phandle);
2902
if (arch == ARCH_HEATHROW) {
2903
OF_prop_int_new(OF_env, via, "interrupts", 0x12);
2905
regs[0].address = 0x00000019;
2906
regs[0].size = 0x00000001;
2907
OF_property_new(OF_env, via, "interrupts",
2908
regs, sizeof(OF_regprop_t));
2910
/* force usage of OF bus speeds */
2911
OF_prop_int_new(OF_env, via, "BusSpeedCorrect", 1);
2913
OF_prop_int_new(OF_env, via, "pmu-version", 0x00D0740C);
2916
OF_node_t *kbd, *mouse;
2917
/* ADB pseudo-device */
2918
adb = OF_node_new(OF_env, via, "adb", OF_ADDRESS_NONE);
2920
ERROR("Cannot create 'adb'\n");
2923
OF_prop_string_new(OF_env, adb, "device_type", "adb");
2925
OF_prop_string_new(OF_env, adb, "compatible", "pmu-99");
2927
OF_prop_string_new(OF_env, adb, "compatible", "adb");
2929
OF_prop_int_new(OF_env, adb, "#address-cells", 1);
2930
OF_prop_int_new(OF_env, adb, "#size-cells", 0);
2931
OF_pack_get_path(OF_env, tmp, 512, adb);
2932
OF_prop_string_new(OF_env, als, "adb", tmp);
2934
kbd = OF_node_new(OF_env, adb, "keyboard", 2);
2936
ERROR("Cannot create 'kbd'\n");
2939
OF_prop_string_new(OF_env, kbd, "device_type", "keyboard");
2940
OF_prop_int_new(OF_env, kbd, "reg", 2);
2942
mouse = OF_node_new(OF_env, adb, "mouse", 3);
2943
if (mouse == NULL) {
2944
ERROR("Cannot create 'mouse'\n");
2947
OF_prop_string_new(OF_env, mouse, "device_type", "mouse");
2948
OF_prop_int_new(OF_env, mouse, "reg", 3);
2949
OF_prop_int_new(OF_env, mouse, "#buttons", 3);
2954
rtc = OF_node_new(OF_env, via, "rtc", OF_ADDRESS_NONE);
2956
ERROR("Cannot create 'rtc'\n");
2959
OF_prop_string_new(OF_env, rtc, "device_type", "rtc");
2961
OF_prop_string_new(OF_env, rtc, "compatible", "rtc,via-pmu");
2963
OF_prop_string_new(OF_env, rtc, "compatible", "rtc");
2965
OF_node_put(OF_env, rtc);
2967
// OF_node_put(OF_env, via);
2971
pmgt = OF_node_new(OF_env, mio, "power-mgt", OF_ADDRESS_NONE);
2972
OF_prop_string_new(OF_env, pmgt, "device_type", "power-mgt");
2973
OF_prop_string_new(OF_env, pmgt, "compatible", "cuda");
2974
OF_prop_string_new(OF_env, pmgt, "mgt-kind", "min-consumption-pwm-led");
2975
OF_node_put(OF_env, pmgt);
2978
if (arch == ARCH_HEATHROW) {
2982
nvr = OF_node_new(OF_env, mio, "nvram", 0x60000);
2983
OF_prop_string_new(OF_env, nvr, "device_type", "nvram");
2984
regs.address = 0x60000;
2985
regs.size = 0x00020000;
2986
OF_property_new(OF_env, nvr, "reg", ®s, sizeof(regs));
2987
OF_prop_int_new(OF_env, nvr, "#bytes", 0x2000);
2988
OF_node_put(OF_env, nvr);
2992
// OF_node_put(OF_env, mio);
2993
OF_node_put(OF_env, chs);
2994
OF_node_put(OF_env, als);
2997
void OF_finalize_pci_ide (void *dev,
2998
uint32_t io_base0, uint32_t io_base1,
2999
uint32_t io_base2, uint32_t io_base3)
3001
OF_env_t *OF_env = OF_env_main;
3002
OF_node_t *pci_ata = dev;
3003
OF_node_t *ata, *atas[2];
3006
OF_prop_int_new(OF_env, pci_ata, "#address-cells", 1);
3007
OF_prop_int_new(OF_env, pci_ata, "#size-cells", 0);
3009
/* XXX: Darwin handles only one device */
3010
for(i = 0; i < 1; i++) {
3011
ata = OF_node_new(OF_env, pci_ata, "ata-4", i);
3013
ERROR("Cannot create 'ata-4'\n");
3016
OF_prop_string_new(OF_env, ata, "device_type", "ata");
3017
OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata");
3018
OF_prop_string_new(OF_env, ata, "model", "ata-4");
3019
OF_prop_int_new(OF_env, ata, "#address-cells", 1);
3020
OF_prop_int_new(OF_env, ata, "#size-cells", 0);
3021
OF_prop_int_new(OF_env, ata, "reg", i);
3024
ide_pci_pc_register(io_base0, io_base1, io_base2, io_base3,
3028
/*****************************************************************************/
3030
static void OF_method_fake (OF_env_t *OF_env)
3034
ihandle = popd(OF_env);
3035
OF_DPRINTF("ih: %0x %d\n", ihandle, stackd_depth(OF_env));
3036
pushd(OF_env, ihandle);
3039
static void OF_mmu_translate (OF_env_t *OF_env)
3041
const unsigned char *args;
3042
uint32_t address, more;
3045
OF_CHECK_NBARGS(OF_env, 4);
3046
/* As we get a 1:1 mapping, do nothing */
3047
ihandle = popd(OF_env);
3048
args = (void *)popd(OF_env);
3049
address = popd(OF_env);
3050
more = popd(OF_env);
3051
OF_DPRINTF("Translate address %0x %0x %0x\n", ihandle, address, more);
3052
// BAT_setup(3, more, address, 0x10000000, 1, 1, 2);
3053
pushd(OF_env, address);
3054
pushd(OF_env, 0x00000000);
3055
pushd(OF_env, 0x00000000);
3059
static void OF_mmu_map (OF_env_t *OF_env)
3061
const unsigned char *args;
3062
uint32_t address, virt, size;
3065
OF_CHECK_NBARGS(OF_env, 6);
3066
/* As we get a 1:1 mapping, do nothing */
3067
ihandle = popd(OF_env);
3068
args = (void *)popd(OF_env);
3070
size = popd(OF_env);
3071
virt = popd(OF_env);
3072
address = popd(OF_env);
3073
OF_DPRINTF("Map %0x %0x %0x %0x\n", ihandle, address,
3078
/* Serial device package */
3079
static void OF_serial_write (OF_env_t *OF_env)
3081
const unsigned char *args;
3088
OF_CHECK_NBARGS(OF_env, 4);
3089
ihandle = popd(OF_env);
3090
args = (void *)popd(OF_env);
3091
str = (void *)popd(OF_env);
3093
inst = OF_inst_find(OF_env, ihandle);
3096
ERROR("Cannot get serial instance\n");
3100
// OF_DPRINTF("args: %p str: %p\n", args, str);
3101
/* XXX: should use directly the serial port
3102
* and have another console package.
3104
console_write(str, len);
3108
static void OF_serial_read (OF_env_t *OF_env)
3110
const unsigned char *args;
3117
OF_CHECK_NBARGS(OF_env, 4);
3118
ihandle = popd(OF_env);
3119
args = (void *)popd(OF_env);
3120
phandle = (ihandle >> 16) & 0xFFFF;
3121
dest = (void *)popd(OF_env);
3123
ret = -1; /* Don't know why gcc thinks it might be uninitialized... */
3124
for (count = 0; count < 1000; count++) {
3125
ret = console_read(dest, len);
3126
/* Stop if we read something or got an error */
3129
/* Random sleep. Seems allright for serial port */
3135
OF_DPRINTF("send '%s'\n", dest);
3140
typedef struct blockdev_inst_t {
3149
static int OF_split_args (unsigned char *args, unsigned char **argv,
3152
unsigned char *pos, *end;
3157
for (i = 0; i < max_args && *pos != '\0' && end != NULL; i++) {
3158
end = strchr(pos, ',');
3168
static void OF_convert_path (unsigned char **path)
3172
OF_DPRINTF("%s: '%s'\n", __func__, *path);
3173
for (pos = *path; *pos != '\0'; pos++) {
3177
OF_DPRINTF("%s: '%s'\n", __func__, *path);
3180
if (pos[0] == '/' && pos[1] == '/') {
3185
for (; *pos == '/'; pos++)
3189
OF_DPRINTF("%s: '%s'\n", __func__, *path);
3192
/* Block devices package */
3193
static void OF_blockdev_open (OF_env_t *OF_env)
3195
unsigned char tmp[OF_NAMELEN_MAX];
3196
unsigned char *args, *argv[4];
3197
OF_inst_t *dsk_inst;
3200
blockdev_inst_t *bdinst;
3205
OF_CHECK_NBARGS(OF_env, 2);
3206
ihandle = popd(OF_env);
3207
args = (void *)popd(OF_env);
3208
phandle = (ihandle >> 16) & 0xFFFF;
3209
dsk_inst = OF_inst_find(OF_env, ihandle);
3210
if (dsk_inst == NULL) {
3211
ERROR("Disk not found (ih: %0x)\n", ihandle);
3215
dsk = dsk_inst->node;
3216
bd = dsk->private_data;
3217
bdinst = malloc(sizeof(blockdev_inst_t));
3218
if (bdinst == NULL) {
3220
ERROR("Cannot alloc blockdev instance\n");
3223
memset(bdinst, 0, sizeof(blockdev_inst_t));
3224
OF_DPRINTF("called with args '%s'\n", args);
3225
nargs = OF_split_args(args, argv, 4);
3228
partnum = strtol(argv[0], NULL, 10);
3230
OF_DPRINTF("Open partition... %d %d\n", partnum, nargs);
3232
bdinst->u.part = part_get(bd, partnum);
3233
if (bdinst->u.part == NULL) {
3234
OF_DPRINTF("Partition %d not found\n", partnum);
3240
/* TODO: open file */
3242
OF_DPRINTF("Open file... %d %d '%s'\n",
3243
partnum, nargs, argv[1]);
3244
OF_convert_path(&argv[1]);
3245
if (*argv[1] != '/') {
3246
sprintf(tmp, "%s/%s",
3247
fs_get_boot_dirname(part_fs(bdinst->u.part)),
3249
bdinst->u.file = fs_open(part_fs(bdinst->u.part), tmp);
3251
bdinst->u.file = fs_open(part_fs(bdinst->u.part), argv[1]);
3253
if (bdinst->u.file == NULL) {
3257
pushd(OF_env, 0x00000000);
3258
ERROR("File not found '%s'\n", argv[1]);
3264
if (nargs == 0 || partnum == 0) {
3265
OF_DPRINTF("Open disk... %d %d\n", nargs, partnum);
3269
/* TODO: find partition &/| file */
3270
dsk_inst->data = bdinst;
3271
OF_node_put(OF_env, dsk);
3273
pushd(OF_env, ihandle);
3276
static void OF_blockdev_seek (OF_env_t *OF_env)
3278
const unsigned char *args;
3279
OF_inst_t *dsk_inst;
3280
blockdev_inst_t *bdinst;
3281
uint32_t posh, posl, bloc, pos, blocsize, tmp;
3286
OF_CHECK_NBARGS(OF_env, 4);
3287
ihandle = popd(OF_env);
3288
args = (void *)popd(OF_env);
3289
phandle = (ihandle >> 16) & 0xFFFF;
3290
posh = popd(OF_env);
3291
posl = popd(OF_env);
3292
dsk_inst = OF_inst_find(OF_env, ihandle);
3293
if (dsk_inst == NULL) {
3294
ERROR("Disk not found (ih: %0x)\n", ihandle);
3298
bdinst = dsk_inst->data;
3299
switch (bdinst->type) {
3301
blocsize = bd_seclen(bdinst->u.bd);
3302
for (tmp = blocsize, sh = 0; tmp != 1; tmp = tmp / 2)
3304
bloc = ((posh << (32 - sh)) | (posl / blocsize));
3305
pos = posl % blocsize;
3306
OF_DPRINTF("disk: bsize %08x %08x %08x => %08x %08x\n", blocsize,
3307
posh, posl, bloc, pos);
3308
pushd(OF_env, bd_seek(bdinst->u.bd, bloc, pos));
3311
blocsize = part_blocsize(bdinst->u.part);
3312
for (tmp = blocsize, sh = 0; tmp != 1; tmp = tmp / 2)
3314
bloc = ((posh << (32 - sh)) | (posl / blocsize));
3315
pos = posl % blocsize;
3316
OF_DPRINTF("part: bsize %08x %08x %08x => %08x %08x\n", blocsize,
3317
posh, posl, bloc, pos);
3318
pushd(OF_env, part_seek(bdinst->u.part, bloc, pos));
3321
blocsize = part_blocsize(fs_inode_get_part(bdinst->u.file));
3322
for (tmp = blocsize, sh = 0; tmp != 1; tmp = tmp / 2)
3324
bloc = ((posh << (32 - sh)) | (posl / blocsize));
3325
pos = posl % blocsize;
3326
OF_DPRINTF("file: bsize %08x %08x %08x => %08x %08x\n", blocsize,
3327
posh, posl, bloc, pos);
3328
pushd(OF_env, fs_seek(bdinst->u.file, bloc, pos));
3333
static void OF_blockdev_read (OF_env_t *OF_env)
3335
const unsigned char *args;
3336
OF_inst_t *dsk_inst;
3337
blockdev_inst_t *bdinst;
3343
OF_CHECK_NBARGS(OF_env, 4);
3344
ihandle = popd(OF_env);
3345
args = (void *)popd(OF_env);
3346
phandle = (ihandle >> 16) & 0xFFFF;
3347
dest = (void *)popd(OF_env);
3349
dsk_inst = OF_inst_find(OF_env, ihandle);
3350
if (dsk_inst == NULL) {
3351
ERROR("Disk not found (ih: %0x)\n", ihandle);
3355
bdinst = dsk_inst->data;
3357
OF_DPRINTF("dest: %p len: %d %d\n", dest, len, bdinst->type);
3358
switch (bdinst->type) {
3360
OF_DPRINTF("read disk\n");
3361
pushd(OF_env, bd_read(bdinst->u.bd, dest, len));
3364
OF_DPRINTF("read partition\n");
3365
pushd(OF_env, part_read(bdinst->u.part, dest, len));
3368
OF_DPRINTF("read file\n");
3369
pushd(OF_env, fs_read(bdinst->u.file, dest, len));
3372
OF_DPRINTF("%08x %08x %08x %08x\n",
3373
((uint32_t *)dest)[0], ((uint32_t *)dest)[1],
3374
((uint32_t *)dest)[2], ((uint32_t *)dest)[3]);
3375
OF_DPRINTF("%08x %08x %08x %08x\n",
3376
((uint32_t *)dest)[4], ((uint32_t *)dest)[5],
3377
((uint32_t *)dest)[6], ((uint32_t *)dest)[7]);
3382
static void OF_blockdev_get_blocsize (OF_env_t *OF_env)
3384
const unsigned char *args;
3385
OF_inst_t *dsk_inst;
3386
blockdev_inst_t *bdinst;
3391
OF_CHECK_NBARGS(OF_env, 2);
3392
ihandle = popd(OF_env);
3393
args = (void *)popd(OF_env);
3394
phandle = (ihandle >> 16) & 0xFFFF;
3395
dsk_inst = OF_inst_find(OF_env, ihandle);
3396
if (dsk_inst == NULL) {
3397
ERROR("Disk not found (ih: %0x)\n", ihandle);
3401
bdinst = dsk_inst->data;
3403
switch (bdinst->type) {
3405
blocsize = bd_seclen(bdinst->u.bd);
3408
blocsize = part_blocsize(bdinst->u.part);
3417
pushd(OF_env, blocsize);
3421
static void OF_blockdev_dma_alloc (OF_env_t *OF_env)
3423
const unsigned char *args;
3428
OF_CHECK_NBARGS(OF_env, 3);
3429
ihandle = popd(OF_env);
3430
args = (void *)popd(OF_env);
3431
size = popd(OF_env);
3432
OF_DPRINTF("size: %08x\n", size);
3434
address = malloc(size);
3435
if (address != NULL)
3436
memset(address, 0, size);
3437
pushd(OF_env, (uint32_t)address);
3441
static void OF_blockdev_dma_free (OF_env_t *OF_env)
3443
const unsigned char *args;
3448
OF_CHECK_NBARGS(OF_env, 4);
3449
ihandle = popd(OF_env);
3450
args = (void *)popd(OF_env);
3451
size = popd(OF_env);
3452
address = (void *)popd(OF_env);
3453
OF_DPRINTF("address: %p size: %08x\n", address, size);
3458
void *OF_blockdev_register (void *parent, void *private,
3459
const unsigned char *type,
3460
const unsigned char *name, int devnum,
3463
unsigned char tmp[OF_NAMELEN_MAX], path[OF_NAMELEN_MAX], *pos;
3465
OF_node_t *dsk, *als;
3468
OF_env = OF_env_main;
3469
dsk = OF_node_new(OF_env, parent, name, devnum);
3471
ERROR("Cannot create blockdev '%s'\n", name);
3474
OF_prop_string_new(OF_env, dsk, "device_type", "block");
3475
OF_prop_string_new(OF_env, dsk, "category", type);
3476
OF_prop_int_new(OF_env, dsk, "device_id", devnum);
3477
OF_prop_int_new(OF_env, dsk, "reg", devnum);
3478
OF_method_new(OF_env, dsk, "open", &OF_blockdev_open);
3479
OF_method_new(OF_env, dsk, "seek", &OF_blockdev_seek);
3480
OF_method_new(OF_env, dsk, "read", &OF_blockdev_read);
3481
OF_method_new(OF_env, dsk, "block-size",
3482
&OF_blockdev_get_blocsize);
3483
OF_method_new(OF_env, dsk, "dma-alloc", &OF_blockdev_dma_alloc);
3484
OF_method_new(OF_env, dsk, "dma-free", &OF_blockdev_dma_free);
3485
if (strcmp(type, "cdrom") == 0)
3486
OF_method_new(OF_env, dsk, "eject", &OF_method_fake);
3487
OF_method_new(OF_env, dsk, "close", &OF_method_fake);
3488
dsk->private_data = private;
3489
/* Set up aliases */
3490
OF_pack_get_path(OF_env, path, OF_NAMELEN_MAX, dsk);
3491
if (alias != NULL) {
3492
als = OF_node_get(OF_env, "aliases");
3494
ERROR("Cannot get 'aliases'\n");
3498
if (OF_property_copy(OF_env, NULL, 0, als, tmp) >= 0) {
3499
pos = tmp + strlen(alias);
3500
for (i = 0; ; i++) {
3501
sprintf(pos, "%d", i);
3502
if (OF_property_copy(OF_env, NULL, 0, als, tmp) < 0)
3506
OF_DPRINTF("Set alias to %s\n", tmp);
3507
OF_prop_string_new(OF_env, dsk, "alias", tmp);
3508
OF_prop_string_new(OF_env, als, tmp, path);
3509
OF_node_put(OF_env, als);
3515
void OF_blockdev_set_boot_device (void *disk, int partnum,
3516
const unsigned char *file)
3518
unsigned char tmp[OF_NAMELEN_MAX], *pos;
3520
OF_node_t *dsk = disk, *opts, *chs;
3522
OF_env = OF_env_main;
3524
if (OF_property_copy(OF_env, tmp, OF_NAMELEN_MAX, dsk, "alias") < 0)
3525
OF_pack_get_path(OF_env, tmp, OF_NAMELEN_MAX, dsk);
3526
sprintf(tmp + strlen(tmp), ":%d", partnum);
3527
/* OpenDarwin 6.02 seems to need this one */
3528
opts = OF_node_get(OF_env, "options");
3530
ERROR("Cannot get 'options'\n");
3533
OF_prop_string_set(OF_env, OF_node_root, "boot-device", tmp);
3534
OF_prop_string_set(OF_env, opts, "boot-device", tmp);
3535
OF_DPRINTF("Set boot device to: '%s'\n", tmp);
3536
OF_node_put(OF_env, opts);
3537
/* Set the real boot path */
3538
pos = tmp + strlen(tmp);
3539
sprintf(pos, ",%s", file);
3540
/* Convert all '/' into '\' in the boot file name */
3541
for (; *pos != '\0'; pos++) {
3545
chs = OF_node_get(OF_env, "chosen");
3547
ERROR("Cannot get 'chosen'\n");
3550
OF_prop_string_set(OF_env, chs, "bootpath", tmp);
3551
OF_DPRINTF("Set boot path to: '%s'\n", tmp);
3552
OF_node_put(OF_env, chs);
3555
/* Display package */
3556
static void OF_vga_draw_rectangle (OF_env_t *OF_env)
3559
const unsigned char *args;
3560
uint32_t posx, posy, width, height;
3563
OF_CHECK_NBARGS(OF_env, 7);
3564
ihandle = popd(OF_env);
3565
args = (void *)popd(OF_env);
3566
height = popd(OF_env);
3567
width = popd(OF_env);
3568
posy = popd(OF_env);
3569
posx = popd(OF_env);
3570
buf = (const void *)popd(OF_env);
3571
OF_DPRINTF("x=%d y=%d h=%d ", posx, posy, width);
3572
OF_DPRINTF("w=%d buf=%p\n", height, buf);
3574
vga_draw_buf(buf, width * vga_fb_bpp, posx, posy, width, height);
3579
static void OF_vga_fill_rectangle (OF_env_t *OF_env)
3581
const unsigned char *args;
3582
uint32_t color, posx, posy, width, height;
3585
OF_CHECK_NBARGS(OF_env, 7);
3586
ihandle = popd(OF_env);
3587
args = (void *)popd(OF_env);
3588
height = popd(OF_env);
3589
width = popd(OF_env);
3590
posy = popd(OF_env);
3591
posx = popd(OF_env);
3592
color = popd(OF_env);
3593
OF_DPRINTF("x=%d y=%d\n", posx, posy);
3594
OF_DPRINTF("h=%d w=%d c=%0x\n", width, height, color);
3595
vga_fill_rect(posx, posy, width, height, color);
3599
static void OF_vga_set_width (OF_env_t *OF_env, OF_prop_t *prop,
3600
const void *data, int len)
3602
uint32_t width, height, depth;
3604
if (len == sizeof(uint32_t)) {
3605
width = *(uint32_t *)data;
3606
OF_property_copy(OF_env, &height, 4, prop->node, "height");
3607
OF_property_copy(OF_env, &depth, 4, prop->node, "depth");
3608
vga_set_mode(width, height, depth);
3612
static void OF_vga_set_height (OF_env_t *OF_env, OF_prop_t *prop,
3613
const void *data, int len)
3615
uint32_t width, height, depth;
3617
if (len == sizeof(uint32_t)) {
3618
OF_property_copy(OF_env, &width, 4, prop->node, "width");
3619
height = *(uint32_t *)data;
3620
OF_property_copy(OF_env, &depth, 4, prop->node, "depth");
3621
vga_set_mode(width, height, depth);
3625
static void OF_vga_set_depth (OF_env_t *OF_env, OF_prop_t *prop,
3626
const void *data, int len)
3628
uint32_t width, height, depth;
3630
if (len == sizeof(uint32_t)) {
3631
OF_property_copy(OF_env, &width, 4, prop->node, "width");
3632
OF_property_copy(OF_env, &height, 4, prop->node, "height");
3633
depth = *(uint32_t *)data;
3634
vga_set_mode(width, height, depth);
3638
void OF_vga_register (const unsigned char *name, unused uint32_t address,
3639
int width, int height, int depth,
3640
unsigned long vga_bios_addr, unsigned long vga_bios_size)
3643
unsigned char tmp[OF_NAMELEN_MAX];
3644
OF_node_t *disp, *chs, *als;
3647
OF_DPRINTF("Set frame buffer %08x %dx%dx%d\n",
3648
address, width, height, depth);
3649
OF_env = OF_env_main;
3650
disp = OF_node_get(OF_env, name);
3652
ERROR("Cannot get display '%s'\n", name);
3655
prop = OF_prop_int_new(OF_env, disp, "width", width);
3657
OF_node_put(OF_env, disp);
3658
ERROR("Cannot create display width property\n");
3661
OF_property_set_cb(OF_env, prop, &OF_vga_set_width);
3662
prop = OF_prop_int_new(OF_env, disp, "height", height);
3664
OF_node_put(OF_env, disp);
3665
ERROR("Cannot create display height property\n");
3668
OF_property_set_cb(OF_env, prop, &OF_vga_set_height);
3678
/* OF spec this is mandatory, but we have no support for it */
3679
printf("%d bits VGA isn't implemented\n", depth);
3681
/* Never come here */
3684
prop = OF_prop_int_new(OF_env, disp, "depth", depth);
3686
ERROR("Cannot create display depth\n");
3689
OF_property_set_cb(OF_env, prop, &OF_vga_set_depth);
3690
OF_prop_int_new(OF_env, disp, "linebytes", vga_fb_linesize);
3691
OF_method_new(OF_env, disp, "draw-rectangle", &OF_vga_draw_rectangle);
3692
OF_method_new(OF_env, disp, "fill-rectangle", &OF_vga_fill_rectangle);
3693
OF_method_new(OF_env, disp, "color!", &OF_method_fake);
3694
chs = OF_node_get(OF_env, "chosen");
3696
ERROR("Cannot get 'chosen'\n");
3699
OF_prop_int_new(OF_env, chs, "display", OF_pack_handle(OF_env, disp));
3700
OF_node_put(OF_env, chs);
3701
OF_pack_get_path(OF_env, tmp, 512, disp);
3702
printf("Set display '%s' path to '%s'\n", name, tmp);
3703
als = OF_node_get(OF_env, "aliases");
3705
ERROR("Cannot get 'aliases'\n");
3708
OF_prop_string_new(OF_env, als, "screen", tmp);
3709
OF_prop_string_new(OF_env, als, "display", tmp);
3710
OF_node_put(OF_env, als);
3711
/* XXX: may also need read-rectangle */
3713
if (vga_bios_size >= 8) {
3716
/* check the QEMU VGA BIOS header */
3717
p = (const uint8_t *)vga_bios_addr;
3718
if (p[0] == 'N' && p[1] == 'D' && p[2] == 'R' && p[3] == 'V') {
3719
size = *(uint32_t *)(p + 4);
3720
OF_property_new(OF_env, disp, "driver,AAPL,MacOS,PowerPC",
3725
OF_node_put(OF_env, disp);
3728
/* Pseudo packages to make BootX happy */
3729
/* sl_words package */
3730
static void slw_set_output_level (OF_env_t *OF_env)
3733
const unsigned char *args;
3736
OF_CHECK_NBARGS(OF_env, 3);
3738
args = (void *)popd(OF_env);
3739
level = popd(OF_env);
3740
slw = OF_node_get(OF_env, "sl_words");
3744
OF_DPRINTF("Set output level to: %d\n", level);
3745
OF_prop_int_set(OF_env, slw, "outputLevel", level);
3746
OF_node_put(OF_env, slw);
3752
#define EMIT_BUFFER_LEN 256
3753
static unsigned char emit_buffer[EMIT_BUFFER_LEN];
3754
static int emit_pos = 0;
3757
static void slw_emit (OF_env_t *OF_env)
3759
const unsigned char *args;
3762
OF_CHECK_NBARGS(OF_env, 3);
3764
args = (void *)popd(OF_env);
3766
// OF_DPRINTF("Emit char %d\n", c);
3768
if (emit_pos < EMIT_BUFFER_LEN - 1) {
3769
emit_buffer[emit_pos++] = c;
3773
emit_buffer[emit_pos] = '\0';
3781
static void slw_cr (OF_env_t *OF_env)
3783
const unsigned char *args;
3785
OF_CHECK_NBARGS(OF_env, 2);
3787
args = (void *)popd(OF_env);
3788
// OF_DPRINTF("Emit CR char\n");
3789
// outb(0xFF01, '\n');
3792
emit_buffer[emit_pos] = '\0';
3793
if (strcmp(emit_buffer, "Call Kernel!") == 0) {
3794
/* Set qemu in debug mode:
3795
* log in_asm,op,int,ioport,cpu
3797
uint16_t loglevel = 0x02 | 0x10 | 0x80;
3798
// outw(0xFF02, loglevel);
3799
outb(0x0F02, loglevel);
3806
static void slw_init_keymap (OF_env_t *OF_env)
3808
const unsigned char *args;
3811
uint32_t phandle, ihandle;
3813
OF_CHECK_NBARGS(OF_env, 3);
3814
ihandle = popd(OF_env);
3815
args = (void *)popd(OF_env);
3816
phandle = ihandle >> 16;
3819
node = OF_pack_find(OF_env, phandle);
3821
ERROR("Cant' init slw keymap\n");
3824
prop = OF_property_get(OF_env, node, "keyMap");
3828
pushd(OF_env, (uint32_t)prop->value);
3834
static void slw_update_keymap (OF_env_t *OF_env)
3836
const unsigned char *args;
3838
OF_CHECK_NBARGS(OF_env, 2);
3840
args = (void *)popd(OF_env);
3845
static void slw_spin (OF_env_t *OF_env)
3847
const unsigned char *args;
3848
/* XXX: cur_spin should be in sl_words package */
3849
static int cur_spin = 0;
3852
OF_CHECK_NBARGS(OF_env, 2);
3854
args = (void *)popd(OF_env);
3855
if (cur_spin > 15) {
3856
c = RGB(0x30, 0x30, 0x50);
3858
c = RGB(0x11, 0x11, 0x11);
3860
c = vga_get_color(c);
3861
vga_fill_rect((cur_spin % 15) * 5 + 280, 420, 4, 3, c);
3862
cur_spin = (cur_spin + 1) & 31;
3867
static void slw_spin_init (OF_env_t *OF_env)
3869
const unsigned char *args;
3871
OF_CHECK_NBARGS(OF_env, 8);
3873
args = (void *)popd(OF_env);
3883
static void slw_pwd (OF_env_t *OF_env)
3885
const unsigned char *args;
3887
OF_CHECK_NBARGS(OF_env, 3);
3889
args = (void *)popd(OF_env);
3894
static void slw_sum (OF_env_t *OF_env)
3896
const unsigned char *args;
3898
OF_CHECK_NBARGS(OF_env, 3);
3900
args = (void *)popd(OF_env);
3905
/*****************************************************************************/
3906
/* Client program interface */
3907
/* Client interface services */
3908
static void OF_test (OF_env_t *OF_env);
3910
/* Device tree services */
3911
/* Get next package */
3912
__attribute__ (( section (".OpenFirmware") ))
3913
static void OF_peer (OF_env_t *OF_env)
3918
OF_CHECK_NBARGS(OF_env, 1);
3919
phandle = popd(OF_env);
3920
OF_DPRINTF("phandle 0x%0x\n", phandle);
3922
node = OF_node_root;
3924
node = OF_pack_next(OF_env, phandle);
3928
pushd(OF_env, OF_pack_handle(OF_env, node));
3931
/* Get first child package */
3932
__attribute__ (( section (".OpenFirmware") ))
3933
static void OF_child (OF_env_t *OF_env)
3938
OF_CHECK_NBARGS(OF_env, 1);
3939
phandle = popd(OF_env);
3940
OF_DPRINTF("phandle 0x%0x\n", phandle);
3941
node = OF_pack_child(OF_env, phandle);
3945
pushd(OF_env, OF_pack_handle(OF_env, node));
3948
/* Get parent package */
3949
__attribute__ (( section (".OpenFirmware") ))
3950
static void OF_parent (OF_env_t *OF_env)
3955
OF_CHECK_NBARGS(OF_env, 1);
3956
phandle = popd(OF_env);
3957
OF_DPRINTF("phandle 0x%0x\n", phandle);
3958
node = OF_pack_parent(OF_env, phandle);
3962
pushd(OF_env, OF_pack_handle(OF_env, node));
3965
/* Get package related to an instance */
3966
__attribute__ (( section (".OpenFirmware") ))
3967
static void OF_instance_to_package (OF_env_t *OF_env)
3971
OF_CHECK_NBARGS(OF_env, 1);
3972
ihandle = popd(OF_env);
3973
OF_DPRINTF("ihandle 0x%0x\n", ihandle);
3974
pushd(OF_env, (ihandle >> 16) & 0xFFFF);
3977
/* Get property len */
3978
__attribute__ (( section (".OpenFirmware") ))
3979
static void OF_getproplen (OF_env_t *OF_env)
3981
unsigned char name[OF_NAMELEN_MAX], *namep;
3985
OF_CHECK_NBARGS(OF_env, 2);
3986
phandle = popd(OF_env);
3987
namep = (unsigned char *)popd(OF_env);
3988
OF_lds(name, namep);
3989
OF_DPRINTF("phandle 0x%0x prop [%s]\n", phandle, name);
3990
node = OF_pack_find(OF_env, phandle);
3994
pushd(OF_env, OF_property_len(OF_env, node, name));
3998
__attribute__ (( section (".OpenFirmware") ))
3999
static void OF_getprop (OF_env_t *OF_env)
4001
unsigned char name[OF_NAMELEN_MAX], *namep;
4007
// OF_CHECK_NBARGS(OF_env, 4);
4008
nb_args = stackd_depth(OF_env);
4009
phandle = popd(OF_env);
4010
namep = (unsigned char *)popd(OF_env);
4011
OF_lds(name, namep);
4012
buffer = (void *)popd(OF_env);
4014
/* This hack is needed to boot MacOS X panther (10.3) */
4019
OF_DPRINTF("phandle 0x%0x prop [%s]\n", phandle, name);
4020
OF_DPRINTF("buffer %p len %d\n", buffer, len);
4021
node = OF_pack_find(OF_env, phandle);
4025
len = OF_property_copy(OF_env, buffer, len, node, name);
4027
OF_DPRINTF("Copied %d bytes\n", len);
4033
/* Check existence of next property */
4034
__attribute__ (( section (".OpenFirmware") ))
4035
static void OF_nextprop (OF_env_t *OF_env)
4037
unsigned char name[OF_NAMELEN_MAX], *namep;
4040
unsigned char *next_name;
4043
OF_CHECK_NBARGS(OF_env, 3);
4044
phandle = popd(OF_env);
4045
namep = (unsigned char *)popd(OF_env);
4046
OF_lds(name, namep);
4047
OF_DPRINTF("phandle 0x%0x prop [%s]\n", phandle, name);
4048
next_name = (unsigned char *)popd(OF_env);
4049
node = OF_pack_find(OF_env, phandle);
4053
next = OF_property_next(OF_env, node, name);
4054
if (next == NULL || next->name == NULL) {
4055
OF_DPRINTF("No next property found [%s]\n", name);
4058
OF_DPRINTF("Return property name [%s]\n", next->name);
4059
OF_sts(next_name, (void *)(next->name));
4060
OF_DUMP_STRING(OF_env, next_name);
4061
pushd(OF_env, strlen(next->name) + 1);
4066
/* Set a property */
4067
__attribute__ (( section (".OpenFirmware") ))
4068
static void OF_setprop (OF_env_t *OF_env)
4070
unsigned char name[OF_NAMELEN_MAX], *namep;
4071
unsigned char *value, *buffer;
4078
OF_CHECK_NBARGS(OF_env, 4);
4079
phandle = popd(OF_env);
4080
namep = (unsigned char *)popd(OF_env);
4081
OF_lds(name, namep);
4082
OF_DPRINTF("phandle 0x%0x prop [%s]\n", phandle, name);
4083
buffer = (unsigned char *)popd(OF_env);
4085
node = OF_pack_find(OF_env, phandle);
4088
ERROR("Cannot get pack %04x\n", phandle);
4091
value = malloc(len);
4092
if (value == NULL && len != 0) {
4094
ERROR("%s: Cannot alloc property '%s' (%d)\n", __func__, name, len);
4097
for (i = 0; i < len; i++)
4098
value[i] = buffer[i];
4099
prop = OF_property_set(OF_env, node, name, value, len);
4107
/* Find a device given its path */
4108
__attribute__ (( section (".OpenFirmware") ))
4109
static OF_node_t *OF_get_alias (OF_env_t *OF_env, const unsigned char *name)
4111
unsigned char tmp[OF_NAMELEN_MAX], *pos, *st;
4112
const unsigned char *alias, *npos;
4113
OF_node_t *als, *node;
4118
for (st = tmp; *st == '/'; st++)
4120
pos = strchr(st, '/');
4122
pos = strchr(st, ':');
4126
npos = name + (pos - tmp);
4130
OF_DPRINTF("Look for alias for '%s' => '%s' '%s'\n", name, tmp, npos);
4131
als = OF_pack_find_by_name(OF_env, OF_node_root, "/aliases");
4133
ERROR("Cannot get 'aliases'\n");
4136
prop = OF_property_get(OF_env, als, tmp);
4138
OF_DPRINTF("No %s alias !\n", tmp);
4141
alias = prop->value;
4142
OF_DPRINTF("Found alias '%s' '%s'\n", alias, npos);
4143
sprintf(tmp, "%s%s", alias, npos);
4144
node = OF_pack_find_by_name(OF_env, OF_node_root, tmp);
4146
printf("%s alias is a broken link !\n", name);
4149
OF_node_put(OF_env, node);
4151
OF_node_put(OF_env, als);
4156
__attribute__ (( section (".OpenFirmware") ))
4157
static void OF_finddevice (OF_env_t *OF_env)
4159
unsigned char name[OF_NAMELEN_MAX], *namep;
4163
OF_CHECK_NBARGS(OF_env, 1);
4164
namep = (unsigned char *)popd(OF_env);
4165
OF_lds(name, namep);
4166
OF_DPRINTF("name %p [%s]\n", namep, name);
4167
/* Search first in "/aliases" */
4168
node = OF_get_alias(OF_env, name);
4170
node = OF_pack_find_by_name(OF_env, OF_node_root, name);
4175
ret = OF_pack_handle(OF_env, node);
4176
OF_DPRINTF("ret 0x%0x\n", ret);
4180
/* "instance-to-path */
4181
__attribute__ (( section (".OpenFirmware") ))
4182
static void OF_instance_to_path (OF_env_t *OF_env)
4189
OF_CHECK_NBARGS(OF_env, 3);
4191
ihandle = popd(OF_env);
4192
buffer = (void *)popd(OF_env);
4194
OF_DPRINTF("ihandle: 0x%0x len=%d\n", ihandle, len);
4195
inst = OF_inst_find(OF_env, ihandle);
4199
len = OF_inst_get_path(OF_env, buffer, len, inst) + 1;
4200
OF_DUMP_STRING(OF_env, buffer);
4204
/* "package-to-path" */
4205
__attribute__ (( section (".OpenFirmware") ))
4206
static void OF_package_to_path (OF_env_t *OF_env)
4213
OF_CHECK_NBARGS(OF_env, 3);
4215
phandle = popd(OF_env);
4216
buffer = (void *)popd(OF_env);
4218
node = OF_pack_find(OF_env, phandle);
4222
len = OF_pack_get_path(OF_env, buffer, len, node) + 1;
4223
OF_DUMP_STRING(OF_env, buffer);
4227
/* Call a package's method */
4228
__attribute__ (( section (".OpenFirmware") ))
4229
static void _OF_callmethod (OF_env_t *OF_env, const unsigned char *name,
4230
uint32_t ihandle, const unsigned char *argp)
4234
OF_method_t *method;
4237
inst = OF_inst_find(OF_env, ihandle);
4238
OF_DPRINTF("Attempt to call method [%s] of package instance 0x%0x\n",
4241
OF_DPRINTF("No instance %0x\n", ihandle);
4246
method = OF_method_get(OF_env, node, name);
4247
if (method != NULL) {
4250
if (strcmp(name, "open") == 0) {
4251
cb = &OF_method_fake;
4253
printf("Method '%s' not found in '%s'\n",
4254
name, node->prop_name->value);
4261
OF_DPRINTF("Push instance method %p (%p)...\n", &method->func,
4266
pushd(OF_env, (uint32_t)argp);
4268
pushd(OF_env, 0x00000000);
4269
pushd(OF_env, ihandle);
4272
__attribute__ (( section (".OpenFirmware") ))
4273
static unsigned char *OF_get_args (unused OF_env_t *env, unsigned char *name)
4277
sd = strchr(name, ':');
4285
__attribute__ (( section (".OpenFirmware") ))
4286
static void OF_callmethod (OF_env_t *OF_env)
4288
const unsigned char *args;
4289
unsigned char name[OF_NAMELEN_MAX], *namep;
4292
OF_DPRINTF("\n\n\n#### CALL METHOD ####\n\n");
4293
namep = (unsigned char *)popd(OF_env);
4294
OF_lds(name, namep);
4295
args = OF_get_args(OF_env, name);
4296
ihandle = popd(OF_env);
4297
_OF_callmethod(OF_env, name, ihandle, args);
4300
/* Device IO services */
4301
/* Create a new instance of a device's package */
4302
__attribute__ (( section (".OpenFirmware") ))
4303
static void OF_open (OF_env_t *OF_env)
4305
const unsigned char *args;
4306
unsigned char name[OF_NAMELEN_MAX], *namep;
4311
OF_CHECK_NBARGS(OF_env, 1);
4312
namep = (unsigned char *)popd(OF_env);
4313
OF_lds(name, namep);
4314
OF_DPRINTF("package [%s]\n", name);
4315
args = OF_get_args(OF_env, name);
4316
node = OF_get_alias(OF_env, name);
4318
node = OF_pack_find_by_name(OF_env, OF_node_root, name);
4321
OF_DPRINTF("package not found !\n");
4325
inst = OF_instance_new(OF_env, node);
4328
ERROR("Cannot create package instance\n");
4331
ihandle = OF_instance_get_id(OF_env, inst);
4332
/* If an "open" method exists in the package, call it */
4333
OF_DPRINTF("package [%s] => %0x\n", name, ihandle);
4334
OF_node_put(OF_env, node);
4335
_OF_callmethod(OF_env, "open", ihandle, args);
4338
/* De-instanciate a package */
4339
__attribute__ (( section (".OpenFirmware") ))
4340
static void OF_close (OF_env_t *OF_env)
4344
OF_CHECK_NBARGS(OF_env, 1);
4345
ihandle = popd(OF_env);
4346
/* If an "close" method exists in the package, call it */
4347
_OF_callmethod(OF_env, "close", ihandle, NULL);
4348
/* XXX: Should free the instance */
4352
__attribute__ (( section (".OpenFirmware") ))
4353
static void OF_read (OF_env_t *OF_env)
4357
OF_CHECK_NBARGS(OF_env, 3);
4358
ihandle = popd(OF_env);
4359
OF_DPRINTF("ih: %0x\n", ihandle);
4360
/* If a "read" method exists in the package, call it */
4361
_OF_callmethod(OF_env, "read", ihandle, NULL);
4364
/* Try call the "read" method of a device's package */
4366
__attribute__ (( section (".OpenFirmware") ))
4367
static void OF_write (OF_env_t *OF_env)
4371
OF_CHECK_NBARGS(OF_env, 3);
4372
ihandle = popd(OF_env);
4373
// OF_DPRINTF("ih: %0x\n", ihandle);
4374
/* If a "write" method exists in the package, call it */
4375
_OF_callmethod(OF_env, "write", ihandle, NULL);
4379
__attribute__ (( section (".OpenFirmware") ))
4380
static void OF_seek (OF_env_t *OF_env)
4384
OF_CHECK_NBARGS(OF_env, 3);
4385
ihandle = popd(OF_env);
4386
OF_DPRINTF("ih: %0x\n", ihandle);
4387
/* If a "seek" method exists in the package, call it */
4388
_OF_callmethod(OF_env, "seek", ihandle, NULL);
4391
/* Memory services */
4392
/* Claim some memory space */
4393
__attribute__ (( section (".OpenFirmware") ))
4394
uint32_t OF_claim_virt (uint32_t virt, uint32_t size, int *range)
4398
OF_DPRINTF("Claim %d bytes at 0x%0x\n", size, virt);
4399
/* First check that the requested memory stands in the physical memory */
4400
if (OF_mem_ranges[0].start > virt ||
4401
(OF_mem_ranges[0].start + OF_mem_ranges[0].size) < (virt + size)) {
4402
ERROR("not in memory: start 0x%0x virt 0x%0x end 0x%0x 0x%0x\n",
4403
OF_mem_ranges[0].start, virt,
4404
OF_mem_ranges[0].start + OF_mem_ranges[0].size,
4406
return (uint32_t)(-1);
4408
/* Now check that it doesn't overlap with already claimed areas */
4409
for (i = 1; i < OF_MAX_MEMRANGES + 1; i++) {
4410
if (OF_mem_ranges[i].start == (uint32_t)(-1) ||
4411
OF_mem_ranges[i].size == (uint32_t)(-1)) {
4416
if (OF_mem_ranges[i].start == virt &&
4417
(OF_mem_ranges[i].start + OF_mem_ranges[i].size) == (virt + size)) {
4420
if (!((OF_mem_ranges[i].start >= (virt + size) ||
4421
(OF_mem_ranges[i].start + OF_mem_ranges[i].size) <= virt))) {
4422
ERROR("overlap: start 0x%0x virt 0x%0x end 0x%0x 0x%0x\n",
4423
OF_mem_ranges[i].start, virt,
4424
OF_mem_ranges[i].start + OF_mem_ranges[i].size,
4427
return (uint32_t)(-1);
4430
OF_DPRINTF("return range: %d\n", keep);
4433
ERROR("No more rooms\n");
4434
return (uint32_t)(-1);
4436
ERROR("Give range: start 0x%0x 0x%0x\n", virt, size);
4444
/* We always try to get the upper address we can */
4445
__attribute__ (( section (".OpenFirmware") ))
4446
static uint32_t OF_claim_size (uint32_t size, int align, int *range)
4448
uint32_t addr, max = (uint32_t)(-1);
4451
OF_DPRINTF("Try map %d bytes at 0x00000000\n", size);
4452
if (OF_claim_virt(0, size, range) != (uint32_t)(-1))
4454
for (i = 1; i < OF_MAX_MEMRANGES + 1; i++) {
4455
if (OF_mem_ranges[i].start == (uint32_t)(-1) ||
4456
OF_mem_ranges[i].size == (uint32_t)(-1))
4458
addr = (OF_mem_ranges[i].start + OF_mem_ranges[i].size + align - 1) &
4460
OF_DPRINTF("Try map %d bytes at 0x%0x\n", size, addr);
4461
if ((addr + 1) > (max + 1)) {
4462
if (OF_claim_virt(addr, size, range) != (uint32_t)(-1))
4470
__attribute__ (( section (".OpenFirmware") ))
4471
static void OF_claim (OF_env_t *OF_env)
4473
uint32_t virt, size, addr;
4477
OF_CHECK_NBARGS(OF_env, 3);
4478
virt = popd(OF_env);
4479
size = popd(OF_env);
4480
align = popd(OF_env);
4481
DPRINTF("virt 0x%0x size 0x%0x align %d\n", virt, size, align);
4483
addr = OF_claim_virt(virt, size, &range);
4485
for (i = 1; i < align; i = i << 1)
4488
size = (size + align - 1) & ~(align - 1);
4489
addr = OF_claim_size(size, align, &range);
4491
if (addr == (uint32_t)-1) {
4492
ERROR("No range match !\n");
4496
OF_mem_ranges[range].start = addr;
4497
OF_mem_ranges[range].size = size;
4499
OF_DPRINTF("Give address 0x%0x\n", addr);
4500
pushd(OF_env, addr);
4503
/* release some previously claimed memory */
4504
__attribute__ (( section (".OpenFirmware") ))
4505
static void OF_release (OF_env_t *OF_env)
4507
uint32_t virt, size;
4510
OF_CHECK_NBARGS(OF_env, 2);
4511
virt = popd(OF_env);
4512
size = popd(OF_env);
4513
OF_DPRINTF("virt 0x%0x size 0x%0x\n", virt, size);
4514
for (i = 0; i < OF_MAX_MEMRANGES; i++) {
4515
if (OF_mem_ranges[i].start == virt && OF_mem_ranges[i].size == size) {
4516
OF_mem_ranges[i].start = (uint32_t)(-1);
4517
OF_mem_ranges[i].size = (uint32_t)(-1);
4523
/* Control transfer services */
4526
/* Enter Open-Firmware interpreter */
4527
__attribute__ (( section (".OpenFirmware") ))
4528
static void OF_enter (OF_env_t *OF_env)
4532
n_args = stackd_depth(OF_env);
4533
/* means that the bootloader has ended.
4536
OF_DPRINTF("%d \n", n_args);
4537
// printf("Bootloader has quitted...\n");
4541
/* Exit client program */
4542
__attribute__ (( section (".OpenFirmware") ))
4543
static void OF_exit (OF_env_t *OF_env)
4547
n_args = stackd_depth(OF_env);
4548
/* means that the bootloader has ended.
4551
OF_DPRINTF("%d \n", n_args);
4552
// printf("Bootloader has quitted...\n");
4558
/* User interface services */
4561
__attribute__ (( section (".OpenFirmware") ))
4562
static void OF_interpret (OF_env_t *OF_env)
4564
const unsigned char *FString;
4567
OF_node_t *pks, *slw, *chs, *disp;
4568
uint32_t ihandle, crc;
4571
// OF_CHECK_NBARGS(OF_env, 1);
4572
FString = (const void *)popd(OF_env);
4573
crc = crc32(0, FString, strlen(FString));
4574
OF_DPRINTF("\n\nOF INTERPRETER CALL:\n [%s]\n crc=%0x\n", FString, crc);
4575
/* Do some hacks to make BootX happy */
4577
case 0x225b6748: /* MacOS X 10.2 and OpenDarwin 1.41 */
4578
case 0xb1cd4d25: /* OpenDarwin 6.02 */
4579
/* Create "sl_words" package */
4581
/* Find "/packages" */
4582
pks = OF_pack_find_by_name(OF_env, OF_node_root, "/packages");
4584
OF_node_put(OF_env, pks);
4586
ERROR("Cannot get '/packages'\n");
4589
slw = OF_node_new(OF_env, pks, "sl_words", OF_ADDRESS_NONE);
4591
OF_node_put(OF_env, pks);
4593
ERROR("Cannot create 'sl_words'\n");
4596
/* Create methods */
4597
OF_method_new(OF_env, slw, "slw_set_output_level",
4598
&slw_set_output_level);
4599
OF_method_new(OF_env, slw, "slw_emit", &slw_emit);
4600
OF_method_new(OF_env, slw, "slw_cr", &slw_cr);
4601
OF_method_new(OF_env, slw, "slw_init_keymap", &slw_init_keymap);
4602
OF_method_new(OF_env, slw, "slw_update_keymap", &slw_update_keymap);
4603
OF_method_new(OF_env, slw, "slw_spin", &slw_spin);
4604
OF_method_new(OF_env, slw, "slw_spin_init", &slw_spin_init);
4605
OF_method_new(OF_env, slw, "slw_pwd", &slw_pwd);
4606
OF_method_new(OF_env, slw, "slw_sum", &slw_sum);
4607
/* Init properties */
4608
OF_prop_int_new(OF_env, slw, "outputLevel", 0);
4609
OF_prop_int_new(OF_env, slw, "keyboardIH", 0);
4613
kbd = OF_pack_find_by_name(OF_env, OF_node_root, "/keyboard");
4615
OF_node_put(OF_env, pks);
4617
ERROR("Cannot get '/keyboard'\n");
4622
OF_node_put(OF_env, pks);
4624
ERROR("Cannot allocate keyboard buff\n");
4630
OF_node_put(OF_env, pks);
4632
ERROR("Cannot allocate keyboard buff\n");
4635
memset(buf, 0, 0x20);
4636
OF_property_new(OF_env, slw, "keyMap", buf, 0x20);
4639
OF_prop_int_new(OF_env, slw, "screenIH", 0);
4640
OF_prop_int_new(OF_env, slw, "cursorAddr", 0);
4641
OF_prop_int_new(OF_env, slw, "cursorX", 0);
4642
OF_prop_int_new(OF_env, slw, "cursorY", 0);
4643
OF_prop_int_new(OF_env, slw, "cursorW", 0);
4644
OF_prop_int_new(OF_env, slw, "cursorH", 0);
4645
OF_prop_int_new(OF_env, slw, "cursorFrames", 0);
4646
OF_prop_int_new(OF_env, slw, "cursorPixelSize", 0);
4647
OF_prop_int_new(OF_env, slw, "cursorStage", 0);
4648
OF_prop_int_new(OF_env, slw, "cursorTime", 0);
4649
OF_prop_int_new(OF_env, slw, "cursorDelay", 0);
4650
/* Instanciate sl_words */
4651
inst = OF_instance_new(OF_env, slw);
4653
OF_node_put(OF_env, pks);
4655
ERROR("Cannot create sl_words instance\n");
4658
ihandle = OF_instance_get_id(OF_env, inst);
4659
/* Release packages */
4660
OF_node_put(OF_env, slw);
4661
OF_node_put(OF_env, pks);
4662
OF_DPRINTF("sl_words instance: %0x\n", ihandle);
4663
/* Set return value */
4664
if (crc == 0xb1cd4d25) /* Hack for OpenDarwin 6.02 */
4665
pushd(OF_env, ihandle);
4666
pushd(OF_env, ihandle);
4669
case 0x233441d3: /* MacOS X 10.2 and OpenDarwin 1.41 */
4670
/* Create "memory-map" pseudo device */
4675
/* Find "/packages" */
4676
chs = OF_pack_find_by_name(OF_env, OF_node_root, "/chosen");
4679
ERROR("Cannot get '/chosen'\n");
4682
map = OF_node_new(OF_env, chs, "memory-map", OF_ADDRESS_NONE);
4685
ERROR("Cannot create 'memory-map'\n");
4688
phandle = OF_pack_handle(OF_env, map);
4689
OF_node_put(OF_env, map);
4690
OF_node_put(OF_env, chs);
4691
pushd(OF_env, phandle);
4695
case 0x32a2d18e: /* MacOS X 10.2 and OpenDarwin 6.02 */
4696
/* Return screen ihandle */
4697
disp = OF_get_alias(OF_env, "screen");
4701
ERROR("Cannot get 'screen' alias\n");
4704
inst = OF_instance_new(OF_env, disp);
4706
OF_node_put(OF_env, disp);
4709
ERROR("Cannot create 'screen' instance\n");
4712
ihandle = OF_instance_get_id(OF_env, inst);
4713
OF_node_put(OF_env, disp);
4714
OF_DPRINTF("Return screen ihandle: %0x\n", ihandle);
4715
pushd(OF_env, ihandle);
4718
case 0xF3A9841F: /* MacOS X 10.2 */
4719
case 0x76fbdf18: /* OpenDarwin 6.02 */
4720
/* Set current display as active package */
4721
disp = OF_get_alias (OF_env, "screen");
4726
OF_node_put(OF_env, disp);
4728
case 0x1c3bc93f: /* MacOS X 10.3 */
4729
/* get-package-property if 0 0 then */
4734
if (len == (uint32_t)-1)
4739
case 0x218d5ccb: /* yaboot */
4747
/* Yaboot: set background color to black */
4750
case 0x299c2c5d: /* gentoo */
4751
/* Yaboot: set foreground color to grey */
4754
/* Yaboot: wait 10 ms: sure ! */
4759
printf("Script: len=%d\n%s\n", (int)strlen(FString), FString);
4760
printf("Call %0x NOT IMPLEMENTED !\n", crc);
4764
OF_DPRINTF("\n\nOF INTERPRETER CALL DONE\n\n");
4767
/* "set-callback" */
4768
/* "set-symbol-lookup" */
4771
/* "milliseconds" */
4772
__attribute__ (( section (".OpenFirmware") ))
4773
static void OF_milliseconds (OF_env_t *OF_env)
4779
OF_CHECK_NBARGS(OF_env, 0);
4780
gettimeofday(&tv, NULL);
4781
pushd(OF_env, (tv.tv_sec * 1000) + (tv.tv_usec / 1000));
4783
static uint32_t ms = 0;
4785
OF_CHECK_NBARGS(OF_env, 0);
4787
usleep(10000); /* XXX: TOFIX: Random sleep */
4792
/* Undocumented in IEEE 1275 */
4793
__attribute__ (( section (".OpenFirmware") ))
4794
static void OF_quiesce (OF_env_t *OF_env)
4796
OF_CHECK_NBARGS(OF_env, 0);
4797
/* Should free all OF resources */
4799
#if defined (DEBUG_BIOS)
4801
uint16_t loglevel = 0x02 | 0x10 | 0x80;
4802
// outw(0xFF02, loglevel);
4803
outb(0x0F02, loglevel);
4808
typedef struct OF_service_t OF_service_t;
4809
struct OF_service_t {
4810
const unsigned char *name;
4814
static OF_service_t services[] = {
4815
{ "test", &OF_test, },
4816
{ "peer", &OF_peer, },
4817
{ "child", &OF_child, },
4818
{ "parent", &OF_parent, },
4819
{ "instance-to-package", &OF_instance_to_package, },
4820
{ "getproplen", &OF_getproplen, },
4821
{ "getprop", &OF_getprop, },
4822
{ "nextprop", &OF_nextprop, },
4823
{ "setprop", &OF_setprop, },
4824
{ "finddevice", &OF_finddevice, },
4825
{ "instance-to-path", &OF_instance_to_path, },
4826
{ "package-to-path", &OF_package_to_path, },
4827
{ "call-method", &OF_callmethod, },
4828
{ "open", &OF_open, },
4829
{ "open-package", &OF_open, },
4830
{ "close", &OF_close, },
4831
{ "read", &OF_read, },
4832
{ "write", &OF_write, },
4833
{ "seek", &OF_seek, },
4834
{ "claim", &OF_claim, },
4835
{ "release", &OF_release, },
4836
{ "enter", &OF_enter, },
4837
{ "exit", &OF_exit, },
4838
{ "interpret", &OF_interpret, },
4839
{ "milliseconds", &OF_milliseconds, },
4840
{ "quiesce", &OF_quiesce, },
4843
/* Probe if a named service exists */
4844
__attribute__ (( section (".OpenFirmware") ))
4845
static void OF_test (OF_env_t *OF_env)
4847
unsigned char name[OF_NAMELEN_MAX], *namep;
4851
OF_CHECK_NBARGS(OF_env, 1);
4852
namep = (unsigned char *)popd(OF_env);
4853
OF_lds(name, namep);
4854
OF_DPRINTF("service [%s]\n", name);
4855
for (i = 0; i < (sizeof(services) / sizeof(OF_service_t)); i++) {
4856
if (strcmp(services[i].name, name) == 0) {
4864
/* Main entry point for PPC clients */
4865
__attribute__ (( section (".OpenFirmware") ))
4866
int OF_client_entry (void *p)
4868
unsigned char buffer[OF_NAMELEN_MAX];
4871
unsigned char *namep;
4874
/* set our environment */
4876
OF_DPRINTF("Called with arg: %p\n", p);
4877
/* Load function name string */
4878
namep = (unsigned char *)(*(uint32_t *)p);
4879
OF_lds(buffer, namep);
4882
OF_DPRINTF("Look for service [%s]\n", buffer);
4883
for (i = 0; i < (sizeof(services) / sizeof(OF_service_t)); i++) {
4884
if (strcmp(services[i].name, buffer) == 0) {
4885
cb = services[i].cb;
4890
OF_DPRINTF("service [%s] not implemented\n", buffer);
4895
OF_DPRINTF("Service [%s] found\n", buffer);
4897
/* Set up stack *NON REENTRANT* */
4898
OF_env_init(&OF_env);
4899
/* Launch Forth glue */
4900
C_to_Forth(&OF_env, (uint32_t *)p + 1, &cb);
4901
OF_DPRINTF("done\n");
4907
/*****************************************************************************/
4908
/* Run-time abstraction services */
4909
/* RTAS RAM is organised this way:
4910
* RTAS_memory is given by the OS when instanciating RTAS.
4911
* it's an 32 kB area divided in 2 zones:
4912
* Up is a stack, used to call RTAS services
4913
* Down is the variables area.
4916
__attribute__ (( section (".RTAS_vars") ))
4917
static OF_cb_t *RTAS_callbacks[32];
4919
__attribute__ (( section (".RTAS_vars") ))
4920
static uint8_t *RTAS_base;
4923
/* RTAS is called in real mode (ie no MMU), privileged with all exceptions
4924
* disabled. It has to preserve all registers except R3 to R12.
4925
* The OS should ensure it's not re-entered.
4927
__attribute__ (( section (".RTAS") ))
4928
int RTAS_entry (void *p)
4933
OF_DPRINTF("Called with arg: %p\n", p);
4934
/* set our environment */
4935
token = *(uint32_t *)p;
4937
RTAS_env.stackb = (uint32_t *)(RTAS_memory + 0x8000 - 4);
4938
RTAS_env.stackp = RTAS_env.stackb;
4939
RTAS_env.funcb = (uint32_t *)(RTAS_memory + 0x8000 - OF_STACK_SIZE - 4);
4940
RTAS_env.funcp = RTAS_env.funcb;
4941
/* Call Forth glue */
4942
C_to_Forth(&RTAS_env, (uint32_t *)p + 1, RTAS_callbacks[token & 0x3F]);
4943
OF_DPRINTF("done\n");
4948
__attribute__ (( section (".RTAS") ))
4949
static void RTAS_restart_rtas (OF_env_t *RTAS_env)
4952
OF_CHECK_NBARGS(RTAS_env, 0);
4953
/* No implementation: return error */
4954
pushd(RTAS_env, -1);
4957
__attribute__ (( section (".RTAS") ))
4958
static void RTAS_nvram_fetch (OF_env_t *RTAS_env)
4965
OF_CHECK_NBARGS(RTAS_env, 3);
4966
offset = popd(RTAS_env);
4967
buffer = (uint8_t *)popd(RTAS_env);
4968
length = popd(RTAS_env);
4969
for (i = 0; i < length; i++) {
4970
if ((i + offset) >= NVRAM_get_size(nvram)) {
4971
pushd(RTAS_env, -3);
4974
*buffer++ = NVRAM_read(nvram, i + offset);
4976
pushd(RTAS_env, length);
4979
__attribute__ (( section (".RTAS") ))
4980
static void RTAS_nvram_store (OF_env_t *RTAS_env)
4987
OF_CHECK_NBARGS(RTAS_env, 3);
4988
offset = popd(RTAS_env);
4989
buffer = (uint8_t *)popd(RTAS_env);
4990
length = popd(RTAS_env);
4991
for (i = 0; i < length; i++) {
4992
if ((i + offset) >= NVRAM_get_size(nvram)) {
4993
pushd(RTAS_env, -3);
4996
NVRAM_write(nvram, i + offset, *buffer++);
4998
pushd(RTAS_env, length);
5001
__attribute__ (( section (".RTAS") ))
5002
static void RTAS_get_time_of_day (OF_env_t *RTAS_env)
5009
OF_CHECK_NBARGS(RTAS_env, 0);
5011
localtime_r(&t, &tm);
5012
pushd(RTAS_env, 0); /* nanoseconds */
5013
pushd(RTAS_env, tm.tm_sec);
5014
pushd(RTAS_env, tm.tm_min);
5015
pushd(RTAS_env, tm.tm_hour);
5016
pushd(RTAS_env, tm.tm_mday);
5017
pushd(RTAS_env, tm.tm_mon);
5018
pushd(RTAS_env, tm.tm_year);
5019
pushd(RTAS_env, 0); /* status */
5032
__attribute__ (( section (".RTAS") ))
5033
static void RTAS_set_time_of_day (OF_env_t *RTAS_env)
5040
OF_CHECK_NBARGS(RTAS_env, 7);
5041
tm.tm_year = popd(RTAS_env);
5042
tm.tm_mon = popd(RTAS_env);
5043
tm.tm_mday = popd(RTAS_env);
5044
tm.tm_hour = popd(RTAS_env);
5045
tm.tm_min = popd(RTAS_env);
5046
tm.tm_sec = popd(RTAS_env);
5047
popd(RTAS_env); /* nanoseconds */
5051
pushd(RTAS_env, 0); /* status */
5054
__attribute__ (( section (".RTAS") ))
5055
static void RTAS_set_time_for_power_on (OF_env_t *RTAS_env)
5058
OF_CHECK_NBARGS(RTAS_env, 7);
5060
pushd(RTAS_env, 0); /* status */
5063
__attribute__ (( section (".RTAS") ))
5064
static void RTAS_event_scan (OF_env_t *RTAS_env)
5067
OF_CHECK_NBARGS(RTAS_env, 4);
5068
/* Pretend there are no new events */
5072
__attribute__ (( section (".RTAS") ))
5073
static void RTAS_check_exception (OF_env_t *RTAS_env)
5076
OF_CHECK_NBARGS(RTAS_env, 6);
5077
/* Pretend we found no exceptions */
5081
__attribute__ (( section (".RTAS") ))
5082
static void RTAS_read_pci_config (OF_env_t *RTAS_env)
5085
OF_CHECK_NBARGS(RTAS_env, 2);
5086
/* Hardware error */
5087
pushd(RTAS_env, -1);
5090
__attribute__ (( section (".RTAS") ))
5091
static void RTAS_write_pci_config (OF_env_t *RTAS_env)
5094
OF_CHECK_NBARGS(RTAS_env, 3);
5095
/* Hardware error */
5096
pushd(RTAS_env, -1);
5099
__attribute__ (( section (".RTAS") ))
5100
static void RTAS_display_character (OF_env_t *RTAS_env)
5105
OF_CHECK_NBARGS(RTAS_env, 1);
5115
__attribute__ (( section (".RTAS") ))
5116
static void RTAS_set_indicator (OF_env_t *RTAS_env)
5118
const unsigned char *name;
5122
OF_CHECK_NBARGS(RTAS_env, 3);
5123
indic = popd(RTAS_env);
5124
state = popd(RTAS_env);
5127
name = "tone frequency";
5130
name = "tone volume";
5133
name = "system power state";
5136
name = "warning light";
5139
name = "disk activity light";
5142
name = "hexadecimal display unit";
5145
name = "batery warning time";
5148
name = "condition cycle request";
5151
name = "vendor specific";
5154
pushd(RTAS_env, -3);
5157
OF_DPRINTF("Set indicator %d [%s] to %d\n", indic, name, state);
5161
__attribute__ (( section (".RTAS") ))
5162
static void RTAS_get_sensor_state (OF_env_t *RTAS_env)
5164
const unsigned char *name;
5169
OF_CHECK_NBARGS(RTAS_env, 2);
5170
type = popd(RTAS_env);
5171
index = popd(RTAS_env);
5174
name = "key switch";
5175
state = 1; /* Normal */
5178
name = "enclosure switch";
5179
state = 0; /* Closed */
5182
name = "thermal sensor";
5183
state = 40; /* in degrees Celsius (not too hot !) */
5186
name = "lid status";
5187
state = 1; /* Open */
5190
name = "power source";
5194
name = "battery voltage";
5195
state = 6; /* Let's have a moderated answer :-) */
5198
name = "battery capacity remaining";
5199
state = 3; /* High */
5202
name = "battery capacity percentage";
5203
state = 1000; /* 100 % */
5206
name = "EPOW sensor";
5210
name = "battery condition cycle state";
5211
state = 0; /* none */
5214
name = "battery charge state";
5215
state = 2; /* No current flow */
5218
name = "vendor specific";
5222
pushd(RTAS_env, -3);
5225
OF_DPRINTF("Pretend sensor %d [%s] is in state %d\n", index, name, state);
5226
pushd(RTAS_env, state);
5230
#if 0 // No power management */
5231
__attribute__ (( section (".RTAS") ))
5232
static void RTAS_set_power_level (OF_env_t *RTAS_env)
5237
__attribute__ (( section (".RTAS") ))
5238
static void RTAS_get_power_level (OF_env_t *RTAS_env)
5243
__attribute__ (( section (".RTAS") ))
5244
static void RTAS_assume_power_management (OF_env_t *RTAS_env)
5249
__attribute__ (( section (".RTAS") ))
5250
static void RTAS_relinquish_power_management (OF_env_t *RTAS_env)
5256
__attribute__ (( section (".RTAS") ))
5257
static void RTAS_power_off (OF_env_t *RTAS_env)
5259
printf("RTAS was asked to switch off\n");
5260
OF_CHECK_NBARGS(RTAS_env, 2);
5264
__attribute__ (( section (".RTAS") ))
5265
static void RTAS_suspend (OF_env_t *RTAS_env)
5268
OF_CHECK_NBARGS(RTAS_env, 3);
5269
/* Pretend we don't succeed */
5270
pushd(RTAS_env, -1);
5273
__attribute__ (( section (".RTAS") ))
5274
static void RTAS_hibernate (OF_env_t *RTAS_env)
5277
OF_CHECK_NBARGS(RTAS_env, 3);
5278
/* Pretend we don't succeed */
5279
pushd(RTAS_env, -1);
5282
__attribute__ (( section (".RTAS") ))
5283
static void RTAS_system_reboot (OF_env_t *RTAS_env)
5285
printf("RTAS was asked to reboot\n");
5286
OF_CHECK_NBARGS(RTAS_env, 0);
5290
#if 0 // No power management nor SMP */
5291
__attribute__ (( section (".RTAS") ))
5292
static void RTAS_cache_control (OF_env_t *RTAS_env)
5297
__attribute__ (( section (".RTAS") ))
5298
static void RTAS_freeze_time_base (OF_env_t *RTAS_env)
5303
__attribute__ (( section (".RTAS") ))
5304
static void RTAS_thaw_time_base (OF_env_t *RTAS_env)
5309
__attribute__ (( section (".RTAS") ))
5310
static void RTAS_stop_self (OF_env_t *RTAS_env)
5315
__attribute__ (( section (".RTAS") ))
5316
static void RTAS_start_cpu (OF_env_t *RTAS_env)
5322
__attribute__ (( section (".RTAS") ))
5323
static void RTAS_instantiate (OF_env_t *RTAS_env)
5325
const unsigned char *args;
5327
uint32_t base_address;
5330
OF_CHECK_NBARGS(RTAS_env, 3);
5331
ihandle = popd(RTAS_env);
5332
args = (void *)popd(RTAS_env);
5333
base_address = popd(RTAS_env);
5334
memmove((void *)base_address, (void *)(&_RTAS_start),
5335
(char *)(&_RTAS_data_end) - (char *)(&_RTAS_start));
5336
OF_DPRINTF("base_address=0x%0x\n", base_address);
5337
pushd(RTAS_env, base_address);
5341
__attribute__ (( section (".RTAS") ))
5342
static void RTAS_new_cb (OF_env_t *env, OF_node_t *rtas,
5343
const unsigned char *name,
5344
OF_cb_t cb, uint32_t *token_next)
5346
OF_prop_int_new(env, rtas, name, 0xabcd0000 | *token_next);
5347
RTAS_callbacks[*token_next] = &cb;
5351
__attribute__ (( section (".RTAS") ))
5352
void RTAS_init (void)
5355
OF_node_t *rtas, *chs;
5357
uint32_t token_next = 0, size;
5359
RTAS_env = OF_env_main;
5360
rtas = OF_node_new(RTAS_env, OF_node_root, "rtas", OF_ADDRESS_NONE);
5362
ERROR("RTAS not found\n");
5365
size = ((char *)(&_RTAS_data_end) - (char *)(&_RTAS_start) + 0x0000FFFF) &
5367
OF_DPRINTF("RTAS size: %d bytes (%d)\n", size,
5368
(char *)(&_RTAS_data_end) - (char *)(&_RTAS_start));
5369
OF_prop_int_new(RTAS_env, rtas, "rtas-size", size);
5370
OF_prop_int_new(RTAS_env, rtas, "rtas-version", 1);
5371
OF_prop_int_new(RTAS_env, rtas, "rtas-event-scan-rate", 0);
5372
OF_prop_int_new(RTAS_env, rtas, "rtas-error-log-max", 0);
5373
chs = OF_node_get(RTAS_env, "chosen");
5375
ERROR("choosen not found\n");
5378
stdout = OF_property_get(RTAS_env, chs, "stdout");
5379
if (stdout == NULL) {
5380
OF_node_put(RTAS_env, chs);
5381
ERROR("stdout not found\n");
5384
OF_prop_int_new(RTAS_env, rtas, "rtas-display-device",
5385
*(uint32_t *)stdout->value);
5387
RTAS_new_cb(RTAS_env, rtas, "restart_rtas",
5388
&RTAS_restart_rtas, &token_next);
5389
RTAS_new_cb(RTAS_env, rtas, "nvram_fetch",
5390
&RTAS_nvram_fetch, &token_next);
5391
RTAS_new_cb(RTAS_env, rtas, "nvram_store",
5392
&RTAS_nvram_store, &token_next);
5393
RTAS_new_cb(RTAS_env, rtas, "get-time-of_day",
5394
&RTAS_get_time_of_day, &token_next);
5395
RTAS_new_cb(RTAS_env, rtas, "set-time-of-day",
5396
&RTAS_set_time_of_day, &token_next);
5397
RTAS_new_cb(RTAS_env, rtas, "set-time-for-power-on",
5398
&RTAS_set_time_for_power_on, &token_next);
5399
RTAS_new_cb(RTAS_env, rtas, "event-scan", &RTAS_event_scan, &token_next);
5400
RTAS_new_cb(RTAS_env, rtas, "check-exception",
5401
&RTAS_check_exception, &token_next);
5402
RTAS_new_cb(RTAS_env, rtas, "read-pci-config",
5403
&RTAS_read_pci_config, &token_next);
5404
RTAS_new_cb(RTAS_env, rtas, "write-pci-config",
5405
&RTAS_write_pci_config, &token_next);
5406
RTAS_new_cb(RTAS_env, rtas, "display-character",
5407
&RTAS_display_character, &token_next);
5408
RTAS_new_cb(RTAS_env, rtas, "set-indicator",
5409
&RTAS_set_indicator, &token_next);
5410
RTAS_new_cb(RTAS_env, rtas, "get-sensor-state",
5411
&RTAS_get_sensor_state, &token_next);
5412
#if 0 // No power management */
5413
RTAS_new_cb(RTAS_env, rtas, "set-power-level",
5414
&RTAS_set_power_level, &token_next);
5415
RTAS_new_cb(RTAS_env, rtas, "get-power-level",
5416
&RTAS_get_power_level, &token_next);
5417
RTAS_new_cb(RTAS_env, rtas, "assume-power-management",
5418
&RTAS_assume_power_management, &token_next);
5419
RTAS_new_cb(RTAS_env, rtas, "relinquish-power-management",
5420
&RTAS_relinquish_power_management, &token_next);
5422
RTAS_new_cb(RTAS_env, rtas, "power-off", &RTAS_power_off, &token_next);
5423
RTAS_new_cb(RTAS_env, rtas, "suspend", &RTAS_suspend, &token_next);
5424
RTAS_new_cb(RTAS_env, rtas, "hibernate", &RTAS_hibernate, &token_next);
5425
RTAS_new_cb(RTAS_env, rtas, "system-reboot",
5426
&RTAS_system_reboot, &token_next);
5427
#if 0 // No power management nor SMP */
5428
RTAS_new_cb(RTAS_env, rtas, "cache-control",
5429
&RTAS_cache_control, &token_next);
5430
RTAS_new_cb(RTAS_env, rtas, "freeze_time_base",
5431
&RTAS_freeze_time_base, &token_next);
5432
RTAS_new_cb(RTAS_env, rtas, "thaw_time_base",
5433
&RTAS_thaw_time_base, &token_next);
5434
RTAS_new_cb(RTAS_env, rtas, "stop-self", &RTAS_stop_self, &token_next);
5435
RTAS_new_cb(RTAS_env, rtas, "start-cpu", &RTAS_start_cpu, &token_next);
5439
* "update-flash-and-reboot"
5440
* "query-cpu-stopped-state" for SMP
5442
OF_method_new(RTAS_env, rtas, "instantiate-rtas", &RTAS_instantiate);
5443
OF_node_put(RTAS_env, rtas);
5444
OF_node_new(RTAS_env, OF_node_root, "nomore", OF_ADDRESS_NONE);
5445
DPRINTF("RTAS done\n");
5448
/*****************************************************************************/
5449
/* That's all for now... */
5450
/*****************************************************************************/