diff options
author | 2017-04-25 03:31:15 -0700 | |
---|---|---|
committer | 2017-05-22 06:48:08 +0000 | |
commit | bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch) | |
tree | ca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/openhackware/src/of.c | |
parent | a14b48d18a9ed03ec191cf16b162206998a895ce (diff) |
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to
kvmfornfv repo and make use of the updated latest qemu for the
execution of all testcase
Change-Id: I1280af507a857675c7f81d30c95255635667bdd7
Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/roms/openhackware/src/of.c')
-rw-r--r-- | qemu/roms/openhackware/src/of.c | 5450 |
1 files changed, 0 insertions, 5450 deletions
diff --git a/qemu/roms/openhackware/src/of.c b/qemu/roms/openhackware/src/of.c deleted file mode 100644 index 33582c308..000000000 --- a/qemu/roms/openhackware/src/of.c +++ /dev/null @@ -1,5450 +0,0 @@ -/* Open firmware emulation. - * - * This is really simplistic. The first goal is to implement all stuff - * needed to boot Linux. Then, I'll try Darwin. - * Note that this emulation run in the host environment. - * There is no Forth interpreter, so standard bootloader cannot be launched. - * In the future, it will be nice to get a complete OpenFirmware implementation - * so that OSes can be launched exactly the way they are in the real world... - * - * Copyright (c) 2003-2005 Jocelyn Mayer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License V2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <stdlib.h> -#include <stdio.h> -#include "bios.h" - -//#define DEBUG_OF 1 - -#if defined (DEBUG_OF) -#define OF_DPRINTF(fmt, args...) \ -do { dprintf("%s: " fmt, __func__ , ##args); } while (0) -#else -#define OF_DPRINTF(fmt, args...) \ -do { } while (0) -#endif - -#define PROT_READ 1 -#define PROT_WRITE 2 - -typedef struct OF_transl_t OF_transl_t; -struct OF_transl_t { - uint32_t virt; - uint32_t size; - uint32_t phys; - uint32_t mode; -}; - -typedef struct OF_env_t OF_env_t; -struct OF_env_t { - uint32_t *stackp; /* Stack pointer */ - uint32_t *stackb; /* Stack base */ - uint32_t *funcp; /* Function stack pointer */ - uint32_t *funcb; /* Function stack base */ -}; - -typedef struct OF_bustyp_t OF_bustyp_t; -struct OF_bustyp_t { - const char *name; - int type; -}; - -typedef struct pci_address_t pci_address_t; -struct pci_address_t { - uint32_t hi; - uint32_t mid; - uint32_t lo; -}; - -typedef struct pci_reg_prop_t pci_reg_prop_t; -struct pci_reg_prop_t { - pci_address_t addr; - uint32_t size_hi; - uint32_t size_lo; -}; - -typedef struct pci_range_t pci_range_t; -struct pci_range_t { - pci_address_t addr; - uint32_t phys; - uint32_t size_hi; - uint32_t size_lo; -}; - -/*****************************************************************************/ -__attribute__ (( section (".OpenFirmware") )) -static void OF_lds (uint8_t *dst, const void *address) -{ - const uint8_t *p; - uint8_t *_d = dst; - - for (p = address; *p != '\0'; p++) { - *_d++ = *p; - } - *_d = '\0'; - OF_DPRINTF("Loaded string %s\n", dst); -} - -__attribute__ (( section (".OpenFirmware") )) -static void OF_sts (void *address, const uint8_t *src) -{ - const uint8_t *_s; - uint8_t *p = address; - - OF_DPRINTF("Store string %s\n", src); - for (_s = src; *_s != '\0'; _s++) { - *p++ = *_s; - } - *p = '\0'; -} - -#define OF_DUMP_STRING(env, buffer) \ -do { \ - unsigned char tmp[OF_NAMELEN_MAX]; \ - OF_lds(tmp, buffer); \ - OF_DPRINTF("[%s]\n", tmp); \ -} while (0) - -/*****************************************************************************/ -/* Forth like environmnent */ -#define OF_CHECK_NBARGS(env, nb) \ -do { \ - int nb_args; \ - nb_args = stackd_depth((env)); \ - if (nb_args != (nb)) { \ - printf("%s: Bad number of arguments (%d - %d)\n", \ - __func__, nb_args, (nb)); \ - bug(); \ - popd_all((env), nb_args); \ - pushd((env), -1); \ - return; \ - } \ -} while (0) - -#define OF_STACK_SIZE 0x1000 -#define OF_FSTACK_SIZE 0x100 -__attribute__ (( section (".OpenFirmware_vars") )) -uint8_t OF_stack[OF_STACK_SIZE]; -__attribute__ (( section (".OpenFirmware_vars") )) -uint8_t OF_fstack[OF_FSTACK_SIZE]; - -typedef void (*OF_cb_t)(OF_env_t *OF_env); - -static inline void _push (uint32_t **stackp, uint32_t data) -{ - // OF_DPRINTF("%p 0x%0x\n", *stackp, data); - **stackp = data; - (*stackp)--; -} - -static inline uint32_t _pop (uint32_t **stackp) -{ - (*stackp)++; - // OF_DPRINTF("%p 0x%0x\n", *stackp, **stackp); - return **stackp; -} - -static inline void _pop_all (uint32_t **stackp, int nb) -{ - int i; - - for (i = 0; i < nb; i++) - (*stackp)++; -} - -static inline int _stack_depth (uint32_t *stackp, uint32_t *basep) -{ - return basep - stackp; -} - -static inline void pushd (OF_env_t *OF_env, uint32_t data) -{ - _push(&OF_env->stackp, data); -} - -static inline uint32_t popd (OF_env_t *OF_env) -{ - return _pop(&OF_env->stackp); -} - -static inline void popd_all (OF_env_t *OF_env, int nb) -{ - _pop_all(&OF_env->stackp, nb); -} - -static inline int stackd_depth (OF_env_t *OF_env) -{ - return _stack_depth(OF_env->stackp, OF_env->stackb); -} - -static inline void pushf (OF_env_t *OF_env, OF_cb_t *func) -{ - _push(&OF_env->funcp, (uint32_t)func); -} - -static inline OF_cb_t *popf (OF_env_t *OF_env) -{ - return (OF_cb_t *)_pop(&OF_env->funcp); -} - -static inline void popf_all (OF_env_t *OF_env, int nb) -{ - _pop_all(&OF_env->funcp, nb); -} - -static inline int stackf_depth (OF_env_t *OF_env) -{ - return _stack_depth(OF_env->funcp, OF_env->funcb); -} - -static inline void OF_env_init (OF_env_t *OF_env) -{ - OF_env->stackb = (uint32_t *)(OF_stack + OF_STACK_SIZE - 4); - OF_env->stackp = OF_env->stackb; - OF_env->funcb = (uint32_t *)(OF_fstack + OF_FSTACK_SIZE - 4); - OF_env->funcp = OF_env->funcb; -} - -/* Forth run-time */ -__attribute__ (( section (".OpenFirmware") )) -static void C_to_Forth (OF_env_t *env, void *p, OF_cb_t *cb) -{ - OF_cb_t *_cb; - uint32_t *u, *rets; - uint32_t i, n_args, n_rets, tmp; - - // OF_DPRINTF("enter\n"); - /* Fill argument structure */ - u = p; - n_args = *u++; - n_rets = *u++; - u += n_args; - rets = u; - // OF_DPRINTF("n_args=%d n_rets=%d\n", n_args, n_rets); - /* Load arguments */ - for (i = 0; i < n_args; i++) - pushd(env, *(--u)); - pushf(env, cb); - while (stackf_depth(env) != 0) { - // OF_DPRINTF("func stack: %p %p\n", env->funcb, env->funcp); - _cb = popf(env); - // OF_DPRINTF("Next func: %p %d\n", cb, stackf_depth(env)); - (*_cb)(env); - } - // OF_DPRINTF("Back to C: n_args=%d n_rets=%d\n", n_args, n_rets); - /* Copy returned values */ - for (i = 0; stackd_depth(env) != 0; i++) { - tmp = popd(env); - // OF_DPRINTF("Store 0x%0x (%d)\n", tmp, tmp); - *rets++ = tmp; - } - for (; i < n_rets; i++) - *rets++ = 0; - OF_CHECK_NBARGS(env, 0); - // OF_DPRINTF("done\n"); -} - -/*****************************************************************************/ -/* Memory pool (will be needed when it'll become native) */ -#if 0 -#define OF_INTBITS_LEN 128 -#define OF_INTPOOL_LEN (OF_INTBITS_LEN * 8) -__attribute__ (( section (".OpenFirmware_vars") )) -static uint32_t OF_int_pool[OF_INTPOOL_LEN]; -__attribute__ (( section (".OpenFirmware_vars") )) -static uint8_t OF_int_bits[OF_INTBITS_LEN]; - -__attribute__ (( section (".OpenFirmware") )) -static uint32_t *OF_int_alloc (unused OF_env_t *env) -{ - uint8_t tmp; - int i, j; - - for (i = 0; i < OF_INTBITS_LEN; i++) { - tmp = OF_int_bits[i]; - if (tmp == 0xFF) - continue; - for (j = 0; j < 7; j++) { - if ((tmp & 1) == 0) { - OF_int_bits[i] |= 1 << j; - return &OF_int_pool[(i << 3) | j]; - } - tmp = tmp >> 1; - } - } - printf("ALERT: unable to \"allocate\" new integer\n"); - - return NULL; -} - -__attribute__ (( section (".OpenFirmware") )) -static void OF_int_free (unused OF_env_t *env, - uint32_t *area) -{ - int i, j; - - i = area - OF_int_pool; - j = i & 7; - i = i >> 3; - OF_int_bits[i] &= ~(1 << j); -} - -__attribute__ (( section (".OpenFirmware") )) -static void OF_free (unused OF_env_t *env, void *area) -{ - uint32_t *check; - - /* Check if it's in our int pool */ - check = area; - if (check >= OF_int_pool && check < (OF_int_pool + OF_INTPOOL_LEN)) { - OF_int_free(env, check); - return; - } -#if 0 - free(area); -#endif -} -#endif - -/*****************************************************************************/ -/* Internal structures */ -/* Property value types */ -typedef struct OF_node_t OF_node_t; -typedef struct OF_prop_t OF_prop_t; -typedef struct OF_method_t OF_method_t; -typedef struct OF_inst_t OF_inst_t; - -#define OF_ADDRESS_NONE ((uint32_t)(-1)) - -/* Tree node */ -struct OF_node_t { - /* Parent node */ - OF_node_t *parent; - /* Link to next node at the same level */ - OF_node_t *next; - /* Link to children, if any */ - OF_node_t *children, *child_last; - /* refcount */ - int refcount; - /* The following ones belong to the package */ - /* Package */ - uint16_t pack_id; - /* links count */ - uint16_t link_count; - uint16_t link_cur; - OF_node_t *link_ref; - /* Properties */ - OF_prop_t *properties, *prop_last, *prop_name, *prop_address; - /* Methods */ - OF_method_t *methods, *method_last; - /* private data */ - void *private_data; - /* static data */ - void *static_data; - /* instances */ - OF_inst_t *instances, *inst_last; -}; - -/* Node property */ -struct OF_prop_t { - /* Link to next property */ - OF_prop_t *next; - /* The node it belongs to */ - OF_node_t *node; - /* property name */ - const unsigned char *name; - /* property value len */ - int vlen; - /* property value buffer */ - char *value; - /* Property change callback */ - void (*cb)(OF_env_t *OF_env, OF_prop_t *prop, const void *data, int len); -}; - -/* Node method */ -enum { - OF_METHOD_INTERNAL = 0, - OF_METHOD_EXPORTED, -}; - -struct OF_method_t { - /* Link to next method */ - OF_method_t *next; - /* The package it belongs to */ - OF_node_t *node; - /* method name */ - unsigned char *name; - /* Method function pointer */ - OF_cb_t func; -}; - -/* Package instance */ -struct OF_inst_t { - /* Link to next instance of the same package */ - OF_inst_t *next; - /* Link to the parent instance */ - OF_inst_t *parent; - /* The package it belongs to */ - OF_node_t *node; - /* Instance identifier */ - uint16_t inst_id; - /* Instance data */ - void *data; -}; - -/* reg property */ -typedef struct OF_regprop_t OF_regprop_t; -struct OF_regprop_t { - uint32_t address; - uint32_t size; -}; - -/* range property */ -typedef struct OF_range_t OF_range_t; -struct OF_range_t { - uint32_t virt; - uint32_t size; - uint32_t phys; -}; - -/* Open firmware tree */ -#define OF_MAX_PACKAGE 256 -/* nodes and packages */ -__attribute__ (( section (".OpenFirmware_vars") )) -static OF_node_t *OF_node_root; -__attribute__ (( section (".OpenFirmware_vars") )) -static uint16_t OF_pack_last_id = 0; -__attribute__ (( section (".OpenFirmware_vars") )) -static uint16_t inst_last_id = 0; -/* To speed up lookup by id, we get a package table */ -__attribute__ (( section (".OpenFirmware_vars") )) -static OF_node_t *OF_packages[OF_MAX_PACKAGE]; -__attribute__ (( section (".OpenFirmware_vars") )) -static OF_node_t *OF_pack_active; - -static OF_prop_t *OF_prop_string_new (OF_env_t *env, OF_node_t *node, - const unsigned char *name, - const unsigned char *string); -static OF_prop_t *OF_prop_int_new (OF_env_t *env, OF_node_t *node, - const unsigned char *name, uint32_t value); -static OF_prop_t *OF_property_get (OF_env_t *env, OF_node_t *node, - const unsigned char *name); -static uint16_t OF_pack_handle (OF_env_t *env, OF_node_t *node); - -__attribute__ (( section (".OpenFirmware_vars") )) -static uint8_t *RTAS_memory; - -/*****************************************************************************/ -/* Node management */ -/* Insert a new node */ -__attribute__ (( section (".OpenFirmware") )) -static uint16_t OF_pack_new_id (unused OF_env_t *env, OF_node_t *node) -{ - uint16_t cur_id; - - for (cur_id = OF_pack_last_id + 1; cur_id != OF_pack_last_id; cur_id++) { - if (cur_id == (uint16_t)(OF_MAX_PACKAGE)) - cur_id = 1; - if (OF_packages[cur_id] == NULL) { - OF_packages[cur_id] = node; - OF_pack_last_id = cur_id; - return cur_id; - } - } - - return (uint16_t)(-1); -} - -static OF_node_t *OF_node_create (OF_env_t *env, OF_node_t *parent, - const unsigned char *name, uint32_t address) -{ - OF_node_t *new; - - OF_DPRINTF("New node: %s\n", name); - new = malloc(sizeof(OF_node_t)); - if (new == NULL) { - ERROR("%s can't alloc new node '%s'\n", __func__, name); - return NULL; - } - memset(new, 0, sizeof(OF_node_t)); - new->parent = parent; - new->refcount = 1; - new->link_count = 1; - new->prop_name = OF_prop_string_new(env, new, "name", name); - if (new->prop_name == NULL) { - free(new); - ERROR("%s can't alloc new node '%s' name\n", __func__, name); - return NULL; - } - new->prop_address = OF_prop_int_new(env, new, "unit-address", address); - if (new->prop_address == NULL) { - free(new->prop_name->value); - free(new->prop_name); - free(new); - ERROR("%s can't alloc new node '%s' address\n", __func__, name); - return NULL; - } - /* Link it in parent tree */ - if (parent != NULL) { - /* SHOULD LOCK */ - if (parent->children == NULL) { - parent->children = new; - } else { - parent->child_last->next = new; - } - parent->child_last = new; - } else { - /* This is a bug and should never happen, but for root node */ - if (strcmp(name, "device-tree") != 0) - ERROR("WARNING: parent of '%s' is NULL!\n", name); - } - // OF_DPRINTF("New node: %s get id\n", name); - - return new; -} - -__attribute__ (( section (".OpenFirmware") )) -static OF_node_t *OF_node_new (OF_env_t *env, OF_node_t *parent, - const unsigned char *name, uint32_t address) -{ - OF_node_t *new; - - new = OF_node_create(env, parent, name, address); - if (new == NULL) - return NULL; - new->pack_id = OF_pack_new_id(env, new); - // OF_DPRINTF("New node: %s id=0x%0x\n", name, new->pack_id); - OF_pack_active = new; - - return new; -} - -static inline OF_node_t *OF_node_parent (unused OF_env_t *env, OF_node_t *node) -{ - return node->parent; -} - -/* Look for a node, given its name */ -__attribute__ (( section (".OpenFirmware") )) -static OF_node_t *OF_node_get_child (OF_env_t *env, OF_node_t *parent, - const unsigned char *name, - uint32_t address) -{ - unsigned char tname[OF_NAMELEN_MAX]; - OF_node_t *parse, *tmp; - OF_prop_t *prop_name, *prop_address; - uint32_t *addr_valp; - int len, i; - - if (parent == OF_node_root) { - OF_DPRINTF("Look for node [%s]\n", name); - } - len = strlen(name); - memcpy(tname, name, len + 1); - for (i = len; i > 0; i--) { - if (tname[i - 1] == ',') { - tname[i - 1] = '\0'; - len = i; - break; - } - } - for (parse = parent->children; parse != NULL; parse = parse->next) { - prop_name = parse->prop_name; - prop_address = parse->prop_address; - if (prop_address == NULL) - addr_valp = NULL; - else - addr_valp = (void *)prop_address->value; -#if 0 - OF_DPRINTF("node [%s] <=> [%s]\n", prop_name->value, tname); -#endif - if (prop_name != NULL && strncmp(prop_name->value, tname, len) == 0 && - (prop_name->value[len] == '\0') && - (address == OF_ADDRESS_NONE || addr_valp == NULL || - address == *addr_valp)) { - parse->refcount++; - return parse; - } -#if 1 - OF_DPRINTF("look in children [%s]\n", prop_name->value); -#endif - tmp = OF_node_get_child(env, parse, tname, address); - if (tmp != NULL) - return tmp; -#if 0 - OF_DPRINTF("didn't find in children [%s]\n", prop_name->value); -#endif - } - if (parent == OF_node_root) { - OF_DPRINTF("node [%s] not found\n", name); - } - - return NULL; -} - -__attribute__ (( section (".OpenFirmware") )) -static OF_node_t *OF_node_get (OF_env_t *env, const unsigned char *name) -{ - unsigned char tname[OF_NAMELEN_MAX]; - unsigned char *addrp; - uint32_t address; - - if (strcmp(name, "device_tree") == 0) - return OF_node_root; - - strcpy(tname, name); - addrp = strchr(tname, '@'); - if (addrp == NULL) { - address = OF_ADDRESS_NONE; - } else { - *addrp++ = '\0'; - address = strtol(addrp, NULL, 16); - } - - /* SHOULD LOCK */ - return OF_node_get_child(env, OF_node_root, name, address); -} - -/* Release a node */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_node_put (unused OF_env_t *env, OF_node_t *node) -{ - if (--node->refcount < 0) - node->refcount = 0; -} - -/*****************************************************************************/ -/* Packages tree walk */ -__attribute__ (( section (".OpenFirmware") )) -static uint16_t OF_pack_handle (unused OF_env_t *env, OF_node_t *node) -{ - if (node == NULL) - return 0; - - return node->pack_id; -} - -__attribute__ (( section (".OpenFirmware") )) -static OF_node_t *OF_pack_find_by_name (OF_env_t *env, OF_node_t *base, - const unsigned char *name) -{ - unsigned char tmp[OF_NAMELEN_MAX], *addrp; - const unsigned char *sl, *st; - OF_node_t *parse; - OF_prop_t *prop_name, *prop_address; - uint32_t address, *addr_valp; - int len; - - OF_DPRINTF("Path [%s] in '%s'\n", name, base->prop_name->value); - st = name; - if (*st == '/') { - st++; - } - if (*st == '\0') { - /* Should never happen */ - OF_DPRINTF("Done\n"); - return base; - } - sl = strchr(st, '/'); - if (sl == NULL) { - len = strlen(st); - } else { - len = sl - st; - } - memcpy(tmp, st, len); - tmp[len] = '\0'; - addrp = strchr(tmp, '@'); - if (addrp == NULL) { - address = OF_ADDRESS_NONE; - } else { - len = addrp - tmp; - *addrp++ = '\0'; - address = strtol(addrp, NULL, 16); - } - OF_DPRINTF("Look for [%s] '%s' %08x\n", tmp, sl, address); - for (parse = base->children; parse != NULL; parse = parse->next) { - prop_name = parse->prop_name; - prop_address = parse->prop_address; - if (prop_address == NULL) - addr_valp = NULL; - else - addr_valp = (void *)prop_address->value; -#if 0 - OF_DPRINTF("Check [%s]\n", prop_name->value); -#endif - if (prop_name == NULL) { - printf("ERROR: missing address in node, parent: '%s'\n", - base->prop_name->value); - bug(); - } - if (strncmp(prop_name->value, tmp, len) == 0 && - prop_name->value[len] == '\0' && - (address == OF_ADDRESS_NONE || addr_valp == NULL || - address == *addr_valp)) { - OF_pack_active = parse; - if (sl == NULL) { - OF_DPRINTF("Done\n"); - return parse; - } - OF_DPRINTF("Recurse: '%s'\n", sl + 1); - return OF_pack_find_by_name(env, parse, sl + 1); - } - } - OF_DPRINTF("Didn't found [%s]\n", tmp); - - return NULL; -} - -__attribute__ (( section (".OpenFirmware") )) -static OF_node_t *OF_pack_find (unused OF_env_t *env, uint16_t phandle) -{ - if (phandle > OF_MAX_PACKAGE) - return NULL; - if (OF_packages[phandle] == NULL) { - OF_DPRINTF("No package %0x\n", phandle); - } else { - OF_DPRINTF("return package: %0x %p [%s]\n", phandle, - OF_packages[phandle], - OF_packages[phandle]->prop_name->value); - } - - return OF_packages[phandle]; -} - -__attribute__ (( section (".OpenFirmware") )) -static OF_node_t *OF_pack_next (OF_env_t *env, uint16_t phandle) -{ - OF_node_t *node; - - for (node = OF_pack_find(env, phandle); node != NULL; node = node->next) { - if (OF_pack_handle(env, node) != phandle) - break; - } -#if 0 - OF_DPRINTF("found node %p [%s]\n", node, node->prop_name->value); -#endif - - return node; -} - -__attribute__ (( section (".OpenFirmware") )) -static OF_node_t *OF_pack_child (OF_env_t *env, uint16_t phandle) -{ - OF_node_t *node; - - node = OF_pack_find(env, phandle); - if (node == NULL) { - ERROR("%s didn't find pack %04x\n", __func__, phandle); - return NULL; - } - node = node->children; -#if 0 - OF_DPRINTF("found node %p [%s]\n", node, node->prop_name->value); -#endif - - return node; -} - -__attribute__ (( section (".OpenFirmware") )) -static OF_node_t *OF_pack_parent (OF_env_t *env, uint16_t phandle) -{ - OF_node_t *node; - - node = OF_pack_find(env, phandle); - if (node == NULL) { - ERROR("%s didn't find pack %04x\n", __func__, phandle); - return NULL; - } - node = OF_node_parent(env, node); -#if 0 - OF_DPRINTF("found node %p [%s]\n", node, node->prop_name->value); -#endif - - return node; -} - -/*****************************************************************************/ -/* Package properties management */ -/* Insert a new property */ -__attribute__ (( section (".OpenFirmware") )) -static OF_prop_t *OF_property_new (unused OF_env_t *env, OF_node_t *node, - const unsigned char *name, - const void *data, int len) -{ - OF_prop_t *prop; - -#ifdef DEBUG_OF - { - OF_prop_t *_prop; - _prop = OF_property_get(env, node, name); - if (_prop != NULL) { - printf("Property '%s' already present !\n", name); - bug(); - } - } -#endif - /* Allocate a new property */ - prop = malloc(sizeof(OF_prop_t)); - if (prop == NULL) { - ERROR("%s cannot allocate property '%s'\n", __func__, name); - return NULL; - } - memset(prop, 0, sizeof(OF_prop_t)); - prop->name = strdup(name); - if (prop->name == NULL) { - free(prop); - ERROR("%s cannot allocate property '%s' name\n", __func__, name); - return NULL; - } - /* Fill it */ - if (data != NULL && len > 0) { - prop->value = malloc(len); - if (prop->value == NULL) { - free(prop); - ERROR("%s cannot allocate property '%s' value\n", __func__, name); - return NULL; - } - prop->vlen = len; - memcpy(prop->value, data, len); - } - OF_DPRINTF("New property [%s] '%s'\n\t%p %p %d %p\n", name, prop->name, prop->name, data, len, prop->value); - /* Link it */ - /* SHOULD LOCK */ - if (node->properties == NULL) - node->properties = prop; - else - node->prop_last->next = prop; - node->prop_last = prop; - - return prop; -} - -/* Find a property given its name */ -__attribute__ (( section (".OpenFirmware") )) -static OF_prop_t *OF_property_get (unused OF_env_t *env, OF_node_t *node, - const unsigned char *name) -{ - OF_prop_t *prop; - -#if 0 - OF_DPRINTF("Look for property [%s] in 0x%0x '%s'\n", name, - node->pack_id, node->prop_name->value); -#endif - if (node == NULL) - return NULL; - /* *SHOULD LOCK* */ - for (prop = node->properties; prop != NULL; prop = prop->next) { -#if 0 - OF_DPRINTF("property [%s] <=> [%s]\n", prop->name, name); -#endif - if (strcmp(prop->name, name) == 0) { - return prop; - } - } -#if 0 - OF_DPRINTF("property [%s] not found in 0x%08x '%s'\n", name, - node->pack_id, node->prop_name->value); -#endif - - return NULL; -} - -/* Change a property */ -__attribute__ (( section (".OpenFirmware") )) -static OF_prop_t *OF_property_set (OF_env_t *env, OF_node_t *node, - const unsigned char *name, - const void *data, int len) -{ - OF_prop_t *prop; - void *tmp; - - if (node == NULL) - return NULL; - prop = OF_property_get(env, node, name); - if (prop != NULL) { - OF_DPRINTF("change property [%s]\n", name); - tmp = malloc(len); - if (tmp == NULL && len != 0) { - ERROR("%s cannot set property '%s'\n", __func__, name); - return NULL; - } - free(prop->value); - prop->value = tmp; - prop->vlen = len; - memcpy(prop->value, data, len); - if (prop->cb != NULL) { - (*prop->cb)(env, prop, data, len); - } - } else { - OF_DPRINTF("new property [%s]\n", name); - prop = OF_property_new(env, node, name, data, len); - } - - return prop; -} - -__attribute__ (( section (".OpenFirmware") )) -static int OF_property_len (OF_env_t *env, OF_node_t *node, - const unsigned char *name) -{ - OF_prop_t *prop; - - prop = OF_property_get(env, node, name); - if (prop == NULL) - return -1; - - return prop->vlen; -} - -__attribute__ (( section (".OpenFirmware") )) -static unsigned char *hex2buf (unsigned char *buf, uint32_t value, int fill) -{ - int pos, d; - - buf[8] = '\0'; - pos = 7; - if (value == 0) { - buf[pos--] = '0'; - } else { - for (; value != 0; pos--) { - d = value & 0xF; - if (d > 9) - d += 'a' - '0' - 10; - buf[pos] = d + '0'; - value = value >> 4; - } - } - if (fill != 0) { - for (; pos != -1; pos--) { - buf[pos] = '0'; - } - } - - return &buf[pos]; -} - -__attribute__ (( section (".OpenFirmware") )) -static int OF_property_copy (OF_env_t *env, void *buffer, int maxlen, - OF_node_t *node, const unsigned char *name) -{ - unsigned char tmp[OF_PROPLEN_MAX]; - OF_prop_t *prop; - int len; - - prop = OF_property_get(env, node, name); - if (prop == NULL) { - ERROR("%s cannot get property '%s' for %s\n", __func__, name, - node->prop_name->value); - return -1; - } - len = prop->vlen > maxlen ? maxlen : prop->vlen; - if (prop->value != NULL) { - tmp[0] = '0'; - tmp[1] = 'x'; - hex2buf(tmp + 2, *((uint32_t *)prop->value), 1); - } else { - *tmp = '\0'; - } - OF_DPRINTF("copy property [%s] len=%d to %p len=%d\n", - name, prop->vlen, buffer, maxlen); - if (strcmp(name, "name") == 0) { - OF_DPRINTF("=> '%s'\n", prop->value); - } - memcpy(buffer, prop->value, len); - // OF_DPRINTF("done\n"); - - return len; -} - -__attribute__ (( section (".OpenFirmware") )) -static OF_prop_t *OF_property_next (OF_env_t *env, OF_node_t *node, - const unsigned char *name) -{ - OF_prop_t *prop, *next; - - if (name == NULL || *name == '\0') { - next = node->properties; - } else { - prop = OF_property_get(env, node, name); - if (prop == NULL) { - OF_DPRINTF("Property [%s] not found\n", name); - next = NULL; - } else { - next = prop->next; - /* Skip address if not set */ - if (next == node->prop_address && - *((uint32_t *)next->value) == OF_ADDRESS_NONE) - next = next->next; - } - } -#if 0 - OF_DPRINTF("Found property %p\n", next); -#endif - - return next; -} - -/* Simplified helpers */ -__attribute__ (( section (".OpenFirmware") )) -static OF_prop_t *OF_prop_string_new (OF_env_t *env, OF_node_t *node, - const unsigned char *name, - const unsigned char *string) -{ -#ifdef DEBUG_OF - { - OF_prop_t *prop; - prop = OF_property_get(env, node, name); - if (prop != NULL) { - printf("Property '%s' already present !\n", name); - bug(); - } - } -#endif - return OF_property_new(env, node, name, - string, strlen(string) + 1); -} - -/* convert '\1' char to '\0' */ -static OF_prop_t *OF_prop_string_new1 (OF_env_t *env, OF_node_t *node, - const unsigned char *name, - const unsigned char *string) -{ - int len, i; - OF_prop_t *ret; - unsigned char *str; - - if (strchr(string, '\1') == NULL) { - return OF_prop_string_new(env, node, name, string); - } else { - len = strlen(string) + 1; - str = malloc(len); - if (!str) - return NULL; - memcpy(str, string, len); - for(i = 0; i < len; i++) - if (str[i] == '\1') - str[i] = '\0'; - ret = OF_property_new(env, node, name, - str, len); - free(str); - return ret; - } -} - -__attribute__ (( section (".OpenFirmware") )) -static OF_prop_t *OF_prop_int_new (OF_env_t *env, OF_node_t *node, - const unsigned char *name, uint32_t value) -{ -#ifdef DEBUG_OF - { - OF_prop_t *prop; - prop = OF_property_get(env, node, name); - if (prop != NULL) { - printf("Property '%s' already present !\n", name); - bug(); - } - } -#endif - return OF_property_new(env, node, name, &value, sizeof(uint32_t)); -} - -__attribute__ (( section (".OpenFirmware") )) -static OF_prop_t *OF_prop_string_set (OF_env_t *env, OF_node_t *node, - const unsigned char *name, - const unsigned char *string) -{ - const unsigned char *tmp; - - tmp = strdup(string); - if (tmp == NULL) { - ERROR("%s cannot duplicate property '%s'\n", __func__, name); - return NULL; - } - - return OF_property_set(env, node, name, tmp, strlen(string) + 1); -} - -__attribute__ (( section (".OpenFirmware") )) -static OF_prop_t *OF_prop_int_set (OF_env_t *env, OF_node_t *node, - const unsigned char *name, uint32_t value) -{ - return OF_property_set(env, node, name, &value, sizeof(uint32_t)); -} - -__attribute__ (( section (".OpenFirmware") )) -unused -static OF_prop_t *OF_set_compatibility (OF_env_t *env, OF_node_t *node, - const unsigned char *compat) -{ - return OF_prop_string_new(env, node, "compatible", compat); -} - -__attribute__ (( section (".OpenFirmware") )) -static inline void OF_property_set_cb (unused OF_env_t *OF_env, - OF_prop_t *prop, - void (*cb)(OF_env_t *OF_env, - OF_prop_t *prop, - const void *data, int len)) -{ - prop->cb = cb; -} - -/*****************************************************************************/ -/* Packages methods management */ -__attribute__ (( section (".OpenFirmware") )) -static OF_method_t *OF_method_new (unused OF_env_t *env, OF_node_t *node, - const unsigned char *name, OF_cb_t cb) -{ - OF_method_t *new; - - new = malloc(sizeof(OF_method_t)); - if (new == NULL) { - ERROR("%s cannot allocate method '%s'\n", __func__, name); - return NULL; - } - memset(new, 0, sizeof(OF_method_t)); - new->node = node; - new->name = strdup(name); - if (new->name == NULL) { - free(new); - ERROR("%s cannot allocate method '%s' name\n", __func__, name); - return NULL; - } - OF_DPRINTF("new method name %p %s\n", new, new->name); - new->func = cb; - /* Link it */ - /* *SHOULD LOCK* */ - if (node->method_last == NULL) - node->methods = new; - else - node->method_last->next = new; - node->method_last = new; - - return new; -} - -__attribute__ (( section (".OpenFirmware") )) -static OF_method_t *OF_method_get (unused OF_env_t *env, OF_node_t *node, - const unsigned char *name) -{ - OF_method_t *parse; - - if (node == NULL) { - OF_DPRINTF("No method in NULL package !\n"); - return NULL; - } -#if 0 - OF_DPRINTF("Look for method %s in package %0x\n", - name, node->pack_id); -#endif - for (parse = node->methods; parse != NULL; parse = parse->next) { -#if 0 - OF_DPRINTF("check %p %p\n", parse, parse->name); - OF_DPRINTF("name=%s\n", parse->name); -#endif - if (strcmp(parse->name, name) == 0) - return parse; - } - - return NULL; -} - -/*****************************************************************************/ -/* Packages instances management */ -__attribute__ (( section (".OpenFirmware") )) -static uint16_t OF_inst_new_id (unused OF_env_t *env, OF_node_t *node) -{ - OF_inst_t *tmp_inst; - uint16_t cur_id; - -#if 0 - OF_DPRINTF("[%s] %d\n", node->prop_name->value, - inst_last_id); -#endif - for (cur_id = inst_last_id + 1; - cur_id != inst_last_id; cur_id++) { - if (cur_id == (uint16_t)(OF_MAX_PACKAGE)) - cur_id = 0; - for (tmp_inst = node->instances; tmp_inst != NULL; - tmp_inst = tmp_inst->next) { - if (tmp_inst->inst_id == cur_id) - continue; - } - inst_last_id = cur_id; -#if 1 - OF_DPRINTF("0x%0x\n", cur_id); -#endif - return cur_id; - } - OF_DPRINTF("no ID found\n"); - - return (uint16_t)(-1); -} - -/* Create a new package's instance */ -__attribute__ (( section (".OpenFirmware") )) -static OF_inst_t *OF_instance_new (OF_env_t *env, OF_node_t *node) -{ - OF_inst_t *new, *parent; - uint16_t new_id; - - /* TODO: recurse to root... */ - new = malloc(sizeof(OF_inst_t)); - if (new == NULL) { - ERROR("%s cannot allocate instance of '%s'\n", __func__, - node->prop_name->value); - return NULL; - } - memset(new, 0, sizeof(OF_inst_t)); - if (OF_node_parent(env, node) != NULL) { - parent = OF_instance_new(env, OF_node_parent(env, node)); - if (parent == NULL) { - free(new); - ERROR("%s cannot allocate instance of '%s' parent\n", __func__, - node->prop_name->value); - return NULL; - } - new->parent = parent; - } else { - new->parent = NULL; - } - new_id = OF_inst_new_id(env, node); - if (new_id == (uint16_t)(-1)) { - free(new); - return NULL; - } - new->inst_id = new_id; - new->node = node; - /* Link it */ - /* SHOULD LOCK */ - if (node->inst_last == NULL) - node->instances = new; - else - node->inst_last->next = new; - node->inst_last = new; - - return new; -} - -__attribute__ (( section (".OpenFirmware") )) -static uint32_t OF_instance_get_id (unused OF_env_t *env, OF_inst_t *instance) -{ - OF_DPRINTF("p: %0x i: %0x\n", instance->node->pack_id, instance->inst_id); - return (instance->node->pack_id << 16) | instance->inst_id; -} - -__attribute__ (( section (".OpenFirmware") )) -static OF_inst_t *OF_inst_find (OF_env_t *env, uint32_t ihandle) -{ - OF_node_t *node; - OF_inst_t *parse; - uint16_t phandle = ihandle >> 16; - - ihandle &= 0xFFFF; - OF_DPRINTF("p: %0x i: %0x\n", phandle, ihandle); - if (ihandle > OF_MAX_PACKAGE) - return NULL; - node = OF_pack_find(env, phandle); - if (node == NULL) - return NULL; - for (parse = node->instances; parse != NULL; parse = parse->next) { - if (parse->inst_id == ihandle) - return parse; - } - - return NULL; -} - -#if 0 -__attribute__ (( section (".OpenFirmware") )) -static OF_inst_t *OF_inst_get_child (OF_env_t *env, OF_node_t *parent, - const uint32_t handle) -{ - OF_node_t *parse, *tmp; - - for (parse = parent->children; parse != NULL; parse = parse->next) { - if (parse->pack_id == (handle >> 16)) { - return NULL; - } - tmp = OF_inst_get_child(env, parse, handle); - if (tmp != NULL) - return tmp; - } - - return NULL; -} - -__attribute__ (( section (".OpenFirmware") )) -static OF_inst_t *OF_inst_get (OF_env_t *env, const unsigned char *name) -{ - return _OF_node_get(env, &OF_node_root); - -} -#endif - -#if 0 -__attribute__ (( section (".OpenFirmware") )) -int get_node_name (OF_env_t *env, unsigned char *name, - int len, OF_node_t *node) -{ - int tmp, total; - int i; - - /* Set up manufacturer name */ - total = 0; - tmp = 0; -#if 0 - if (OF_node_parent(env, node) == NULL || - node->manufct != OF_node_parent(env, node)->manufct) { - tmp = strlen(node->manufct); - if ((tmp + 2) > len) - return -1; - memcpy(name, node->manufct, tmp); - name += tmp; - } else if (len < 2) { - return -1; - } - *name++ = ','; - len -= tmp + 1; - total += tmp + 1; -#endif - /* Set up device model */ - tmp = strlen(node->name); - if ((tmp + 2) > len) - return -1; - memcpy(name, node->model, tmp); - name += tmp; - *name++ = '@'; - len -= tmp + 1; - total += tmp + 1; - /* Set up unit address */ - tmp = strlen(node->address); - if ((tmp + 2) > len) - return -1; - memcpy(name, node->address, tmp); - name += tmp; - *name++ = ':'; - len -= tmp + 1; - total += tmp + 1; - for (i = 0; node->arguments[i] != NULL; i++) { - if (i != 0) - *name++ = ','; - tmp = strlen(node->arguments[i]); - if ((tmp + 2) > len) - return -1; - memcpy(name, node->arguments[i], tmp); - name += tmp; - len -= tmp + 1; - total += tmp + 1; - } - *name = '\0'; - - return total; -} -#endif - -__attribute__ (( section (".OpenFirmware") )) -static int OF_pack_get_path (OF_env_t *env, unsigned char *name, - int len, OF_node_t *node) -{ - OF_prop_t *prop_name, *prop_address; - uint32_t address; - int tmp, nlen; - - /* Recurse until we reach the root node */ - OF_DPRINTF("look for [%s]\n", node->prop_name->value); - if (OF_node_parent(env, node) == NULL) { - name[0] = '/'; - tmp = 0; - nlen = 1; - } else { - tmp = OF_pack_get_path(env, name, len, OF_node_parent(env, node)); - /* Add node name */ - prop_name = node->prop_name; - prop_address = node->prop_address; -#if 1 - OF_DPRINTF("Found [%s]\n", prop_name->value); -#endif - if ((len - tmp) < 2) { - OF_DPRINTF("Buffer too short (%d 2)\n", len - tmp); - return 0; - } - if (prop_name == NULL) { - printf("No name in node !\n"); - bug(); - } - nlen = strlen(prop_name->value); -#if 1 - OF_DPRINTF("got '%s' for '%s' parent (%d %d)\n", - name, prop_name->value, tmp, nlen); -#endif - if (name[tmp - 1] != '/') { - name[tmp] = '/'; - tmp++; - } - address = *((uint32_t *)prop_address->value); - if (address != OF_ADDRESS_NONE) { - if ((len - tmp - nlen) < 10) { - OF_DPRINTF("Buffer too short (%d %d)\n", len - tmp, nlen + 10); - return 0; - } - } else { - if ((len - tmp - nlen) < 1) { - OF_DPRINTF("Buffer too short (%d %d)\n", len - tmp, nlen + 1); - return 0; - } - } - memcpy(name + tmp, prop_name->value, nlen); - if (address != OF_ADDRESS_NONE) { - OF_DPRINTF("Add address 0x%08x\n", address); - sprintf(name + tmp + nlen, "@%x", address); - nlen += strlen(name + tmp + nlen); - } else { - OF_DPRINTF("No address....\n"); - } - } - name[tmp + nlen] = '\0'; - OF_DPRINTF("stored [%d]\n", tmp + nlen); - OF_DUMP_STRING(env, name); -#if 1 - OF_DPRINTF("name '%s' => '%s' %d\n", - node->properties->value, name, tmp + nlen); -#endif - - return tmp + nlen; -} - -__attribute__ (( section (".OpenFirmware") )) -static int OF_inst_get_path (OF_env_t *env, unsigned char *name, - int len, OF_inst_t *inst) -{ - return OF_pack_get_path(env, name, len, inst->node); -} - -/*****************************************************************************/ -/* Open firmware C interface */ -static void OF_serial_write (OF_env_t *OF_env); -static void OF_serial_read (OF_env_t *OF_env); -static void OF_mmu_translate (OF_env_t *OF_env); -static void OF_mmu_map (OF_env_t *OF_env); -static void RTAS_instantiate (OF_env_t *RTAS_env); - -static OF_env_t *OF_env_main; - -/* Init standard OF structures */ -__attribute__ (( section (".OpenFirmware") )) -int OF_init (void) -{ -#if 0 - "PowerMac3,1\0MacRISC\0Power Macintosh\0"; - "PowerMac1,2\0MacRISC\0Power Macintosh\0"; - "AAPL,PowerMac G3\0PowerMac G3\0MacRISC\0Power Macintosh\0"; - "AAPL,PowerMac3,0\0MacRISC\0Power Macintosh\0"; - "AAPL,Gossamer\0MacRISC\0Power Macintosh\0"; -#endif - OF_env_t *OF_env; - OF_node_t *als, *opt, *chs, *pks; - OF_inst_t *inst; - OF_range_t range; - - OF_DPRINTF("start\n"); - OF_env_main = malloc(sizeof(OF_env_t)); - if (OF_env_main == NULL) { - ERROR("%s cannot allocate main OF env\n", __func__); - return -1; - } - // memset(OF_env_main, 0, sizeof(OF_env_t)); - OF_env = OF_env_main; - // OF_env_init(OF_env); - - OF_DPRINTF("start\n"); - /* Set up standard IEEE 1275 nodes */ - /* "/device-tree" */ - OF_node_root = OF_node_new(OF_env, NULL, "device-tree", OF_ADDRESS_NONE); - if (OF_node_root == NULL) { - ERROR("Cannot create 'device-tree'\n"); - return -1; - } - OF_prop_string_new(OF_env, OF_node_root, "device_type", "bootrom"); - if (arch == ARCH_HEATHROW) { - const unsigned char compat_str[] = - "PowerMac1,1\0MacRISC\0Power Macintosh"; - OF_property_new(OF_env, OF_node_root, "compatible", - compat_str, sizeof(compat_str)); - OF_prop_string_new(OF_env, OF_node_root, - "model", "Power Macintosh"); - } else { - const unsigned char compat_str[] = - "PowerMac3,1\0MacRISC\0Power Macintosh"; - OF_property_new(OF_env, OF_node_root, "compatible", - compat_str, sizeof(compat_str)); - OF_prop_string_new(OF_env, OF_node_root, - "model", "PowerMac3,1"); - } -#if 0 - OF_prop_string_new(OF_env, OF_node_root, "copyright", copyright); -#else - OF_prop_string_new(OF_env, OF_node_root, "copyright", - "Copyright 1983-1999 Apple Computer, Inc. All Rights Reserved"); -#endif - OF_prop_string_new(OF_env, OF_node_root, "system-id", "42"); - OF_prop_int_new(OF_env, OF_node_root, "#address-cells", 1); - OF_prop_int_new(OF_env, OF_node_root, "#size-cells", 1); - OF_prop_int_new(OF_env, OF_node_root, "clock-frequency", 0x05F03E4D); - /* "/aliases" node */ - als = OF_node_new(OF_env, OF_node_root, "aliases", OF_ADDRESS_NONE); - if (als == NULL) { - ERROR("Cannot create 'aliases'\n"); - return -1; - } - /* "/chosen" node */ - chs = OF_node_new(OF_env, OF_node_root, "chosen", OF_ADDRESS_NONE); - if (chs == NULL) { - ERROR("Cannot create 'choosen'\n"); - return -1; - } - /* "/packages" node */ - pks = OF_node_new(OF_env, OF_node_root, "packages", OF_ADDRESS_NONE); - if (pks == NULL) { - ERROR("Cannot create 'packages'\n"); - return -1; - } - /* "/cpus" node */ - { - OF_node_t *cpus; - cpus = OF_node_new(OF_env, OF_node_root, "cpus", OF_ADDRESS_NONE); - if (cpus == NULL) { - ERROR("Cannot create 'cpus'\n"); - return -1; - } - OF_prop_int_new(OF_env, cpus, "#address-cells", 1); - OF_prop_int_new(OF_env, cpus, "#size-cells", 0); - OF_node_put(OF_env, cpus); - } - /* "/memory@0" node */ - { - OF_node_t *mem; - mem = OF_node_new(OF_env, OF_node_root, "memory", 0); - if (mem == NULL) { - ERROR("Cannot create 'memory'\n"); - return -1; - } - OF_prop_string_new(OF_env, mem, "device_type", "memory"); - OF_prop_int_new(OF_env, chs, "memory", OF_pack_handle(OF_env, mem)); - OF_node_put(OF_env, mem); - } - /* "/openprom" node */ - { - OF_node_t *opp; - opp = OF_node_new(OF_env, OF_node_root, "openprom", OF_ADDRESS_NONE); - if (opp == NULL) { - ERROR("Cannot create 'openprom'\n"); - return -1; - } - OF_prop_string_new(OF_env, opp, "device_type", "BootROM"); - OF_prop_string_new(OF_env, opp, "model", "OpenFirmware 3"); - OF_prop_int_new(OF_env, opp, "boot-syntax", 0x0001); - OF_property_new(OF_env, opp, "relative-addressing", NULL, 0); - OF_property_new(OF_env, opp, "supports-bootinfo", NULL, 0); - OF_prop_string_new(OF_env, opp, "built-on", stringify(BUILD_DATE)); - OF_prop_string_new(OF_env, als, "rom", "/openprom"); - OF_node_put(OF_env, opp); - } - /* "/options" node */ - opt = OF_node_new(OF_env, OF_node_root, "options", OF_ADDRESS_NONE); - if (opt == NULL) { - ERROR("Cannot create 'options'\n"); - return -1; - } - OF_prop_string_new(OF_env, opt, "little-endian?", "false"); - OF_prop_string_new(OF_env, opt, "real-mode?", "false"); - // Will play with this... - OF_prop_string_new(OF_env, opt, "security-mode", "none"); - /* "/rom@ff800000" node */ - { - OF_regprop_t regs; - OF_node_t *rom, *brom; - - rom = OF_node_new(OF_env, OF_node_root, "rom", 0xff800000); - if (rom == NULL) { - ERROR("Cannot create 'rom'\n"); - return -1; - } - regs.address = 0xFF800000; - regs.size = 0x00000000; - OF_property_new(OF_env, rom, "reg", ®s, sizeof(OF_regprop_t)); - range.virt = 0xFF800000; - range.phys = 0xFF800000; - range.size = 0x00800000; - OF_property_new(OF_env, rom, "ranges", &range, sizeof(OF_range_t)); - OF_prop_int_new(OF_env, rom, "#address-cells", 1); - - /* "/rom/boot-rom@fff00000" node */ - brom = OF_node_new(OF_env, rom, "boot-rom", 0xfff00000); - if (brom == NULL) { - ERROR("Cannot create 'boot-rom'\n"); - return -1; - } - regs.address = 0xFFF00000; - regs.size = 0x00100000; - OF_property_new(OF_env, brom, "reg", ®s, sizeof(OF_regprop_t)); - OF_prop_string_new(OF_env, brom, "write-characteristic", "flash"); - OF_prop_string_new(OF_env, brom, "BootROM-build-date", - stringify(BUILD_DATE) " at " stringify(BUILD_TIME)); - OF_prop_string_new(OF_env, brom, "BootROM-version", BIOS_VERSION); - OF_prop_string_new(OF_env, brom, "copyright", copyright); - OF_prop_string_new(OF_env, brom, "model", BIOS_str); - OF_prop_int_new(OF_env, brom, "result", 0); -#if 1 - { - /* Hack taken 'as-is' from PearPC */ - unsigned char info[] = { - 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, - 0x00, 0x01, 0x12, 0xf2, 0x19, 0x99, 0x08, 0x19, - 0x94, 0x4e, 0x73, 0x27, 0xff, 0xf0, 0x80, 0x00, - 0x00, 0x07, 0x80, 0x01, 0x00, 0x01, 0x12, 0xf2, - 0x19, 0x99, 0x08, 0x19, 0xd7, 0xf3, 0xfc, 0x17, - 0xff, 0xf8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, - 0x00, 0x01, 0x12, 0xf2, 0x19, 0x99, 0x08, 0x19, - 0xbb, 0x10, 0xfc, 0x17, - }; - OF_property_new(OF_env, brom, "info", info, sizeof(info)); - } -#endif - OF_node_put(OF_env, brom); - OF_node_put(OF_env, rom); - } -#if 0 - /* From here, hardcoded hacks to get a Mac-like machine */ - /* XXX: Core99 does not seem to like this NVRAM tree */ - /* "/nvram@fff04000" node */ - { - OF_regprop_t regs; - OF_node_t *nvr; - - nvr = OF_node_new(OF_env, OF_node_root, "nvram", 0xfff04000); - if (nvr == NULL) { - ERROR("Cannot create 'nvram'\n"); - return -1; - } - OF_prop_string_new(OF_env, nvr, "device_type", "nvram"); - /* XXX: use real NVRAM size instead */ - OF_prop_int_new(OF_env, nvr, "#bytes", 0x2000); - OF_prop_string_new(OF_env, nvr, "compatible", "nvram,flash"); - regs.address = 0xFFF04000; - regs.size = 0x00004000; /* Strange, isn't it ? */ - OF_property_new(OF_env, nvr, "reg", ®s, sizeof(regs)); - OF_prop_int_new(OF_env, chs, "nvram", OF_pack_handle(OF_env, nvr)); - OF_node_put(OF_env, nvr); - } -#endif - /* "/pseudo-hid" : hid emulation as Apple does */ - { - OF_node_t *hid; - - hid = OF_node_new(OF_env, OF_node_root, - "pseudo-hid", OF_ADDRESS_NONE); - if (hid == NULL) { - ERROR("Cannot create 'pseudo-hid'\n"); - return -1; - } - - /* "keyboard" node */ - { - OF_node_t *kbd; - kbd = OF_node_new(OF_env, hid, "keyboard", OF_ADDRESS_NONE); - if (kbd == NULL) { - ERROR("Cannot create 'keyboard'\n"); - return -1; - } - OF_prop_string_new(OF_env, kbd, "device_type", "keyboard"); - OF_node_put(OF_env, kbd); - } - /* "mouse" node */ - { - OF_node_t *mouse; - mouse = OF_node_new(OF_env, hid, "mouse", OF_ADDRESS_NONE); - if (mouse == NULL) { - ERROR("Cannot create 'mouse'\n"); - return -1; - } - OF_prop_string_new(OF_env, mouse, "device_type", "mouse"); - OF_node_put(OF_env, mouse); - } - /* "eject-key" node */ - { - OF_node_t *ejk; - ejk = OF_node_new(OF_env, hid, "eject-key", OF_ADDRESS_NONE); - if (ejk == NULL) { - ERROR("Cannot create 'eject-key'\n"); - return -1; - } - OF_prop_string_new(OF_env, ejk, "device_type", "eject-key"); - OF_node_put(OF_env, ejk); - } - OF_node_put(OF_env, hid); - } - if (arch == ARCH_MAC99) { - OF_node_t *unin; - OF_regprop_t regs; - - unin = OF_node_new(OF_env, OF_node_root, - "uni-n", 0xf8000000); - if (unin == NULL) { - ERROR("Cannot create 'uni-n'\n"); - return -1; - } - OF_prop_string_new(OF_env, unin, "device-type", "memory-controller"); - OF_prop_string_new(OF_env, unin, "model", "AAPL,UniNorth"); - OF_prop_string_new(OF_env, unin, "compatible", "uni-north"); - regs.address = 0xf8000000; - regs.size = 0x01000000; - OF_property_new(OF_env, unin, "reg", ®s, sizeof(regs)); - OF_prop_int_new(OF_env, unin, "#address-cells", 1); - OF_prop_int_new(OF_env, unin, "#size-cells", 1); - OF_prop_int_new(OF_env, unin, "device-rev", 3); - OF_node_put(OF_env, unin); - } - -#if 1 /* This is mandatory for claim to work - * but I don't know where it should really be (in cpu ?) - */ - { - OF_node_t *mmu; - - /* "/mmu" node */ - mmu = OF_node_new(OF_env, OF_node_root, "mmu", OF_ADDRESS_NONE); - if (mmu == NULL) { - ERROR("Cannot create 'mmu'\n"); - return -1; - } - inst = OF_instance_new(OF_env, mmu); - if (inst == NULL) { - OF_node_put(OF_env, mmu); - ERROR("Cannot create 'mmu' instance\n"); - return -1; - } - OF_prop_int_new(OF_env, chs, "mmu", - OF_instance_get_id(OF_env, inst)); - OF_method_new(OF_env, mmu, "translate", &OF_mmu_translate); - OF_method_new(OF_env, mmu, "map", &OF_mmu_map); - OF_node_put(OF_env, mmu); - } -#endif - - /* "/options/boot-args" node */ - { - // const unsigned char *args = "-v rootdev cdrom"; - //const unsigned char *args = "-v io=0xffffffff"; - const unsigned char *args = "-v"; - /* Ask MacOS X to print debug messages */ - // OF_prop_string_new(OF_env, chs, "machargs", args); - // OF_prop_string_new(OF_env, opt, "boot-command", args); - OF_prop_string_new(OF_env, opt, "boot-args", args); - } - - /* Release nodes */ - OF_node_put(OF_env, opt); - OF_node_put(OF_env, pks); - OF_node_put(OF_env, chs); - OF_node_put(OF_env, als); - OF_node_put(OF_env, OF_node_root); - OF_DPRINTF("done\n"); - - return 0; -} - -/* Motherboard */ -#if 0 // For now, static values are used -__attribute__ (( section (".OpenFirmware") )) -int OF_register_mb (const unsigned char *model, const unsigned char **compats) -{ - OF_env_t *OF_env; - OF_node_t *root; - int i; - - OF_env = OF_env_main; - OF_DPRINTF("start\n"); - root = OF_node_get(OF_env, "device_tree"); - if (root == NULL) { - ERROR("Cannot get 'device-tree'\n"); - return -1; - } - OF_DPRINTF("add model\n"); - OF_prop_string_new(OF_env, OF_node_root, "model", model); - for (i = 0; i < 1 && compats[i] != NULL; i++) { - OF_DPRINTF("add compats %s\n", compats[i]); - OF_set_compatibility(OF_env, OF_node_root, compats[i]); - } - /* we don't implement neither "l2-cache" nor "cache" nodes */ - OF_node_put(OF_env, root); - OF_DPRINTF("done\n"); - - return 0; -} -#endif - -/* CPU */ -__attribute__ (( section (".OpenFirmware") )) -int OF_register_cpu (const unsigned char *name, int num, uint32_t pvr, - uint32_t min_freq, uint32_t max_freq, uint32_t bus_freq, - uint32_t tb_freq, uint32_t reset_io) -{ - unsigned char tmp[OF_NAMELEN_MAX]; - OF_env_t *OF_env; - OF_node_t *cpus, *cpu, *l2c, *chs, *als; - - OF_env = OF_env_main; - OF_DPRINTF("start\n"); - cpus = OF_node_get(OF_env, "cpus"); - if (cpus == NULL) { - ERROR("Cannot get 'cpus'\n"); - return -1; - } - cpu = OF_node_new(OF_env, cpus, name, OF_ADDRESS_NONE); - if (cpu == NULL) { - OF_node_put(OF_env, cpus); - ERROR("Cannot create cpu '%s'\n", name); - return -1; - } - OF_prop_string_new(OF_env, cpu, "device_type", "cpu"); - OF_prop_int_new(OF_env, cpu, "#address-cells", 0x00000001); - OF_prop_int_new(OF_env, cpu, "#size-cells", 0x00000000); - OF_prop_int_new(OF_env, cpu, "reg", num); - OF_prop_int_new(OF_env, cpu, "cpu-version", pvr); - OF_prop_int_new(OF_env, cpu, "clock-frequency", max_freq); - OF_prop_int_new(OF_env, cpu, "timebase-frequency", tb_freq); - OF_prop_int_new(OF_env, cpu, "bus-frequency", bus_freq); - OF_prop_int_new(OF_env, cpu, "min-clock-frequency", min_freq); - OF_prop_int_new(OF_env, cpu, "max-clock-frequency", max_freq); - OF_prop_int_new(OF_env, cpu, "tlb-size", 0x80); - OF_prop_int_new(OF_env, cpu, "tlb-sets", 0x40); - OF_prop_int_new(OF_env, cpu, "i-tlb-size", 0x40); - OF_prop_int_new(OF_env, cpu, "i-tlb-sets", 0x20); - OF_prop_int_new(OF_env, cpu, "i-cache-size", 0x8000); - OF_prop_int_new(OF_env, cpu, "i-cache-sets", 0x80); - OF_prop_int_new(OF_env, cpu, "i-cache-bloc-size", 0x20); - OF_prop_int_new(OF_env, cpu, "i-cache-line-size", 0x20); - OF_prop_int_new(OF_env, cpu, "d-tlb-size", 0x40); - OF_prop_int_new(OF_env, cpu, "d-tlb-sets", 0x20); - OF_prop_int_new(OF_env, cpu, "d-cache-size", 0x8000); - OF_prop_int_new(OF_env, cpu, "d-cache-sets", 0x80); - OF_prop_int_new(OF_env, cpu, "d-cache-bloc-size", 0x20); - OF_prop_int_new(OF_env, cpu, "d-cache-line-size", 0x20); - OF_prop_int_new(OF_env, cpu, "reservation-granule-size", 0x20); - OF_prop_int_new(OF_env, cpus, "soft-reset", reset_io); - OF_prop_string_new(OF_env, cpus, "graphics", ""); - OF_prop_string_new(OF_env, cpus, "performance-monitor", ""); - OF_prop_string_new(OF_env, cpus, "data-streams", ""); - OF_prop_string_new(OF_env, cpu, "state", "running"); - /* We don't implement: - * "dynamic-powerstep" & "reduced-clock-frequency" - * "l2cr-value" - */ - /* Add L2 cache */ - l2c = OF_node_new(OF_env, cpu, "l2cache", OF_ADDRESS_NONE); - if (l2c == NULL) { - ERROR("Cannot create 'l2cache'\n"); - return -1; - } - OF_prop_string_new(OF_env, l2c, "device_type", "cache"); - OF_prop_int_new(OF_env, l2c, "i-cache-size", 0x100000); - OF_prop_int_new(OF_env, l2c, "i-cache-sets", 0x2000); - OF_prop_int_new(OF_env, l2c, "i-cache-line-size", 0x40); - OF_prop_int_new(OF_env, l2c, "d-cache-size", 0x100000); - OF_prop_int_new(OF_env, l2c, "d-cache-sets", 0x2000); - OF_prop_int_new(OF_env, l2c, "d-cache-line-size", 0x40); - /* Register it in the cpu node */ - OF_prop_int_new(OF_env, cpu, "l2-cache", OF_pack_handle(OF_env, l2c)); - OF_node_put(OF_env, l2c); - /* Set it in "/chosen" and "/aliases" */ - if (num == 0) { - OF_pack_get_path(OF_env, tmp, 512, cpu); - chs = OF_node_get(OF_env, "chosen"); - if (chs == NULL) { - OF_node_put(OF_env, cpus); - ERROR("Cannot get 'chosen'\n"); - return -1; - } - OF_prop_int_new(OF_env, chs, "cpu", OF_pack_handle(OF_env, cpu)); - OF_node_put(OF_env, chs); - als = OF_node_get(OF_env, "aliases"); - if (als == NULL) { - OF_node_put(OF_env, cpus); - ERROR("Cannot get 'aliases'\n"); - return -1; - } - OF_prop_string_new(OF_env, als, "cpu", tmp); - OF_node_put(OF_env, als); - } - OF_node_put(OF_env, cpu); - OF_node_put(OF_env, cpus); - OF_DPRINTF("done\n"); - - return 0; -} - -__attribute__ (( section (".OpenFirmware") )) -int OF_register_translations (int nb, OF_transl_t *translations) -{ - OF_env_t *OF_env; - OF_node_t *cpus, *cpu; - OF_transl_t *new; - int i; - - OF_env = OF_env_main; - OF_DPRINTF("start\n"); - cpus = OF_node_get(OF_env, "cpus"); - if (cpus == NULL) { - OF_node_put(OF_env, cpus); - ERROR("Cannot get 'cpus'\n"); - return -1; - } - cpu = cpus->children; - new = malloc(nb * sizeof(OF_transl_t)); - if (new == NULL) { - ERROR("Cannot create new translation\n"); - return -1; - } - for (i = 0; i < nb; i++) { - new->virt = translations[i].virt; - new->size = translations[i].size; - new->phys = translations[i].phys; - new->mode = translations[i].mode; - OF_DPRINTF("%d\n", i); - } - OF_property_new(OF_env, cpu, "translations", - new, nb * sizeof(OF_transl_t)); - OF_node_put(OF_env, cpus); - OF_DPRINTF("done\n"); - - return 0; -} - -/* Memory ranges */ -typedef struct OF_mem_t OF_mem_t; -struct OF_mem_t { - uint32_t start; - uint32_t size; -}; - -#define OF_MAX_MEMRANGES 16 -/* First entry is the whole known memory space */ -static OF_mem_t OF_mem_ranges[OF_MAX_MEMRANGES + 1]; - -__attribute__ (( section (".OpenFirmware") )) -int OF_register_memory (uint32_t memsize, unused uint32_t bios_size) -{ - OF_env_t *OF_env; - OF_node_t *mem; - OF_regprop_t regs[4]; - int i; - - OF_env = OF_env_main; - OF_DPRINTF("find node\n"); - mem = OF_node_get(OF_env, "memory"); - if (mem == NULL) { - ERROR("Cannot get 'memory'\n"); - return -1; - } - OF_DPRINTF("Memory package: %04x\n", OF_pack_handle(OF_env, mem)); - regs[0].address = 0x00000000; - regs[0].size = memsize; - regs[1].address = 0x00000000; - regs[1].size = 0x00000000; - regs[2].address = 0x00000000; - regs[2].size = 0x00000000; - regs[3].address = 0x00000000; - regs[3].size = 0x00000000; - OF_property_new(OF_env, mem, "reg", regs, 4 * sizeof(OF_regprop_t)); -#if 0 -#if 1 - regs[0].address = 0x00000000; - regs[0].size = 0x05800000; - regs[1].address = 0x06000000; - regs[1].size = memsize - 0x06000000; - regs[2].address = 0x00000000; - regs[2].size = 0x00000000; - OF_property_new(OF_env, mem, "available", - regs, 3 * sizeof(OF_regprop_t)); -#else - regs[0].address = 0x06000000; - regs[0].size = memsize - 0x06000000; - regs[1].address = 0x00000000; - regs[1].size = 0x00000000; - OF_property_new(OF_env, mem, "available", - regs, 2 * sizeof(OF_regprop_t)); -#endif -#endif - OF_node_put(OF_env, mem); -#if 0 - { - OF_node_t *mmu; - mmu = OF_node_get(OF_env, "mmu"); - if (mmu == NULL) { - ERROR("Cannot get 'mmu'\n"); - return -1; - } - regs[0].address = 0x00000000; - regs[0].size = memsize; - OF_property_new(OF_env, mmu, "reg", regs, sizeof(OF_regprop_t)); - regs[0].address = 0x00000000; - regs[0].size = 0x05800000; - regs[1].address = 0x06000000; - regs[1].size = memsize - 0x06000000; - regs[2].address = 0x00000000; - regs[2].size = 0x00000000; - OF_property_new(OF_env, mmu, "available", - regs, 3 * sizeof(OF_regprop_t)); - OF_node_put(OF_env, mmu); - } -#endif - /* Also update the claim areas */ - OF_mem_ranges[0].start = 0x00000000; - OF_mem_ranges[0].size = memsize; - OF_mem_ranges[1].start = 0x58000000; - OF_mem_ranges[1].size = 0x08000000; - for (i = 2; i < OF_MAX_MEMRANGES + 1; i++) { - OF_mem_ranges[i].start = -1; - OF_mem_ranges[i].size = -1; - } - OF_DPRINTF("done\n"); - - return 0; -} - -/* Linux kernel command line */ -__attribute__ (( section (".OpenFirmware") )) -int OF_register_bootargs (const unsigned char *bootargs) -{ - OF_env_t *OF_env; - OF_node_t *chs; - - OF_env = OF_env_main; - if (bootargs == NULL) - bootargs = ""; - chs = OF_node_get(OF_env, "chosen"); - if (chs == NULL) { - ERROR("Cannot get 'chosen'\n"); - return -1; - } - OF_prop_string_set(OF_env, chs, "bootargs", bootargs); - // OF_prop_string_set(OF_env, OF_node_root, "bootargs", ""); - OF_node_put(OF_env, chs); - - return 0; -} - -__attribute__ (( section (".OpenFirmware") )) -static void *OF_pci_device_new (OF_env_t *OF_env, OF_node_t *parent, - pci_dev_t *dev, uint32_t address, - uint16_t rev, uint32_t ccode, - uint16_t min_grant, uint16_t max_latency) -{ - OF_node_t *node; - - dprintf("register '%s' '%s' '%s' '%s' 0x%08x in '%s' 0x%08x\n", - dev->name, dev->type, dev->compat, dev->model, address, - parent->prop_name->value, *(uint32_t *)parent->prop_address->value); - node = OF_node_new(OF_env, parent, dev->name, address); - if (node == NULL) - return NULL; - OF_prop_int_new(OF_env, node, "vendor-id", dev->vendor); - OF_prop_int_new(OF_env, node, "device-id", dev->product); - OF_prop_int_new(OF_env, node, "revision-id", rev); - OF_prop_int_new(OF_env, node, "class-code", ccode); - OF_prop_int_new(OF_env, node, "min-grant", min_grant); - OF_prop_int_new(OF_env, node, "max-latency", max_latency); - if (dev->type != NULL) - OF_prop_string_new1(OF_env, node, "device_type", dev->type); - if (dev->compat != NULL) - OF_prop_string_new1(OF_env, node, "compatible", dev->compat); - if (dev->model != NULL) - OF_prop_string_new1(OF_env, node, "model", dev->model); - if (dev->acells != 0) - OF_prop_int_new(OF_env, node, "#address-cells", dev->acells); - if (dev->scells != 0) - OF_prop_int_new(OF_env, node, "#size-cells", dev->scells); - if (dev->icells != 0) - OF_prop_int_new(OF_env, node, "#interrupt-cells", dev->icells); - dprintf("Done %p %p\n", parent, node); - - return node; -} - -__attribute__ (( section (".OpenFirmware") )) -void *OF_register_pci_host (pci_dev_t *dev, uint16_t rev, uint32_t ccode, - uint32_t cfg_base, uint32_t cfg_len, - uint32_t mem_base, uint32_t mem_len, - uint32_t io_base, uint32_t io_len, - uint32_t rbase, uint32_t rlen, - uint16_t min_grant, uint16_t max_latency) -{ - OF_env_t *OF_env; - pci_range_t ranges[3]; - OF_regprop_t regs[1]; - OF_node_t *pci_host, *als; - int nranges; - unsigned char buffer[OF_NAMELEN_MAX]; - - OF_env = OF_env_main; - dprintf("register PCI host '%s' '%s' '%s' '%s'\n", - dev->name, dev->type, dev->compat, dev->model); - pci_host = OF_pci_device_new(OF_env, OF_node_root, dev, cfg_base, - rev, ccode, min_grant, max_latency); - if (pci_host == NULL) { - ERROR("Cannot create pci host\n"); - return NULL; - } - - als = OF_node_get(OF_env, "aliases"); - if (als == NULL) { - ERROR("Cannot get 'aliases'\n"); - return NULL; - } - sprintf(buffer, "/%s", dev->name); - OF_prop_string_set(OF_env, als, "pci", buffer); - OF_node_put(OF_env, als); - - - regs[0].address = cfg_base; - regs[0].size = cfg_len; - OF_property_new(OF_env, pci_host, "reg", regs, sizeof(OF_regprop_t)); - nranges = 0; - if (rbase != 0x00000000) { - ranges[nranges].addr.hi = 0x02000000; - ranges[nranges].addr.mid = 0x00000000; - ranges[nranges].addr.lo = rbase; - ranges[nranges].phys = rbase; - ranges[nranges].size_hi = 0x00000000; - ranges[nranges].size_lo = rlen; - nranges++; - } - if (io_base != 0x00000000) { - ranges[nranges].addr.hi = 0x01000000; - ranges[nranges].addr.mid = 0x00000000; - ranges[nranges].addr.lo = 0x00000000; - ranges[nranges].phys = io_base; - ranges[nranges].size_hi = 0x00000000; - ranges[nranges].size_lo = io_len; - nranges++; - } - if (mem_base != 0x00000000) { - ranges[nranges].addr.hi = 0x02000000; - ranges[nranges].addr.mid = 0x00000000; - ranges[nranges].addr.lo = mem_base; - ranges[nranges].phys = mem_base; - ranges[nranges].size_hi = 0x00000000; - ranges[nranges].size_lo = mem_len; - nranges++; - } - OF_property_new(OF_env, pci_host, "ranges", ranges, - nranges * sizeof(pci_range_t)); - - return pci_host; -} - -__attribute__ (( section (".OpenFirmware") )) -void *OF_register_pci_bridge (void *parent, pci_dev_t *dev, - uint32_t cfg_base, uint32_t cfg_len, - uint8_t devfn, uint8_t rev, uint32_t ccode, - uint16_t min_grant, uint16_t max_latency) -{ - OF_env_t *OF_env; - OF_regprop_t regs[1]; - OF_node_t *pci_bridge; - - OF_env = OF_env_main; - OF_DPRINTF("register '%s' %08x '%s' '%s' '%s'\n", - dev->name, devfn >> 3, dev->type, dev->compat, dev->model); - dprintf("register PCI bridge '%s' %08x '%s' '%s' '%s'\n", - dev->name, devfn >> 3, dev->type, dev->compat, dev->model); - pci_bridge = OF_pci_device_new(OF_env, parent, dev, devfn >> 3, - rev, ccode, min_grant, max_latency); - if (pci_bridge == NULL) { - ERROR("Cannot create pci bridge\n"); - return NULL; - } - regs[0].address = cfg_base; - regs[0].size = cfg_len; - OF_property_new(OF_env, pci_bridge, "reg", regs, sizeof(OF_regprop_t)); - - return pci_bridge; -} - -__attribute__ (( section (".OpenFirmware") )) -void *OF_register_pci_device (void *parent, pci_dev_t *dev, - uint8_t devfn, uint8_t rev, uint32_t ccode, - uint16_t min_grant, uint16_t max_latency) -{ - OF_env_t *OF_env; - OF_node_t *pci_dev; - - OF_env = OF_env_main; - OF_DPRINTF("register '%s' %08x '%s' '%s' '%s'\n", - dev->name, devfn >> 3, dev->type, dev->compat, dev->model); - dprintf("register pci device '%s' %08x '%s' '%s' '%s'\n", - dev->name, devfn >> 3, dev->type, dev->compat, dev->model); - pci_dev = OF_pci_device_new(OF_env, parent, dev, devfn >> 3, - rev, ccode, min_grant, max_latency); - - return pci_dev; -} - -/* XXX: suppress that, used for interrupt map init */ -OF_node_t *pci_host_node; -uint32_t pci_host_interrupt_map[7 * 32]; -int pci_host_interrupt_map_len = 0; - -void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses) -{ - OF_env_t *OF_env; - OF_regprop_t regs[1]; - - OF_env = OF_env_main; - regs[0].address = first_bus; - regs[0].size = nb_busses; - OF_property_new(OF_env, dev, "bus-range", regs, sizeof(OF_regprop_t)); - pci_host_node = dev; -} - -void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn, - uint32_t *regions, uint32_t *sizes, - int irq_line) -{ - OF_env_t *OF_env; - pci_reg_prop_t pregs[6], rregs[6]; - uint32_t mask; - int i, j, k; - - OF_env = OF_env_main; - /* XXX: only useful for VGA card in fact */ - if (regions[0] != 0x00000000) - OF_prop_int_set(OF_env, dev, "address", regions[0] & ~0x0000000F); - for (i = 0, j = 0, k = 0; i < 6; i++) { - if (regions[i] != 0x00000000 && sizes[i] != 0x00000000) { - /* Generate "reg" property - */ - if (regions[i] & 1) { - /* IO space */ - rregs[j].addr.hi = 0x01000000; - mask = 0x00000001; - } else if (regions[i] & 4) { - /* 64 bits address space */ - rregs[j].addr.hi = 0x83000000; - mask = 0x0000000F; -#if 0 - } else if ((regions[i] & 0xF) == 0x00) { /* ? */ - /* Configuration space */ - rregs[j].addr.hi = 0x00000000; - mask = 0x0000000F; -#endif - } else { - /* 32 bits address space */ - rregs[j].addr.hi = 0x82000000; - mask = 0x0000000F; - } - /* Set bus number */ - rregs[j].addr.hi |= bus << 16; - /* Set device/function */ - rregs[j].addr.hi |= devfn << 8; - /* Set register */ -#if 1 - rregs[j].addr.hi |= 0x10 + (i * sizeof(uint32_t)); /* ? */ -#endif - /* Set address */ - rregs[j].addr.mid = 0x00000000; - rregs[j].addr.lo = regions[i] & ~mask; - /* Set size */ - rregs[j].size_hi = 0x00000000; - rregs[j].size_lo = sizes[i]; -#if 0 - if ((rregs[j].addr.hi & 0x03000000) != 0x00000000) -#endif - { - /* No assigned address for configuration space */ - pregs[k].addr.hi = rregs[j].addr.hi; /* ? */ - pregs[k].addr.mid = rregs[j].addr.mid; - pregs[k].addr.lo = rregs[j].addr.lo; /* ? */ - pregs[k].size_hi = rregs[j].size_hi; - pregs[k].size_lo = rregs[j].size_lo; - k++; - } - j++; - } - } - if (j > 0) { - OF_property_new(OF_env, dev, "reg", - rregs, j * sizeof(pci_reg_prop_t)); - } else { - OF_property_new(OF_env, dev, "reg", NULL, 0); - } - if (k > 0) { - OF_property_new(OF_env, dev, "assigned-addresses", - pregs, k * sizeof(pci_reg_prop_t)); - } else { - OF_property_new(OF_env, dev, "assigned-addresses", NULL, 0); - } - if (irq_line >= 0) { - int i; - OF_prop_int_new(OF_env, dev, "interrupts", 1); - i = pci_host_interrupt_map_len; - pci_host_interrupt_map[i++] = (devfn << 8) & 0xf800; - pci_host_interrupt_map[i++] = 0; - pci_host_interrupt_map[i++] = 0; - pci_host_interrupt_map[i++] = 0; - pci_host_interrupt_map[i++] = 0; /* pic handle will be patched later */ - pci_host_interrupt_map[i++] = irq_line; - if (arch != ARCH_HEATHROW) { - pci_host_interrupt_map[i++] = 1; - } - pci_host_interrupt_map_len = i; - } -#if 1 - { - OF_prop_t *prop_name = ((OF_node_t *)dev)->prop_name; - - if (j > 0) { - dprintf("PCI device '%s' %d %d %d reg properties:\n", - prop_name->value, bus, devfn >> 3, devfn & 7); - for (i = 0; i < j; i++) { - dprintf(" addr: %08x %08x %08x size: %08x %08x\n", - rregs[i].addr.hi, rregs[i].addr.mid, rregs[i].addr.lo, - rregs[i].size_hi, rregs[i].size_lo); - } - } else { - dprintf("PCI device '%s' %d %d %d has no reg properties:\n", - prop_name->value, bus, devfn >> 3, devfn & 7); - } - if (k > 0) { - dprintf("PCI device '%s' %d %d %d " - "assigned addresses properties:\n", - prop_name->value, bus, devfn >> 3, devfn & 7); - for (i = 0; i < j; i++) { - dprintf(" addr: %08x %08x %08x size: %08x %08x\n", - pregs[i].addr.hi, pregs[i].addr.mid, pregs[i].addr.lo, - pregs[i].size_hi, pregs[i].size_lo); - } - } else { - dprintf("PCI device '%s' %d %d %d has no " - "assigned addresses properties:\n", - prop_name->value, bus, devfn >> 3, devfn & 7); - } - } -#endif -} - -__attribute__ (( section (".OpenFirmware") )) -int OF_register_bus (const unsigned char *name, uint32_t address, - const unsigned char *type) -{ - unsigned char buffer[OF_NAMELEN_MAX]; - OF_env_t *OF_env; - OF_node_t *bus, *als; - - OF_env = OF_env_main; - als = OF_node_get(OF_env, "aliases"); - if (als == NULL) { - ERROR("Cannot get 'aliases'\n"); - return -1; - } - bus = OF_node_new(OF_env, OF_node_root, name, address); - if (bus == NULL) { - OF_node_put(OF_env, als); - ERROR("Cannot create bus '%s'\n", name); - return -1; - } - OF_prop_string_set(OF_env, bus, "type", type); - sprintf(buffer, "/%s", name); - OF_prop_string_set(OF_env, als, name, buffer); - /* For ISA, should add DMA ranges */ - OF_node_put(OF_env, bus); - OF_node_put(OF_env, als); - - return 0; -} - -// We will need to register stdin & stdout via the serial port -__attribute__ (( section (".OpenFirmware") )) -int OF_register_serial (const unsigned char *bus, const unsigned char *name, - uint32_t io_base, unused int irq) -{ - unsigned char tmp[OF_NAMELEN_MAX]; - OF_env_t *OF_env; - OF_node_t *busn, *srl, *als; - - OF_env = OF_env_main; - als = OF_node_get(OF_env, "aliases"); - if (als == NULL) { - ERROR("Cannot get 'aliases'\n"); - return -1; - } - busn = OF_node_get(OF_env, bus); - srl = OF_node_new(OF_env, busn, name, io_base); - if (srl == NULL) { - OF_node_put(OF_env, als); - ERROR("Cannot create serial '%s'\n", name); - return -1; - } - OF_prop_string_set(OF_env, srl, "device_type", "serial"); - OF_prop_string_set(OF_env, srl, "compatible", "pnpPNP,501"); - switch (io_base) { - case 0x3F8: - OF_pack_get_path(OF_env, tmp, 512, srl); - OF_prop_string_new(OF_env, als, "com1", tmp); - break; - case 0x2F8: - OF_pack_get_path(OF_env, tmp, 512, srl); - OF_prop_string_new(OF_env, als, "com2", tmp); - break; - default: - break; - } - /* register read/write methods and create an instance of the package */ - OF_method_new(OF_env, srl, "write", &OF_serial_write); - OF_method_new(OF_env, srl, "read", &OF_serial_read); - OF_node_put(OF_env, srl); - OF_node_put(OF_env, busn); - OF_node_put(OF_env, als); - - return 0; -} - -/* We will also need /isa/rtc */ - -__attribute__ (( section (".OpenFirmware") )) -int OF_register_stdio (const unsigned char *dev_in, - const unsigned char *dev_out) -{ - OF_env_t *OF_env; - OF_node_t *chs, *ndev_in, *ndev_out, *kbd; - OF_inst_t *in_inst, *out_inst; - - OF_env = OF_env_main; - chs = OF_node_get(OF_env, "chosen"); - if (chs == NULL) { - ERROR("Cannot get 'chosen'\n"); - return -1; - } - ndev_in = OF_node_get(OF_env, dev_in); - ndev_out = OF_node_get(OF_env, dev_out); - in_inst = OF_instance_new(OF_env, ndev_in); - if (in_inst == NULL) { - OF_node_put(OF_env, ndev_out); - OF_node_put(OF_env, ndev_in); - OF_node_put(OF_env, chs); - ERROR("Cannot create in_inst\n"); - return -1; - } - out_inst = OF_instance_new(OF_env, ndev_out); - if (out_inst == NULL) { - OF_node_put(OF_env, ndev_out); - OF_node_put(OF_env, ndev_in); - OF_node_put(OF_env, chs); - ERROR("Cannot create out_inst\n"); - return -1; - } - OF_prop_int_set(OF_env, chs, "stdin", - OF_instance_get_id(OF_env, in_inst)); - OF_prop_int_set(OF_env, chs, "stdout", - OF_instance_get_id(OF_env, out_inst)); - kbd = OF_node_new(OF_env, ndev_in, "keyboard", OF_ADDRESS_NONE); - if (kbd == NULL) { - OF_node_put(OF_env, ndev_out); - OF_node_put(OF_env, ndev_in); - OF_node_put(OF_env, chs); - ERROR("Cannot create 'keyboard' for stdio\n"); - return -1; - } - OF_prop_string_new(OF_env, kbd, "device_type", "keyboard"); - OF_node_put(OF_env, kbd); - OF_DPRINTF("stdin h: 0x%0x out : 0x%0x\n", - OF_instance_get_id(OF_env, in_inst), - OF_instance_get_id(OF_env, out_inst)); - OF_node_put(OF_env, ndev_out); - OF_node_put(OF_env, ndev_in); - OF_node_put(OF_env, chs); - - return 0; -} - -static void keylargo_ata(OF_node_t *mio, uint32_t base_address, - uint32_t base, int irq1, int irq2, - uint16_t pic_phandle) -{ - OF_env_t *OF_env = OF_env_main; - OF_node_t *ata; - OF_regprop_t regs[2]; - - ata = OF_node_new(OF_env, mio, "ata-4", base); - if (ata == NULL) { - ERROR("Cannot create 'ata-4'\n"); - return; - } - OF_prop_string_new(OF_env, ata, "device_type", "ata"); -#if 1 - OF_prop_string_new(OF_env, ata, "compatible", "key2largo-ata"); - OF_prop_string_new(OF_env, ata, "model", "ata-4"); - OF_prop_string_new(OF_env, ata, "cable-type", "80-conductor"); -#else - OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata"); - OF_prop_string_new(OF_env, ata, "model", "ata-4"); -#endif - OF_prop_int_new(OF_env, ata, "#address-cells", 1); - OF_prop_int_new(OF_env, ata, "#size-cells", 0); - regs[0].address = base; - regs[0].size = 0x00001000; -#if 0 // HACK: Don't set up DMA registers - regs[1].address = 0x00008A00; - regs[1].size = 0x00001000; - OF_property_new(OF_env, ata, "reg", - regs, 2 * sizeof(OF_regprop_t)); -#else - OF_property_new(OF_env, ata, "reg", - regs, sizeof(OF_regprop_t)); -#endif - OF_prop_int_new(OF_env, ata, "interrupt-parent", pic_phandle); - regs[0].address = irq1; - regs[0].size = 0x00000001; - regs[1].address = irq2; - regs[1].size = 0x00000000; - OF_property_new(OF_env, ata, "interrupts", - regs, 2 * sizeof(OF_regprop_t)); - if (base == 0x1f000) - ide_pci_pmac_register(base_address + base, 0x00000000, ata); - else - ide_pci_pmac_register(0x00000000, base_address + base, ata); -} - -void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size, - void *private_data) -{ - unsigned char tmp[OF_NAMELEN_MAX]; - OF_env_t *OF_env; - pci_reg_prop_t pregs[2]; - OF_node_t *mio, *chs, *als; - uint16_t pic_phandle; - int rec_len; - OF_prop_t *mio_reg; - - OF_DPRINTF("mac-io: %p\n", dev); - OF_env = OF_env_main; - chs = OF_node_get(OF_env, "chosen"); - if (chs == NULL) { - ERROR("Cannot get 'chosen'\n"); - return; - } - als = OF_node_get(OF_env, "aliases"); - if (als == NULL) { - OF_node_put(OF_env, als); - ERROR("Cannot get 'aliases'\n"); - return; - } - /* Mac-IO is mandatory for OSX to boot */ - mio = dev; - mio->private_data = private_data; - pregs[0].addr.hi = 0x00000000; - pregs[0].addr.mid = 0x00000000; - pregs[0].addr.lo = 0x00000000; - pregs[0].size_hi = base_address; - pregs[0].size_lo = size; - mio_reg = OF_property_get(OF_env, mio, "reg"); - if (mio_reg && mio_reg->vlen >= 5 * 4) { - pregs[0].addr.mid = ((pci_reg_prop_t *)mio_reg->value)->addr.hi; - } - OF_property_new(OF_env, mio, "ranges", - &pregs, sizeof(pci_reg_prop_t)); -#if 0 - pregs[0].addr.hi = 0x82013810; - pregs[0].addr.mid = 0x00000000; - pregs[0].addr.lo = 0x80800000; - pregs[0].size_hi = 0x00000000; - pregs[0].size_lo = 0x00080000; - OF_property_new(OF_env, mio, "assigned-addresses", - &pregs, sizeof(pci_reg_prop_t)); -#endif - - if (arch == ARCH_HEATHROW) { - /* Heathrow PIC */ - OF_regprop_t regs; - OF_node_t *mpic; - const char compat_str[] = "heathrow\0mac-risc"; - - mpic = OF_node_new(OF_env, mio, "interrupt-controller", 0x10); - if (mpic == NULL) { - ERROR("Cannot create 'mpic'\n"); - goto out; - } - OF_prop_string_new(OF_env, mpic, "device_type", "interrupt-controller"); - OF_property_new(OF_env, mpic, "compatible", compat_str, sizeof(compat_str)); - OF_prop_int_new(OF_env, mpic, "#interrupt-cells", 1); - regs.address = 0x10; - regs.size = 0x20; - OF_property_new(OF_env, mpic, "reg", - ®s, sizeof(regs)); - OF_property_new(OF_env, mpic, "interrupt-controller", NULL, 0); - pic_phandle = OF_pack_handle(OF_env, mpic); - OF_prop_int_new(OF_env, chs, "interrupt-controller", pic_phandle); - OF_node_put(OF_env, mpic); - rec_len = 6; - } else { - /* OpenPIC */ - OF_regprop_t regs[4]; - OF_node_t *mpic; - mpic = OF_node_new(OF_env, mio, "interrupt-controller", 0x40000); - if (mpic == NULL) { - ERROR("Cannot create 'mpic'\n"); - goto out; - } - OF_prop_string_new(OF_env, mpic, "device_type", "open-pic"); - OF_prop_string_new(OF_env, mpic, "compatible", "chrp,open-pic"); - OF_property_new(OF_env, mpic, "interrupt-controller", NULL, 0); - OF_property_new(OF_env, mpic, "built-in", NULL, 0); - OF_prop_int_new(OF_env, mpic, "clock-frequency", 0x003F7A00); - OF_prop_int_new(OF_env, mpic, "#address-cells", 0); - OF_prop_int_new(OF_env, mpic, "#interrupt-cells", 2); - memset(regs, 0, 4 * sizeof(OF_regprop_t)); - regs[0].address = 0x00040000; - regs[0].size = 0x00040000; - OF_property_new(OF_env, mpic, "reg", - ®s, 1 * sizeof(OF_regprop_t)); - pic_phandle = OF_pack_handle(OF_env, mpic); - OF_prop_int_new(OF_env, chs, "interrupt-controller", pic_phandle); - OF_node_put(OF_env, mpic); - rec_len = 7; - } - - /* patch pci host table */ - /* XXX: do it after the PCI init */ - { - int i; - uint32_t tab[4]; - - for(i = 0; i < pci_host_interrupt_map_len; i += rec_len) - pci_host_interrupt_map[i + 4] = pic_phandle; -#if 0 - dprintf("interrupt-map:\n"); - for(i = 0; i < pci_host_interrupt_map_len; i++) { - dprintf(" %08x", pci_host_interrupt_map[i]); - if ((i % rec_len) == (rec_len - 1)) - dprintf("\n"); - } - dprintf("\n"); -#endif - OF_property_new(OF_env, pci_host_node, "interrupt-map", - pci_host_interrupt_map, - pci_host_interrupt_map_len * sizeof(uint32_t)); - tab[0] = 0xf800; - tab[1] = 0; - tab[2] = 0; - tab[3] = 0; - OF_property_new(OF_env, pci_host_node, "interrupt-map-mask", - tab, 4 * sizeof(uint32_t)); - } -#if 0 - /* escc is useful to get MacOS X debug messages */ - { - OF_regprop_t regs[8]; - uint32_t irqs[6]; - OF_node_t *scc, *chann; - scc = OF_node_new(OF_env, mio, "escc", 0x13000); - if (scc == NULL) { - ERROR("Cannot create 'escc'\n"); - goto out; - } - OF_prop_string_new(OF_env, scc, "device_type", "escc"); - OF_prop_string_new(OF_env, scc, "compatible", "chrp,es0"); - OF_property_new(OF_env, scc, "built-in", NULL, 0); - OF_prop_int_new(OF_env, scc, "#address-cells", 1); - memset(regs, 0, 8 * sizeof(OF_regprop_t)); - regs[0].address = 0x00013000; - regs[0].size = 0x00001000; - regs[1].address = 0x00008400; - regs[1].size = 0x00000100; - regs[2].address = 0x00008500; - regs[2].size = 0x00000100; - regs[3].address = 0x00008600; - regs[3].size = 0x00000100; - regs[4].address = 0x00008700; - regs[4].size = 0x00000100; - OF_property_new(OF_env, scc, "reg", - regs, 5 * sizeof(OF_regprop_t)); - OF_property_new(OF_env, scc, "ranges", NULL, 0); - /* Set up two channels */ - chann = OF_node_new(OF_env, scc, "ch-a", 0x13020); - if (chann == NULL) { - ERROR("Cannot create 'ch-a'\n"); - goto out; - } - OF_prop_string_new(OF_env, chann, "device_type", "serial"); - OF_prop_string_new(OF_env, chann, "compatible", "chrp,es2"); - OF_property_new(OF_env, chann, "built-in", NULL, 0); - OF_prop_int_new(OF_env, chann, "slot-names", 0); - OF_prop_int_new(OF_env, chann, "interrupt-parent", pic_phandle); - memset(regs, 0, 8 * sizeof(OF_regprop_t)); - regs[0].address = 0x00013020; - regs[0].size = 0x00000001; - regs[1].address = 0x00013030; - regs[1].size = 0x00000001; - regs[2].address = 0x00013050; - regs[2].size = 0x00000001; - regs[3].address = 0x00008400; - regs[3].size = 0x00000100; - regs[4].address = 0x00008500; - regs[4].size = 0x00000100; - OF_property_new(OF_env, chann, "reg", - regs, 5 * sizeof(OF_regprop_t)); - /* XXX: tofix: those are regprops */ - irqs[0] = 0x16; - irqs[1] = 0x01; - irqs[2] = 0x05; - irqs[3] = 0x00; - irqs[4] = 0x06; - irqs[5] = 0x00; - OF_property_new(OF_env, chann, "interrupts", - irqs, 6 * sizeof(uint32_t)); - OF_node_put(OF_env, chann); - chann = OF_node_new(OF_env, scc, "ch-b", 0x13000); - if (chann == NULL) { - ERROR("Cannot create 'ch-b'\n"); - goto out; - } - OF_prop_string_new(OF_env, chann, "device_type", "serial"); - OF_prop_string_new(OF_env, chann, "compatible", "chrp,es3"); - OF_property_new(OF_env, chann, "built-in", NULL, 0); - OF_prop_int_new(OF_env, chann, "slot-names", 0); - OF_prop_int_new(OF_env, chann, "interrupt-parent", pic_phandle); - memset(regs, 0, 8 * sizeof(OF_regprop_t)); - regs[0].address = 0x00013000; - regs[0].size = 0x00000001; - regs[1].address = 0x00013010; - regs[1].size = 0x00000001; - regs[2].address = 0x00013040; - regs[2].size = 0x00000001; - regs[3].address = 0x00008600; - regs[3].size = 0x00000100; - regs[4].address = 0x00008700; - regs[4].size = 0x00000100; - OF_property_new(OF_env, chann, "reg", - regs, 5 * sizeof(OF_regprop_t)); - /* XXX: tofix: those are regprops */ - irqs[0] = 0x17; - irqs[1] = 0x01; - irqs[2] = 0x07; - irqs[3] = 0x00; - irqs[4] = 0x08; - irqs[5] = 0x00; - OF_property_new(OF_env, chann, "interrupts", - irqs, 6 * sizeof(uint32_t)); - OF_node_put(OF_env, chann); - OF_node_put(OF_env, scc); - /* MacOS likes escc-legacy */ - scc = OF_node_new(OF_env, mio, "escc-legacy", 0x12000); - if (scc == NULL) { - ERROR("Cannot create 'escc-legacy'\n"); - goto out; - } - OF_prop_string_new(OF_env, scc, "device_type", "escc-legacy"); - OF_prop_string_new(OF_env, scc, "compatible", "chrp,es1"); - OF_property_new(OF_env, scc, "built-in", NULL, 0); - OF_prop_int_new(OF_env, scc, "#address-cells", 1); - memset(regs, 0, 8 * sizeof(OF_regprop_t)); - regs[0].address = 0x00012000; - regs[0].size = 0x00001000; - regs[1].address = 0x00008400; - regs[1].size = 0x00000100; - regs[2].address = 0x00008500; - regs[2].size = 0x00000100; - regs[3].address = 0x00008600; - regs[3].size = 0x00000100; - regs[4].address = 0x00008700; - regs[4].size = 0x00000100; - OF_property_new(OF_env, scc, "reg", - regs, 8 * sizeof(OF_regprop_t)); - OF_property_new(OF_env, scc, "ranges", NULL, 0); - /* Set up two channels */ - chann = OF_node_new(OF_env, scc, "ch-a", 0x12004); - if (chann == NULL) { - ERROR("Cannot create 'ch-a'\n"); - goto out; - } - OF_prop_string_new(OF_env, chann, "device_type", "serial"); - OF_prop_string_new(OF_env, chann, "compatible", "chrp,es4"); - OF_property_new(OF_env, chann, "built-in", NULL, 0); - OF_prop_int_new(OF_env, chann, "interrupt-parent", pic_phandle); - memset(regs, 0, 8 * sizeof(OF_regprop_t)); - regs[0].address = 0x00012004; - regs[0].size = 0x00000001; - regs[1].address = 0x00012006; - regs[1].size = 0x00000001; - regs[2].address = 0x0001200A; - regs[2].size = 0x00000001; - regs[3].address = 0x00008400; - regs[3].size = 0x00000100; - regs[4].address = 0x00008500; - regs[4].size = 0x00000100; - OF_property_new(OF_env, chann, "reg", - regs, 8 * sizeof(OF_regprop_t)); - /* XXX: tofix: those are regprops */ - irqs[0] = 0x16; - irqs[1] = 0x01; - irqs[2] = 0x05; - irqs[3] = 0x00; - irqs[4] = 0x06; - irqs[5] = 0x00; - OF_property_new(OF_env, chann, "interrupts", - irqs, 6 * sizeof(uint32_t)); - OF_node_put(OF_env, chann); - chann = OF_node_new(OF_env, scc, "ch-b", 0x12000); - if (chann == NULL) { - ERROR("Cannot create 'ch-b'\n"); - goto out; - } - OF_prop_string_new(OF_env, chann, "device_type", "serial"); - OF_prop_string_new(OF_env, chann, "compatible", "chrp,es5"); - OF_property_new(OF_env, chann, "built-in", NULL, 0); - OF_prop_int_new(OF_env, chann, "interrupt-parent", pic_phandle); - memset(regs, 0, 8 * sizeof(OF_regprop_t)); - regs[0].address = 0x00012000; - regs[0].size = 0x00000001; - regs[1].address = 0x00012002; - regs[1].size = 0x00000001; - regs[2].address = 0x00012008; - regs[2].size = 0x00000001; - regs[3].address = 0x00008600; - regs[3].size = 0x00000100; - regs[4].address = 0x00008700; - regs[4].size = 0x00000100; - OF_property_new(OF_env, chann, "reg", - regs, 8 * sizeof(OF_regprop_t)); - /* XXX: tofix: those are regprops */ - irqs[0] = 0x17; - irqs[1] = 0x01; - irqs[2] = 0x07; - irqs[3] = 0x00; - irqs[4] = 0x08; - irqs[5] = 0x00; - OF_property_new(OF_env, chann, "interrupts", - irqs, 6 * sizeof(uint32_t)); - OF_node_put(OF_env, chann); - OF_node_put(OF_env, scc); - } -#endif - /* Keylargo IDE controller: need some work (DMA problem ?) */ - if (arch == ARCH_MAC99) { - keylargo_ata(mio, base_address, 0x1f000, 0x13, 0xb, pic_phandle); - keylargo_ata(mio, base_address, 0x20000, 0x14, 0xb, pic_phandle); - } -#if 0 - /* Timer */ - { - OF_node_t *tmr; - OF_regprop_t regs[1]; - tmr = OF_node_new(OF_env, mio, "timer", 0x15000); - if (tmr == NULL) { - ERROR("Cannot create 'timer'\n"); - goto out; - } - OF_prop_string_new(OF_env, tmr, "device_type", "timer"); - OF_prop_string_new(OF_env, tmr, "compatible", "keylargo-timer"); - OF_prop_int_new(OF_env, tmr, "clock-frequency", 0x01194000); - regs[0].address = 0x00015000; - regs[0].size = 0x00001000; - OF_property_new(OF_env, tmr, "reg", regs, sizeof(OF_regprop_t)); - OF_prop_int_new(OF_env, tmr, "interrupt-parent", pic_phandle); - regs[0].address = 0x00000020; - regs[0].size = 0x00000001; - OF_property_new(OF_env, tmr, "interrupts", - regs, sizeof(OF_regprop_t)); - OF_node_put(OF_env, tmr); - } -#endif - /* VIA-PMU */ - { - /* Controls adb, RTC and power-mgt (forget it !) */ - OF_node_t *via, *adb; - OF_regprop_t regs[1]; -#if 0 // THIS IS A HACK AND IS COMPLETELY ABSURD ! - // (but needed has Qemu doesn't emulate via-pmu). - via = OF_node_new(OF_env, mio, "via-pmu", 0x16000); - if (via == NULL) { - ERROR("Cannot create 'via-pmu'\n"); - goto out; - } - OF_prop_string_new(OF_env, via, "device_type", "via-pmu"); - OF_prop_string_new(OF_env, via, "compatible", "pmu"); -#else - via = OF_node_new(OF_env, mio, "via-cuda", 0x16000); - if (via == NULL) { - ERROR("Cannot create 'via-cuda'\n"); - goto out; - } - OF_prop_string_new(OF_env, via, "device_type", "via-cuda"); - OF_prop_string_new(OF_env, via, "compatible", "cuda"); -#endif - regs[0].address = 0x00016000; - regs[0].size = 0x00002000; - OF_property_new(OF_env, via, "reg", regs, sizeof(OF_regprop_t)); - OF_prop_int_new(OF_env, via, "interrupt-parent", pic_phandle); - if (arch == ARCH_HEATHROW) { - OF_prop_int_new(OF_env, via, "interrupts", 0x12); - } else { - regs[0].address = 0x00000019; - regs[0].size = 0x00000001; - OF_property_new(OF_env, via, "interrupts", - regs, sizeof(OF_regprop_t)); - } - /* force usage of OF bus speeds */ - OF_prop_int_new(OF_env, via, "BusSpeedCorrect", 1); -#if 0 - OF_prop_int_new(OF_env, via, "pmu-version", 0x00D0740C); -#endif - { - OF_node_t *kbd, *mouse; - /* ADB pseudo-device */ - adb = OF_node_new(OF_env, via, "adb", OF_ADDRESS_NONE); - if (adb == NULL) { - ERROR("Cannot create 'adb'\n"); - goto out; - } - OF_prop_string_new(OF_env, adb, "device_type", "adb"); -#if 0 - OF_prop_string_new(OF_env, adb, "compatible", "pmu-99"); -#else - OF_prop_string_new(OF_env, adb, "compatible", "adb"); -#endif - OF_prop_int_new(OF_env, adb, "#address-cells", 1); - OF_prop_int_new(OF_env, adb, "#size-cells", 0); - OF_pack_get_path(OF_env, tmp, 512, adb); - OF_prop_string_new(OF_env, als, "adb", tmp); - - kbd = OF_node_new(OF_env, adb, "keyboard", 2); - if (kbd == NULL) { - ERROR("Cannot create 'kbd'\n"); - goto out; - } - OF_prop_string_new(OF_env, kbd, "device_type", "keyboard"); - OF_prop_int_new(OF_env, kbd, "reg", 2); - - mouse = OF_node_new(OF_env, adb, "mouse", 3); - if (mouse == NULL) { - ERROR("Cannot create 'mouse'\n"); - goto out; - } - OF_prop_string_new(OF_env, mouse, "device_type", "mouse"); - OF_prop_int_new(OF_env, mouse, "reg", 3); - OF_prop_int_new(OF_env, mouse, "#buttons", 3); - } - { - OF_node_t *rtc; - - rtc = OF_node_new(OF_env, via, "rtc", OF_ADDRESS_NONE); - if (rtc == NULL) { - ERROR("Cannot create 'rtc'\n"); - goto out; - } - OF_prop_string_new(OF_env, rtc, "device_type", "rtc"); -#if 0 - OF_prop_string_new(OF_env, rtc, "compatible", "rtc,via-pmu"); -#else - OF_prop_string_new(OF_env, rtc, "compatible", "rtc"); -#endif - OF_node_put(OF_env, rtc); - } - // OF_node_put(OF_env, via); - } - { - OF_node_t *pmgt; - pmgt = OF_node_new(OF_env, mio, "power-mgt", OF_ADDRESS_NONE); - OF_prop_string_new(OF_env, pmgt, "device_type", "power-mgt"); - OF_prop_string_new(OF_env, pmgt, "compatible", "cuda"); - OF_prop_string_new(OF_env, pmgt, "mgt-kind", "min-consumption-pwm-led"); - OF_node_put(OF_env, pmgt); - } - - if (arch == ARCH_HEATHROW) { - /* NVRAM */ - OF_node_t *nvr; - OF_regprop_t regs; - nvr = OF_node_new(OF_env, mio, "nvram", 0x60000); - OF_prop_string_new(OF_env, nvr, "device_type", "nvram"); - regs.address = 0x60000; - regs.size = 0x00020000; - OF_property_new(OF_env, nvr, "reg", ®s, sizeof(regs)); - OF_prop_int_new(OF_env, nvr, "#bytes", 0x2000); - OF_node_put(OF_env, nvr); - } - - out: - // OF_node_put(OF_env, mio); - OF_node_put(OF_env, chs); - OF_node_put(OF_env, als); -} - -void OF_finalize_pci_ide (void *dev, - uint32_t io_base0, uint32_t io_base1, - uint32_t io_base2, uint32_t io_base3) -{ - OF_env_t *OF_env = OF_env_main; - OF_node_t *pci_ata = dev; - OF_node_t *ata, *atas[2]; - int i; - - OF_prop_int_new(OF_env, pci_ata, "#address-cells", 1); - OF_prop_int_new(OF_env, pci_ata, "#size-cells", 0); - - /* XXX: Darwin handles only one device */ - for(i = 0; i < 1; i++) { - ata = OF_node_new(OF_env, pci_ata, "ata-4", i); - if (ata == NULL) { - ERROR("Cannot create 'ata-4'\n"); - return; - } - OF_prop_string_new(OF_env, ata, "device_type", "ata"); - OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata"); - OF_prop_string_new(OF_env, ata, "model", "ata-4"); - OF_prop_int_new(OF_env, ata, "#address-cells", 1); - OF_prop_int_new(OF_env, ata, "#size-cells", 0); - OF_prop_int_new(OF_env, ata, "reg", i); - atas[i] = ata; - } - ide_pci_pc_register(io_base0, io_base1, io_base2, io_base3, - atas[0], atas[1]); -} - -/*****************************************************************************/ -/* Fake package */ -static void OF_method_fake (OF_env_t *OF_env) -{ - uint32_t ihandle; - - ihandle = popd(OF_env); - OF_DPRINTF("ih: %0x %d\n", ihandle, stackd_depth(OF_env)); - pushd(OF_env, ihandle); -} - -static void OF_mmu_translate (OF_env_t *OF_env) -{ - const unsigned char *args; - uint32_t address, more; - uint32_t ihandle; - - OF_CHECK_NBARGS(OF_env, 4); - /* As we get a 1:1 mapping, do nothing */ - ihandle = popd(OF_env); - args = (void *)popd(OF_env); - address = popd(OF_env); - more = popd(OF_env); - OF_DPRINTF("Translate address %0x %0x %0x\n", ihandle, address, more); - // BAT_setup(3, more, address, 0x10000000, 1, 1, 2); - pushd(OF_env, address); - pushd(OF_env, 0x00000000); - pushd(OF_env, 0x00000000); - pushd(OF_env, 0); -} - -static void OF_mmu_map (OF_env_t *OF_env) -{ - const unsigned char *args; - uint32_t address, virt, size; - uint32_t ihandle; - - OF_CHECK_NBARGS(OF_env, 6); - /* As we get a 1:1 mapping, do nothing */ - ihandle = popd(OF_env); - args = (void *)popd(OF_env); - popd(OF_env); - size = popd(OF_env); - virt = popd(OF_env); - address = popd(OF_env); - OF_DPRINTF("Map %0x %0x %0x %0x\n", ihandle, address, - virt, size); - pushd(OF_env, 0); -} - -/* Serial device package */ -static void OF_serial_write (OF_env_t *OF_env) -{ - const unsigned char *args; - OF_inst_t *inst; - OF_node_t *node; - uint32_t ihandle; - unsigned char *str; - int len; - - OF_CHECK_NBARGS(OF_env, 4); - ihandle = popd(OF_env); - args = (void *)popd(OF_env); - str = (void *)popd(OF_env); - len = popd(OF_env); - inst = OF_inst_find(OF_env, ihandle); - if (inst == NULL) { - pushd(OF_env, -1); - ERROR("Cannot get serial instance\n"); - return; - } - node = inst->node; - // OF_DPRINTF("args: %p str: %p\n", args, str); - /* XXX: should use directly the serial port - * and have another console package. - */ - console_write(str, len); - pushd(OF_env, 0); -} - -static void OF_serial_read (OF_env_t *OF_env) -{ - const unsigned char *args; - char *dest; - uint32_t len; - uint32_t ihandle; - uint16_t phandle; - int ret, count; - - OF_CHECK_NBARGS(OF_env, 4); - ihandle = popd(OF_env); - args = (void *)popd(OF_env); - phandle = (ihandle >> 16) & 0xFFFF; - dest = (void *)popd(OF_env); - len = popd(OF_env); - ret = -1; /* Don't know why gcc thinks it might be uninitialized... */ - for (count = 0; count < 1000; count++) { - ret = console_read(dest, len); - /* Stop if we read something or got an error */ - if (ret != 0) - break; - /* Random sleep. Seems allright for serial port */ - usleep(10000); - } - if (ret <= 0) { - pushd(OF_env, 0); - } else { - OF_DPRINTF("send '%s'\n", dest); - pushd(OF_env, ret); - } -} - -typedef struct blockdev_inst_t { - int type; - union { - bloc_device_t *bd; - part_t *part; - inode_t *file; - } u; -} blockdev_inst_t; - -static int OF_split_args (unsigned char *args, unsigned char **argv, - int max_args) -{ - unsigned char *pos, *end; - int i; - - pos = args; - end = pos; - for (i = 0; i < max_args && *pos != '\0' && end != NULL; i++) { - end = strchr(pos, ','); - if (end != NULL) - *end = '\0'; - argv[i] = pos; - pos = end + 1; - } - - return i; -} - -static void OF_convert_path (unsigned char **path) -{ - unsigned char *pos; - - OF_DPRINTF("%s: '%s'\n", __func__, *path); - for (pos = *path; *pos != '\0'; pos++) { - if (*pos == '\\') - *pos = '/'; - } - OF_DPRINTF("%s: '%s'\n", __func__, *path); - pos = *path; -#if 1 - if (pos[0] == '/' && pos[1] == '/') { - pos += 2; - *path = pos; - } -#else - for (; *pos == '/'; pos++) - continue; - *path = pos; -#endif - OF_DPRINTF("%s: '%s'\n", __func__, *path); -} - -/* Block devices package */ -static void OF_blockdev_open (OF_env_t *OF_env) -{ - unsigned char tmp[OF_NAMELEN_MAX]; - unsigned char *args, *argv[4]; - OF_inst_t *dsk_inst; - OF_node_t *dsk; - bloc_device_t *bd; - blockdev_inst_t *bdinst; - uint32_t ihandle; - uint16_t phandle; - int nargs, partnum; - - OF_CHECK_NBARGS(OF_env, 2); - ihandle = popd(OF_env); - args = (void *)popd(OF_env); - phandle = (ihandle >> 16) & 0xFFFF; - dsk_inst = OF_inst_find(OF_env, ihandle); - if (dsk_inst == NULL) { - ERROR("Disk not found (ih: %0x)\n", ihandle); - pushd(OF_env, -1); - return; - } - dsk = dsk_inst->node; - bd = dsk->private_data; - bdinst = malloc(sizeof(blockdev_inst_t)); - if (bdinst == NULL) { - ihandle = -1; - ERROR("Cannot alloc blockdev instance\n"); - goto out; - } - memset(bdinst, 0, sizeof(blockdev_inst_t)); - OF_DPRINTF("called with args '%s'\n", args); - nargs = OF_split_args(args, argv, 4); - partnum = -1; - if (nargs > 0) { - partnum = strtol(argv[0], NULL, 10); - if (partnum > 0) { - OF_DPRINTF("Open partition... %d %d\n", partnum, nargs); - bdinst->type = 1; - bdinst->u.part = part_get(bd, partnum); - if (bdinst->u.part == NULL) { - OF_DPRINTF("Partition %d not found\n", partnum); - free(bdinst); - pushd(OF_env, -1); - return; - } - if (nargs > 1) { - /* TODO: open file */ - bdinst->type = 2; - OF_DPRINTF("Open file... %d %d '%s'\n", - partnum, nargs, argv[1]); - OF_convert_path(&argv[1]); - if (*argv[1] != '/') { - sprintf(tmp, "%s/%s", - fs_get_boot_dirname(part_fs(bdinst->u.part)), - argv[1]); - bdinst->u.file = fs_open(part_fs(bdinst->u.part), tmp); - } else { - bdinst->u.file = fs_open(part_fs(bdinst->u.part), argv[1]); - } - if (bdinst->u.file == NULL) { -#if 0 - bug(); -#endif - pushd(OF_env, 0x00000000); - ERROR("File not found '%s'\n", argv[1]); - return; - } - } - } - } - if (nargs == 0 || partnum == 0) { - OF_DPRINTF("Open disk... %d %d\n", nargs, partnum); - bdinst->type = 0; - bdinst->u.bd = bd; - } - /* TODO: find partition &/| file */ - dsk_inst->data = bdinst; - OF_node_put(OF_env, dsk); - out: - pushd(OF_env, ihandle); -} - -static void OF_blockdev_seek (OF_env_t *OF_env) -{ - const unsigned char *args; - OF_inst_t *dsk_inst; - blockdev_inst_t *bdinst; - uint32_t posh, posl, bloc, pos, blocsize, tmp; - uint32_t ihandle; - uint16_t phandle; - int sh; - - OF_CHECK_NBARGS(OF_env, 4); - ihandle = popd(OF_env); - args = (void *)popd(OF_env); - phandle = (ihandle >> 16) & 0xFFFF; - posh = popd(OF_env); - posl = popd(OF_env); - dsk_inst = OF_inst_find(OF_env, ihandle); - if (dsk_inst == NULL) { - ERROR("Disk not found (ih: %0x)\n", ihandle); - pushd(OF_env, -1); - return; - } - bdinst = dsk_inst->data; - switch (bdinst->type) { - case 0: - blocsize = bd_seclen(bdinst->u.bd); - for (tmp = blocsize, sh = 0; tmp != 1; tmp = tmp / 2) - sh++; - bloc = ((posh << (32 - sh)) | (posl / blocsize)); - pos = posl % blocsize; - OF_DPRINTF("disk: bsize %08x %08x %08x => %08x %08x\n", blocsize, - posh, posl, bloc, pos); - pushd(OF_env, bd_seek(bdinst->u.bd, bloc, pos)); - break; - case 1: - blocsize = part_blocsize(bdinst->u.part); - for (tmp = blocsize, sh = 0; tmp != 1; tmp = tmp / 2) - sh++; - bloc = ((posh << (32 - sh)) | (posl / blocsize)); - pos = posl % blocsize; - OF_DPRINTF("part: bsize %08x %08x %08x => %08x %08x\n", blocsize, - posh, posl, bloc, pos); - pushd(OF_env, part_seek(bdinst->u.part, bloc, pos)); - break; - case 2: - blocsize = part_blocsize(fs_inode_get_part(bdinst->u.file)); - for (tmp = blocsize, sh = 0; tmp != 1; tmp = tmp / 2) - sh++; - bloc = ((posh << (32 - sh)) | (posl / blocsize)); - pos = posl % blocsize; - OF_DPRINTF("file: bsize %08x %08x %08x => %08x %08x\n", blocsize, - posh, posl, bloc, pos); - pushd(OF_env, fs_seek(bdinst->u.file, bloc, pos)); - break; - } -} - -static void OF_blockdev_read (OF_env_t *OF_env) -{ - const unsigned char *args; - OF_inst_t *dsk_inst; - blockdev_inst_t *bdinst; - void *dest; - uint32_t len; - uint32_t ihandle; - uint16_t phandle; - - OF_CHECK_NBARGS(OF_env, 4); - ihandle = popd(OF_env); - args = (void *)popd(OF_env); - phandle = (ihandle >> 16) & 0xFFFF; - dest = (void *)popd(OF_env); - len = popd(OF_env); - dsk_inst = OF_inst_find(OF_env, ihandle); - if (dsk_inst == NULL) { - ERROR("Disk not found (ih: %0x)\n", ihandle); - pushd(OF_env, -1); - return; - } - bdinst = dsk_inst->data; - set_check(0); - OF_DPRINTF("dest: %p len: %d %d\n", dest, len, bdinst->type); - switch (bdinst->type) { - case 0: - OF_DPRINTF("read disk\n"); - pushd(OF_env, bd_read(bdinst->u.bd, dest, len)); - break; - case 1: - OF_DPRINTF("read partition\n"); - pushd(OF_env, part_read(bdinst->u.part, dest, len)); - break; - case 2: - OF_DPRINTF("read file\n"); - pushd(OF_env, fs_read(bdinst->u.file, dest, len)); - break; - } - OF_DPRINTF("%08x %08x %08x %08x\n", - ((uint32_t *)dest)[0], ((uint32_t *)dest)[1], - ((uint32_t *)dest)[2], ((uint32_t *)dest)[3]); - OF_DPRINTF("%08x %08x %08x %08x\n", - ((uint32_t *)dest)[4], ((uint32_t *)dest)[5], - ((uint32_t *)dest)[6], ((uint32_t *)dest)[7]); - - set_check(1); -} - -static void OF_blockdev_get_blocsize (OF_env_t *OF_env) -{ - const unsigned char *args; - OF_inst_t *dsk_inst; - blockdev_inst_t *bdinst; - uint32_t ihandle; - uint16_t phandle; - uint32_t blocsize; - - OF_CHECK_NBARGS(OF_env, 2); - ihandle = popd(OF_env); - args = (void *)popd(OF_env); - phandle = (ihandle >> 16) & 0xFFFF; - dsk_inst = OF_inst_find(OF_env, ihandle); - if (dsk_inst == NULL) { - ERROR("Disk not found (ih: %0x)\n", ihandle); - pushd(OF_env, -1); - return; - } - bdinst = dsk_inst->data; -#if 0 - switch (bdinst->type) { - case 0: - blocsize = bd_seclen(bdinst->u.bd); - break; - case 1: - blocsize = part_blocsize(bdinst->u.part); - break; - case 2: - blocsize = 512; - break; - } -#else - blocsize = 512; -#endif - pushd(OF_env, blocsize); - pushd(OF_env, 0); -} - -static void OF_blockdev_dma_alloc (OF_env_t *OF_env) -{ - const unsigned char *args; - void *address; - uint32_t ihandle; - uint32_t size; - - OF_CHECK_NBARGS(OF_env, 3); - ihandle = popd(OF_env); - args = (void *)popd(OF_env); - size = popd(OF_env); - OF_DPRINTF("size: %08x\n", size); - mem_align(size); - address = malloc(size); - if (address != NULL) - memset(address, 0, size); - pushd(OF_env, (uint32_t)address); - pushd(OF_env, 0); -} - -static void OF_blockdev_dma_free (OF_env_t *OF_env) -{ - const unsigned char *args; - void *address; - uint32_t ihandle; - uint32_t size; - - OF_CHECK_NBARGS(OF_env, 4); - ihandle = popd(OF_env); - args = (void *)popd(OF_env); - size = popd(OF_env); - address = (void *)popd(OF_env); - OF_DPRINTF("address: %p size: %08x\n", address, size); - free(address); - pushd(OF_env, 0); -} - -void *OF_blockdev_register (void *parent, void *private, - const unsigned char *type, - const unsigned char *name, int devnum, - const char *alias) -{ - unsigned char tmp[OF_NAMELEN_MAX], path[OF_NAMELEN_MAX], *pos; - OF_env_t *OF_env; - OF_node_t *dsk, *als; - int i; - - OF_env = OF_env_main; - dsk = OF_node_new(OF_env, parent, name, devnum); - if (dsk == NULL) { - ERROR("Cannot create blockdev '%s'\n", name); - return NULL; - } - OF_prop_string_new(OF_env, dsk, "device_type", "block"); - OF_prop_string_new(OF_env, dsk, "category", type); - OF_prop_int_new(OF_env, dsk, "device_id", devnum); - OF_prop_int_new(OF_env, dsk, "reg", devnum); - OF_method_new(OF_env, dsk, "open", &OF_blockdev_open); - OF_method_new(OF_env, dsk, "seek", &OF_blockdev_seek); - OF_method_new(OF_env, dsk, "read", &OF_blockdev_read); - OF_method_new(OF_env, dsk, "block-size", - &OF_blockdev_get_blocsize); - OF_method_new(OF_env, dsk, "dma-alloc", &OF_blockdev_dma_alloc); - OF_method_new(OF_env, dsk, "dma-free", &OF_blockdev_dma_free); - if (strcmp(type, "cdrom") == 0) - OF_method_new(OF_env, dsk, "eject", &OF_method_fake); - OF_method_new(OF_env, dsk, "close", &OF_method_fake); - dsk->private_data = private; - /* Set up aliases */ - OF_pack_get_path(OF_env, path, OF_NAMELEN_MAX, dsk); - if (alias != NULL) { - als = OF_node_get(OF_env, "aliases"); - if (als == NULL) { - ERROR("Cannot get 'aliases'\n"); - return NULL; - } - strcpy(tmp, alias); - if (OF_property_copy(OF_env, NULL, 0, als, tmp) >= 0) { - pos = tmp + strlen(alias); - for (i = 0; ; i++) { - sprintf(pos, "%d", i); - if (OF_property_copy(OF_env, NULL, 0, als, tmp) < 0) - break; - } - } - OF_DPRINTF("Set alias to %s\n", tmp); - OF_prop_string_new(OF_env, dsk, "alias", tmp); - OF_prop_string_new(OF_env, als, tmp, path); - OF_node_put(OF_env, als); - } - - return dsk; -} - -void OF_blockdev_set_boot_device (void *disk, int partnum, - const unsigned char *file) -{ - unsigned char tmp[OF_NAMELEN_MAX], *pos; - OF_env_t *OF_env; - OF_node_t *dsk = disk, *opts, *chs; - - OF_env = OF_env_main; - - if (OF_property_copy(OF_env, tmp, OF_NAMELEN_MAX, dsk, "alias") < 0) - OF_pack_get_path(OF_env, tmp, OF_NAMELEN_MAX, dsk); - sprintf(tmp + strlen(tmp), ":%d", partnum); - /* OpenDarwin 6.02 seems to need this one */ - opts = OF_node_get(OF_env, "options"); - if (opts == NULL) { - ERROR("Cannot get 'options'\n"); - return; - } - OF_prop_string_set(OF_env, OF_node_root, "boot-device", tmp); - OF_prop_string_set(OF_env, opts, "boot-device", tmp); - OF_DPRINTF("Set boot device to: '%s'\n", tmp); - OF_node_put(OF_env, opts); - /* Set the real boot path */ - pos = tmp + strlen(tmp); - sprintf(pos, ",%s", file); - /* Convert all '/' into '\' in the boot file name */ - for (; *pos != '\0'; pos++) { - if (*pos == '/') - *pos = '\\'; - } - chs = OF_node_get(OF_env, "chosen"); - if (chs == NULL) { - ERROR("Cannot get 'chosen'\n"); - return; - } - OF_prop_string_set(OF_env, chs, "bootpath", tmp); - OF_DPRINTF("Set boot path to: '%s'\n", tmp); - OF_node_put(OF_env, chs); -} - -/* Display package */ -static void OF_vga_draw_rectangle (OF_env_t *OF_env) -{ - const void *buf; - const unsigned char *args; - uint32_t posx, posy, width, height; - uint32_t ihandle; - - OF_CHECK_NBARGS(OF_env, 7); - ihandle = popd(OF_env); - args = (void *)popd(OF_env); - height = popd(OF_env); - width = popd(OF_env); - posy = popd(OF_env); - posx = popd(OF_env); - buf = (const void *)popd(OF_env); - OF_DPRINTF("x=%d y=%d h=%d ", posx, posy, width); - OF_DPRINTF("w=%d buf=%p\n", height, buf); - set_check(0); - vga_draw_buf(buf, width * vga_fb_bpp, posx, posy, width, height); - set_check(1); - pushd(OF_env, 0); -} - -static void OF_vga_fill_rectangle (OF_env_t *OF_env) -{ - const unsigned char *args; - uint32_t color, posx, posy, width, height; - uint32_t ihandle; - - OF_CHECK_NBARGS(OF_env, 7); - ihandle = popd(OF_env); - args = (void *)popd(OF_env); - height = popd(OF_env); - width = popd(OF_env); - posy = popd(OF_env); - posx = popd(OF_env); - color = popd(OF_env); - OF_DPRINTF("x=%d y=%d\n", posx, posy); - OF_DPRINTF("h=%d w=%d c=%0x\n", width, height, color); - vga_fill_rect(posx, posy, width, height, color); - pushd(OF_env, 0); -} - -static void OF_vga_set_width (OF_env_t *OF_env, OF_prop_t *prop, - const void *data, int len) -{ - uint32_t width, height, depth; - - if (len == sizeof(uint32_t)) { - width = *(uint32_t *)data; - OF_property_copy(OF_env, &height, 4, prop->node, "height"); - OF_property_copy(OF_env, &depth, 4, prop->node, "depth"); - vga_set_mode(width, height, depth); - } -} - -static void OF_vga_set_height (OF_env_t *OF_env, OF_prop_t *prop, - const void *data, int len) -{ - uint32_t width, height, depth; - - if (len == sizeof(uint32_t)) { - OF_property_copy(OF_env, &width, 4, prop->node, "width"); - height = *(uint32_t *)data; - OF_property_copy(OF_env, &depth, 4, prop->node, "depth"); - vga_set_mode(width, height, depth); - } -} - -static void OF_vga_set_depth (OF_env_t *OF_env, OF_prop_t *prop, - const void *data, int len) -{ - uint32_t width, height, depth; - - if (len == sizeof(uint32_t)) { - OF_property_copy(OF_env, &width, 4, prop->node, "width"); - OF_property_copy(OF_env, &height, 4, prop->node, "height"); - depth = *(uint32_t *)data; - vga_set_mode(width, height, depth); - } -} - -void OF_vga_register (const unsigned char *name, unused uint32_t address, - int width, int height, int depth, - unsigned long vga_bios_addr, unsigned long vga_bios_size) -{ - OF_env_t *OF_env; - unsigned char tmp[OF_NAMELEN_MAX]; - OF_node_t *disp, *chs, *als; - OF_prop_t *prop; - - OF_DPRINTF("Set frame buffer %08x %dx%dx%d\n", - address, width, height, depth); - OF_env = OF_env_main; - disp = OF_node_get(OF_env, name); - if (disp == NULL) { - ERROR("Cannot get display '%s'\n", name); - return; - } - prop = OF_prop_int_new(OF_env, disp, "width", width); - if (prop == NULL) { - OF_node_put(OF_env, disp); - ERROR("Cannot create display width property\n"); - return; - } - OF_property_set_cb(OF_env, prop, &OF_vga_set_width); - prop = OF_prop_int_new(OF_env, disp, "height", height); - if (prop == NULL) { - OF_node_put(OF_env, disp); - ERROR("Cannot create display height property\n"); - return; - } - OF_property_set_cb(OF_env, prop, &OF_vga_set_height); - switch (depth) { - case 8: - break; - case 15: - depth = 16; - break; - case 32: - break; - default: - /* OF spec this is mandatory, but we have no support for it */ - printf("%d bits VGA isn't implemented\n", depth); - bug(); - /* Never come here */ - break; - } - prop = OF_prop_int_new(OF_env, disp, "depth", depth); - if (prop == NULL) { - ERROR("Cannot create display depth\n"); - goto out; - } - OF_property_set_cb(OF_env, prop, &OF_vga_set_depth); - OF_prop_int_new(OF_env, disp, "linebytes", vga_fb_linesize); - OF_method_new(OF_env, disp, "draw-rectangle", &OF_vga_draw_rectangle); - OF_method_new(OF_env, disp, "fill-rectangle", &OF_vga_fill_rectangle); - OF_method_new(OF_env, disp, "color!", &OF_method_fake); - chs = OF_node_get(OF_env, "chosen"); - if (chs == NULL) { - ERROR("Cannot get 'chosen'\n"); - goto out; - } - OF_prop_int_new(OF_env, chs, "display", OF_pack_handle(OF_env, disp)); - OF_node_put(OF_env, chs); - OF_pack_get_path(OF_env, tmp, 512, disp); - printf("Set display '%s' path to '%s'\n", name, tmp); - als = OF_node_get(OF_env, "aliases"); - if (als == NULL) { - ERROR("Cannot get 'aliases'\n"); - goto out; - } - OF_prop_string_new(OF_env, als, "screen", tmp); - OF_prop_string_new(OF_env, als, "display", tmp); - OF_node_put(OF_env, als); - /* XXX: may also need read-rectangle */ - - if (vga_bios_size >= 8) { - const uint8_t *p; - int size; - /* check the QEMU VGA BIOS header */ - p = (const uint8_t *)vga_bios_addr; - if (p[0] == 'N' && p[1] == 'D' && p[2] == 'R' && p[3] == 'V') { - size = *(uint32_t *)(p + 4); - OF_property_new(OF_env, disp, "driver,AAPL,MacOS,PowerPC", - p + 8, size); - } - } - out: - OF_node_put(OF_env, disp); -} - -/* Pseudo packages to make BootX happy */ -/* sl_words package */ -static void slw_set_output_level (OF_env_t *OF_env) -{ - OF_node_t *slw; - const unsigned char *args; - int level; - - OF_CHECK_NBARGS(OF_env, 3); - popd(OF_env); - args = (void *)popd(OF_env); - level = popd(OF_env); - slw = OF_node_get(OF_env, "sl_words"); - if (slw == NULL) { - pushd(OF_env, -1); - } else { - OF_DPRINTF("Set output level to: %d\n", level); - OF_prop_int_set(OF_env, slw, "outputLevel", level); - OF_node_put(OF_env, slw); - pushd(OF_env, 0); - } -} - -#ifdef DEBUG_BIOS -#define EMIT_BUFFER_LEN 256 -static unsigned char emit_buffer[EMIT_BUFFER_LEN]; -static int emit_pos = 0; -#endif - -static void slw_emit (OF_env_t *OF_env) -{ - const unsigned char *args; - int c; - - OF_CHECK_NBARGS(OF_env, 3); - popd(OF_env); - args = (void *)popd(OF_env); - c = popd(OF_env); - // OF_DPRINTF("Emit char %d\n", c); -#ifdef DEBUG_BIOS - if (emit_pos < EMIT_BUFFER_LEN - 1) { - emit_buffer[emit_pos++] = c; - // outb(0xFF00, c); - outb(0x0F00, c); - } else { - emit_buffer[emit_pos] = '\0'; - } -#else - outb(0x0F00, c); -#endif - pushd(OF_env, 0); -} - -static void slw_cr (OF_env_t *OF_env) -{ - const unsigned char *args; - - OF_CHECK_NBARGS(OF_env, 2); - popd(OF_env); - args = (void *)popd(OF_env); - // OF_DPRINTF("Emit CR char\n"); - // outb(0xFF01, '\n'); - outb(0x0F01, '\n'); -#ifdef DEBUG_BIOS - emit_buffer[emit_pos] = '\0'; - if (strcmp(emit_buffer, "Call Kernel!") == 0) { - /* Set qemu in debug mode: - * log in_asm,op,int,ioport,cpu - */ - uint16_t loglevel = 0x02 | 0x10 | 0x80; - // outw(0xFF02, loglevel); - outb(0x0F02, loglevel); - } - emit_pos = 0; -#endif - pushd(OF_env, 0); -} - -static void slw_init_keymap (OF_env_t *OF_env) -{ - const unsigned char *args; - OF_node_t *node; - OF_prop_t *prop; - uint32_t phandle, ihandle; - - OF_CHECK_NBARGS(OF_env, 3); - ihandle = popd(OF_env); - args = (void *)popd(OF_env); - phandle = ihandle >> 16; - ihandle &= 0xFFFF; - OF_DPRINTF("\n"); - node = OF_pack_find(OF_env, phandle); - if (node == NULL) { - ERROR("Cant' init slw keymap\n"); - pushd(OF_env, -1); - } else { - prop = OF_property_get(OF_env, node, "keyMap"); - if (prop == NULL) { - pushd(OF_env, -1); - } else { - pushd(OF_env, (uint32_t)prop->value); - pushd(OF_env, 0); - } - } -} - -static void slw_update_keymap (OF_env_t *OF_env) -{ - const unsigned char *args; - - OF_CHECK_NBARGS(OF_env, 2); - popd(OF_env); - args = (void *)popd(OF_env); - OF_DPRINTF("\n"); - pushd(OF_env, 0); -} - -static void slw_spin (OF_env_t *OF_env) -{ - const unsigned char *args; - /* XXX: cur_spin should be in sl_words package */ - static int cur_spin = 0; - int c; - - OF_CHECK_NBARGS(OF_env, 2); - popd(OF_env); - args = (void *)popd(OF_env); - if (cur_spin > 15) { - c = RGB(0x30, 0x30, 0x50); - } else { - c = RGB(0x11, 0x11, 0x11); - } - c = vga_get_color(c); - vga_fill_rect((cur_spin % 15) * 5 + 280, 420, 4, 3, c); - cur_spin = (cur_spin + 1) & 31; - OF_DPRINTF("\n"); - pushd(OF_env, -1); -} - -static void slw_spin_init (OF_env_t *OF_env) -{ - const unsigned char *args; - - OF_CHECK_NBARGS(OF_env, 8); - popd(OF_env); - args = (void *)popd(OF_env); - popd(OF_env); - popd(OF_env); - popd(OF_env); - popd(OF_env); - popd(OF_env); - popd(OF_env); - pushd(OF_env, -1); -} - -static void slw_pwd (OF_env_t *OF_env) -{ - const unsigned char *args; - - OF_CHECK_NBARGS(OF_env, 3); - popd(OF_env); - args = (void *)popd(OF_env); - OF_DPRINTF("\n"); - pushd(OF_env, -1); -} - -static void slw_sum (OF_env_t *OF_env) -{ - const unsigned char *args; - - OF_CHECK_NBARGS(OF_env, 3); - popd(OF_env); - args = (void *)popd(OF_env); - OF_DPRINTF("\n"); - pushd(OF_env, -1); -} - -/*****************************************************************************/ -/* Client program interface */ -/* Client interface services */ -static void OF_test (OF_env_t *OF_env); - -/* Device tree services */ -/* Get next package */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_peer (OF_env_t *OF_env) -{ - OF_node_t *node; - uint32_t phandle; - - OF_CHECK_NBARGS(OF_env, 1); - phandle = popd(OF_env); - OF_DPRINTF("phandle 0x%0x\n", phandle); - if (phandle == 0) - node = OF_node_root; - else - node = OF_pack_next(OF_env, phandle); - if (node == NULL) - pushd(OF_env, 0); - else - pushd(OF_env, OF_pack_handle(OF_env, node)); -} - -/* Get first child package */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_child (OF_env_t *OF_env) -{ - OF_node_t *node; - uint32_t phandle; - - OF_CHECK_NBARGS(OF_env, 1); - phandle = popd(OF_env); - OF_DPRINTF("phandle 0x%0x\n", phandle); - node = OF_pack_child(OF_env, phandle); - if (node == NULL) - pushd(OF_env, 0); - else - pushd(OF_env, OF_pack_handle(OF_env, node)); -} - -/* Get parent package */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_parent (OF_env_t *OF_env) -{ - OF_node_t *node; - uint32_t phandle; - - OF_CHECK_NBARGS(OF_env, 1); - phandle = popd(OF_env); - OF_DPRINTF("phandle 0x%0x\n", phandle); - node = OF_pack_parent(OF_env, phandle); - if (node == NULL) - pushd(OF_env, 0); - else - pushd(OF_env, OF_pack_handle(OF_env, node)); -} - -/* Get package related to an instance */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_instance_to_package (OF_env_t *OF_env) -{ - uint32_t ihandle; - - OF_CHECK_NBARGS(OF_env, 1); - ihandle = popd(OF_env); - OF_DPRINTF("ihandle 0x%0x\n", ihandle); - pushd(OF_env, (ihandle >> 16) & 0xFFFF); -} - -/* Get property len */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_getproplen (OF_env_t *OF_env) -{ - unsigned char name[OF_NAMELEN_MAX], *namep; - OF_node_t *node; - uint32_t phandle; - - OF_CHECK_NBARGS(OF_env, 2); - phandle = popd(OF_env); - namep = (unsigned char *)popd(OF_env); - OF_lds(name, namep); - OF_DPRINTF("phandle 0x%0x prop [%s]\n", phandle, name); - node = OF_pack_find(OF_env, phandle); - if (node == NULL) - pushd(OF_env, -1); - else - pushd(OF_env, OF_property_len(OF_env, node, name)); -} - -/* Get property */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_getprop (OF_env_t *OF_env) -{ - unsigned char name[OF_NAMELEN_MAX], *namep; - OF_node_t *node; - void *buffer; - uint32_t phandle; - int len, nb_args; - - // OF_CHECK_NBARGS(OF_env, 4); - nb_args = stackd_depth(OF_env); - phandle = popd(OF_env); - namep = (unsigned char *)popd(OF_env); - OF_lds(name, namep); - buffer = (void *)popd(OF_env); - if (nb_args == 3) { - /* This hack is needed to boot MacOS X panther (10.3) */ - len = 1024; - } else { - len = popd(OF_env); - } - OF_DPRINTF("phandle 0x%0x prop [%s]\n", phandle, name); - OF_DPRINTF("buffer %p len %d\n", buffer, len); - node = OF_pack_find(OF_env, phandle); - if (node == NULL) { - len = -1; - } else { - len = OF_property_copy(OF_env, buffer, len, node, name); - if (len != -1) { - OF_DPRINTF("Copied %d bytes\n", len); - } - } - pushd(OF_env, len); -} - -/* Check existence of next property */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_nextprop (OF_env_t *OF_env) -{ - unsigned char name[OF_NAMELEN_MAX], *namep; - OF_node_t *node; - OF_prop_t *next; - unsigned char *next_name; - uint32_t phandle; - - OF_CHECK_NBARGS(OF_env, 3); - phandle = popd(OF_env); - namep = (unsigned char *)popd(OF_env); - OF_lds(name, namep); - OF_DPRINTF("phandle 0x%0x prop [%s]\n", phandle, name); - next_name = (unsigned char *)popd(OF_env); - node = OF_pack_find(OF_env, phandle); - if (node == NULL) { - pushd(OF_env, -1); - } else { - next = OF_property_next(OF_env, node, name); - if (next == NULL || next->name == NULL) { - OF_DPRINTF("No next property found [%s]\n", name); - pushd(OF_env, 0); - } else { - OF_DPRINTF("Return property name [%s]\n", next->name); - OF_sts(next_name, (void *)(next->name)); - OF_DUMP_STRING(OF_env, next_name); - pushd(OF_env, strlen(next->name) + 1); - } - } -} - -/* Set a property */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_setprop (OF_env_t *OF_env) -{ - unsigned char name[OF_NAMELEN_MAX], *namep; - unsigned char *value, *buffer; - OF_node_t *node; - OF_prop_t *prop; - uint32_t phandle; - int len; - int i; - - OF_CHECK_NBARGS(OF_env, 4); - phandle = popd(OF_env); - namep = (unsigned char *)popd(OF_env); - OF_lds(name, namep); - OF_DPRINTF("phandle 0x%0x prop [%s]\n", phandle, name); - buffer = (unsigned char *)popd(OF_env); - len = popd(OF_env); - node = OF_pack_find(OF_env, phandle); - if (node == NULL) { - pushd(OF_env, -1); - ERROR("Cannot get pack %04x\n", phandle); - return; - } - value = malloc(len); - if (value == NULL && len != 0) { - pushd(OF_env, -1); - ERROR("%s: Cannot alloc property '%s' (%d)\n", __func__, name, len); - return; - } - for (i = 0; i < len; i++) - value[i] = buffer[i]; - prop = OF_property_set(OF_env, node, name, value, len); - if (prop == NULL) - len = -1; - pushd(OF_env, len); -} - -/* "canon" */ - -/* Find a device given its path */ -__attribute__ (( section (".OpenFirmware") )) -static OF_node_t *OF_get_alias (OF_env_t *OF_env, const unsigned char *name) -{ - unsigned char tmp[OF_NAMELEN_MAX], *pos, *st; - const unsigned char *alias, *npos; - OF_node_t *als, *node; - OF_prop_t *prop; - - node = NULL; - strcpy(tmp, name); - for (st = tmp; *st == '/'; st++) - continue; - pos = strchr(st, '/'); - if (pos == NULL) { - pos = strchr(st, ':'); - } - if (pos != NULL) { - *pos = '\0'; - npos = name + (pos - tmp); - } else { - npos = ""; - } - OF_DPRINTF("Look for alias for '%s' => '%s' '%s'\n", name, tmp, npos); - als = OF_pack_find_by_name(OF_env, OF_node_root, "/aliases"); - if (als == NULL) { - ERROR("Cannot get 'aliases'\n"); - return NULL; - } - prop = OF_property_get(OF_env, als, tmp); - if (prop == NULL) { - OF_DPRINTF("No %s alias !\n", tmp); - goto out; - } - alias = prop->value; - OF_DPRINTF("Found alias '%s' '%s'\n", alias, npos); - sprintf(tmp, "%s%s", alias, npos); - node = OF_pack_find_by_name(OF_env, OF_node_root, tmp); - if (node == NULL) { - printf("%s alias is a broken link !\n", name); - goto out; - } - OF_node_put(OF_env, node); - out: - OF_node_put(OF_env, als); - - return node; -} - -__attribute__ (( section (".OpenFirmware") )) -static void OF_finddevice (OF_env_t *OF_env) -{ - unsigned char name[OF_NAMELEN_MAX], *namep; - OF_node_t *node; - int ret; - - OF_CHECK_NBARGS(OF_env, 1); - namep = (unsigned char *)popd(OF_env); - OF_lds(name, namep); - OF_DPRINTF("name %p [%s]\n", namep, name); - /* Search first in "/aliases" */ - node = OF_get_alias(OF_env, name); - if (node == NULL) { - node = OF_pack_find_by_name(OF_env, OF_node_root, name); - } - if (node == NULL) - ret = -1; - else - ret = OF_pack_handle(OF_env, node); - OF_DPRINTF("ret 0x%0x\n", ret); - pushd(OF_env, ret); -} - -/* "instance-to-path */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_instance_to_path (OF_env_t *OF_env) -{ - void *buffer; - OF_inst_t *inst; - uint32_t ihandle; - int len; - - OF_CHECK_NBARGS(OF_env, 3); - OF_DPRINTF("\n"); - ihandle = popd(OF_env); - buffer = (void *)popd(OF_env); - len = popd(OF_env); - OF_DPRINTF("ihandle: 0x%0x len=%d\n", ihandle, len); - inst = OF_inst_find(OF_env, ihandle); - if (inst == NULL) - len = -1; - else - len = OF_inst_get_path(OF_env, buffer, len, inst) + 1; - OF_DUMP_STRING(OF_env, buffer); - pushd(OF_env, len); -} - -/* "package-to-path" */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_package_to_path (OF_env_t *OF_env) -{ - void *buffer; - OF_node_t *node; - uint32_t phandle; - int len; - - OF_CHECK_NBARGS(OF_env, 3); - OF_DPRINTF("\n"); - phandle = popd(OF_env); - buffer = (void *)popd(OF_env); - len = popd(OF_env); - node = OF_pack_find(OF_env, phandle); - if (node == NULL) - len = -1; - else - len = OF_pack_get_path(OF_env, buffer, len, node) + 1; - OF_DUMP_STRING(OF_env, buffer); - pushd(OF_env, len); -} - -/* Call a package's method */ -__attribute__ (( section (".OpenFirmware") )) -static void _OF_callmethod (OF_env_t *OF_env, const unsigned char *name, - uint32_t ihandle, const unsigned char *argp) -{ - OF_node_t *node; - OF_inst_t *inst; - OF_method_t *method; - OF_cb_t cb; - - inst = OF_inst_find(OF_env, ihandle); - OF_DPRINTF("Attempt to call method [%s] of package instance 0x%0x\n", - name, ihandle); - if (inst == NULL) { - OF_DPRINTF("No instance %0x\n", ihandle); - pushd(OF_env, -1); - return; - } - node = inst->node; - method = OF_method_get(OF_env, node, name); - if (method != NULL) { - cb = method->func; - } else { - if (strcmp(name, "open") == 0) { - cb = &OF_method_fake; - } else { - printf("Method '%s' not found in '%s'\n", - name, node->prop_name->value); - pushd(OF_env, -1); - bug(); - return; - } - } -#if 0 - OF_DPRINTF("Push instance method %p (%p)...\n", &method->func, - &slw_emit); -#endif - pushf(OF_env, &cb); - if (argp != NULL) - pushd(OF_env, (uint32_t)argp); - else - pushd(OF_env, 0x00000000); - pushd(OF_env, ihandle); -} - -__attribute__ (( section (".OpenFirmware") )) -static unsigned char *OF_get_args (unused OF_env_t *env, unsigned char *name) -{ - unsigned char *sd; - - sd = strchr(name, ':'); - if (sd == NULL) - return NULL; - *sd = '\0'; - - return sd + 1; -} - -__attribute__ (( section (".OpenFirmware") )) -static void OF_callmethod (OF_env_t *OF_env) -{ - const unsigned char *args; - unsigned char name[OF_NAMELEN_MAX], *namep; - uint32_t ihandle; - - OF_DPRINTF("\n\n\n#### CALL METHOD ####\n\n"); - namep = (unsigned char *)popd(OF_env); - OF_lds(name, namep); - args = OF_get_args(OF_env, name); - ihandle = popd(OF_env); - _OF_callmethod(OF_env, name, ihandle, args); -} - -/* Device IO services */ -/* Create a new instance of a device's package */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_open (OF_env_t *OF_env) -{ - const unsigned char *args; - unsigned char name[OF_NAMELEN_MAX], *namep; - OF_node_t *node; - OF_inst_t *inst; - uint32_t ihandle; - - OF_CHECK_NBARGS(OF_env, 1); - namep = (unsigned char *)popd(OF_env); - OF_lds(name, namep); - OF_DPRINTF("package [%s]\n", name); - args = OF_get_args(OF_env, name); - node = OF_get_alias(OF_env, name); - if (node == NULL) { - node = OF_pack_find_by_name(OF_env, OF_node_root, name); - } - if (node == NULL) { - OF_DPRINTF("package not found !\n"); - pushd(OF_env, -1); - return; - } - inst = OF_instance_new(OF_env, node); - if (inst == NULL) { - pushd(OF_env, -1); - ERROR("Cannot create package instance\n"); - return; - } - ihandle = OF_instance_get_id(OF_env, inst); - /* If an "open" method exists in the package, call it */ - OF_DPRINTF("package [%s] => %0x\n", name, ihandle); - OF_node_put(OF_env, node); - _OF_callmethod(OF_env, "open", ihandle, args); -} - -/* De-instanciate a package */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_close (OF_env_t *OF_env) -{ - uint32_t ihandle; - - OF_CHECK_NBARGS(OF_env, 1); - ihandle = popd(OF_env); - /* If an "close" method exists in the package, call it */ - _OF_callmethod(OF_env, "close", ihandle, NULL); - /* XXX: Should free the instance */ -} - -/* "read" */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_read (OF_env_t *OF_env) -{ - uint32_t ihandle; - - OF_CHECK_NBARGS(OF_env, 3); - ihandle = popd(OF_env); - OF_DPRINTF("ih: %0x\n", ihandle); - /* If a "read" method exists in the package, call it */ - _OF_callmethod(OF_env, "read", ihandle, NULL); -} - -/* Try call the "read" method of a device's package */ -/* "write" */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_write (OF_env_t *OF_env) -{ - uint32_t ihandle; - - OF_CHECK_NBARGS(OF_env, 3); - ihandle = popd(OF_env); - // OF_DPRINTF("ih: %0x\n", ihandle); - /* If a "write" method exists in the package, call it */ - _OF_callmethod(OF_env, "write", ihandle, NULL); -} - -/* "seek" */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_seek (OF_env_t *OF_env) -{ - uint32_t ihandle; - - OF_CHECK_NBARGS(OF_env, 3); - ihandle = popd(OF_env); - OF_DPRINTF("ih: %0x\n", ihandle); - /* If a "seek" method exists in the package, call it */ - _OF_callmethod(OF_env, "seek", ihandle, NULL); -} - -/* Memory services */ -/* Claim some memory space */ -__attribute__ (( section (".OpenFirmware") )) -uint32_t OF_claim_virt (uint32_t virt, uint32_t size, int *range) -{ - int i, keep = -1; - - OF_DPRINTF("Claim %d bytes at 0x%0x\n", size, virt); - /* First check that the requested memory stands in the physical memory */ - if (OF_mem_ranges[0].start > virt || - (OF_mem_ranges[0].start + OF_mem_ranges[0].size) < (virt + size)) { - ERROR("not in memory: start 0x%0x virt 0x%0x end 0x%0x 0x%0x\n", - OF_mem_ranges[0].start, virt, - OF_mem_ranges[0].start + OF_mem_ranges[0].size, - virt + size); - return (uint32_t)(-1); - } - /* Now check that it doesn't overlap with already claimed areas */ - for (i = 1; i < OF_MAX_MEMRANGES + 1; i++) { - if (OF_mem_ranges[i].start == (uint32_t)(-1) || - OF_mem_ranges[i].size == (uint32_t)(-1)) { - if (keep == -1) - keep = i; - continue; - } - if (OF_mem_ranges[i].start == virt && - (OF_mem_ranges[i].start + OF_mem_ranges[i].size) == (virt + size)) { - return virt; - } - if (!((OF_mem_ranges[i].start >= (virt + size) || - (OF_mem_ranges[i].start + OF_mem_ranges[i].size) <= virt))) { - ERROR("overlap: start 0x%0x virt 0x%0x end 0x%0x 0x%0x\n", - OF_mem_ranges[i].start, virt, - OF_mem_ranges[i].start + OF_mem_ranges[i].size, - virt + size); - /* Aie... */ - return (uint32_t)(-1); - } - } - OF_DPRINTF("return range: %d\n", keep); - if (keep == -1) { - /* no more rooms */ - ERROR("No more rooms\n"); - return (uint32_t)(-1); - } else { - ERROR("Give range: start 0x%0x 0x%0x\n", virt, size); - } - if (range != NULL) - *range = keep; - - return virt; -} - -/* We always try to get the upper address we can */ -__attribute__ (( section (".OpenFirmware") )) -static uint32_t OF_claim_size (uint32_t size, int align, int *range) -{ - uint32_t addr, max = (uint32_t)(-1); - int i; - - OF_DPRINTF("Try map %d bytes at 0x00000000\n", size); - if (OF_claim_virt(0, size, range) != (uint32_t)(-1)) - max = 0; - for (i = 1; i < OF_MAX_MEMRANGES + 1; i++) { - if (OF_mem_ranges[i].start == (uint32_t)(-1) || - OF_mem_ranges[i].size == (uint32_t)(-1)) - continue; - addr = (OF_mem_ranges[i].start + OF_mem_ranges[i].size + align - 1) & - ~(align - 1); - OF_DPRINTF("Try map %d bytes at 0x%0x\n", size, addr); - if ((addr + 1) > (max + 1)) { - if (OF_claim_virt(addr, size, range) != (uint32_t)(-1)) - max = addr; - } - } - - return max; -} - -__attribute__ (( section (".OpenFirmware") )) -static void OF_claim (OF_env_t *OF_env) -{ - uint32_t virt, size, addr; - int align; - int i, range; - - OF_CHECK_NBARGS(OF_env, 3); - virt = popd(OF_env); - size = popd(OF_env); - align = popd(OF_env); - DPRINTF("virt 0x%0x size 0x%0x align %d\n", virt, size, align); - if (align == 0) { - addr = OF_claim_virt(virt, size, &range); - } else { - for (i = 1; i < align; i = i << 1) - continue; - align = i; - size = (size + align - 1) & ~(align - 1); - addr = OF_claim_size(size, align, &range); - } - if (addr == (uint32_t)-1) { - ERROR("No range match !\n"); - pushd(OF_env, -1); - } - if (range != -1) { - OF_mem_ranges[range].start = addr; - OF_mem_ranges[range].size = size; - } - OF_DPRINTF("Give address 0x%0x\n", addr); - pushd(OF_env, addr); -} - -/* release some previously claimed memory */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_release (OF_env_t *OF_env) -{ - uint32_t virt, size; - int i; - - OF_CHECK_NBARGS(OF_env, 2); - virt = popd(OF_env); - size = popd(OF_env); - OF_DPRINTF("virt 0x%0x size 0x%0x\n", virt, size); - for (i = 0; i < OF_MAX_MEMRANGES; i++) { - if (OF_mem_ranges[i].start == virt && OF_mem_ranges[i].size == size) { - OF_mem_ranges[i].start = (uint32_t)(-1); - OF_mem_ranges[i].size = (uint32_t)(-1); - break; - } - } -} - -/* Control transfer services */ -/* "boot" */ - -/* Enter Open-Firmware interpreter */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_enter (OF_env_t *OF_env) -{ - int n_args; - - n_args = stackd_depth(OF_env); - /* means that the bootloader has ended. - * So qemu will... - */ - OF_DPRINTF("%d \n", n_args); - // printf("Bootloader has quitted...\n"); - // abort(); -} - -/* Exit client program */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_exit (OF_env_t *OF_env) -{ - int n_args; - - n_args = stackd_depth(OF_env); - /* means that the bootloader has ended. - * So qemu will... - */ - OF_DPRINTF("%d \n", n_args); - // printf("Bootloader has quitted...\n"); - // abort(); -} - -/* "chain" */ - -/* User interface services */ -/* "interpret" */ - -__attribute__ (( section (".OpenFirmware") )) -static void OF_interpret (OF_env_t *OF_env) -{ - const unsigned char *FString; - void *buf; - OF_inst_t *inst; - OF_node_t *pks, *slw, *chs, *disp; - uint32_t ihandle, crc; - - OF_DPRINTF("\n"); - // OF_CHECK_NBARGS(OF_env, 1); - FString = (const void *)popd(OF_env); - crc = crc32(0, FString, strlen(FString)); - OF_DPRINTF("\n\nOF INTERPRETER CALL:\n [%s]\n crc=%0x\n", FString, crc); - /* Do some hacks to make BootX happy */ - switch (crc) { - case 0x225b6748: /* MacOS X 10.2 and OpenDarwin 1.41 */ - case 0xb1cd4d25: /* OpenDarwin 6.02 */ - /* Create "sl_words" package */ - popd(OF_env); - /* Find "/packages" */ - pks = OF_pack_find_by_name(OF_env, OF_node_root, "/packages"); - if (pks == NULL) { - OF_node_put(OF_env, pks); - pushd(OF_env, -1); - ERROR("Cannot get '/packages'\n"); - break; - } - slw = OF_node_new(OF_env, pks, "sl_words", OF_ADDRESS_NONE); - if (slw == NULL) { - OF_node_put(OF_env, pks); - pushd(OF_env, -1); - ERROR("Cannot create 'sl_words'\n"); - break; - } - /* Create methods */ - OF_method_new(OF_env, slw, "slw_set_output_level", - &slw_set_output_level); - OF_method_new(OF_env, slw, "slw_emit", &slw_emit); - OF_method_new(OF_env, slw, "slw_cr", &slw_cr); - OF_method_new(OF_env, slw, "slw_init_keymap", &slw_init_keymap); - OF_method_new(OF_env, slw, "slw_update_keymap", &slw_update_keymap); - OF_method_new(OF_env, slw, "slw_spin", &slw_spin); - OF_method_new(OF_env, slw, "slw_spin_init", &slw_spin_init); - OF_method_new(OF_env, slw, "slw_pwd", &slw_pwd); - OF_method_new(OF_env, slw, "slw_sum", &slw_sum); - /* Init properties */ - OF_prop_int_new(OF_env, slw, "outputLevel", 0); - OF_prop_int_new(OF_env, slw, "keyboardIH", 0); - { -#if 0 - OF_node_t *kbd; - kbd = OF_pack_find_by_name(OF_env, OF_node_root, "/keyboard"); - if (kbd == NULL) { - OF_node_put(OF_env, pks); - pushd(OF_env, -1); - ERROR("Cannot get '/keyboard'\n"); - break; - } - buf = malloc(0x20); - if (buf == NULL) { - OF_node_put(OF_env, pks); - pushd(OF_env, -1); - ERROR("Cannot allocate keyboard buff\n"); - break; - } -#else - buf = malloc(0x20); - if (buf == NULL) { - OF_node_put(OF_env, pks); - pushd(OF_env, -1); - ERROR("Cannot allocate keyboard buff\n"); - break; - } - memset(buf, 0, 0x20); - OF_property_new(OF_env, slw, "keyMap", buf, 0x20); -#endif - } - OF_prop_int_new(OF_env, slw, "screenIH", 0); - OF_prop_int_new(OF_env, slw, "cursorAddr", 0); - OF_prop_int_new(OF_env, slw, "cursorX", 0); - OF_prop_int_new(OF_env, slw, "cursorY", 0); - OF_prop_int_new(OF_env, slw, "cursorW", 0); - OF_prop_int_new(OF_env, slw, "cursorH", 0); - OF_prop_int_new(OF_env, slw, "cursorFrames", 0); - OF_prop_int_new(OF_env, slw, "cursorPixelSize", 0); - OF_prop_int_new(OF_env, slw, "cursorStage", 0); - OF_prop_int_new(OF_env, slw, "cursorTime", 0); - OF_prop_int_new(OF_env, slw, "cursorDelay", 0); - /* Instanciate sl_words */ - inst = OF_instance_new(OF_env, slw); - if (inst == NULL) { - OF_node_put(OF_env, pks); - pushd(OF_env, -1); - ERROR("Cannot create sl_words instance\n"); - break; - } - ihandle = OF_instance_get_id(OF_env, inst); - /* Release packages */ - OF_node_put(OF_env, slw); - OF_node_put(OF_env, pks); - OF_DPRINTF("sl_words instance: %0x\n", ihandle); - /* Set return value */ - if (crc == 0xb1cd4d25) /* Hack for OpenDarwin 6.02 */ - pushd(OF_env, ihandle); - pushd(OF_env, ihandle); - pushd(OF_env, 0); - break; - case 0x233441d3: /* MacOS X 10.2 and OpenDarwin 1.41 */ - /* Create "memory-map" pseudo device */ - { - OF_node_t *map; - uint32_t phandle; - - /* Find "/packages" */ - chs = OF_pack_find_by_name(OF_env, OF_node_root, "/chosen"); - if (chs == NULL) { - pushd(OF_env, -1); - ERROR("Cannot get '/chosen'\n"); - break; - } - map = OF_node_new(OF_env, chs, "memory-map", OF_ADDRESS_NONE); - if (map == NULL) { - pushd(OF_env, -1); - ERROR("Cannot create 'memory-map'\n"); - break; - } - phandle = OF_pack_handle(OF_env, map); - OF_node_put(OF_env, map); - OF_node_put(OF_env, chs); - pushd(OF_env, phandle); - pushd(OF_env, 0); - } - break; - case 0x32a2d18e: /* MacOS X 10.2 and OpenDarwin 6.02 */ - /* Return screen ihandle */ - disp = OF_get_alias(OF_env, "screen"); - if (disp == NULL) { - pushd(OF_env, 0); - pushd(OF_env, -1); - ERROR("Cannot get 'screen' alias\n"); - break; - } - inst = OF_instance_new(OF_env, disp); - if (inst == NULL) { - OF_node_put(OF_env, disp); - pushd(OF_env, 0); - pushd(OF_env, -1); - ERROR("Cannot create 'screen' instance\n"); - break; - } - ihandle = OF_instance_get_id(OF_env, inst); - OF_node_put(OF_env, disp); - OF_DPRINTF("Return screen ihandle: %0x\n", ihandle); - pushd(OF_env, ihandle); - pushd(OF_env, 0); - break; - case 0xF3A9841F: /* MacOS X 10.2 */ - case 0x76fbdf18: /* OpenDarwin 6.02 */ - /* Set current display as active package */ - disp = OF_get_alias (OF_env, "screen"); - if (disp == NULL) { - pushd(OF_env, 0); - pushd(OF_env, -1); - } - OF_node_put(OF_env, disp); - break; - case 0x1c3bc93f: /* MacOS X 10.3 */ - /* get-package-property if 0 0 then */ - OF_getprop(OF_env); - { - uint32_t len; - len = popd(OF_env); - if (len == (uint32_t)-1) - len = 0; - pushd(OF_env, len); - } - break; - case 0x218d5ccb: /* yaboot */ - case 0x27b32255: - case 0x05d332ef: - case 0xc7b5d3b5: - /* skip it */ - break; - case 0xf541a878: - case 0x6a9b2be6: - /* Yaboot: set background color to black */ - break; - case 0x846077fb: - case 0x299c2c5d: /* gentoo */ - /* Yaboot: set foreground color to grey */ - break; - case 0x4ad41f2d: - /* Yaboot: wait 10 ms: sure ! */ - break; - - default: - /* ERROR */ - printf("Script: len=%d\n%s\n", (int)strlen(FString), FString); - printf("Call %0x NOT IMPLEMENTED !\n", crc); - bug(); - break; - } - OF_DPRINTF("\n\nOF INTERPRETER CALL DONE\n\n"); -} - -/* "set-callback" */ -/* "set-symbol-lookup" */ - -/* Time services */ -/* "milliseconds" */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_milliseconds (OF_env_t *OF_env) -{ -#if 0 - struct timeval tv; - - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(OF_env, 0); - gettimeofday(&tv, NULL); - pushd(OF_env, (tv.tv_sec * 1000) + (tv.tv_usec / 1000)); -#else - static uint32_t ms = 0; - - OF_CHECK_NBARGS(OF_env, 0); - pushd(OF_env, ms); - usleep(10000); /* XXX: TOFIX: Random sleep */ - ms += 10; -#endif -} - -/* Undocumented in IEEE 1275 */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_quiesce (OF_env_t *OF_env) -{ - OF_CHECK_NBARGS(OF_env, 0); - /* Should free all OF resources */ - bd_reset_all(); -#if defined (DEBUG_BIOS) - { - uint16_t loglevel = 0x02 | 0x10 | 0x80; - // outw(0xFF02, loglevel); - outb(0x0F02, loglevel); - } -#endif -} - -typedef struct OF_service_t OF_service_t; -struct OF_service_t { - const unsigned char *name; - OF_cb_t cb; -}; - -static OF_service_t services[] = { - { "test", &OF_test, }, - { "peer", &OF_peer, }, - { "child", &OF_child, }, - { "parent", &OF_parent, }, - { "instance-to-package", &OF_instance_to_package, }, - { "getproplen", &OF_getproplen, }, - { "getprop", &OF_getprop, }, - { "nextprop", &OF_nextprop, }, - { "setprop", &OF_setprop, }, - { "finddevice", &OF_finddevice, }, - { "instance-to-path", &OF_instance_to_path, }, - { "package-to-path", &OF_package_to_path, }, - { "call-method", &OF_callmethod, }, - { "open", &OF_open, }, - { "open-package", &OF_open, }, - { "close", &OF_close, }, - { "read", &OF_read, }, - { "write", &OF_write, }, - { "seek", &OF_seek, }, - { "claim", &OF_claim, }, - { "release", &OF_release, }, - { "enter", &OF_enter, }, - { "exit", &OF_exit, }, - { "interpret", &OF_interpret, }, - { "milliseconds", &OF_milliseconds, }, - { "quiesce", &OF_quiesce, }, -}; - -/* Probe if a named service exists */ -__attribute__ (( section (".OpenFirmware") )) -static void OF_test (OF_env_t *OF_env) -{ - unsigned char name[OF_NAMELEN_MAX], *namep; - uint32_t i; - int ret = -1; - - OF_CHECK_NBARGS(OF_env, 1); - namep = (unsigned char *)popd(OF_env); - OF_lds(name, namep); - OF_DPRINTF("service [%s]\n", name); - for (i = 0; i < (sizeof(services) / sizeof(OF_service_t)); i++) { - if (strcmp(services[i].name, name) == 0) { - ret = 0; - break; - } - } - pushd(OF_env, ret); -} - -/* Main entry point for PPC clients */ -__attribute__ (( section (".OpenFirmware") )) -int OF_client_entry (void *p) -{ - unsigned char buffer[OF_NAMELEN_MAX]; - OF_env_t OF_env; - OF_cb_t cb; - unsigned char *namep; - uint32_t i; - - /* set our environment */ - MMU_off(); - OF_DPRINTF("Called with arg: %p\n", p); - /* Load function name string */ - namep = (unsigned char *)(*(uint32_t *)p); - OF_lds(buffer, namep); - /* Find callback */ - cb = NULL; - OF_DPRINTF("Look for service [%s]\n", buffer); - for (i = 0; i < (sizeof(services) / sizeof(OF_service_t)); i++) { - if (strcmp(services[i].name, buffer) == 0) { - cb = services[i].cb; - break; - } - } - if (cb == NULL) { - OF_DPRINTF("service [%s] not implemented\n", buffer); - // bug(); - return -1; - } -#if 0 - OF_DPRINTF("Service [%s] found\n", buffer); -#endif - /* Set up stack *NON REENTRANT* */ - OF_env_init(&OF_env); - /* Launch Forth glue */ - C_to_Forth(&OF_env, (uint32_t *)p + 1, &cb); - OF_DPRINTF("done\n"); - MMU_on(); - - return 0; -} - -/*****************************************************************************/ -/* Run-time abstraction services */ -/* RTAS RAM is organised this way: - * RTAS_memory is given by the OS when instanciating RTAS. - * it's an 32 kB area divided in 2 zones: - * Up is a stack, used to call RTAS services - * Down is the variables area. - */ - -__attribute__ (( section (".RTAS_vars") )) -static OF_cb_t *RTAS_callbacks[32]; -#if 0 -__attribute__ (( section (".RTAS_vars") )) -static uint8_t *RTAS_base; -#endif - -/* RTAS is called in real mode (ie no MMU), privileged with all exceptions - * disabled. It has to preserve all registers except R3 to R12. - * The OS should ensure it's not re-entered. - */ -__attribute__ (( section (".RTAS") )) -int RTAS_entry (void *p) -{ - OF_env_t RTAS_env; - uint32_t token; - - OF_DPRINTF("Called with arg: %p\n", p); - /* set our environment */ - token = *(uint32_t *)p; - /* Set up stack */ - RTAS_env.stackb = (uint32_t *)(RTAS_memory + 0x8000 - 4); - RTAS_env.stackp = RTAS_env.stackb; - RTAS_env.funcb = (uint32_t *)(RTAS_memory + 0x8000 - OF_STACK_SIZE - 4); - RTAS_env.funcp = RTAS_env.funcb; - /* Call Forth glue */ - C_to_Forth(&RTAS_env, (uint32_t *)p + 1, RTAS_callbacks[token & 0x3F]); - OF_DPRINTF("done\n"); - - return 0; -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_restart_rtas (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 0); - /* No implementation: return error */ - pushd(RTAS_env, -1); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_nvram_fetch (OF_env_t *RTAS_env) -{ - uint8_t *buffer; - int offset, length; - int i; - - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 3); - offset = popd(RTAS_env); - buffer = (uint8_t *)popd(RTAS_env); - length = popd(RTAS_env); - for (i = 0; i < length; i++) { - if ((i + offset) >= NVRAM_get_size(nvram)) { - pushd(RTAS_env, -3); - return; - } - *buffer++ = NVRAM_read(nvram, i + offset); - } - pushd(RTAS_env, length); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_nvram_store (OF_env_t *RTAS_env) -{ - uint8_t *buffer; - int offset, length; - int i; - - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 3); - offset = popd(RTAS_env); - buffer = (uint8_t *)popd(RTAS_env); - length = popd(RTAS_env); - for (i = 0; i < length; i++) { - if ((i + offset) >= NVRAM_get_size(nvram)) { - pushd(RTAS_env, -3); - return; - } - NVRAM_write(nvram, i + offset, *buffer++); - } - pushd(RTAS_env, length); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_get_time_of_day (OF_env_t *RTAS_env) -{ -#if 0 - struct tm tm; - time_t t; - - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 0); - t = get_time(); - localtime_r(&t, &tm); - pushd(RTAS_env, 0); /* nanoseconds */ - pushd(RTAS_env, tm.tm_sec); - pushd(RTAS_env, tm.tm_min); - pushd(RTAS_env, tm.tm_hour); - pushd(RTAS_env, tm.tm_mday); - pushd(RTAS_env, tm.tm_mon); - pushd(RTAS_env, tm.tm_year); - pushd(RTAS_env, 0); /* status */ -#else - pushd(RTAS_env, 0); - pushd(RTAS_env, 0); - pushd(RTAS_env, 0); - pushd(RTAS_env, 0); - pushd(RTAS_env, 0); - pushd(RTAS_env, 0); - pushd(RTAS_env, 0); - pushd(RTAS_env, 0); -#endif -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_set_time_of_day (OF_env_t *RTAS_env) -{ -#if 0 - struct tm tm; - time_t t; - - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 7); - tm.tm_year = popd(RTAS_env); - tm.tm_mon = popd(RTAS_env); - tm.tm_mday = popd(RTAS_env); - tm.tm_hour = popd(RTAS_env); - tm.tm_min = popd(RTAS_env); - tm.tm_sec = popd(RTAS_env); - popd(RTAS_env); /* nanoseconds */ - t = mktime(&tm); - set_time_offset(t); -#endif - pushd(RTAS_env, 0); /* status */ -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_set_time_for_power_on (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 7); - /* Do nothing */ - pushd(RTAS_env, 0); /* status */ -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_event_scan (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 4); - /* Pretend there are no new events */ - pushd(RTAS_env, 1); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_check_exception (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 6); - /* Pretend we found no exceptions */ - pushd(RTAS_env, 1); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_read_pci_config (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 2); - /* Hardware error */ - pushd(RTAS_env, -1); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_write_pci_config (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 3); - /* Hardware error */ - pushd(RTAS_env, -1); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_display_character (OF_env_t *RTAS_env) -{ - int c; - - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 1); - c = popd(RTAS_env); -#if 0 - printf("%c", c); -#else - outb(0x0F00, c); -#endif - pushd(RTAS_env, 0); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_set_indicator (OF_env_t *RTAS_env) -{ - const unsigned char *name; - int indic, state; - - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 3); - indic = popd(RTAS_env); - state = popd(RTAS_env); - switch (indic) { - case 1: - name = "tone frequency"; - break; - case 2: - name = "tone volume"; - break; - case 3: - name = "system power state"; - break; - case 4: - name = "warning light"; - break; - case 5: - name = "disk activity light"; - break; - case 6: - name = "hexadecimal display unit"; - break; - case 7: - name = "batery warning time"; - break; - case 8: - name = "condition cycle request"; - break; - case 9000 ... 9999: - name = "vendor specific"; - break; - default: - pushd(RTAS_env, -3); - return; - } - OF_DPRINTF("Set indicator %d [%s] to %d\n", indic, name, state); - pushd(RTAS_env, 0); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_get_sensor_state (OF_env_t *RTAS_env) -{ - const unsigned char *name; - int type, index; - int state; - - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 2); - type = popd(RTAS_env); - index = popd(RTAS_env); - switch (index) { - case 1: - name = "key switch"; - state = 1; /* Normal */ - break; - case 2: - name = "enclosure switch"; - state = 0; /* Closed */ - break; - case 3: - name = "thermal sensor"; - state = 40; /* in degrees Celsius (not too hot !) */ - break; - case 4: - name = "lid status"; - state = 1; /* Open */ - break; - case 5: - name = "power source"; - state = 0; /* AC */ - break; - case 6: - name = "battery voltage"; - state = 6; /* Let's have a moderated answer :-) */ - break; - case 7: - name = "battery capacity remaining"; - state = 3; /* High */ - break; - case 8: - name = "battery capacity percentage"; - state = 1000; /* 100 % */ - break; - case 9: - name = "EPOW sensor"; - state = 5; /* ? */ - break; - case 10: - name = "battery condition cycle state"; - state = 0; /* none */ - break; - case 11: - name = "battery charge state"; - state = 2; /* No current flow */ - break; - case 9000 ... 9999: - name = "vendor specific"; - state = 0; - break; - default: - pushd(RTAS_env, -3); - return; - } - OF_DPRINTF("Pretend sensor %d [%s] is in state %d\n", index, name, state); - pushd(RTAS_env, state); - pushd(RTAS_env, 0); -} - -#if 0 // No power management */ -__attribute__ (( section (".RTAS") )) -static void RTAS_set_power_level (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_get_power_level (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_assume_power_management (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_relinquish_power_management (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); -} -#endif - -__attribute__ (( section (".RTAS") )) -static void RTAS_power_off (OF_env_t *RTAS_env) -{ - printf("RTAS was asked to switch off\n"); - OF_CHECK_NBARGS(RTAS_env, 2); - // abort(); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_suspend (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 3); - /* Pretend we don't succeed */ - pushd(RTAS_env, -1); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_hibernate (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 3); - /* Pretend we don't succeed */ - pushd(RTAS_env, -1); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_system_reboot (OF_env_t *RTAS_env) -{ - printf("RTAS was asked to reboot\n"); - OF_CHECK_NBARGS(RTAS_env, 0); - // abort(); -} - -#if 0 // No power management nor SMP */ -__attribute__ (( section (".RTAS") )) -static void RTAS_cache_control (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_freeze_time_base (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_thaw_time_base (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_stop_self (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_start_cpu (OF_env_t *RTAS_env) -{ - OF_DPRINTF("\n"); -} -#endif - -__attribute__ (( section (".RTAS") )) -static void RTAS_instantiate (OF_env_t *RTAS_env) -{ - const unsigned char *args; - uint32_t ihandle; - uint32_t base_address; - - OF_DPRINTF("\n"); - OF_CHECK_NBARGS(RTAS_env, 3); - ihandle = popd(RTAS_env); - args = (void *)popd(RTAS_env); - base_address = popd(RTAS_env); - memmove((void *)base_address, (void *)(&_RTAS_start), - (char *)(&_RTAS_data_end) - (char *)(&_RTAS_start)); - OF_DPRINTF("base_address=0x%0x\n", base_address); - pushd(RTAS_env, base_address); - pushd(RTAS_env, 0); -} - -__attribute__ (( section (".RTAS") )) -static void RTAS_new_cb (OF_env_t *env, OF_node_t *rtas, - const unsigned char *name, - OF_cb_t cb, uint32_t *token_next) -{ - OF_prop_int_new(env, rtas, name, 0xabcd0000 | *token_next); - RTAS_callbacks[*token_next] = &cb; - (*token_next)++; -} - -__attribute__ (( section (".RTAS") )) -void RTAS_init (void) -{ - OF_env_t *RTAS_env; - OF_node_t *rtas, *chs; - OF_prop_t *stdout; - uint32_t token_next = 0, size; - - RTAS_env = OF_env_main; - rtas = OF_node_new(RTAS_env, OF_node_root, "rtas", OF_ADDRESS_NONE); - if (rtas == NULL) { - ERROR("RTAS not found\n"); - return; - } - size = ((char *)(&_RTAS_data_end) - (char *)(&_RTAS_start) + 0x0000FFFF) & - ~0x0000FFFF; - OF_DPRINTF("RTAS size: %d bytes (%d)\n", size, - (char *)(&_RTAS_data_end) - (char *)(&_RTAS_start)); - OF_prop_int_new(RTAS_env, rtas, "rtas-size", size); - OF_prop_int_new(RTAS_env, rtas, "rtas-version", 1); - OF_prop_int_new(RTAS_env, rtas, "rtas-event-scan-rate", 0); - OF_prop_int_new(RTAS_env, rtas, "rtas-error-log-max", 0); - chs = OF_node_get(RTAS_env, "chosen"); - if (chs == NULL) { - ERROR("choosen not found\n"); - return; - } - stdout = OF_property_get(RTAS_env, chs, "stdout"); - if (stdout == NULL) { - OF_node_put(RTAS_env, chs); - ERROR("stdout not found\n"); - return; - } - OF_prop_int_new(RTAS_env, rtas, "rtas-display-device", - *(uint32_t *)stdout->value); - /* RTAS tokens */ - RTAS_new_cb(RTAS_env, rtas, "restart_rtas", - &RTAS_restart_rtas, &token_next); - RTAS_new_cb(RTAS_env, rtas, "nvram_fetch", - &RTAS_nvram_fetch, &token_next); - RTAS_new_cb(RTAS_env, rtas, "nvram_store", - &RTAS_nvram_store, &token_next); - RTAS_new_cb(RTAS_env, rtas, "get-time-of_day", - &RTAS_get_time_of_day, &token_next); - RTAS_new_cb(RTAS_env, rtas, "set-time-of-day", - &RTAS_set_time_of_day, &token_next); - RTAS_new_cb(RTAS_env, rtas, "set-time-for-power-on", - &RTAS_set_time_for_power_on, &token_next); - RTAS_new_cb(RTAS_env, rtas, "event-scan", &RTAS_event_scan, &token_next); - RTAS_new_cb(RTAS_env, rtas, "check-exception", - &RTAS_check_exception, &token_next); - RTAS_new_cb(RTAS_env, rtas, "read-pci-config", - &RTAS_read_pci_config, &token_next); - RTAS_new_cb(RTAS_env, rtas, "write-pci-config", - &RTAS_write_pci_config, &token_next); - RTAS_new_cb(RTAS_env, rtas, "display-character", - &RTAS_display_character, &token_next); - RTAS_new_cb(RTAS_env, rtas, "set-indicator", - &RTAS_set_indicator, &token_next); - RTAS_new_cb(RTAS_env, rtas, "get-sensor-state", - &RTAS_get_sensor_state, &token_next); -#if 0 // No power management */ - RTAS_new_cb(RTAS_env, rtas, "set-power-level", - &RTAS_set_power_level, &token_next); - RTAS_new_cb(RTAS_env, rtas, "get-power-level", - &RTAS_get_power_level, &token_next); - RTAS_new_cb(RTAS_env, rtas, "assume-power-management", - &RTAS_assume_power_management, &token_next); - RTAS_new_cb(RTAS_env, rtas, "relinquish-power-management", - &RTAS_relinquish_power_management, &token_next); -#endif - RTAS_new_cb(RTAS_env, rtas, "power-off", &RTAS_power_off, &token_next); - RTAS_new_cb(RTAS_env, rtas, "suspend", &RTAS_suspend, &token_next); - RTAS_new_cb(RTAS_env, rtas, "hibernate", &RTAS_hibernate, &token_next); - RTAS_new_cb(RTAS_env, rtas, "system-reboot", - &RTAS_system_reboot, &token_next); -#if 0 // No power management nor SMP */ - RTAS_new_cb(RTAS_env, rtas, "cache-control", - &RTAS_cache_control, &token_next); - RTAS_new_cb(RTAS_env, rtas, "freeze_time_base", - &RTAS_freeze_time_base, &token_next); - RTAS_new_cb(RTAS_env, rtas, "thaw_time_base", - &RTAS_thaw_time_base, &token_next); - RTAS_new_cb(RTAS_env, rtas, "stop-self", &RTAS_stop_self, &token_next); - RTAS_new_cb(RTAS_env, rtas, "start-cpu", &RTAS_start_cpu, &token_next); -#endif - /* missing - * "update-flash" - * "update-flash-and-reboot" - * "query-cpu-stopped-state" for SMP - */ - OF_method_new(RTAS_env, rtas, "instantiate-rtas", &RTAS_instantiate); - OF_node_put(RTAS_env, rtas); - OF_node_new(RTAS_env, OF_node_root, "nomore", OF_ADDRESS_NONE); - DPRINTF("RTAS done\n"); -} - -/*****************************************************************************/ -/* That's all for now... */ -/*****************************************************************************/ |