diff options
28 files changed, 1526 insertions, 677 deletions
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index 7570d93..901e36d 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -30,9 +30,11 @@ dev/kbd/kbd.c optional sc dev/ofw/openfirm.c optional aim dev/ofw/openfirmio.c optional aim dev/ofw/ofw_bus_if.m optional aim +dev/ofw/ofw_if.m optional aim dev/ofw/ofw_bus_subr.c optional aim dev/ofw/ofw_console.c optional aim dev/ofw/ofw_disk.c optional ofwd aim +dev/ofw/ofw_standard.c optional aim dev/powermac_nvram/powermac_nvram.c optional powermac_nvram powermac dev/quicc/quicc_bfe_ocp.c optional quicc mpc85xx dev/scc/scc_bfe_macio.c optional scc powermac diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64 index 25ef599..311027c 100644 --- a/sys/conf/files.sparc64 +++ b/sys/conf/files.sparc64 @@ -42,8 +42,10 @@ dev/kbd/kbd.c optional atkbd | sc | ukbd dev/le/if_le_lebuffer.c optional le sbus dev/le/if_le_ledma.c optional le sbus dev/le/lebuffer_sbus.c optional le sbus +dev/ofw/ofw_if.m standard dev/ofw/ofw_bus_if.m standard dev/ofw/ofw_bus_subr.c standard +dev/ofw/ofw_standard.c standard dev/ofw/ofw_console.c optional ofw_console dev/ofw/openfirm.c standard dev/ofw/openfirmio.c standard diff --git a/sys/conf/files.sun4v b/sys/conf/files.sun4v index 150e931..384c13a 100644 --- a/sys/conf/files.sun4v +++ b/sys/conf/files.sun4v @@ -21,8 +21,10 @@ ukbdmap.h optional ukbd_dflt_keymap \ crypto/blowfish/bf_enc.c optional crypto | ipsec crypto/des/des_enc.c optional crypto | ipsec | netsmb dev/ofw/ofw_bus_if.m standard +dev/ofw/ofw_if.m standard dev/ofw/ofw_bus_subr.c standard dev/ofw/ofw_console.c optional ofw_console +dev/ofw/ofw_standard.c standard dev/ofw/openfirm.c standard dev/ofw/openfirmio.c standard dev/ofw/openpromio.c standard diff --git a/sys/dev/ofw/ofw_if.m b/sys/dev/ofw/ofw_if.m new file mode 100644 index 0000000..431ac91 --- /dev/null +++ b/sys/dev/ofw/ofw_if.m @@ -0,0 +1,357 @@ +#- +# Copyright (c) 2008 Nathan Whitehorn +# 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 THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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 <dev/ofw/openfirm.h> +#include <dev/ofw/ofwvar.h> + +/** + * @defgroup OFW ofw - KObj methods for Open Firmware RTAS implementations + * @brief A set of methods to implement the Open Firmware client side interface. + *@{ + */ + +INTERFACE ofw; + +/** + * @brief Initialize OFW client interface + * + * @param _cookie A handle to the client interface, generally the OF + * callback routine. + */ +METHOD void init { + ofw_t _ofw; + void *_cookie; +}; + +/** + * @brief Return next sibling of node + * + * @param _node Selected node + */ +METHOD phandle_t peer { + ofw_t _ofw; + phandle_t _node; +}; + +/** + * @brief Return parent of node + * + * @param _node Selected node + */ +METHOD phandle_t parent { + ofw_t _ofw; + phandle_t _node; +}; + +/** + * @brief Return first child of node + * + * @param _node Selected node + */ +METHOD phandle_t child { + ofw_t _ofw; + phandle_t _node; +}; + +/** + * @brief Return package corresponding to instance + * + * @param _handle Selected instance + */ +METHOD phandle_t instance_to_package { + ofw_t _ofw; + ihandle_t _handle; +}; + +/** + * @brief Return length of node property + * + * @param _node Selected node + * @param _prop Property name + */ +METHOD ssize_t getproplen { + ofw_t _ofw; + phandle_t _node; + const char *_prop; +}; + +/** + * @brief Read node property + * + * @param _node Selected node + * @param _prop Property name + * @param _buf Pointer to buffer + * @param _size Size of buffer + */ +METHOD ssize_t getprop { + ofw_t _ofw; + phandle_t _node; + const char *_prop; + void *_buf; + size_t _size; +}; + +/** + * @brief Get next property name + * + * @param _node Selected node + * @param _prop Current property name + * @param _buf Buffer for next property name + * @param _size Size of buffer + */ +METHOD int nextprop { + ofw_t _ofw; + phandle_t _node; + const char *_prop; + char *_buf; + size_t _size; +}; + +/** + * @brief Set property + * + * @param _node Selected node + * @param _prop Property name + * @param _buf Value to set + * @param _size Size of buffer + */ +METHOD int setprop { + ofw_t _ofw; + phandle_t _node; + const char *_prop; + const void *_buf; + size_t _size; +}; + +/** + * @brief Canonicalize path + * + * @param _path Path to canonicalize + * @param _buf Buffer for canonicalized path + * @param _size Size of buffer + */ +METHOD ssize_t canon { + ofw_t _ofw; + const char *_path; + char *_buf; + size_t _size; +}; + +/** + * @brief Return phandle for named device + * + * @param _path Device path + */ +METHOD phandle_t finddevice { + ofw_t _ofw; + const char *_path; +}; + +/** + * @brief Return path for node instance + * + * @param _handle Instance handle + * @param _path Buffer for path + * @param _size Size of buffer + */ +METHOD ssize_t instance_to_path { + ofw_t _ofw; + ihandle_t _handle; + char *_path; + size_t _size; +}; + +/** + * @brief Return path for node + * + * @param _node Package node + * @param _path Buffer for path + * @param _size Size of buffer + */ +METHOD ssize_t package_to_path { + ofw_t _ofw; + phandle_t _node; + char *_path; + size_t _size; +}; + + +# Methods for OF method calls (optional) + +/** + * @brief Test to see if a service exists. + * + * @param _name name of the service + */ +METHOD int test { + ofw_t _ofw; + const char *_name; +}; + +/** + * @brief Call method belonging to an instance handle + * + * @param _instance Instance handle + * @param _method Method name + * @param _nargs Number of arguments + * @param _nreturns Number of return values + * @param _args_and_returns Values for arguments, followed by returns + */ + +METHOD int call_method { + ofw_t _ofw; + ihandle_t _instance; + const char *_method; + int _nargs; + int _nreturns; + + unsigned long *_args_and_returns; +}; + +/** + * @brief Interpret a forth command + * + * @param _cmd Command + * @param _nreturns Number of return values + * @param _returns Values for returns + */ + +METHOD int interpret { + ofw_t _ofw; + const char *_cmd; + int _nreturns; + unsigned long *_returns; +}; + +# Device I/O Functions (optional) + +/** + * @brief Open node, returning instance handle + * + * @param _path Path to node + */ +METHOD ihandle_t open { + ofw_t _ofw; + const char *_path; +} + +/** + * @brief Close node instance + * + * @param _instance Instance to close + */ +METHOD void close { + ofw_t _ofw; + ihandle_t _instance; +} + +/** + * @brief Read from device + * + * @param _instance Device instance + * @param _buf Buffer to read to + * @param _size Size of buffer + */ +METHOD ssize_t read { + ofw_t _ofw; + ihandle_t _instance; + void *_buf; + size_t size; +} + +/** + * @brief Write to device + * + * @param _instance Device instance + * @param _buf Buffer to write from + * @param _size Size of buffer + */ +METHOD ssize_t write { + ofw_t _ofw; + ihandle_t _instance; + const void *_buf; + size_t size; +} + +/** + * @brief Seek device + * + * @param _instance Device instance + * @param _off Offset to which to seek + */ +METHOD int seek { + ofw_t _ofw; + ihandle_t _instance; + uint64_t _off; +} + +# Open Firmware memory management + +/** + * @brief Claim virtual memory + * + * @param _addr Requested memory location (NULL for first available) + * @param _size Requested size in bytes + * @param _align Requested alignment + */ +METHOD caddr_t claim { + ofw_t _ofw; + void *_addr; + size_t _size; + u_int _align; +} + +/** + * @brief Release virtual memory + * + * @param _addr Memory location + * @param _size Size in bytes + */ +METHOD void release { + ofw_t _ofw; + void *_addr; + size_t _size; +}; + +# Commands for returning control to the firmware + +/** + * @brief Temporarily return control to firmware + */ +METHOD void enter { + ofw_t _ofw; +}; + +/** + * @brief Halt and return control to firmware + */ +METHOD void exit { + ofw_t _ofw; +}; + + diff --git a/sys/dev/ofw/ofw_standard.c b/sys/dev/ofw/ofw_standard.c new file mode 100644 index 0000000..e097145 --- /dev/null +++ b/sys/dev/ofw/ofw_standard.c @@ -0,0 +1,763 @@ +/* $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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/systm.h> + +#include <machine/stdarg.h> + +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofwvar.h> +#include "ofw_if.h" + +static void ofw_std_init(ofw_t ofw, void *openfirm); +static int ofw_std_test(ofw_t ofw, const char *name); +static int ofw_std_interpret(ofw_t ofw, const char *cmd, int nreturns, + unsigned long *returns); +static phandle_t ofw_std_peer(ofw_t ofw, phandle_t node); +static phandle_t ofw_std_child(ofw_t ofw, phandle_t node); +static phandle_t ofw_std_parent(ofw_t ofw, phandle_t node); +static phandle_t ofw_std_instance_to_package(ofw_t ofw, ihandle_t instance); +static ssize_t ofw_std_getproplen(ofw_t ofw, phandle_t package, + const char *propname); +static ssize_t ofw_std_getprop(ofw_t ofw, phandle_t package, + const char *propname, void *buf, size_t buflen); +static int ofw_std_nextprop(ofw_t ofw, phandle_t package, const char *previous, + char *buf, size_t); +static int ofw_std_setprop(ofw_t ofw, phandle_t package, char *propname, + void *buf, size_t len); +static ssize_t ofw_std_canon(ofw_t ofw, const char *device, char *buf, + size_t len); +static phandle_t ofw_std_finddevice(ofw_t ofw, const char *device); +static ssize_t ofw_std_instance_to_path(ofw_t ofw, ihandle_t instance, + char *buf, size_t len); +static ssize_t ofw_std_package_to_path(ofw_t ofw, phandle_t package, char *buf, + size_t len); +static int ofw_std_call_method(ofw_t ofw, ihandle_t instance, + const char *method, int nargs, int nreturns, + unsigned long *args_and_returns); +static ihandle_t ofw_std_open(ofw_t ofw, const char *device); +static void ofw_std_close(ofw_t ofw, ihandle_t instance); +static ssize_t ofw_std_read(ofw_t ofw, ihandle_t instance, void *addr, + size_t len); +static ssize_t ofw_std_write(ofw_t ofw, ihandle_t instance, const void *addr, + size_t len); +static int ofw_std_seek(ofw_t ofw, ihandle_t instance, u_int64_t pos); +static caddr_t ofw_std_claim(ofw_t ofw, void *virt, size_t size, u_int align); +static void ofw_std_release(ofw_t ofw, void *virt, size_t size); +static void ofw_std_enter(ofw_t ofw); +static void ofw_std_exit(ofw_t ofw); + +static ofw_method_t ofw_std_methods[] = { + OFWMETHOD(ofw_init, ofw_std_init), + OFWMETHOD(ofw_peer, ofw_std_peer), + OFWMETHOD(ofw_child, ofw_std_child), + OFWMETHOD(ofw_parent, ofw_std_parent), + OFWMETHOD(ofw_instance_to_package, ofw_std_instance_to_package), + OFWMETHOD(ofw_getproplen, ofw_std_getproplen), + OFWMETHOD(ofw_getprop, ofw_std_getprop), + OFWMETHOD(ofw_nextprop, ofw_std_nextprop), + OFWMETHOD(ofw_setprop, ofw_std_setprop), + OFWMETHOD(ofw_canon, ofw_std_canon), + OFWMETHOD(ofw_finddevice, ofw_std_finddevice), + OFWMETHOD(ofw_instance_to_path, ofw_std_instance_to_path), + OFWMETHOD(ofw_package_to_path, ofw_std_package_to_path), + + OFWMETHOD(ofw_test, ofw_std_test), + OFWMETHOD(ofw_call_method, ofw_std_call_method), + OFWMETHOD(ofw_interpret, ofw_std_interpret), + OFWMETHOD(ofw_open, ofw_std_open), + OFWMETHOD(ofw_close, ofw_std_close), + OFWMETHOD(ofw_read, ofw_std_read), + OFWMETHOD(ofw_write, ofw_std_write), + OFWMETHOD(ofw_seek, ofw_std_seek), + OFWMETHOD(ofw_claim, ofw_std_claim), + OFWMETHOD(ofw_release, ofw_std_release), + OFWMETHOD(ofw_enter, ofw_std_enter), + OFWMETHOD(ofw_exit, ofw_std_exit), + + { 0, 0 } +}; + +static ofw_def_t ofw_std = { + OFW_STD_DIRECT, + ofw_std_methods, + 0 +}; +OFW_DEF(ofw_std); + +static int (*openfirmware)(void *); + +/* Initialiser */ + +static void +ofw_std_init(ofw_t ofw, void *openfirm) +{ + openfirmware = (int (*)(void *))openfirm; +} + +/* + * Generic functions + */ + +/* Test to see if a service exists. */ +static int +ofw_std_test(ofw_t ofw, const char *name) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t service; + cell_t missing; + } args = { + (cell_t)"test", + 1, + 1, + }; + + args.service = (cell_t)name; + if (openfirmware(&args) == -1) + return (-1); + return (args.missing); +} + +static int +ofw_std_interpret(ofw_t ofw, const char *cmd, int nreturns, + unsigned long *returns) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t slot[16]; + } args = { + (cell_t)"interpret", + 1, + }; + cell_t status; + int i = 0, j = 0; + + args.nreturns = ++nreturns; + args.slot[i++] = (cell_t)cmd; + if (openfirmware(&args) == -1) { + return (-1); + } + status = args.slot[i++]; + while (i < 1 + nreturns) + returns[j] = args.slot[i++]; + return (status); +} + +/* + * Device tree functions + */ + +/* Return the next sibling of this node or 0. */ +static phandle_t +ofw_std_peer(ofw_t ofw, phandle_t node) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t node; + cell_t next; + } args = { + (cell_t)"peer", + 1, + 1, + }; + + args.node = node; + if (openfirmware(&args) == -1) + return (-1); + return (args.next); +} + +/* Return the first child of this node or 0. */ +static phandle_t +ofw_std_child(ofw_t ofw, phandle_t node) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t node; + cell_t child; + } args = { + (cell_t)"child", + 1, + 1, + }; + + args.node = node; + if (openfirmware(&args) == -1) + return (-1); + return (args.child); +} + +/* Return the parent of this node or 0. */ +static phandle_t +ofw_std_parent(ofw_t ofw, phandle_t node) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t node; + cell_t parent; + } args = { + (cell_t)"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. */ +static phandle_t +ofw_std_instance_to_package(ofw_t ofw, ihandle_t instance) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t instance; + cell_t package; + } args = { + (cell_t)"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. */ +static ssize_t +ofw_std_getproplen(ofw_t ofw, phandle_t package, const char *propname) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t package; + cell_t propname; + cell_t proplen; + } args = { + (cell_t)"getproplen", + 2, + 1, + }; + + args.package = package; + args.propname = (cell_t)propname; + if (openfirmware(&args) == -1) + return (-1); + return (args.proplen); +} + +/* Get the value of a property of a package. */ +static ssize_t +ofw_std_getprop(ofw_t ofw, phandle_t package, const char *propname, void *buf, + size_t buflen) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t package; + cell_t propname; + cell_t buf; + cell_t buflen; + cell_t size; + } args = { + (cell_t)"getprop", + 4, + 1, + }; + + args.package = package; + args.propname = (cell_t)propname; + args.buf = (cell_t)buf; + args.buflen = buflen; + if (openfirmware(&args) == -1) + return (-1); + return (args.size); +} + +/* Get the next property of a package. */ +static int +ofw_std_nextprop(ofw_t ofw, phandle_t package, const char *previous, char *buf, + size_t size) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t package; + cell_t previous; + cell_t buf; + cell_t flag; + } args = { + (cell_t)"nextprop", + 3, + 1, + }; + + args.package = package; + args.previous = (cell_t)previous; + args.buf = (cell_t)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 */ +static int +ofw_std_setprop(ofw_t ofw, phandle_t package, char *propname, void *buf, + size_t len) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t package; + cell_t propname; + cell_t buf; + cell_t len; + cell_t size; + } args = { + (cell_t)"setprop", + 4, + 1, + }; + + args.package = package; + args.propname = (cell_t)propname; + args.buf = (cell_t)buf; + args.len = len; + if (openfirmware(&args) == -1) + return (-1); + return (args.size); +} + +/* Convert a device specifier to a fully qualified pathname. */ +static ssize_t +ofw_std_canon(ofw_t ofw, const char *device, char *buf, size_t len) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t device; + cell_t buf; + cell_t len; + cell_t size; + } args = { + (cell_t)"canon", + 3, + 1, + }; + + args.device = (cell_t)device; + args.buf = (cell_t)buf; + args.len = len; + if (openfirmware(&args) == -1) + return (-1); + return (args.size); +} + +/* Return a package handle for the specified device. */ +static phandle_t +ofw_std_finddevice(ofw_t ofw, const char *device) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t device; + cell_t package; + } args = { + (cell_t)"finddevice", + 1, + 1, + }; + + args.device = (cell_t)device; + if (openfirmware(&args) == -1) + return (-1); + return (args.package); +} + +/* Return the fully qualified pathname corresponding to an instance. */ +static ssize_t +ofw_std_instance_to_path(ofw_t ofw, ihandle_t instance, char *buf, size_t len) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t instance; + cell_t buf; + cell_t len; + cell_t size; + } args = { + (cell_t)"instance-to-path", + 3, + 1, + }; + + args.instance = instance; + args.buf = (cell_t)buf; + args.len = len; + if (openfirmware(&args) == -1) + return (-1); + return (args.size); +} + +/* Return the fully qualified pathname corresponding to a package. */ +static ssize_t +ofw_std_package_to_path(ofw_t ofw, phandle_t package, char *buf, size_t len) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t package; + cell_t buf; + cell_t len; + cell_t size; + } args = { + (cell_t)"package-to-path", + 3, + 1, + }; + + args.package = package; + args.buf = (cell_t)buf; + args.len = len; + if (openfirmware(&args) == -1) + return (-1); + return (args.size); +} + +/* Call the method in the scope of a given instance. */ +static int +ofw_std_call_method(ofw_t ofw, ihandle_t instance, const char *method, + int nargs, int nreturns, unsigned long *args_and_returns) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t method; + cell_t instance; + cell_t args_n_results[12]; + } args = { + (cell_t)"call-method", + 2, + 1, + }; + cell_t *cp; + unsigned long *ap; + int n; + + if (nargs > 6) + return (-1); + args.nargs = nargs + 2; + args.nreturns = nreturns + 1; + args.method = (cell_t)method; + args.instance = instance; + + ap = args_and_returns; + for (cp = args.args_n_results + (n = nargs); --n >= 0;) + *--cp = *(ap++); + if (openfirmware(&args) == -1) + return (-1); + if (args.args_n_results[nargs]) + return (args.args_n_results[nargs]); + for (cp = args.args_n_results + nargs + (n = args.nreturns); --n > 0;) + *(ap++) = *--cp; + return (0); +} + +/* + * Device I/O functions + */ + +/* Open an instance for a device. */ +static ihandle_t +ofw_std_open(ofw_t ofw, const char *device) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t device; + cell_t instance; + } args = { + (cell_t)"open", + 1, + 1, + }; + + args.device = (cell_t)device; + if (openfirmware(&args) == -1 || args.instance == 0) { + return (-1); + } + return (args.instance); +} + +/* Close an instance. */ +static void +ofw_std_close(ofw_t ofw, ihandle_t instance) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t instance; + } args = { + (cell_t)"close", + 1, + }; + + args.instance = instance; + openfirmware(&args); +} + +/* Read from an instance. */ +static ssize_t +ofw_std_read(ofw_t ofw, ihandle_t instance, void *addr, size_t len) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t instance; + cell_t addr; + cell_t len; + cell_t actual; + } args = { + (cell_t)"read", + 3, + 1, + }; + + args.instance = instance; + args.addr = (cell_t)addr; + args.len = len; + if (openfirmware(&args) == -1) + return (-1); + + return (args.actual); +} + +/* Write to an instance. */ +static ssize_t +ofw_std_write(ofw_t ofw, ihandle_t instance, const void *addr, size_t len) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t instance; + cell_t addr; + cell_t len; + cell_t actual; + } args = { + (cell_t)"write", + 3, + 1, + }; + + args.instance = instance; + args.addr = (cell_t)addr; + args.len = len; + if (openfirmware(&args) == -1) + return (-1); + return (args.actual); +} + +/* Seek to a position. */ +static int +ofw_std_seek(ofw_t ofw, ihandle_t instance, u_int64_t pos) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t instance; + cell_t poshi; + cell_t poslo; + cell_t status; + } args = { + (cell_t)"seek", + 3, + 1, + }; + + args.instance = instance; + args.poshi = pos >> 32; + args.poslo = pos; + if (openfirmware(&args) == -1) + return (-1); + return (args.status); +} + +/* + * Memory functions + */ + +/* Claim an area of memory. */ +static caddr_t +ofw_std_claim(ofw_t ofw, void *virt, size_t size, u_int align) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t virt; + cell_t size; + cell_t align; + cell_t baseaddr; + } args = { + (cell_t)"claim", + 3, + 1, + }; + + args.virt = (cell_t)virt; + args.size = size; + args.align = align; + if (openfirmware(&args) == -1) + return ((void *)-1); + return ((void *)args.baseaddr); +} + +/* Release an area of memory. */ +static void +ofw_std_release(ofw_t ofw, void *virt, size_t size) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t virt; + cell_t size; + } args = { + (cell_t)"release", + 2, + }; + + args.virt = (cell_t)virt; + args.size = size; + openfirmware(&args); +} + +/* + * Control transfer functions + */ + +/* Suspend and drop back to the Open Firmware interface. */ +static void +ofw_std_enter(ofw_t ofw) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + } args = { + (cell_t)"enter", + }; + + openfirmware(&args); + /* We may come back. */ +} + +/* Shut down and drop back to the Open Firmware interface. */ +static void +ofw_std_exit(ofw_t ofw) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + } args = { + (cell_t)"exit", + }; + + openfirmware(&args); + for (;;) /* just in case */ + ; +} + diff --git a/sys/dev/ofw/ofwvar.h b/sys/dev/ofw/ofwvar.h new file mode 100644 index 0000000..950dded --- /dev/null +++ b/sys/dev/ofw/ofwvar.h @@ -0,0 +1,89 @@ +/*- + * Copyright (c) 2005 Peter Grehan + * Copyright (c) 2008 Nathan Whitehorn + * 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 THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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$ + */ + +#ifndef _OFW_OFWVAR_H_ +#define _OFW_OFWVAR_H_ + +/* + * An Open Firmware client implementation is declared with a kernel object and + * an associated method table, similar to a device driver. + * + * e.g. + * + * static ofw_method_t fdt_methods[] = { + * OFWMETHOD(ofw_init, fdt_init), + * OFWMETHOD(ofw_finddevice, fdt_finddevice), + * ... + * OFWMETHOD(ofw_nextprop, fdt_nextprop), + * { 0, 0 } + * }; + * + * static ofw_def_t ofw_fdt = { + * "ofw_fdt", + * fdt_methods, + * sizeof(fdt_softc), // or 0 if no softc + * }; + * + * OFW_DEF(ofw_fdt); + */ + +#include <sys/kobj.h> + +struct ofw_kobj { + /* + * An OFW instance is a kernel object. + */ + KOBJ_FIELDS; + + /* + * Utility elements that an instance may use + */ + struct mtx ofw_mtx; /* available for instance use */ + void *ofw_iptr; /* instance data pointer */ + + /* + * Opaque data that can be overlaid with an instance-private + * structure. OFW code can test that this is large enough at + * compile time with a sizeof() test againt it's softc. There + * is also a run-time test when the MMU kernel object is + * registered. + */ +#define OFW_OPAQUESZ 64 + u_int ofw_opaque[OFW_OPAQUESZ]; +}; + +typedef struct ofw_kobj *ofw_t; +typedef struct kobj_class ofw_def_t; + +#define ofw_method_t kobj_method_t +#define OFWMETHOD KOBJMETHOD + +#define OFW_DEF(name) DATA_SET(ofw_set, name) + +#endif /* _OFW_OFWVAR_H_ */ diff --git a/sys/dev/ofw/openfirm.c b/sys/dev/ofw/openfirm.c index ff889e5..c7b2203 100644 --- a/sys/dev/ofw/openfirm.c +++ b/sys/dev/ofw/openfirm.c @@ -66,23 +66,70 @@ __FBSDID("$FreeBSD$"); #include <machine/stdarg.h> #include <dev/ofw/openfirm.h> +#include <dev/ofw/ofwvar.h> + +#include "ofw_if.h" MALLOC_DEFINE(M_OFWPROP, "openfirm", "Open Firmware properties"); static ihandle_t stdout; +static ofw_def_t *ofw_def_impl; +static ofw_t ofw_obj; +static struct ofw_kobj ofw_kernel_obj; +static struct kobj_ops ofw_kernel_kops; + +/* + * OFW install routines. Highest priority wins, equal priority also + * overrides allowing last-set to win. + */ +SET_DECLARE(ofw_set, ofw_def_t); + +boolean_t +OF_install(char *name, int prio) +{ + ofw_def_t **ofwpp, *ofwp; + static int curr_prio = 0; + + /* + * Try and locate the OFW kobj corresponding to the name + */ + SET_FOREACH(ofwpp, ofw_set) { + ofwp = *ofwpp; + + if (ofwp->name && + !strcmp(ofwp->name, name) && + prio >= curr_prio) { + curr_prio = prio; + ofw_def_impl = ofwp; + return (TRUE); + } + } + + return (FALSE); +} + /* Initialiser */ void -OF_init(int (*openfirm)(void *)) +OF_init(void *cookie) { phandle_t chosen; - set_openfirm_callback(openfirm); + ofw_obj = &ofw_kernel_obj; + /* + * Take care of compiling the selected class, and + * then statically initialize the OFW object + */ + kobj_class_compile_static(ofw_def_impl, &ofw_kernel_kops); + kobj_init((kobj_t)ofw_obj, ofw_def_impl); + + OFW_INIT(ofw_obj, cookie); + if ((chosen = OF_finddevice("/chosen")) == -1) OF_exit(); if (OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) == -1) - OF_exit(); + stdout = -1; } void @@ -103,75 +150,27 @@ OF_printf(const char *fmt, ...) /* Test to see if a service exists. */ int -OF_test(char *name) +OF_test(const char *name) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t service; - cell_t missing; - } args = { - (cell_t)"test", - 1, - 1, - }; - - args.service = (cell_t)name; - if (openfirmware(&args) == -1) - return (-1); - return (args.missing); + return (OFW_TEST(ofw_obj, name)); } int -OF_interpret(char *cmd, int nreturns, ...) +OF_interpret(const char *cmd, int nreturns, ...) { va_list ap; - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t slot[16]; - } args = { - (cell_t)"interpret", - 1, - }; - cell_t status; + unsigned long slots[16]; int i = 0; + int status; + + status = OFW_INTERPRET(ofw_obj, cmd, nreturns, slots); va_start(ap, nreturns); - args.nreturns = ++nreturns; - args.slot[i++] = (cell_t)cmd; - while (i < 1) - args.slot[i++] = va_arg(ap, cell_t); - if (openfirmware(&args) == -1) { - va_end(ap); - return (-1); - } - status = args.slot[i++]; while (i < 1 + nreturns) - *va_arg(ap, cell_t *) = args.slot[i++]; + *va_arg(ap, cell_t *) = slots[i++]; va_end(ap); - return (status); -} -/* Return firmware millisecond count. */ -int -OF_milliseconds() -{ - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t ms; - } args = { - (cell_t)"milliseconds", - 0, - 1, - }; - - openfirmware(&args); - return (args.ms); + return (status); } /* @@ -182,140 +181,42 @@ OF_milliseconds() phandle_t OF_peer(phandle_t node) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t node; - cell_t next; - } args = { - (cell_t)"peer", - 1, - 1, - }; - - args.node = node; - if (openfirmware(&args) == -1) - return (-1); - return (args.next); + return (OFW_PEER(ofw_obj, node)); } /* Return the first child of this node or 0. */ phandle_t OF_child(phandle_t node) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t node; - cell_t child; - } args = { - (cell_t)"child", - 1, - 1, - }; - - args.node = node; - if (openfirmware(&args) == -1) - return (-1); - return (args.child); + return (OFW_CHILD(ofw_obj, node)); } /* Return the parent of this node or 0. */ phandle_t OF_parent(phandle_t node) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t node; - cell_t parent; - } args = { - (cell_t)"parent", - 1, - 1, - }; - - args.node = node; - if (openfirmware(&args) == -1) - return (-1); - return (args.parent); + return (OFW_PARENT(ofw_obj, node)); } /* Return the package handle that corresponds to an instance handle. */ phandle_t OF_instance_to_package(ihandle_t instance) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t instance; - cell_t package; - } args = { - (cell_t)"instance-to-package", - 1, - 1, - }; - - args.instance = instance; - if (openfirmware(&args) == -1) - return (-1); - return (args.package); + return (OFW_INSTANCE_TO_PACKAGE(ofw_obj, instance)); } /* Get the length of a property of a package. */ -int -OF_getproplen(phandle_t package, char *propname) +ssize_t +OF_getproplen(phandle_t package, const char *propname) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t package; - cell_t propname; - cell_t proplen; - } args = { - (cell_t)"getproplen", - 2, - 1, - }; - - args.package = package; - args.propname = (cell_t)propname; - if (openfirmware(&args) == -1) - return (-1); - return (args.proplen); + return (OFW_GETPROPLEN(ofw_obj, package, propname)); } /* Get the value of a property of a package. */ -int -OF_getprop(phandle_t package, char *propname, void *buf, int buflen) +ssize_t +OF_getprop(phandle_t package, const char *propname, void *buf, size_t buflen) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t package; - cell_t propname; - cell_t buf; - cell_t buflen; - cell_t size; - } args = { - (cell_t)"getprop", - 4, - 1, - }; - - args.package = package; - args.propname = (cell_t)propname; - args.buf = (cell_t)buf; - args.buflen = buflen; - if (openfirmware(&args) == -1) - return (-1); - return (args.size); + return (OFW_GETPROP(ofw_obj, package, propname, buf, buflen)); } /* @@ -323,8 +224,8 @@ OF_getprop(phandle_t package, char *propname, void *buf, int buflen) * (using the M_OFWPROP malloc pool and M_WAITOK). elsz is the size of a * single element, the number of elements is return in number. */ -int -OF_getprop_alloc(phandle_t package, char *propname, int elsz, void **buf) +ssize_t +OF_getprop_alloc(phandle_t package, const char *propname, int elsz, void **buf) { int len; @@ -344,194 +245,69 @@ OF_getprop_alloc(phandle_t package, char *propname, int elsz, void **buf) /* Get the next property of a package. */ int -OF_nextprop(phandle_t package, char *previous, char *buf) +OF_nextprop(phandle_t package, const char *previous, char *buf, size_t size) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t package; - cell_t previous; - cell_t buf; - cell_t flag; - } args = { - (cell_t)"nextprop", - 3, - 1, - }; - - args.package = package; - args.previous = (cell_t)previous; - args.buf = (cell_t)buf; - if (openfirmware(&args) == -1) - return (-1); - return (args.flag); + return (OFW_NEXTPROP(ofw_obj, package, previous, buf, size)); } /* 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) +OF_setprop(phandle_t package, const char *propname, const void *buf, size_t len) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t package; - cell_t propname; - cell_t buf; - cell_t len; - cell_t size; - } args = { - (cell_t)"setprop", - 4, - 1, - }; - - args.package = package; - args.propname = (cell_t)propname; - args.buf = (cell_t)buf; - args.len = len; - if (openfirmware(&args) == -1) - return (-1); - return (args.size); + return (OFW_SETPROP(ofw_obj, package, propname, buf,len)); } /* Convert a device specifier to a fully qualified pathname. */ -int -OF_canon(const char *device, char *buf, int len) +ssize_t +OF_canon(const char *device, char *buf, size_t len) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t device; - cell_t buf; - cell_t len; - cell_t size; - } args = { - (cell_t)"canon", - 3, - 1, - }; - - args.device = (cell_t)device; - args.buf = (cell_t)buf; - args.len = len; - if (openfirmware(&args) == -1) - return (-1); - return (args.size); + return (OFW_CANON(ofw_obj, device, buf, len)); } /* Return a package handle for the specified device. */ phandle_t OF_finddevice(const char *device) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t device; - cell_t package; - } args = { - (cell_t)"finddevice", - 1, - 1, - }; - - args.device = (cell_t)device; - if (openfirmware(&args) == -1) - return (-1); - return (args.package); + return (OFW_FINDDEVICE(ofw_obj, device)); } /* Return the fully qualified pathname corresponding to an instance. */ -int -OF_instance_to_path(ihandle_t instance, char *buf, int len) +ssize_t +OF_instance_to_path(ihandle_t instance, char *buf, size_t len) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t instance; - cell_t buf; - cell_t len; - cell_t size; - } args = { - (cell_t)"instance-to-path", - 3, - 1, - }; - - args.instance = instance; - args.buf = (cell_t)buf; - args.len = len; - if (openfirmware(&args) == -1) - return (-1); - return (args.size); + return (OFW_INSTANCE_TO_PATH(ofw_obj, instance, buf, len)); } /* Return the fully qualified pathname corresponding to a package. */ -int -OF_package_to_path(phandle_t package, char *buf, int len) +ssize_t +OF_package_to_path(phandle_t package, char *buf, size_t len) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t package; - cell_t buf; - cell_t len; - cell_t size; - } args = { - (cell_t)"package-to-path", - 3, - 1, - }; - - args.package = package; - args.buf = (cell_t)buf; - args.len = len; - if (openfirmware(&args) == -1) - return (-1); - return (args.size); + return (OFW_PACKAGE_TO_PATH(ofw_obj, package, buf, len)); } /* Call the method in the scope of a given instance. */ int -OF_call_method(char *method, ihandle_t instance, int nargs, int nreturns, ...) +OF_call_method(const char *method, ihandle_t instance, int nargs, int nreturns, + ...) { va_list ap; - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t method; - cell_t instance; - cell_t args_n_results[12]; - } args = { - (cell_t)"call-method", - 2, - 1, - }; - cell_t *cp; - int n; + unsigned long args_n_results[12]; + int n, status; if (nargs > 6) return (-1); - args.nargs = nargs + 2; - args.nreturns = nreturns + 1; - args.method = (cell_t)method; - args.instance = instance; va_start(ap, nreturns); - for (cp = args.args_n_results + (n = nargs); --n >= 0;) - *--cp = va_arg(ap, cell_t); - if (openfirmware(&args) == -1) - return (-1); - if (args.args_n_results[nargs]) - return (args.args_n_results[nargs]); - for (cp = args.args_n_results + nargs + (n = args.nreturns); --n > 0;) - *va_arg(ap, cell_t *) = *--cp; + for (n = 0; n < nargs; n++) + args_n_results[n] = va_arg(ap, unsigned long); + + status = OFW_CALL_METHOD(ofw_obj, instance, method, nargs, nreturns, + args_n_results); + + if (status != 0) + return (status); + + for (; n < nargs + nreturns; n++) + *va_arg(ap, unsigned long *) = args_n_results[n]; va_end(ap); return (0); } @@ -542,122 +318,37 @@ OF_call_method(char *method, ihandle_t instance, int nargs, int nreturns, ...) /* Open an instance for a device. */ ihandle_t -OF_open(char *device) +OF_open(const char *device) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t device; - cell_t instance; - } args = { - (cell_t)"open", - 1, - 1, - }; - - args.device = (cell_t)device; - if (openfirmware(&args) == -1 || args.instance == 0) { - return (-1); - } - return (args.instance); + return (OFW_OPEN(ofw_obj, device)); } /* Close an instance. */ void OF_close(ihandle_t instance) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t instance; - } args = { - (cell_t)"close", - 1, - }; - - args.instance = instance; - openfirmware(&args); + OFW_CLOSE(ofw_obj, instance); } /* Read from an instance. */ -int -OF_read(ihandle_t instance, void *addr, int len) +ssize_t +OF_read(ihandle_t instance, void *addr, size_t len) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t instance; - cell_t addr; - cell_t len; - cell_t actual; - } args = { - (cell_t)"read", - 3, - 1, - }; - - args.instance = instance; - args.addr = (cell_t)addr; - args.len = len; - if (openfirmware(&args) == -1) - return (-1); - - return (args.actual); + return (OFW_READ(ofw_obj, instance, addr, len)); } /* Write to an instance. */ -int -OF_write(ihandle_t instance, void *addr, int len) +ssize_t +OF_write(ihandle_t instance, const void *addr, size_t len) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t instance; - cell_t addr; - cell_t len; - cell_t actual; - } args = { - (cell_t)"write", - 3, - 1, - }; - - args.instance = instance; - args.addr = (cell_t)addr; - args.len = len; - if (openfirmware(&args) == -1) - return (-1); - return (args.actual); + return (OFW_WRITE(ofw_obj, instance, addr, len)); } /* Seek to a position. */ int -OF_seek(ihandle_t instance, u_int64_t pos) +OF_seek(ihandle_t instance, uint64_t pos) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t instance; - cell_t poshi; - cell_t poslo; - cell_t status; - } args = { - (cell_t)"seek", - 3, - 1, - }; - - args.instance = instance; - args.poshi = pos >> 32; - args.poslo = pos; - if (openfirmware(&args) == -1) - return (-1); - return (args.status); + return (OFW_SEEK(ofw_obj, instance, pos)); } /* @@ -666,145 +357,37 @@ OF_seek(ihandle_t instance, u_int64_t pos) /* Claim an area of memory. */ void * -OF_claim(void *virt, u_int size, u_int align) +OF_claim(void *virt, size_t size, u_int align) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t virt; - cell_t size; - cell_t align; - cell_t baseaddr; - } args = { - (cell_t)"claim", - 3, - 1, - }; - - args.virt = (cell_t)virt; - args.size = size; - args.align = align; - if (openfirmware(&args) == -1) - return ((void *)-1); - return ((void *)args.baseaddr); + return (OFW_CLAIM(ofw_obj, virt, size, align)); } /* Release an area of memory. */ void -OF_release(void *virt, u_int size) +OF_release(void *virt, size_t size) { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t virt; - cell_t size; - } args = { - (cell_t)"release", - 2, - }; - - args.virt = (cell_t)virt; - args.size = size; - openfirmware(&args); + OFW_RELEASE(ofw_obj, virt, size); } /* * Control transfer functions */ -/* Reset the system and call "boot <bootspec>". */ -void -OF_boot(char *bootspec) -{ - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t bootspec; - } args = { - (cell_t)"boot", - 1, - }; - - args.bootspec = (cell_t)bootspec; - openfirmware(&args); - for (;;) /* just in case */ - ; -} - /* Suspend and drop back to the Open Firmware interface. */ void OF_enter() { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - } args = { - (cell_t)"enter", - }; - - openfirmware(&args); - /* We may come back. */ + OFW_ENTER(ofw_obj); } /* Shut down and drop back to the Open Firmware interface. */ void OF_exit() { - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - } args = { - (cell_t)"exit", - }; - - openfirmware(&args); + /* Should not return */ + OFW_EXIT(ofw_obj); + for (;;) /* just in case */ ; } -/* Free <size> bytes starting at <virt>, then call <entry> with <arg>. */ -#if 0 -void -OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) -{ - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t virt; - cell_t size; - cell_t entry; - cell_t arg; - cell_t len; - } args = { - (cell_t)"chain", - 5, - }; - - args.virt = (cell_t)virt; - args.size = size; - args.entry = (cell_t)entry; - args.arg = (cell_t)arg; - args.len = len; - openfirmware(&args); -} -#else -void -OF_chain(void *virt, u_int size, - void (*entry)(void *, u_int, void *, void *, u_int), void *arg, u_int len) -{ - /* - * This is a REALLY dirty hack till the firmware gets this going - */ -#if 0 - if (size > 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 index a676fc56..08a0544 100644 --- a/sys/dev/ofw/openfirm.h +++ b/sys/dev/ofw/openfirm.h @@ -60,84 +60,82 @@ #ifndef _OPENFIRM_H_ #define _OPENFIRM_H_ +#include <sys/types.h> + /* * Prototypes for Open Firmware Interface Routines */ -typedef unsigned long cell_t; - -typedef unsigned int ihandle_t; -typedef unsigned int phandle_t; +typedef uint32_t ihandle_t; +typedef uint32_t phandle_t; +typedef uint32_t pcell_t; #ifdef _KERNEL -#include <sys/cdefs.h> -#include <sys/types.h> #include <sys/malloc.h> +#include <machine/ofw_machdep.h> + MALLOC_DECLARE(M_OFWPROP); /* - * Other than in Open Firmware calls, the size of a bus cell seems to be - * always the same. + * Open Firmware interface initialization. OF_install installs the named + * interface as the Open Firmware access mechanism, OF_init initializes it. */ -typedef u_int32_t pcell_t; -/* - * Stuff that is used by the Open Firmware code. - */ -void set_openfirm_callback(int (*)(void *)); -int openfirmware(void *); +boolean_t OF_install(char *name, int prio); +void OF_init(void *cookie); /* - * This isn't actually an Open Firmware function, but it seemed like the right - * place for it to go. + * Known Open Firmware interface names */ -void OF_init(int (*openfirm)(void *)); + +#define OFW_STD_DIRECT "ofw_std" /* Standard OF interface */ +#define OFW_STD_REAL "ofw_real" /* Real-mode OF interface */ +#define OFW_FDT "ofw_fdt" /* Flattened Device Tree */ /* Generic functions */ -int OF_test(char *); +int OF_test(const char *); void OF_printf(const 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_getprop_alloc(phandle_t package, char *propname, int elsz, - void **buf); -int OF_nextprop(phandle_t, char *, char *); -int OF_setprop(phandle_t, char *, void *, int); -int OF_canon(const char *, char *, int); -phandle_t OF_finddevice(const 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, ...); +phandle_t OF_peer(phandle_t node); +phandle_t OF_child(phandle_t node); +phandle_t OF_parent(phandle_t node); +ssize_t OF_getproplen(phandle_t node, const char *propname); +ssize_t OF_getprop(phandle_t node, const char *propname, void *buf, + size_t len); +ssize_t OF_getprop_alloc(phandle_t node, const char *propname, + int elsz, void **buf); +int OF_nextprop(phandle_t node, const char *propname, char *buf, + size_t len); +int OF_setprop(phandle_t node, const char *name, const void *buf, + size_t len); +ssize_t OF_canon(const char *path, char *buf, size_t len); +phandle_t OF_finddevice(const char *path); +ssize_t OF_package_to_path(phandle_t node, char *buf, size_t len); /* 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); +ihandle_t OF_open(const char *path); +void OF_close(ihandle_t instance); +ssize_t OF_read(ihandle_t instance, void *buf, size_t len); +ssize_t OF_write(ihandle_t instance, const void *buf, size_t len); +int OF_seek(ihandle_t instance, uint64_t where); + +phandle_t OF_instance_to_package(ihandle_t instance); +ssize_t OF_instance_to_path(ihandle_t instance, char *buf, size_t len); +int OF_call_method(const char *method, ihandle_t instance, + int nargs, int nreturns, ...); /* Memory functions */ -void *OF_claim(void *, u_int, u_int); -void OF_release(void *, u_int); +void *OF_claim(void *virtrequest, size_t size, u_int align); +void OF_release(void *virt, size_t size); /* Control transfer functions */ -void OF_boot(char *); void OF_enter(void); void OF_exit(void) __attribute__((noreturn)); -void OF_chain(void *, u_int, - void (*)(void *, u_int, void *, void *, u_int), void *, u_int); /* User interface functions */ -int OF_interpret(char *, int, ...); - -/* Time function */ -int OF_milliseconds(void); +int OF_interpret(const char *cmd, int nreturns, ...); #endif /* _KERNEL */ #endif /* _OPENFIRM_H_ */ diff --git a/sys/dev/ofw/openfirmio.c b/sys/dev/ofw/openfirmio.c index 47f2517..d042f02 100644 --- a/sys/dev/ofw/openfirmio.c +++ b/sys/dev/ofw/openfirmio.c @@ -221,7 +221,7 @@ openfirm_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, if (error) break; } - ok = OF_nextprop(node, name, newname); + ok = OF_nextprop(node, name, newname, sizeof(newname)); if (ok == 0) { error = ENOENT; break; diff --git a/sys/dev/ofw/openpromio.c b/sys/dev/ofw/openpromio.c index cb7343f..8ba6d3a 100644 --- a/sys/dev/ofw/openpromio.c +++ b/sys/dev/ofw/openpromio.c @@ -174,7 +174,7 @@ openprom_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, error = OF_getprop(node, prop, buf, proplen); break; case OPROMNXTPROP: - error = OF_nextprop(node, prop, buf); + error = OF_nextprop(node, prop, buf, OPROMMAXPARAM); proplen = strlen(buf); break; } diff --git a/sys/kern/subr_kobj.c b/sys/kern/subr_kobj.c index 4e2f096..bc36667 100644 --- a/sys/kern/subr_kobj.c +++ b/sys/kern/subr_kobj.c @@ -60,6 +60,19 @@ static struct mtx kobj_mtx; static int kobj_mutex_inited; static int kobj_next_id = 1; +/* + * In the event that kobj_mtx has not been initialized yet, + * we will ignore it, and run without locks in order to support + * use of KOBJ before mutexes are available. This early in the boot + * process, everything is single threaded and so races should not + * happen. This is used to provide the PMAP layer on PowerPC, as well + * as board support. + */ + +#define KOBJ_LOCK() if (kobj_mutex_inited) mtx_lock(&kobj_mtx); +#define KOBJ_UNLOCK() if (kobj_mutex_inited) mtx_unlock(&kobj_mtx); +#define KOBJ_ASSERT(what) if (kobj_mutex_inited) mtx_assert(&kobj_mtx,what); + SYSCTL_UINT(_kern, OID_AUTO, kobj_methodcount, CTLFLAG_RD, &kobj_next_id, 0, ""); @@ -74,12 +87,6 @@ kobj_init_mutex(void *arg) SYSINIT(kobj, SI_SUB_LOCK, SI_ORDER_ANY, kobj_init_mutex, NULL); -void -kobj_machdep_init(void) -{ - kobj_init_mutex(NULL); -} - /* * This method structure is used to initialise new caches. Since the * desc pointer is NULL, it is guaranteed never to match any read @@ -99,8 +106,8 @@ kobj_error_method(void) static void kobj_register_method(struct kobjop_desc *desc) { + KOBJ_ASSERT(MA_OWNED); - mtx_assert(&kobj_mtx, MA_OWNED); if (desc->id == 0) { desc->id = kobj_next_id++; } @@ -117,7 +124,7 @@ kobj_class_compile_common(kobj_class_t cls, kobj_ops_t ops) kobj_method_t *m; int i; - mtx_assert(&kobj_mtx, MA_OWNED); + KOBJ_ASSERT(MA_OWNED); /* * Don't do anything if we are already compiled. @@ -145,7 +152,7 @@ kobj_class_compile(kobj_class_t cls) { kobj_ops_t ops; - mtx_assert(&kobj_mtx, MA_NOTOWNED); + KOBJ_ASSERT(MA_NOTOWNED); /* * Allocate space for the compiled ops table. @@ -154,7 +161,7 @@ kobj_class_compile(kobj_class_t cls) if (!ops) panic("kobj_compile_methods: out of memory"); - mtx_lock(&kobj_mtx); + KOBJ_LOCK(); /* * We may have lost a race for kobj_class_compile here - check @@ -162,28 +169,30 @@ kobj_class_compile(kobj_class_t cls) * class. */ if (cls->ops) { - mtx_unlock(&kobj_mtx); + KOBJ_UNLOCK(); free(ops, M_KOBJ); return; } kobj_class_compile_common(cls, ops); - mtx_unlock(&kobj_mtx); + KOBJ_UNLOCK(); } void kobj_class_compile_static(kobj_class_t cls, kobj_ops_t ops) { - mtx_assert(&kobj_mtx, MA_NOTOWNED); + KOBJ_ASSERT(MA_NOTOWNED); /* * Increment refs to make sure that the ops table is not freed. */ - mtx_lock(&kobj_mtx); + KOBJ_LOCK(); + cls->refs++; kobj_class_compile_common(cls, ops); - mtx_unlock(&kobj_mtx); + + KOBJ_UNLOCK(); } static kobj_method_t* @@ -254,8 +263,8 @@ kobj_class_free(kobj_class_t cls) kobj_method_t *m; void* ops = 0; - mtx_assert(&kobj_mtx, MA_NOTOWNED); - mtx_lock(&kobj_mtx); + KOBJ_ASSERT(MA_NOTOWNED); + KOBJ_LOCK(); /* * Protect against a race between kobj_create and @@ -275,7 +284,7 @@ kobj_class_free(kobj_class_t cls) cls->ops = 0; } - mtx_unlock(&kobj_mtx); + KOBJ_UNLOCK(); if (ops) free(ops, M_KOBJ); @@ -302,9 +311,9 @@ kobj_create(kobj_class_t cls, void kobj_init(kobj_t obj, kobj_class_t cls) { - mtx_assert(&kobj_mtx, MA_NOTOWNED); + KOBJ_ASSERT(MA_NOTOWNED); retry: - mtx_lock(&kobj_mtx); + KOBJ_LOCK(); /* * Consider compiling the class' method table. @@ -315,7 +324,7 @@ kobj_init(kobj_t obj, kobj_class_t cls) * because of the call to malloc - we drop the lock * and re-try. */ - mtx_unlock(&kobj_mtx); + KOBJ_UNLOCK(); kobj_class_compile(cls); goto retry; } @@ -323,7 +332,7 @@ kobj_init(kobj_t obj, kobj_class_t cls) obj->ops = cls->ops; cls->refs++; - mtx_unlock(&kobj_mtx); + KOBJ_UNLOCK(); } void @@ -337,11 +346,11 @@ kobj_delete(kobj_t obj, struct malloc_type *mtype) * after its last instance is deleted. As an optimisation, we * should defer this for a short while to avoid thrashing. */ - mtx_assert(&kobj_mtx, MA_NOTOWNED); - mtx_lock(&kobj_mtx); + KOBJ_ASSERT(MA_NOTOWNED); + KOBJ_LOCK(); cls->refs--; refs = cls->refs; - mtx_unlock(&kobj_mtx); + KOBJ_UNLOCK(); if (!refs) kobj_class_free(cls); diff --git a/sys/powerpc/aim/locore.S b/sys/powerpc/aim/locore.S index cfe75d9..60e5e9d 100644 --- a/sys/powerpc/aim/locore.S +++ b/sys/powerpc/aim/locore.S @@ -129,14 +129,6 @@ kernel_text: .text .globl __start __start: -#ifdef FIRMWORKSBUGS - mfmsr 0 - andi. 0,0,PSL_IR|PSL_DR - beq 1f - - bl ofwr_init -1: -#endif li 8,0 li 9,0x100 mtctr 9 @@ -154,7 +146,6 @@ __start: lis 8,openfirmware_entry@ha stw 5,openfirmware_entry@l(8) /* save client interface handler */ - mr 3,5 lis 1,(tmpstk+TMPSTKSZ-16)@ha addi 1,1,(tmpstk+TMPSTKSZ-16)@l @@ -172,7 +163,7 @@ __start: mfsprg3 0 stw 0,16(9) /* ofmsr[4] = sprg3 */ - bl OF_init + bl OF_initial_setup lis 4,end@ha addi 4,4,end@l diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index 13fc2a7..2199cb1 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -291,9 +291,19 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp) __asm __volatile("mtsprg 0, %0" :: "r"(pc)); + /* + * Init mutexes, which we use heavily in PMAP + */ + mutex_init(); /* + * Install the OF client interface + */ + + OF_bootstrap(); + + /* * Initialize the console before printing anything. */ cninit(); @@ -307,8 +317,6 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp) kdb_init(); - kobj_machdep_init(); - /* * XXX: Initialize the interrupt tables. * Disable translation in case the vector area diff --git a/sys/powerpc/aim/ofw_machdep.c b/sys/powerpc/aim/ofw_machdep.c index 2755819..0d5f03b 100644 --- a/sys/powerpc/aim/ofw_machdep.c +++ b/sys/powerpc/aim/ofw_machdep.c @@ -65,6 +65,10 @@ static struct mem_region OFfree[OFMEM_REGIONS + 3]; extern register_t ofmsr[5]; extern struct pmap ofw_pmap; static int (*ofwcall)(void *); +static void *fdt; +int ofw_real_mode; + +static int openfirmware(void *args); /* * Saved SPRG0-3 from OpenFirmware. Will be restored prior to the callback. @@ -192,13 +196,45 @@ mem_regions(struct mem_region **memp, int *memsz, } void -set_openfirm_callback(int (*openfirm)(void *)) +OF_initial_setup(void *fdt_ptr, void *junk, int (*openfirm)(void *)) { + if (ofmsr[0] & PSL_DR) + ofw_real_mode = 0; + else + ofw_real_mode = 1; ofwcall = openfirm; + fdt = fdt_ptr; } -int +boolean_t +OF_bootstrap() +{ + boolean_t status = FALSE; + + if (ofwcall != NULL) { + if (ofw_real_mode) + status = OF_install(OFW_STD_REAL, 0); + else + status = OF_install(OFW_STD_DIRECT, 0); + + if (status != TRUE) + return status; + + OF_init(openfirmware); + } else { + status = OF_install(OFW_FDT, 0); + + if (status != TRUE) + return status; + + OF_init(fdt); + } + + return (status); +} + +static int openfirmware(void *args) { long oldmsr; @@ -206,6 +242,9 @@ openfirmware(void *args) u_int srsave[16]; u_int i; + if (pmap_bootstrapped && ofw_real_mode) + args = (void *)pmap_kextract((vm_offset_t)args); + __asm __volatile( "\t" "sync\n\t" "mfmsr %0\n\t" @@ -217,7 +256,7 @@ openfirmware(void *args) ofw_sprg_prepare(); - if (pmap_bootstrapped) { + if (pmap_bootstrapped && !ofw_real_mode) { /* * Swap the kernel's address space with Open Firmware's */ @@ -236,7 +275,7 @@ openfirmware(void *args) result = ofwcall(args); - if (pmap_bootstrapped) { + if (pmap_bootstrapped && !ofw_real_mode) { /* * Restore the kernel's addr space. The isync() doesn;t * work outside the loop unless mtsrin() is open-coded diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c index 85cc184..a48ece1 100644 --- a/sys/powerpc/booke/machdep.c +++ b/sys/powerpc/booke/machdep.c @@ -430,7 +430,6 @@ e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp) if (boothowto & RB_KDB) kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); #endif - kobj_machdep_init(); /* Initialise virtual memory. */ pmap_mmu_install(MMU_TYPE_BOOKE, 0); diff --git a/sys/powerpc/include/ofw_machdep.h b/sys/powerpc/include/ofw_machdep.h index a4b601e..1dd2027 100644 --- a/sys/powerpc/include/ofw_machdep.h +++ b/sys/powerpc/include/ofw_machdep.h @@ -28,9 +28,18 @@ #ifndef _MACHINE_OFW_MACHDEP_H_ #define _MACHINE_OFW_MACHDEP_H_ +#include <sys/cdefs.h> +#include <sys/types.h> +#include <sys/rman.h> #include <sys/bus.h> +#include <dev/ofw/openfirm.h> + +typedef uint32_t cell_t; int OF_decode_addr(phandle_t, int, bus_space_tag_t *, bus_space_handle_t *); void OF_getetheraddr(device_t dev, u_char *addr); +void OF_initial_setup(void *fdt_ptr, void *junk, int (*openfirm)(void *)); +boolean_t OF_bootstrap(void); + #endif /* _MACHINE_OFW_MACHDEP_H_ */ diff --git a/sys/powerpc/powerpc/pmap_dispatch.c b/sys/powerpc/powerpc/pmap_dispatch.c index 55112bb..33e94d1 100644 --- a/sys/powerpc/powerpc/pmap_dispatch.c +++ b/sys/powerpc/powerpc/pmap_dispatch.c @@ -37,9 +37,8 @@ __FBSDID("$FreeBSD$"); * the highest priority call will be installed as the default * MMU handler when pmap_bootstrap() is called. * - * It is required that kobj_machdep_init() be called before - * pmap_bootstrap() to allow the kobj subsystem to initialise. This - * in turn requires that mutex_init() has been called. + * It is required that mutex_init() be called before pmap_bootstrap(), + * as the PMAP layer makes extensive use of mutexes. */ #include <sys/param.h> diff --git a/sys/sparc64/include/ofw_machdep.h b/sys/sparc64/include/ofw_machdep.h index ac1fcc1..625b131 100644 --- a/sys/sparc64/include/ofw_machdep.h +++ b/sys/sparc64/include/ofw_machdep.h @@ -29,10 +29,15 @@ #define _MACHINE_OFW_MACHDEP_H_ #include <sys/bus.h> +#include <machine/bus.h> +#include <dev/ofw/openfirm.h> + +typedef uint64_t cell_t; int OF_decode_addr(phandle_t, int, int *, bus_addr_t *); void OF_getetheraddr(device_t, u_char *); void cpu_shutdown(void *); -void openfirmware_exit(void *); +int ofw_entry(void *); +void ofw_exit(void *); #endif /* _MACHINE_OFW_MACHDEP_H_ */ diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c index 0be9af9..4e1e300 100644 --- a/sys/sparc64/sparc64/machdep.c +++ b/sys/sparc64/sparc64/machdep.c @@ -276,9 +276,10 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) tick_stop(); /* - * Initialize Open Firmware (needed for console). + * Set up Open Firmware entry points */ - OF_init(vec); + ofw_tba = rdpr(tba); + ofw_vec = (u_long)vec; /* * Parse metadata if present and fetch parameters. Must be before the @@ -301,6 +302,12 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) init_param1(); /* + * Initialize Open Firmware (needed for console). + */ + OF_install(OFW_STD_DIRECT, 0); + OF_init(ofw_entry); + + /* * Prime our per-CPU data page for use. Note, we are using it for * our stack, so don't pass the real size (PAGE_SIZE) to pcpu_init * or it'll zero it out from under us. @@ -481,14 +488,6 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) } void -set_openfirm_callback(ofw_vec_t *vec) -{ - - ofw_tba = rdpr(tba); - ofw_vec = (u_long)vec; -} - -void sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) { struct trapframe *tf; @@ -725,7 +724,7 @@ cpu_shutdown(void *args) #ifdef SMP cpu_mp_shutdown(); #endif - openfirmware_exit(args); + ofw_exit(args); } /* Get current clock frequency for the given CPU ID. */ diff --git a/sys/sparc64/sparc64/mp_machdep.c b/sys/sparc64/sparc64/mp_machdep.c index 5cace48..bf79adf 100644 --- a/sys/sparc64/sparc64/mp_machdep.c +++ b/sys/sparc64/sparc64/mp_machdep.c @@ -221,7 +221,7 @@ sun4u_startcpu(phandle_t cpu, void *func, u_long arg) args.cpu = cpu; args.func = (cell_t)func; args.arg = (cell_t)arg; - openfirmware(&args); + ofw_entry(&args); } /* @@ -238,7 +238,7 @@ sun4u_stopself(void) (cell_t)SUNW_STOPSELF, }; - openfirmware_exit(&args); + ofw_exit(&args); panic("%s: failed.", __func__); } diff --git a/sys/sparc64/sparc64/support.S b/sys/sparc64/sparc64/support.S index a3f6501..821e694 100644 --- a/sys/sparc64/sparc64/support.S +++ b/sys/sparc64/sparc64/support.S @@ -745,9 +745,9 @@ ENTRY(setjmp) END(setjmp) /* - * void openfirmware(cell_t args[]) + * void ofw_entry(cell_t args[]) */ -ENTRY(openfirmware) +ENTRY(ofw_entry) save %sp, -CCFSZ, %sp SET(ofw_vec, %l7, %l6) ldx [%l6], %l6 @@ -758,12 +758,12 @@ ENTRY(openfirmware) wrpr %l7, 0, %pil ret restore %o0, %g0, %o0 -END(openfirmware) +END(ofw_entry) /* - * void openfirmware_exit(cell_t args[]) + * void ofw_exit(cell_t args[]) */ -ENTRY(openfirmware_exit) +ENTRY(ofw_exit) save %sp, -CCFSZ, %sp flushw wrpr %g0, PIL_TICK, %pil @@ -783,7 +783,7 @@ ENTRY(openfirmware_exit) call %l6 mov %i0, %o0 ! never to return -END(openfirmware_exit) +END(ofw_exit) #ifdef GPROF diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c index 9de8e26..c10dbc4 100644 --- a/sys/sparc64/sparc64/trap.c +++ b/sys/sparc64/sparc64/trap.c @@ -71,6 +71,7 @@ __FBSDID("$FreeBSD$"); #include <security/audit/audit.h> #include <dev/ofw/openfirm.h> +#include <machine/ofw_machdep.h> #include <vm/vm.h> #include <vm/pmap.h> @@ -248,7 +249,7 @@ sun4u_set_traptable(void *tba_addr) }; args.tba_addr = (cell_t)tba_addr; - openfirmware(&args); + ofw_entry(&args); } void diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c index c163fd8..b769753 100644 --- a/sys/sparc64/sparc64/vm_machdep.c +++ b/sys/sparc64/sparc64/vm_machdep.c @@ -334,7 +334,7 @@ cpu_reset(void) bspec[sizeof(bspec) - 1] = '\0'; } - openfirmware_exit(&args); + ofw_exit(&args); } /* diff --git a/sys/sun4v/sun4v/machdep.c b/sys/sun4v/sun4v/machdep.c index 6281f00..b7c0869 100644 --- a/sys/sun4v/sun4v/machdep.c +++ b/sys/sun4v/sun4v/machdep.c @@ -310,18 +310,18 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) end = 0; kmdp = NULL; - /* - * Initialize Open Firmware (needed for console). - */ - OF_init(vec); - - /* * XXX */ bootverbose = 1; /* + * Set up Open Firmware entry points + */ + ofw_tba = rdpr(tba); + ofw_vec = (u_long)vec; + + /* * Parse metadata if present and fetch parameters. Must be before the * console is inited so cninit gets the right value of boothowto. */ @@ -344,6 +344,12 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) init_param1(); + /* + * Initialize Open Firmware (needed for console). + */ + OF_install(OFW_STD_DIRECT, 0); + OF_init(ofw_entry); + root = OF_peer(0); for (child = OF_child(root); child != 0; child = OF_peer(child)) { OF_getprop(child, "device_type", type, sizeof(type)); @@ -516,13 +522,6 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) } void -set_openfirm_callback(ofw_vec_t *vec) -{ - ofw_tba = rdpr(tba); - ofw_vec = (u_long)vec; -} - -void sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) { struct trapframe *tf; diff --git a/sys/sun4v/sun4v/mp_machdep.c b/sys/sun4v/sun4v/mp_machdep.c index 8bd4ba6..5f4f632 100644 --- a/sys/sun4v/sun4v/mp_machdep.c +++ b/sys/sun4v/sun4v/mp_machdep.c @@ -272,7 +272,7 @@ start_ap_bycpuid(int cpuid, void *func, u_long arg) args.cpuid = cpuid; args.func = (cell_t)func; args.arg = (cell_t)arg; - openfirmware(&args); + ofw_entry(&args); return (int)args.result; } diff --git a/sys/sun4v/sun4v/support.S b/sys/sun4v/sun4v/support.S index e6bac5d..699a40f 100644 --- a/sys/sun4v/sun4v/support.S +++ b/sys/sun4v/sun4v/support.S @@ -622,9 +622,9 @@ ENTRY(setjmp) END(setjmp) /* - * void openfirmware(cell_t args[]) + * void ofw_entry(cell_t args[]) */ -ENTRY(openfirmware) +ENTRY(ofw_entry) save %sp, -CCFSZ, %sp SET(ofw_vec, %l7, %l6) ldx [%l6], %l6 @@ -635,14 +635,14 @@ ENTRY(openfirmware) wrpr %l7, 0, %pil ret restore %o0, %g0, %o0 -END(openfirmware) +END(ofw_entry) #ifdef notyet /* SUN4V_FIXME - uses a now illegal ASI */ /* * void ofw_exit(cell_t args[]) */ -ENTRY(openfirmware_exit) +ENTRY(ofw_exit) save %sp, -CCFSZ, %sp flushw wrpr %g0, PIL_TICK, %pil @@ -661,7 +661,7 @@ ENTRY(openfirmware_exit) call %l6 mov %i0, %o0 ! never to return -END(openfirmware_exit) +END(ofw_exit) #endif ENTRY(set_mmfsa_scratchpad) diff --git a/sys/sun4v/sun4v/trap.c b/sys/sun4v/sun4v/trap.c index f04c424..bac4f55 100644 --- a/sys/sun4v/sun4v/trap.c +++ b/sys/sun4v/sun4v/trap.c @@ -261,7 +261,7 @@ set_mmfsa_traptable(void *tba_addr, uint64_t mmfsa_ra) args.tba_addr = (cell_t)tba_addr; args.mmfsa_ra = mmfsa_ra; - openfirmware(&args); + ofw_entry(&args); } void diff --git a/sys/sys/kobj.h b/sys/sys/kobj.h index b744db8..64a666a 100644 --- a/sys/sys/kobj.h +++ b/sys/sys/kobj.h @@ -246,9 +246,4 @@ kobj_method_t* kobj_lookup_method(kobj_class_t cls, */ int kobj_error_method(void); -/* - * Machine-dependent initialisation call for boot-time kobj clients - */ -void kobj_machdep_init(void); - #endif /* !_SYS_KOBJ_H_ */ |