summaryrefslogtreecommitdiffstats
path: root/qemu/roms/openhackware/src/of.c
diff options
context:
space:
mode:
authorRajithaY <rajithax.yerrumsetty@intel.com>2017-04-25 03:31:15 -0700
committerRajitha Yerrumchetty <rajithax.yerrumsetty@intel.com>2017-05-22 06:48:08 +0000
commitbb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch)
treeca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/openhackware/src/of.c
parenta14b48d18a9ed03ec191cf16b162206998a895ce (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.c5450
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", &regs, 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", &regs, 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", &regs, 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", &regs, 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",
- &regs, 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",
- &regs, 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", &regs, 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... */
-/*****************************************************************************/