summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/conf/files.powerpc2
-rw-r--r--sys/conf/files.sparc642
-rw-r--r--sys/conf/files.sun4v2
-rw-r--r--sys/dev/ofw/ofw_if.m357
-rw-r--r--sys/dev/ofw/ofw_standard.c763
-rw-r--r--sys/dev/ofw/ofwvar.h89
-rw-r--r--sys/dev/ofw/openfirm.c655
-rw-r--r--sys/dev/ofw/openfirm.h92
-rw-r--r--sys/dev/ofw/openfirmio.c2
-rw-r--r--sys/dev/ofw/openpromio.c2
-rw-r--r--sys/kern/subr_kobj.c59
-rw-r--r--sys/powerpc/aim/locore.S11
-rw-r--r--sys/powerpc/aim/machdep.c12
-rw-r--r--sys/powerpc/aim/ofw_machdep.c47
-rw-r--r--sys/powerpc/booke/machdep.c1
-rw-r--r--sys/powerpc/include/ofw_machdep.h9
-rw-r--r--sys/powerpc/powerpc/pmap_dispatch.c5
-rw-r--r--sys/sparc64/include/ofw_machdep.h7
-rw-r--r--sys/sparc64/sparc64/machdep.c21
-rw-r--r--sys/sparc64/sparc64/mp_machdep.c4
-rw-r--r--sys/sparc64/sparc64/support.S12
-rw-r--r--sys/sparc64/sparc64/trap.c3
-rw-r--r--sys/sparc64/sparc64/vm_machdep.c2
-rw-r--r--sys/sun4v/sun4v/machdep.c25
-rw-r--r--sys/sun4v/sun4v/mp_machdep.c2
-rw-r--r--sys/sun4v/sun4v/support.S10
-rw-r--r--sys/sun4v/sun4v/trap.c2
-rw-r--r--sys/sys/kobj.h5
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_ */
OpenPOWER on IntegriCloud