diff options
author | obrien <obrien@FreeBSD.org> | 2000-10-16 10:46:22 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2000-10-16 10:46:22 +0000 |
commit | d84d862cbd66f3f9ab4ce65fe69893664689c73b (patch) | |
tree | e051ab95c375090e547a86f54c45811bb79822a8 /sys/dev/ofw | |
parent | cecaff41fbf7d4fb5808812b72674971cd0a94dd (diff) | |
download | FreeBSD-src-d84d862cbd66f3f9ab4ce65fe69893664689c73b.zip FreeBSD-src-d84d862cbd66f3f9ab4ce65fe69893664689c73b.tar.gz |
"Ok, my loader's now up to putting up a prompt. It probes disks partially
but can't boot from them yet."
Thanks to Stephane Potvin for the some of the code in this set.
Submitted by: Benno Rice <benno@jeamland.net>
Diffstat (limited to 'sys/dev/ofw')
-rw-r--r-- | sys/dev/ofw/openfirm.c | 733 | ||||
-rw-r--r-- | sys/dev/ofw/openfirm.h | 119 |
2 files changed, 852 insertions, 0 deletions
diff --git a/sys/dev/ofw/openfirm.c b/sys/dev/ofw/openfirm.c new file mode 100644 index 0000000..76ec191 --- /dev/null +++ b/sys/dev/ofw/openfirm.c @@ -0,0 +1,733 @@ +/* $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Copyright (C) 2000 Benno Rice. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <machine/stdarg.h> + +#include "openfirm.h" + +static int (*openfirmware)(void *); +static ihandle_t stdin; +static ihandle_t stdout; + +/* Initialiaser */ + +void +OF_init(int (*openfirm)(void *)) +{ + openfirmware = openfirm; +} + +/* + * Generic functions + */ + +/* Test to see if a service exists. */ +int +OF_test(char *name) +{ + static struct { + char *name; + int nargs; + int nreturns; + char *service; + int missing; + } args = { + "test", + 1, + 1, + }; + + args.service = name; + if (openfirmware(&args) == -1) + return -1; + return args.missing; +} + +/* Return firmware millisecond count. */ +int +OF_milliseconds() +{ + static struct { + char *name; + int nargs; + int nreturns; + int ms; + } args = { + "milliseconds", + 0, + 1, + }; + + openfirmware(&args); + return args.ms; +} + +/* + * Device tree functions + */ + +/* Return the next sibling of this node or 0. */ +phandle_t +OF_peer(phandle_t node) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t node; + phandle_t next; + } args = { + "peer", + 1, + 1, + }; + + args.node = node; + if (openfirmware(&args) == -1) + return -1; + return args.next; +} + +/* Return the first child of this node or 0. */ +phandle_t +OF_child(phandle_t node) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t node; + phandle_t child; + } args = { + "child", + 1, + 1, + }; + + args.node = node; + if (openfirmware(&args) == -1) + return -1; + return args.child; +} + +/* Return the parent of this node or 0. */ +phandle_t +OF_parent(phandle_t node) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t node; + phandle_t parent; + } args = { + "parent", + 1, + 1, + }; + + args.node = node; + if (openfirmware(&args) == -1) + return -1; + return args.parent; +} + +/* Return the package handle that corresponds to an instance handle. */ +phandle_t +OF_instance_to_package(ihandle_t instance) +{ + static struct { + char *name; + int nargs; + int nreturns; + ihandle_t instance; + phandle_t package; + } args = { + "instance-to-package", + 1, + 1, + }; + + args.instance = instance; + if (openfirmware(&args) == -1) + return -1; + return args.package; +} + +/* Get the length of a property of a package. */ +int +OF_getproplen(phandle_t package, char *propname) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t package; + char *propname; + int proplen; + } args = { + "getproplen", + 2, + 1, + }; + + args.package = package; + args.propname = propname; + if (openfirmware(&args) == -1) + return -1; + return args.proplen; +} + +/* Get the value of a property of a package. */ +int +OF_getprop(phandle_t package, char *propname, void *buf, int buflen) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t package; + char *propname; + void *buf; + int buflen; + int size; + } args = { + "getprop", + 4, + 1, + }; + + args.package = package; + args.propname = propname; + args.buf = buf; + args.buflen = buflen; + if (openfirmware(&args) == -1) + return -1; + return args.size; +} + +/* Get the next property of a package. */ +int +OF_nextprop(phandle_t package, char *previous, char *buf) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t package; + char *previous; + char *buf; + int flag; + } args = { + "nextprop", + 3, + 1, + }; + + args.package = package; + args.previous = previous; + args.buf = buf; + if (openfirmware(&args) == -1) + return -1; + return args.flag; +} + +/* Set the value of a property of a package. */ +/* XXX Has a bug on FirePower */ +int +OF_setprop(phandle_t package, char *propname, void *buf, int len) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t package; + char *propname; + void *buf; + int len; + int size; + } args = { + "setprop", + 4, + 1, + }; + + args.package = package; + args.propname = propname; + args.buf = buf; + args.len = len; + if (openfirmware(&args) == -1) + return -1; + return args.size; +} + +/* Convert a device specifier to a fully qualified pathname. */ +int +OF_canon(char *device, char *buf, int len) +{ + static struct { + char *name; + int nargs; + int nreturns; + char *device; + char *buf; + int len; + int size; + } args = { + "canon", + 3, + 1, + }; + + args.device = device; + args.buf = buf; + args.len = len; + if (openfirmware(&args) == -1) + return -1; + return args.size; +} + +/* Return a package handle for the specified device. */ +phandle_t +OF_finddevice(char *device) +{ + static struct { + char *name; + int nargs; + int nreturns; + char *device; + phandle_t package; + } args = { + "finddevice", + 1, + 1, + }; + + args.device = device; + if (openfirmware(&args) == -1) + return -1; + return args.package; +} + +/* Return the fully qualified pathname corresponding to an instance. */ +int +OF_instance_to_path(ihandle_t instance, char *buf, int len) +{ + static struct { + char *name; + int nargs; + int nreturns; + ihandle_t instance; + char *buf; + int len; + int size; + } args = { + "instance-to-path", + 3, + 1, + }; + + args.instance = instance; + args.buf = buf; + args.len = len; + if (openfirmware(&args) == -1) + return -1; + return(args.size); +} + +/* Return the fully qualified pathname corresponding to a package. */ +int +OF_package_to_path(phandle_t package, char *buf, int len) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t package; + char *buf; + int len; + int size; + } args = { + "package-to-path", + 3, + 1, + }; + + args.package = package; + args.buf = buf; + args.len = len; + if (openfirmware(&args) == -1) + return -1; + return(args.size); +} + +/* Call the method in the scope of a given instance. */ +int +OF_call_method(char *method, ihandle_t instance, int nargs, int nreturns, ...) +{ + va_list ap; + static struct { + char *name; + int nargs; + int nreturns; + char *method; + ihandle_t instance; + int args_n_results[12]; + } args = { + "call-method", + 2, + 1, + }; + int *ip, n; + + if (nargs > 6) + return -1; + args.nargs = nargs + 2; + args.nreturns = nreturns + 1; + args.method = method; + args.instance = instance; + va_start(ap, nreturns); + for (ip = args.args_n_results + (n = nargs); --n >= 0;) + *--ip = va_arg(ap, int); + + if (openfirmware(&args) == -1) + return -1; + if (args.args_n_results[nargs]) + return args.args_n_results[nargs]; + for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;) + *va_arg(ap, int *) = *--ip; + va_end(ap); + return 0; +} + +/* + * Device I/O functions. + */ + +/* Open an instance for a device. */ +ihandle_t +OF_open(char *device) +{ + static struct { + char *name; + int nargs; + int nreturns; + char *device; + ihandle_t instance; + } args = { + "open", + 1, + 1, + }; + + args.device = device; + if (openfirmware(&args) == -1 || args.instance == 0) { + return -1; + } + return args.instance; +} + +/* Close an instance. */ +void +OF_close(ihandle_t instance) +{ + static struct { + char *name; + int nargs; + int nreturns; + ihandle_t instance; + } args = { + "close", + 1, + 0, + }; + + args.instance = instance; + openfirmware(&args); +} + +/* Read from an instance. */ +int +OF_read(ihandle_t instance, void *addr, int len) +{ + static struct { + char *name; + int nargs; + int nreturns; + ihandle_t instance; + void *addr; + int len; + int actual; + } args = { + "read", + 3, + 1, + }; + + args.instance = instance; + args.addr = addr; + args.len = len; + if (openfirmware(&args) == -1) + return -1; + return args.actual; +} + +/* Write to an instance. */ +int +OF_write(ihandle_t instance, void *addr, int len) +{ + static struct { + char *name; + int nargs; + int nreturns; + ihandle_t instance; + void *addr; + int len; + int actual; + } args = { + "write", + 3, + 1, + }; + + args.instance = instance; + args.addr = addr; + args.len = len; + if (openfirmware(&args) == -1) + return -1; + return args.actual; +} + +/* Seek to a position. */ +int +OF_seek(ihandle_t instance, u_quad_t pos) +{ + static struct { + char *name; + int nargs; + int nreturns; + ihandle_t instance; + int poshi; + int poslo; + int status; + } args = { + "seek", + 3, + 1, + }; + + args.instance = instance; + args.poshi = (int)(pos >> 32); + args.poslo = (int)pos; + if (openfirmware(&args) == -1) + return -1; + return args.status; +} + +/* + * Memory functions. + */ + +/* Claim an area of memory. */ +void * +OF_claim(void *virt, u_int size, u_int align) +{ + static struct { + char *name; + int nargs; + int nreturns; + void *virt; + u_int size; + u_int align; + void *baseaddr; + } args = { + "claim", + 3, + 1, + }; + + args.virt = virt; + args.size = size; + args.align = align; + if (openfirmware(&args) == -1) + return (void *)-1; + return args.baseaddr; +} + +/* Release an area of memory. */ +void +OF_release(void *virt, u_int size) +{ + static struct { + char *name; + int nargs; + int nreturns; + void *virt; + u_int size; + } args = { + "release", + 2, + 0, + }; + + args.virt = virt; + args.size = size; + openfirmware(&args); +} + +/* + * Control transfer functions. + */ + +/* Reset the system and call "boot <bootspec>". */ +void +OF_boot(char *bootspec) +{ + static struct { + char *name; + int nargs; + int nreturns; + char *bootspec; + } args = { + "boot", + 1, + 0, + }; + + args.bootspec = bootspec; + openfirmware(&args); + for (;;); /* just in case */ +} + +/* Suspend and drop back to the OpenFirmware interface. */ +void +OF_enter() +{ + static struct { + char *name; + int nargs; + int nreturns; + } args = { + "enter", + 0, + 0 + }; + + openfirmware(&args); + return; /* We may come back. */ +} + +/* Shut down and drop back to the OpenFirmware interface. */ +__dead void +OF_exit() +{ + static struct { + char *name; + int nargs; + int nreturns; + } args = { + "exit", + 0, + 0 + }; + + openfirmware(&args); + for (;;); /* just in case */ +} + +/* Free <size> bytes starting at <virt>, then call <entry> with <arg>. */ +#ifdef __notyet__ +void +OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) +{ + static struct { + char *name; + int nargs; + int nreturns; + void *virt; + u_int size; + void (*entry)(); + void *arg; + u_int len; + } args = { + "chain", + 5, + 0, + }; + + args.virt = virt; + args.size = size; + args.entry = entry; + args.arg = arg; + args.len = len; + openfirmware(&args); +} +#else +void +OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) +{ + /* + * This is a REALLY dirty hack till the firmware gets this going + */ +#if 0 + OF_release(virt, size); +#endif + entry(0, 0, openfirmware, arg, len); +} +#endif diff --git a/sys/dev/ofw/openfirm.h b/sys/dev/ofw/openfirm.h new file mode 100644 index 0000000..815e0ef --- /dev/null +++ b/sys/dev/ofw/openfirm.h @@ -0,0 +1,119 @@ +/* $NetBSD: openfirm.h,v 1.1 1998/05/15 10:16:00 tsubai Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Copyright (C) 2000 Benno Rice. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * Prototypes for Openfirmware Interface Routines + */ + +#include <sys/cdefs.h> +#include <sys/types.h> + +typedef int ihandle_t; +typedef int phandle_t; + +/* + * This isn't actually an OpenFirmware function, but it seemed like the right + * place for it to go. + */ +void OF_init(int (*openfirm)(void *)); + +/* Generic functions */ +int OF_test(char *); + +/* Device tree functions */ +phandle_t OF_peer(phandle_t); +phandle_t OF_child(phandle_t); +phandle_t OF_parent(phandle_t); +phandle_t OF_instance_to_package(ihandle_t); +int OF_getproplen(phandle_t, char *); +int OF_getprop(phandle_t, char *, void *, int); +int OF_nextprop(phandle_t, char *, char *); +int OF_setprop(phandle_t, char *, void *, int); +int OF_canon(char *, char *, int); +phandle_t OF_finddevice(char *); +int OF_instance_to_path(ihandle_t, char *, int); +int OF_package_to_path(phandle_t, char *, int); +int OF_call_method(char *, ihandle_t, int, int, ...); + +/* Device I/O functions */ +ihandle_t OF_open(char *); +void OF_close(ihandle_t); +int OF_read(ihandle_t, void *, int); +int OF_write(ihandle_t, void *, int); +int OF_seek(ihandle_t, u_quad_t); + +/* Memory functions */ +void *OF_claim(void *, u_int, u_int); +void OF_release(void *, u_int); + +/* Control transfer functions */ +void OF_boot(char *); +void OF_enter(void); +__dead void OF_exit(void) __attribute__((noreturn)); +void OF_chain(void *, u_int, void (*)(), void *, u_int); + +#if 0 +/* User interface functions */ +/* OF_interpret */ +void *OF_set_callback(void *); +void OF_set_symbol_lookup(void *, void *); +#endif + +/* Time function */ +int OF_milliseconds(void); |