18446b206SNathan Whitehorn /* $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai Exp $ */ 28446b206SNathan Whitehorn 38446b206SNathan Whitehorn /*- 48446b206SNathan Whitehorn * Copyright (C) 1995, 1996 Wolfgang Solfrank. 58446b206SNathan Whitehorn * Copyright (C) 1995, 1996 TooLs GmbH. 68446b206SNathan Whitehorn * All rights reserved. 78446b206SNathan Whitehorn * 88446b206SNathan Whitehorn * Redistribution and use in source and binary forms, with or without 98446b206SNathan Whitehorn * modification, are permitted provided that the following conditions 108446b206SNathan Whitehorn * are met: 118446b206SNathan Whitehorn * 1. Redistributions of source code must retain the above copyright 128446b206SNathan Whitehorn * notice, this list of conditions and the following disclaimer. 138446b206SNathan Whitehorn * 2. Redistributions in binary form must reproduce the above copyright 148446b206SNathan Whitehorn * notice, this list of conditions and the following disclaimer in the 158446b206SNathan Whitehorn * documentation and/or other materials provided with the distribution. 168446b206SNathan Whitehorn * 3. All advertising materials mentioning features or use of this software 178446b206SNathan Whitehorn * must display the following acknowledgement: 188446b206SNathan Whitehorn * This product includes software developed by TooLs GmbH. 198446b206SNathan Whitehorn * 4. The name of TooLs GmbH may not be used to endorse or promote products 208446b206SNathan Whitehorn * derived from this software without specific prior written permission. 218446b206SNathan Whitehorn * 228446b206SNathan Whitehorn * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 238446b206SNathan Whitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 248446b206SNathan Whitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 258446b206SNathan Whitehorn * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 268446b206SNathan Whitehorn * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 278446b206SNathan Whitehorn * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 288446b206SNathan Whitehorn * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 298446b206SNathan Whitehorn * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 308446b206SNathan Whitehorn * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 318446b206SNathan Whitehorn * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 328446b206SNathan Whitehorn */ 338446b206SNathan Whitehorn /*- 348446b206SNathan Whitehorn * Copyright (C) 2000 Benno Rice. 358446b206SNathan Whitehorn * All rights reserved. 368446b206SNathan Whitehorn * 378446b206SNathan Whitehorn * Redistribution and use in source and binary forms, with or without 388446b206SNathan Whitehorn * modification, are permitted provided that the following conditions 398446b206SNathan Whitehorn * are met: 408446b206SNathan Whitehorn * 1. Redistributions of source code must retain the above copyright 418446b206SNathan Whitehorn * notice, this list of conditions and the following disclaimer. 428446b206SNathan Whitehorn * 2. Redistributions in binary form must reproduce the above copyright 438446b206SNathan Whitehorn * notice, this list of conditions and the following disclaimer in the 448446b206SNathan Whitehorn * documentation and/or other materials provided with the distribution. 458446b206SNathan Whitehorn * 468446b206SNathan Whitehorn * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 478446b206SNathan Whitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 488446b206SNathan Whitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 498446b206SNathan Whitehorn * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 508446b206SNathan Whitehorn * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 518446b206SNathan Whitehorn * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 528446b206SNathan Whitehorn * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 538446b206SNathan Whitehorn * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 548446b206SNathan Whitehorn * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 558446b206SNathan Whitehorn * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 568446b206SNathan Whitehorn */ 578446b206SNathan Whitehorn 588446b206SNathan Whitehorn #include <sys/cdefs.h> 598446b206SNathan Whitehorn __FBSDID("$FreeBSD$"); 608446b206SNathan Whitehorn 618446b206SNathan Whitehorn #include <sys/param.h> 628446b206SNathan Whitehorn #include <sys/kernel.h> 638446b206SNathan Whitehorn #include <sys/lock.h> 648446b206SNathan Whitehorn #include <sys/mutex.h> 658446b206SNathan Whitehorn #include <sys/systm.h> 668446b206SNathan Whitehorn 678446b206SNathan Whitehorn #include <vm/vm.h> 688446b206SNathan Whitehorn #include <vm/pmap.h> 698446b206SNathan Whitehorn 708446b206SNathan Whitehorn #include <machine/stdarg.h> 718446b206SNathan Whitehorn #include <machine/bus.h> 728446b206SNathan Whitehorn #include <machine/pmap.h> 738446b206SNathan Whitehorn #include <machine/ofw_machdep.h> 748446b206SNathan Whitehorn 758446b206SNathan Whitehorn #include <dev/ofw/openfirm.h> 768446b206SNathan Whitehorn #include <dev/ofw/ofwvar.h> 778446b206SNathan Whitehorn #include "ofw_if.h" 788446b206SNathan Whitehorn 798446b206SNathan Whitehorn static void ofw_real_init(ofw_t, void *openfirm); 808446b206SNathan Whitehorn static int ofw_real_test(ofw_t, const char *name); 818446b206SNathan Whitehorn static phandle_t ofw_real_peer(ofw_t, phandle_t node); 828446b206SNathan Whitehorn static phandle_t ofw_real_child(ofw_t, phandle_t node); 838446b206SNathan Whitehorn static phandle_t ofw_real_parent(ofw_t, phandle_t node); 848446b206SNathan Whitehorn static phandle_t ofw_real_instance_to_package(ofw_t, ihandle_t instance); 858446b206SNathan Whitehorn static ssize_t ofw_real_getproplen(ofw_t, phandle_t package, 868446b206SNathan Whitehorn const char *propname); 878446b206SNathan Whitehorn static ssize_t ofw_real_getprop(ofw_t, phandle_t package, const char *propname, 888446b206SNathan Whitehorn void *buf, size_t buflen); 898446b206SNathan Whitehorn static int ofw_real_nextprop(ofw_t, phandle_t package, const char *previous, 908446b206SNathan Whitehorn char *buf, size_t); 914fc23012SAndriy Gapon static int ofw_real_setprop(ofw_t, phandle_t package, const char *propname, 924fc23012SAndriy Gapon const void *buf, size_t len); 938446b206SNathan Whitehorn static ssize_t ofw_real_canon(ofw_t, const char *device, char *buf, size_t len); 948446b206SNathan Whitehorn static phandle_t ofw_real_finddevice(ofw_t, const char *device); 958446b206SNathan Whitehorn static ssize_t ofw_real_instance_to_path(ofw_t, ihandle_t instance, char *buf, 968446b206SNathan Whitehorn size_t len); 978446b206SNathan Whitehorn static ssize_t ofw_real_package_to_path(ofw_t, phandle_t package, char *buf, 988446b206SNathan Whitehorn size_t len); 998446b206SNathan Whitehorn static int ofw_real_call_method(ofw_t, ihandle_t instance, const char *method, 1008446b206SNathan Whitehorn int nargs, int nreturns, unsigned long *args_and_returns); 1018446b206SNathan Whitehorn static ihandle_t ofw_real_open(ofw_t, const char *device); 1028446b206SNathan Whitehorn static void ofw_real_close(ofw_t, ihandle_t instance); 1038446b206SNathan Whitehorn static ssize_t ofw_real_read(ofw_t, ihandle_t instance, void *addr, size_t len); 1048446b206SNathan Whitehorn static ssize_t ofw_real_write(ofw_t, ihandle_t instance, const void *addr, 1058446b206SNathan Whitehorn size_t len); 1068446b206SNathan Whitehorn static int ofw_real_seek(ofw_t, ihandle_t instance, u_int64_t pos); 1078446b206SNathan Whitehorn static caddr_t ofw_real_claim(ofw_t, void *virt, size_t size, u_int align); 1088446b206SNathan Whitehorn static void ofw_real_release(ofw_t, void *virt, size_t size); 1098446b206SNathan Whitehorn static void ofw_real_enter(ofw_t); 1108446b206SNathan Whitehorn static void ofw_real_exit(ofw_t); 1118446b206SNathan Whitehorn 1128446b206SNathan Whitehorn static ofw_method_t ofw_real_methods[] = { 1138446b206SNathan Whitehorn OFWMETHOD(ofw_init, ofw_real_init), 1148446b206SNathan Whitehorn OFWMETHOD(ofw_peer, ofw_real_peer), 1158446b206SNathan Whitehorn OFWMETHOD(ofw_child, ofw_real_child), 1168446b206SNathan Whitehorn OFWMETHOD(ofw_parent, ofw_real_parent), 1178446b206SNathan Whitehorn OFWMETHOD(ofw_instance_to_package, ofw_real_instance_to_package), 1188446b206SNathan Whitehorn OFWMETHOD(ofw_getproplen, ofw_real_getproplen), 1198446b206SNathan Whitehorn OFWMETHOD(ofw_getprop, ofw_real_getprop), 1208446b206SNathan Whitehorn OFWMETHOD(ofw_nextprop, ofw_real_nextprop), 1218446b206SNathan Whitehorn OFWMETHOD(ofw_setprop, ofw_real_setprop), 1228446b206SNathan Whitehorn OFWMETHOD(ofw_canon, ofw_real_canon), 1238446b206SNathan Whitehorn OFWMETHOD(ofw_finddevice, ofw_real_finddevice), 1248446b206SNathan Whitehorn OFWMETHOD(ofw_instance_to_path, ofw_real_instance_to_path), 1258446b206SNathan Whitehorn OFWMETHOD(ofw_package_to_path, ofw_real_package_to_path), 1268446b206SNathan Whitehorn 1278446b206SNathan Whitehorn OFWMETHOD(ofw_test, ofw_real_test), 1288446b206SNathan Whitehorn OFWMETHOD(ofw_call_method, ofw_real_call_method), 1298446b206SNathan Whitehorn OFWMETHOD(ofw_open, ofw_real_open), 1308446b206SNathan Whitehorn OFWMETHOD(ofw_close, ofw_real_close), 1318446b206SNathan Whitehorn OFWMETHOD(ofw_read, ofw_real_read), 1328446b206SNathan Whitehorn OFWMETHOD(ofw_write, ofw_real_write), 1338446b206SNathan Whitehorn OFWMETHOD(ofw_seek, ofw_real_seek), 1348446b206SNathan Whitehorn OFWMETHOD(ofw_claim, ofw_real_claim), 1358446b206SNathan Whitehorn OFWMETHOD(ofw_release, ofw_real_release), 1368446b206SNathan Whitehorn OFWMETHOD(ofw_enter, ofw_real_enter), 1378446b206SNathan Whitehorn OFWMETHOD(ofw_exit, ofw_real_exit), 1388446b206SNathan Whitehorn 1398446b206SNathan Whitehorn { 0, 0 } 1408446b206SNathan Whitehorn }; 1418446b206SNathan Whitehorn 1428446b206SNathan Whitehorn static ofw_def_t ofw_real = { 1438446b206SNathan Whitehorn OFW_STD_REAL, 1448446b206SNathan Whitehorn ofw_real_methods, 1458446b206SNathan Whitehorn 0 1468446b206SNathan Whitehorn }; 1478446b206SNathan Whitehorn OFW_DEF(ofw_real); 1488446b206SNathan Whitehorn 1498446b206SNathan Whitehorn MALLOC_DEFINE(M_OFWREAL, "ofwreal", "Open Firmware Real Mode Bounce Page"); 1508446b206SNathan Whitehorn 1518446b206SNathan Whitehorn static int (*openfirmware)(void *); 1528446b206SNathan Whitehorn 1538446b206SNathan Whitehorn static vm_offset_t of_bounce_phys; 1548446b206SNathan Whitehorn static caddr_t of_bounce_virt; 1558446b206SNathan Whitehorn static off_t of_bounce_offset; 1568446b206SNathan Whitehorn static size_t of_bounce_size; 1578446b206SNathan Whitehorn static struct mtx of_bounce_mtx; 1588446b206SNathan Whitehorn 1598446b206SNathan Whitehorn /* 1608446b206SNathan Whitehorn * After the VM is up, allocate a wired, low memory bounce page. 1618446b206SNathan Whitehorn */ 1628446b206SNathan Whitehorn 1638446b206SNathan Whitehorn static void ofw_real_bounce_alloc(void *); 1648446b206SNathan Whitehorn 1658446b206SNathan Whitehorn SYSINIT(ofw_real_bounce_alloc, SI_SUB_VM, SI_ORDER_ANY, 1668446b206SNathan Whitehorn ofw_real_bounce_alloc, NULL); 1678446b206SNathan Whitehorn 1688446b206SNathan Whitehorn static void 1698446b206SNathan Whitehorn ofw_real_start(void) 1708446b206SNathan Whitehorn { 1718446b206SNathan Whitehorn mtx_lock(&of_bounce_mtx); 1728446b206SNathan Whitehorn of_bounce_offset = 0; 1738446b206SNathan Whitehorn } 1748446b206SNathan Whitehorn 1758446b206SNathan Whitehorn static void 1768446b206SNathan Whitehorn ofw_real_stop(void) 1778446b206SNathan Whitehorn { 1788446b206SNathan Whitehorn mtx_unlock(&of_bounce_mtx); 1798446b206SNathan Whitehorn } 1808446b206SNathan Whitehorn 1818446b206SNathan Whitehorn static void 1828446b206SNathan Whitehorn ofw_real_bounce_alloc(void *junk) 1838446b206SNathan Whitehorn { 1848446b206SNathan Whitehorn /* 1858446b206SNathan Whitehorn * Check that ofw_real is actually in use before allocating wads 1868446b206SNathan Whitehorn * of memory. Do this by checking if our mutex has been set up. 1878446b206SNathan Whitehorn */ 1888446b206SNathan Whitehorn if (!mtx_initialized(&of_bounce_mtx)) 1898446b206SNathan Whitehorn return; 1908446b206SNathan Whitehorn 1918446b206SNathan Whitehorn /* 1928446b206SNathan Whitehorn * Allocate a page of contiguous, wired physical memory that can 1938446b206SNathan Whitehorn * fit into a 32-bit address space. 1948446b206SNathan Whitehorn */ 1958446b206SNathan Whitehorn 1968446b206SNathan Whitehorn mtx_lock(&of_bounce_mtx); 1978446b206SNathan Whitehorn 1988446b206SNathan Whitehorn of_bounce_virt = contigmalloc(PAGE_SIZE, M_OFWREAL, 0, 1998446b206SNathan Whitehorn 0, BUS_SPACE_MAXADDR_32BIT, PAGE_SIZE, PAGE_SIZE); 2008446b206SNathan Whitehorn of_bounce_phys = vtophys(of_bounce_virt); 2018446b206SNathan Whitehorn of_bounce_size = PAGE_SIZE; 2028446b206SNathan Whitehorn 2038446b206SNathan Whitehorn mtx_unlock(&of_bounce_mtx); 2048446b206SNathan Whitehorn } 2058446b206SNathan Whitehorn 2068446b206SNathan Whitehorn static cell_t 2078446b206SNathan Whitehorn ofw_real_map(const void *buf, size_t len) 2088446b206SNathan Whitehorn { 2098446b206SNathan Whitehorn cell_t phys; 2108446b206SNathan Whitehorn 2118446b206SNathan Whitehorn mtx_assert(&of_bounce_mtx, MA_OWNED); 2128446b206SNathan Whitehorn 2138446b206SNathan Whitehorn if (of_bounce_virt == NULL) { 2148446b206SNathan Whitehorn if (!pmap_bootstrapped) 2158446b206SNathan Whitehorn return (cell_t)buf; 2168446b206SNathan Whitehorn 2178446b206SNathan Whitehorn /* 2188446b206SNathan Whitehorn * XXX: It is possible for us to get called before the VM has 2198446b206SNathan Whitehorn * come online, but after the MMU is up. We don't have the 2208446b206SNathan Whitehorn * bounce buffer yet, but can no longer presume a 1:1 mapping. 2218446b206SNathan Whitehorn * Grab the physical address of the buffer, and hope it is 2228446b206SNathan Whitehorn * in range if this happens. 2238446b206SNathan Whitehorn */ 2248446b206SNathan Whitehorn return (cell_t)vtophys(buf); 2258446b206SNathan Whitehorn } 2268446b206SNathan Whitehorn 2278446b206SNathan Whitehorn /* 2288446b206SNathan Whitehorn * Make sure the bounce page offset satisfies any reasonable 2298446b206SNathan Whitehorn * alignment constraint. 2308446b206SNathan Whitehorn */ 2318446b206SNathan Whitehorn of_bounce_offset += of_bounce_offset % sizeof(register_t); 2328446b206SNathan Whitehorn 2338446b206SNathan Whitehorn if (of_bounce_offset + len > of_bounce_size) { 2348446b206SNathan Whitehorn panic("Oversize Open Firmware call!"); 2358446b206SNathan Whitehorn return 0; 2368446b206SNathan Whitehorn } 2378446b206SNathan Whitehorn 2388446b206SNathan Whitehorn memcpy(of_bounce_virt + of_bounce_offset, buf, len); 2398446b206SNathan Whitehorn phys = of_bounce_phys + of_bounce_offset; 2408446b206SNathan Whitehorn 2418446b206SNathan Whitehorn of_bounce_offset += len; 2428446b206SNathan Whitehorn 2438446b206SNathan Whitehorn return phys; 2448446b206SNathan Whitehorn } 2458446b206SNathan Whitehorn 2468446b206SNathan Whitehorn static void 2478446b206SNathan Whitehorn ofw_real_unmap(cell_t physaddr, void *buf, size_t len) 2488446b206SNathan Whitehorn { 2498446b206SNathan Whitehorn mtx_assert(&of_bounce_mtx, MA_OWNED); 2508446b206SNathan Whitehorn 2518446b206SNathan Whitehorn if (of_bounce_virt == NULL) 2528446b206SNathan Whitehorn return; 2538446b206SNathan Whitehorn 2548446b206SNathan Whitehorn memcpy(buf,of_bounce_virt + (physaddr - of_bounce_phys),len); 2558446b206SNathan Whitehorn } 2568446b206SNathan Whitehorn 2578446b206SNathan Whitehorn /* Initialiser */ 2588446b206SNathan Whitehorn 2598446b206SNathan Whitehorn static void 2608446b206SNathan Whitehorn ofw_real_init(ofw_t ofw, void *openfirm) 2618446b206SNathan Whitehorn { 2628446b206SNathan Whitehorn openfirmware = (int (*)(void *))openfirm; 2638446b206SNathan Whitehorn 2648446b206SNathan Whitehorn mtx_init(&of_bounce_mtx, "OF Bounce Page", MTX_DEF, 0); 2658446b206SNathan Whitehorn of_bounce_virt = NULL; 2668446b206SNathan Whitehorn } 2678446b206SNathan Whitehorn 2688446b206SNathan Whitehorn /* 2698446b206SNathan Whitehorn * Generic functions 2708446b206SNathan Whitehorn */ 2718446b206SNathan Whitehorn 2728446b206SNathan Whitehorn /* Test to see if a service exists. */ 2738446b206SNathan Whitehorn static int 2748446b206SNathan Whitehorn ofw_real_test(ofw_t ofw, const char *name) 2758446b206SNathan Whitehorn { 2768446b206SNathan Whitehorn static struct { 2778446b206SNathan Whitehorn cell_t name; 2788446b206SNathan Whitehorn cell_t nargs; 2798446b206SNathan Whitehorn cell_t nreturns; 2808446b206SNathan Whitehorn cell_t service; 2818446b206SNathan Whitehorn cell_t missing; 2828446b206SNathan Whitehorn } args = { 2838446b206SNathan Whitehorn (cell_t)"test", 2848446b206SNathan Whitehorn 1, 2858446b206SNathan Whitehorn 1, 2868446b206SNathan Whitehorn }; 2878446b206SNathan Whitehorn 2888446b206SNathan Whitehorn ofw_real_start(); 2898446b206SNathan Whitehorn 2908446b206SNathan Whitehorn args.service = ofw_real_map(name, strlen(name) + 1); 2918446b206SNathan Whitehorn if (args.service == 0 || openfirmware(&args) == -1) { 2928446b206SNathan Whitehorn ofw_real_stop(); 2938446b206SNathan Whitehorn return (-1); 2948446b206SNathan Whitehorn } 2958446b206SNathan Whitehorn ofw_real_stop(); 2968446b206SNathan Whitehorn return (args.missing); 2978446b206SNathan Whitehorn } 2988446b206SNathan Whitehorn 2998446b206SNathan Whitehorn /* 3008446b206SNathan Whitehorn * Device tree functions 3018446b206SNathan Whitehorn */ 3028446b206SNathan Whitehorn 3038446b206SNathan Whitehorn /* Return the next sibling of this node or 0. */ 3048446b206SNathan Whitehorn static phandle_t 3058446b206SNathan Whitehorn ofw_real_peer(ofw_t ofw, phandle_t node) 3068446b206SNathan Whitehorn { 3078446b206SNathan Whitehorn static struct { 3088446b206SNathan Whitehorn cell_t name; 3098446b206SNathan Whitehorn cell_t nargs; 3108446b206SNathan Whitehorn cell_t nreturns; 3118446b206SNathan Whitehorn cell_t node; 3128446b206SNathan Whitehorn cell_t next; 3138446b206SNathan Whitehorn } args = { 3148446b206SNathan Whitehorn (cell_t)"peer", 3158446b206SNathan Whitehorn 1, 3168446b206SNathan Whitehorn 1, 3178446b206SNathan Whitehorn }; 3188446b206SNathan Whitehorn 3198446b206SNathan Whitehorn args.node = node; 3208446b206SNathan Whitehorn if (openfirmware(&args) == -1) 3218446b206SNathan Whitehorn return (-1); 3228446b206SNathan Whitehorn return (args.next); 3238446b206SNathan Whitehorn } 3248446b206SNathan Whitehorn 3258446b206SNathan Whitehorn /* Return the first child of this node or 0. */ 3268446b206SNathan Whitehorn static phandle_t 3278446b206SNathan Whitehorn ofw_real_child(ofw_t ofw, phandle_t node) 3288446b206SNathan Whitehorn { 3298446b206SNathan Whitehorn static struct { 3308446b206SNathan Whitehorn cell_t name; 3318446b206SNathan Whitehorn cell_t nargs; 3328446b206SNathan Whitehorn cell_t nreturns; 3338446b206SNathan Whitehorn cell_t node; 3348446b206SNathan Whitehorn cell_t child; 3358446b206SNathan Whitehorn } args = { 3368446b206SNathan Whitehorn (cell_t)"child", 3378446b206SNathan Whitehorn 1, 3388446b206SNathan Whitehorn 1, 3398446b206SNathan Whitehorn }; 3408446b206SNathan Whitehorn 3418446b206SNathan Whitehorn args.node = node; 3428446b206SNathan Whitehorn if (openfirmware(&args) == -1) 3438446b206SNathan Whitehorn return (-1); 3448446b206SNathan Whitehorn return (args.child); 3458446b206SNathan Whitehorn } 3468446b206SNathan Whitehorn 3478446b206SNathan Whitehorn /* Return the parent of this node or 0. */ 3488446b206SNathan Whitehorn static phandle_t 3498446b206SNathan Whitehorn ofw_real_parent(ofw_t ofw, phandle_t node) 3508446b206SNathan Whitehorn { 3518446b206SNathan Whitehorn static struct { 3528446b206SNathan Whitehorn cell_t name; 3538446b206SNathan Whitehorn cell_t nargs; 3548446b206SNathan Whitehorn cell_t nreturns; 3558446b206SNathan Whitehorn cell_t node; 3568446b206SNathan Whitehorn cell_t parent; 3578446b206SNathan Whitehorn } args = { 3588446b206SNathan Whitehorn (cell_t)"parent", 3598446b206SNathan Whitehorn 1, 3608446b206SNathan Whitehorn 1, 3618446b206SNathan Whitehorn }; 3628446b206SNathan Whitehorn 3638446b206SNathan Whitehorn args.node = node; 3648446b206SNathan Whitehorn if (openfirmware(&args) == -1) 3658446b206SNathan Whitehorn return (-1); 3668446b206SNathan Whitehorn return (args.parent); 3678446b206SNathan Whitehorn } 3688446b206SNathan Whitehorn 3698446b206SNathan Whitehorn /* Return the package handle that corresponds to an instance handle. */ 3708446b206SNathan Whitehorn static phandle_t 3718446b206SNathan Whitehorn ofw_real_instance_to_package(ofw_t ofw, ihandle_t instance) 3728446b206SNathan Whitehorn { 3738446b206SNathan Whitehorn static struct { 3748446b206SNathan Whitehorn cell_t name; 3758446b206SNathan Whitehorn cell_t nargs; 3768446b206SNathan Whitehorn cell_t nreturns; 3778446b206SNathan Whitehorn cell_t instance; 3788446b206SNathan Whitehorn cell_t package; 3798446b206SNathan Whitehorn } args = { 3808446b206SNathan Whitehorn (cell_t)"instance-to-package", 3818446b206SNathan Whitehorn 1, 3828446b206SNathan Whitehorn 1, 3838446b206SNathan Whitehorn }; 3848446b206SNathan Whitehorn 3858446b206SNathan Whitehorn args.instance = instance; 3868446b206SNathan Whitehorn if (openfirmware(&args) == -1) 3878446b206SNathan Whitehorn return (-1); 3888446b206SNathan Whitehorn return (args.package); 3898446b206SNathan Whitehorn } 3908446b206SNathan Whitehorn 3918446b206SNathan Whitehorn /* Get the length of a property of a package. */ 3928446b206SNathan Whitehorn static ssize_t 3938446b206SNathan Whitehorn ofw_real_getproplen(ofw_t ofw, phandle_t package, const char *propname) 3948446b206SNathan Whitehorn { 3958446b206SNathan Whitehorn static struct { 3968446b206SNathan Whitehorn cell_t name; 3978446b206SNathan Whitehorn cell_t nargs; 3988446b206SNathan Whitehorn cell_t nreturns; 3998446b206SNathan Whitehorn cell_t package; 4008446b206SNathan Whitehorn cell_t propname; 4018446b206SNathan Whitehorn cell_t proplen; 4028446b206SNathan Whitehorn } args = { 4038446b206SNathan Whitehorn (cell_t)"getproplen", 4048446b206SNathan Whitehorn 2, 4058446b206SNathan Whitehorn 1, 4068446b206SNathan Whitehorn }; 4078446b206SNathan Whitehorn 4088446b206SNathan Whitehorn ofw_real_start(); 4098446b206SNathan Whitehorn 4108446b206SNathan Whitehorn args.package = package; 4118446b206SNathan Whitehorn args.propname = ofw_real_map(propname, strlen(propname) + 1); 4128446b206SNathan Whitehorn if (args.propname == 0 || openfirmware(&args) == -1) { 4138446b206SNathan Whitehorn ofw_real_stop(); 4148446b206SNathan Whitehorn return (-1); 4158446b206SNathan Whitehorn } 4168446b206SNathan Whitehorn ofw_real_stop(); 4178446b206SNathan Whitehorn return (args.proplen); 4188446b206SNathan Whitehorn } 4198446b206SNathan Whitehorn 4208446b206SNathan Whitehorn /* Get the value of a property of a package. */ 4218446b206SNathan Whitehorn static ssize_t 4228446b206SNathan Whitehorn ofw_real_getprop(ofw_t ofw, phandle_t package, const char *propname, void *buf, 4238446b206SNathan Whitehorn size_t buflen) 4248446b206SNathan Whitehorn { 4258446b206SNathan Whitehorn static struct { 4268446b206SNathan Whitehorn cell_t name; 4278446b206SNathan Whitehorn cell_t nargs; 4288446b206SNathan Whitehorn cell_t nreturns; 4298446b206SNathan Whitehorn cell_t package; 4308446b206SNathan Whitehorn cell_t propname; 4318446b206SNathan Whitehorn cell_t buf; 4328446b206SNathan Whitehorn cell_t buflen; 4338446b206SNathan Whitehorn cell_t size; 4348446b206SNathan Whitehorn } args = { 4358446b206SNathan Whitehorn (cell_t)"getprop", 4368446b206SNathan Whitehorn 4, 4378446b206SNathan Whitehorn 1, 4388446b206SNathan Whitehorn }; 4398446b206SNathan Whitehorn 4408446b206SNathan Whitehorn ofw_real_start(); 4418446b206SNathan Whitehorn 4428446b206SNathan Whitehorn args.package = package; 4438446b206SNathan Whitehorn args.propname = ofw_real_map(propname, strlen(propname) + 1); 4448446b206SNathan Whitehorn args.buf = ofw_real_map(buf, buflen); 4458446b206SNathan Whitehorn args.buflen = buflen; 4468446b206SNathan Whitehorn if (args.propname == 0 || args.buf == 0 || openfirmware(&args) == -1) { 4478446b206SNathan Whitehorn ofw_real_stop(); 4488446b206SNathan Whitehorn return (-1); 4498446b206SNathan Whitehorn } 4508446b206SNathan Whitehorn ofw_real_unmap(args.buf, buf, buflen); 4518446b206SNathan Whitehorn 4528446b206SNathan Whitehorn ofw_real_stop(); 4538446b206SNathan Whitehorn return (args.size); 4548446b206SNathan Whitehorn } 4558446b206SNathan Whitehorn 4568446b206SNathan Whitehorn /* Get the next property of a package. */ 4578446b206SNathan Whitehorn static int 4588446b206SNathan Whitehorn ofw_real_nextprop(ofw_t ofw, phandle_t package, const char *previous, 4598446b206SNathan Whitehorn char *buf, size_t size) 4608446b206SNathan Whitehorn { 4618446b206SNathan Whitehorn static struct { 4628446b206SNathan Whitehorn cell_t name; 4638446b206SNathan Whitehorn cell_t nargs; 4648446b206SNathan Whitehorn cell_t nreturns; 4658446b206SNathan Whitehorn cell_t package; 4668446b206SNathan Whitehorn cell_t previous; 4678446b206SNathan Whitehorn cell_t buf; 4688446b206SNathan Whitehorn cell_t flag; 4698446b206SNathan Whitehorn } args = { 4708446b206SNathan Whitehorn (cell_t)"nextprop", 4718446b206SNathan Whitehorn 3, 4728446b206SNathan Whitehorn 1, 4738446b206SNathan Whitehorn }; 4748446b206SNathan Whitehorn 4758446b206SNathan Whitehorn ofw_real_start(); 4768446b206SNathan Whitehorn 4778446b206SNathan Whitehorn args.package = package; 4788446b206SNathan Whitehorn args.previous = ofw_real_map(previous, strlen(previous) + 1); 4798446b206SNathan Whitehorn args.buf = ofw_real_map(buf, size); 4808446b206SNathan Whitehorn if (args.previous == 0 || args.buf == 0 || openfirmware(&args) == -1) { 4818446b206SNathan Whitehorn ofw_real_stop(); 4828446b206SNathan Whitehorn return (-1); 4838446b206SNathan Whitehorn } 4848446b206SNathan Whitehorn ofw_real_unmap(args.buf, buf, size); 4858446b206SNathan Whitehorn 4868446b206SNathan Whitehorn ofw_real_stop(); 4878446b206SNathan Whitehorn return (args.flag); 4888446b206SNathan Whitehorn } 4898446b206SNathan Whitehorn 4908446b206SNathan Whitehorn /* Set the value of a property of a package. */ 4918446b206SNathan Whitehorn /* XXX Has a bug on FirePower */ 4928446b206SNathan Whitehorn static int 4934fc23012SAndriy Gapon ofw_real_setprop(ofw_t ofw, phandle_t package, const char *propname, 4944fc23012SAndriy Gapon const void *buf, size_t len) 4958446b206SNathan Whitehorn { 4968446b206SNathan Whitehorn static struct { 4978446b206SNathan Whitehorn cell_t name; 4988446b206SNathan Whitehorn cell_t nargs; 4998446b206SNathan Whitehorn cell_t nreturns; 5008446b206SNathan Whitehorn cell_t package; 5018446b206SNathan Whitehorn cell_t propname; 5028446b206SNathan Whitehorn cell_t buf; 5038446b206SNathan Whitehorn cell_t len; 5048446b206SNathan Whitehorn cell_t size; 5058446b206SNathan Whitehorn } args = { 5068446b206SNathan Whitehorn (cell_t)"setprop", 5078446b206SNathan Whitehorn 4, 5088446b206SNathan Whitehorn 1, 5098446b206SNathan Whitehorn }; 5108446b206SNathan Whitehorn 5118446b206SNathan Whitehorn ofw_real_start(); 5128446b206SNathan Whitehorn 5138446b206SNathan Whitehorn args.package = package; 5148446b206SNathan Whitehorn args.propname = ofw_real_map(propname, strlen(propname) + 1); 5158446b206SNathan Whitehorn args.buf = ofw_real_map(buf, len); 5168446b206SNathan Whitehorn args.len = len; 5178446b206SNathan Whitehorn if (args.propname == 0 || args.buf == 0 || openfirmware(&args) == -1) { 5188446b206SNathan Whitehorn ofw_real_stop(); 5198446b206SNathan Whitehorn return (-1); 5208446b206SNathan Whitehorn } 5218446b206SNathan Whitehorn ofw_real_stop(); 5228446b206SNathan Whitehorn return (args.size); 5238446b206SNathan Whitehorn } 5248446b206SNathan Whitehorn 5258446b206SNathan Whitehorn /* Convert a device specifier to a fully qualified pathname. */ 5268446b206SNathan Whitehorn static ssize_t 5278446b206SNathan Whitehorn ofw_real_canon(ofw_t ofw, const char *device, char *buf, size_t len) 5288446b206SNathan Whitehorn { 5298446b206SNathan Whitehorn static struct { 5308446b206SNathan Whitehorn cell_t name; 5318446b206SNathan Whitehorn cell_t nargs; 5328446b206SNathan Whitehorn cell_t nreturns; 5338446b206SNathan Whitehorn cell_t device; 5348446b206SNathan Whitehorn cell_t buf; 5358446b206SNathan Whitehorn cell_t len; 5368446b206SNathan Whitehorn cell_t size; 5378446b206SNathan Whitehorn } args = { 5388446b206SNathan Whitehorn (cell_t)"canon", 5398446b206SNathan Whitehorn 3, 5408446b206SNathan Whitehorn 1, 5418446b206SNathan Whitehorn }; 5428446b206SNathan Whitehorn 5438446b206SNathan Whitehorn ofw_real_start(); 5448446b206SNathan Whitehorn 5458446b206SNathan Whitehorn args.device = ofw_real_map(device, strlen(device) + 1); 5468446b206SNathan Whitehorn args.buf = ofw_real_map(buf, len); 5478446b206SNathan Whitehorn args.len = len; 5488446b206SNathan Whitehorn if (args.device == 0 || args.buf == 0 || openfirmware(&args) == -1) { 5498446b206SNathan Whitehorn ofw_real_stop(); 5508446b206SNathan Whitehorn return (-1); 5518446b206SNathan Whitehorn } 5528446b206SNathan Whitehorn ofw_real_unmap(args.buf, buf, len); 5538446b206SNathan Whitehorn 5548446b206SNathan Whitehorn ofw_real_stop(); 5558446b206SNathan Whitehorn return (args.size); 5568446b206SNathan Whitehorn } 5578446b206SNathan Whitehorn 5588446b206SNathan Whitehorn /* Return a package handle for the specified device. */ 5598446b206SNathan Whitehorn static phandle_t 5608446b206SNathan Whitehorn ofw_real_finddevice(ofw_t ofw, const char *device) 5618446b206SNathan Whitehorn { 5628446b206SNathan Whitehorn static struct { 5638446b206SNathan Whitehorn cell_t name; 5648446b206SNathan Whitehorn cell_t nargs; 5658446b206SNathan Whitehorn cell_t nreturns; 5668446b206SNathan Whitehorn cell_t device; 5678446b206SNathan Whitehorn cell_t package; 5688446b206SNathan Whitehorn } args = { 5698446b206SNathan Whitehorn (cell_t)"finddevice", 5708446b206SNathan Whitehorn 1, 5718446b206SNathan Whitehorn 1, 5728446b206SNathan Whitehorn }; 5738446b206SNathan Whitehorn 5748446b206SNathan Whitehorn ofw_real_start(); 5758446b206SNathan Whitehorn 5768446b206SNathan Whitehorn args.device = ofw_real_map(device, strlen(device) + 1); 5778446b206SNathan Whitehorn if (args.device == 0 || openfirmware(&args) == -1) { 5788446b206SNathan Whitehorn ofw_real_stop(); 5798446b206SNathan Whitehorn return (-1); 5808446b206SNathan Whitehorn } 5818446b206SNathan Whitehorn ofw_real_stop(); 5828446b206SNathan Whitehorn return (args.package); 5838446b206SNathan Whitehorn } 5848446b206SNathan Whitehorn 5858446b206SNathan Whitehorn /* Return the fully qualified pathname corresponding to an instance. */ 5868446b206SNathan Whitehorn static ssize_t 5878446b206SNathan Whitehorn ofw_real_instance_to_path(ofw_t ofw, ihandle_t instance, char *buf, size_t len) 5888446b206SNathan Whitehorn { 5898446b206SNathan Whitehorn static struct { 5908446b206SNathan Whitehorn cell_t name; 5918446b206SNathan Whitehorn cell_t nargs; 5928446b206SNathan Whitehorn cell_t nreturns; 5938446b206SNathan Whitehorn cell_t instance; 5948446b206SNathan Whitehorn cell_t buf; 5958446b206SNathan Whitehorn cell_t len; 5968446b206SNathan Whitehorn cell_t size; 5978446b206SNathan Whitehorn } args = { 5988446b206SNathan Whitehorn (cell_t)"instance-to-path", 5998446b206SNathan Whitehorn 3, 6008446b206SNathan Whitehorn 1, 6018446b206SNathan Whitehorn }; 6028446b206SNathan Whitehorn 6038446b206SNathan Whitehorn ofw_real_start(); 6048446b206SNathan Whitehorn 6058446b206SNathan Whitehorn args.instance = instance; 6068446b206SNathan Whitehorn args.buf = ofw_real_map(buf, len); 6078446b206SNathan Whitehorn args.len = len; 6088446b206SNathan Whitehorn if (args.buf == 0 || openfirmware(&args) == -1) { 6098446b206SNathan Whitehorn ofw_real_stop(); 6108446b206SNathan Whitehorn return (-1); 6118446b206SNathan Whitehorn } 6128446b206SNathan Whitehorn ofw_real_unmap(args.buf, buf, len); 6138446b206SNathan Whitehorn 6148446b206SNathan Whitehorn ofw_real_stop(); 6158446b206SNathan Whitehorn return (args.size); 6168446b206SNathan Whitehorn } 6178446b206SNathan Whitehorn 6188446b206SNathan Whitehorn /* Return the fully qualified pathname corresponding to a package. */ 6198446b206SNathan Whitehorn static ssize_t 6208446b206SNathan Whitehorn ofw_real_package_to_path(ofw_t ofw, phandle_t package, char *buf, size_t len) 6218446b206SNathan Whitehorn { 6228446b206SNathan Whitehorn static struct { 6238446b206SNathan Whitehorn cell_t name; 6248446b206SNathan Whitehorn cell_t nargs; 6258446b206SNathan Whitehorn cell_t nreturns; 6268446b206SNathan Whitehorn cell_t package; 6278446b206SNathan Whitehorn cell_t buf; 6288446b206SNathan Whitehorn cell_t len; 6298446b206SNathan Whitehorn cell_t size; 6308446b206SNathan Whitehorn } args = { 6318446b206SNathan Whitehorn (cell_t)"package-to-path", 6328446b206SNathan Whitehorn 3, 6338446b206SNathan Whitehorn 1, 6348446b206SNathan Whitehorn }; 6358446b206SNathan Whitehorn 6368446b206SNathan Whitehorn ofw_real_start(); 6378446b206SNathan Whitehorn 6388446b206SNathan Whitehorn args.package = package; 6398446b206SNathan Whitehorn args.buf = ofw_real_map(buf, len); 6408446b206SNathan Whitehorn args.len = len; 6418446b206SNathan Whitehorn if (args.buf == 0 || openfirmware(&args) == -1) { 6428446b206SNathan Whitehorn ofw_real_stop(); 6438446b206SNathan Whitehorn return (-1); 6448446b206SNathan Whitehorn } 6458446b206SNathan Whitehorn ofw_real_unmap(args.buf, buf, len); 6468446b206SNathan Whitehorn 6478446b206SNathan Whitehorn ofw_real_stop(); 6488446b206SNathan Whitehorn return (args.size); 6498446b206SNathan Whitehorn } 6508446b206SNathan Whitehorn 6518446b206SNathan Whitehorn /* Call the method in the scope of a given instance. */ 6528446b206SNathan Whitehorn static int 6538446b206SNathan Whitehorn ofw_real_call_method(ofw_t ofw, ihandle_t instance, const char *method, 6548446b206SNathan Whitehorn int nargs, int nreturns, unsigned long *args_and_returns) 6558446b206SNathan Whitehorn { 6568446b206SNathan Whitehorn static struct { 6578446b206SNathan Whitehorn cell_t name; 6588446b206SNathan Whitehorn cell_t nargs; 6598446b206SNathan Whitehorn cell_t nreturns; 6608446b206SNathan Whitehorn cell_t method; 6618446b206SNathan Whitehorn cell_t instance; 6628446b206SNathan Whitehorn cell_t args_n_results[12]; 6638446b206SNathan Whitehorn } args = { 6648446b206SNathan Whitehorn (cell_t)"call-method", 6658446b206SNathan Whitehorn 2, 6668446b206SNathan Whitehorn 1, 6678446b206SNathan Whitehorn }; 6688446b206SNathan Whitehorn cell_t *cp; 6698446b206SNathan Whitehorn unsigned long *ap; 6708446b206SNathan Whitehorn int n; 6718446b206SNathan Whitehorn 6728446b206SNathan Whitehorn if (nargs > 6) 6738446b206SNathan Whitehorn return (-1); 6748446b206SNathan Whitehorn 6758446b206SNathan Whitehorn ofw_real_start(); 6768446b206SNathan Whitehorn args.nargs = nargs + 2; 6778446b206SNathan Whitehorn args.nreturns = nreturns + 1; 6788446b206SNathan Whitehorn args.method = ofw_real_map(method, strlen(method) + 1); 6798446b206SNathan Whitehorn args.instance = instance; 6808446b206SNathan Whitehorn 6818446b206SNathan Whitehorn ap = args_and_returns; 6828446b206SNathan Whitehorn for (cp = args.args_n_results + (n = nargs); --n >= 0;) 6838446b206SNathan Whitehorn *--cp = *(ap++); 6848446b206SNathan Whitehorn if (args.method == 0 || openfirmware(&args) == -1) { 6858446b206SNathan Whitehorn ofw_real_stop(); 6868446b206SNathan Whitehorn return (-1); 6878446b206SNathan Whitehorn } 6888446b206SNathan Whitehorn ofw_real_stop(); 6898446b206SNathan Whitehorn if (args.args_n_results[nargs]) 6908446b206SNathan Whitehorn return (args.args_n_results[nargs]); 6918446b206SNathan Whitehorn for (cp = args.args_n_results + nargs + (n = args.nreturns); --n > 0;) 6928446b206SNathan Whitehorn *(ap++) = *--cp; 6938446b206SNathan Whitehorn return (0); 6948446b206SNathan Whitehorn } 6958446b206SNathan Whitehorn 6968446b206SNathan Whitehorn /* 6978446b206SNathan Whitehorn * Device I/O functions 6988446b206SNathan Whitehorn */ 6998446b206SNathan Whitehorn 7008446b206SNathan Whitehorn /* Open an instance for a device. */ 7018446b206SNathan Whitehorn static ihandle_t 7028446b206SNathan Whitehorn ofw_real_open(ofw_t ofw, const char *device) 7038446b206SNathan Whitehorn { 7048446b206SNathan Whitehorn static struct { 7058446b206SNathan Whitehorn cell_t name; 7068446b206SNathan Whitehorn cell_t nargs; 7078446b206SNathan Whitehorn cell_t nreturns; 7088446b206SNathan Whitehorn cell_t device; 7098446b206SNathan Whitehorn cell_t instance; 7108446b206SNathan Whitehorn } args = { 7118446b206SNathan Whitehorn (cell_t)"open", 7128446b206SNathan Whitehorn 1, 7138446b206SNathan Whitehorn 1, 7148446b206SNathan Whitehorn }; 7158446b206SNathan Whitehorn 7168446b206SNathan Whitehorn ofw_real_start(); 7178446b206SNathan Whitehorn 7188446b206SNathan Whitehorn args.device = ofw_real_map(device, strlen(device) + 1); 7198446b206SNathan Whitehorn if (args.device == 0 || openfirmware(&args) == -1 7208446b206SNathan Whitehorn || args.instance == 0) { 7218446b206SNathan Whitehorn ofw_real_stop(); 7228446b206SNathan Whitehorn return (-1); 7238446b206SNathan Whitehorn } 7248446b206SNathan Whitehorn ofw_real_stop(); 7258446b206SNathan Whitehorn return (args.instance); 7268446b206SNathan Whitehorn } 7278446b206SNathan Whitehorn 7288446b206SNathan Whitehorn /* Close an instance. */ 7298446b206SNathan Whitehorn static void 7308446b206SNathan Whitehorn ofw_real_close(ofw_t ofw, ihandle_t instance) 7318446b206SNathan Whitehorn { 7328446b206SNathan Whitehorn static struct { 7338446b206SNathan Whitehorn cell_t name; 7348446b206SNathan Whitehorn cell_t nargs; 7358446b206SNathan Whitehorn cell_t nreturns; 7368446b206SNathan Whitehorn cell_t instance; 7378446b206SNathan Whitehorn } args = { 7388446b206SNathan Whitehorn (cell_t)"close", 7398446b206SNathan Whitehorn 1, 7408446b206SNathan Whitehorn }; 7418446b206SNathan Whitehorn 7428446b206SNathan Whitehorn args.instance = instance; 7438446b206SNathan Whitehorn openfirmware(&args); 7448446b206SNathan Whitehorn } 7458446b206SNathan Whitehorn 7468446b206SNathan Whitehorn /* Read from an instance. */ 7478446b206SNathan Whitehorn static ssize_t 7488446b206SNathan Whitehorn ofw_real_read(ofw_t ofw, ihandle_t instance, void *addr, size_t len) 7498446b206SNathan Whitehorn { 7508446b206SNathan Whitehorn static struct { 7518446b206SNathan Whitehorn cell_t name; 7528446b206SNathan Whitehorn cell_t nargs; 7538446b206SNathan Whitehorn cell_t nreturns; 7548446b206SNathan Whitehorn cell_t instance; 7558446b206SNathan Whitehorn cell_t addr; 7568446b206SNathan Whitehorn cell_t len; 7578446b206SNathan Whitehorn cell_t actual; 7588446b206SNathan Whitehorn } args = { 7598446b206SNathan Whitehorn (cell_t)"read", 7608446b206SNathan Whitehorn 3, 7618446b206SNathan Whitehorn 1, 7628446b206SNathan Whitehorn }; 7638446b206SNathan Whitehorn 7648446b206SNathan Whitehorn ofw_real_start(); 7658446b206SNathan Whitehorn 7668446b206SNathan Whitehorn args.instance = instance; 7678446b206SNathan Whitehorn args.addr = ofw_real_map(addr, len); 7688446b206SNathan Whitehorn args.len = len; 7698446b206SNathan Whitehorn if (args.addr == 0 || openfirmware(&args) == -1) { 7708446b206SNathan Whitehorn ofw_real_stop(); 7718446b206SNathan Whitehorn return (-1); 7728446b206SNathan Whitehorn } 7738446b206SNathan Whitehorn ofw_real_unmap(args.addr, addr, len); 7748446b206SNathan Whitehorn 7758446b206SNathan Whitehorn ofw_real_stop(); 7768446b206SNathan Whitehorn return (args.actual); 7778446b206SNathan Whitehorn } 7788446b206SNathan Whitehorn 7798446b206SNathan Whitehorn /* Write to an instance. */ 7808446b206SNathan Whitehorn static ssize_t 7818446b206SNathan Whitehorn ofw_real_write(ofw_t ofw, ihandle_t instance, const void *addr, size_t len) 7828446b206SNathan Whitehorn { 7838446b206SNathan Whitehorn static struct { 7848446b206SNathan Whitehorn cell_t name; 7858446b206SNathan Whitehorn cell_t nargs; 7868446b206SNathan Whitehorn cell_t nreturns; 7878446b206SNathan Whitehorn cell_t instance; 7888446b206SNathan Whitehorn cell_t addr; 7898446b206SNathan Whitehorn cell_t len; 7908446b206SNathan Whitehorn cell_t actual; 7918446b206SNathan Whitehorn } args = { 7928446b206SNathan Whitehorn (cell_t)"write", 7938446b206SNathan Whitehorn 3, 7948446b206SNathan Whitehorn 1, 7958446b206SNathan Whitehorn }; 7968446b206SNathan Whitehorn 7978446b206SNathan Whitehorn ofw_real_start(); 7988446b206SNathan Whitehorn 7998446b206SNathan Whitehorn args.instance = instance; 8008446b206SNathan Whitehorn args.addr = ofw_real_map(addr, len); 8018446b206SNathan Whitehorn args.len = len; 8028446b206SNathan Whitehorn if (args.addr == 0 || openfirmware(&args) == -1) { 8038446b206SNathan Whitehorn ofw_real_stop(); 8048446b206SNathan Whitehorn return (-1); 8058446b206SNathan Whitehorn } 8068446b206SNathan Whitehorn ofw_real_stop(); 8078446b206SNathan Whitehorn return (args.actual); 8088446b206SNathan Whitehorn } 8098446b206SNathan Whitehorn 8108446b206SNathan Whitehorn /* Seek to a position. */ 8118446b206SNathan Whitehorn static int 8128446b206SNathan Whitehorn ofw_real_seek(ofw_t ofw, ihandle_t instance, u_int64_t pos) 8138446b206SNathan Whitehorn { 8148446b206SNathan Whitehorn static struct { 8158446b206SNathan Whitehorn cell_t name; 8168446b206SNathan Whitehorn cell_t nargs; 8178446b206SNathan Whitehorn cell_t nreturns; 8188446b206SNathan Whitehorn cell_t instance; 8198446b206SNathan Whitehorn cell_t poshi; 8208446b206SNathan Whitehorn cell_t poslo; 8218446b206SNathan Whitehorn cell_t status; 8228446b206SNathan Whitehorn } args = { 8238446b206SNathan Whitehorn (cell_t)"seek", 8248446b206SNathan Whitehorn 3, 8258446b206SNathan Whitehorn 1, 8268446b206SNathan Whitehorn }; 8278446b206SNathan Whitehorn 8288446b206SNathan Whitehorn args.instance = instance; 8298446b206SNathan Whitehorn args.poshi = pos >> 32; 8308446b206SNathan Whitehorn args.poslo = pos; 8318446b206SNathan Whitehorn if (openfirmware(&args) == -1) 8328446b206SNathan Whitehorn return (-1); 8338446b206SNathan Whitehorn return (args.status); 8348446b206SNathan Whitehorn } 8358446b206SNathan Whitehorn 8368446b206SNathan Whitehorn /* 8378446b206SNathan Whitehorn * Memory functions 8388446b206SNathan Whitehorn */ 8398446b206SNathan Whitehorn 8408446b206SNathan Whitehorn /* Claim an area of memory. */ 8418446b206SNathan Whitehorn static caddr_t 8428446b206SNathan Whitehorn ofw_real_claim(ofw_t ofw, void *virt, size_t size, u_int align) 8438446b206SNathan Whitehorn { 8448446b206SNathan Whitehorn static struct { 8458446b206SNathan Whitehorn cell_t name; 8468446b206SNathan Whitehorn cell_t nargs; 8478446b206SNathan Whitehorn cell_t nreturns; 8488446b206SNathan Whitehorn cell_t virt; 8498446b206SNathan Whitehorn cell_t size; 8508446b206SNathan Whitehorn cell_t align; 8518446b206SNathan Whitehorn cell_t baseaddr; 8528446b206SNathan Whitehorn } args = { 8538446b206SNathan Whitehorn (cell_t)"claim", 8548446b206SNathan Whitehorn 3, 8558446b206SNathan Whitehorn 1, 8568446b206SNathan Whitehorn }; 8578446b206SNathan Whitehorn 8588446b206SNathan Whitehorn args.virt = (cell_t)virt; 8598446b206SNathan Whitehorn args.size = size; 8608446b206SNathan Whitehorn args.align = align; 8618446b206SNathan Whitehorn if (openfirmware(&args) == -1) 8628446b206SNathan Whitehorn return ((void *)-1); 8638446b206SNathan Whitehorn return ((void *)args.baseaddr); 8648446b206SNathan Whitehorn } 8658446b206SNathan Whitehorn 8668446b206SNathan Whitehorn /* Release an area of memory. */ 8678446b206SNathan Whitehorn static void 8688446b206SNathan Whitehorn ofw_real_release(ofw_t ofw, void *virt, size_t size) 8698446b206SNathan Whitehorn { 8708446b206SNathan Whitehorn static struct { 8718446b206SNathan Whitehorn cell_t name; 8728446b206SNathan Whitehorn cell_t nargs; 8738446b206SNathan Whitehorn cell_t nreturns; 8748446b206SNathan Whitehorn cell_t virt; 8758446b206SNathan Whitehorn cell_t size; 8768446b206SNathan Whitehorn } args = { 8778446b206SNathan Whitehorn (cell_t)"release", 8788446b206SNathan Whitehorn 2, 8798446b206SNathan Whitehorn }; 8808446b206SNathan Whitehorn 8818446b206SNathan Whitehorn args.virt = (cell_t)virt; 8828446b206SNathan Whitehorn args.size = size; 8838446b206SNathan Whitehorn openfirmware(&args); 8848446b206SNathan Whitehorn } 8858446b206SNathan Whitehorn 8868446b206SNathan Whitehorn /* 8878446b206SNathan Whitehorn * Control transfer functions 8888446b206SNathan Whitehorn */ 8898446b206SNathan Whitehorn 8908446b206SNathan Whitehorn /* Suspend and drop back to the Open Firmware interface. */ 8918446b206SNathan Whitehorn static void 8928446b206SNathan Whitehorn ofw_real_enter(ofw_t ofw) 8938446b206SNathan Whitehorn { 8948446b206SNathan Whitehorn static struct { 8958446b206SNathan Whitehorn cell_t name; 8968446b206SNathan Whitehorn cell_t nargs; 8978446b206SNathan Whitehorn cell_t nreturns; 8988446b206SNathan Whitehorn } args = { 8998446b206SNathan Whitehorn (cell_t)"enter", 9008446b206SNathan Whitehorn }; 9018446b206SNathan Whitehorn 9028446b206SNathan Whitehorn openfirmware(&args); 9038446b206SNathan Whitehorn /* We may come back. */ 9048446b206SNathan Whitehorn } 9058446b206SNathan Whitehorn 9068446b206SNathan Whitehorn /* Shut down and drop back to the Open Firmware interface. */ 9078446b206SNathan Whitehorn static void 9088446b206SNathan Whitehorn ofw_real_exit(ofw_t ofw) 9098446b206SNathan Whitehorn { 9108446b206SNathan Whitehorn static struct { 9118446b206SNathan Whitehorn cell_t name; 9128446b206SNathan Whitehorn cell_t nargs; 9138446b206SNathan Whitehorn cell_t nreturns; 9148446b206SNathan Whitehorn } args = { 9158446b206SNathan Whitehorn (cell_t)"exit", 9168446b206SNathan Whitehorn }; 9178446b206SNathan Whitehorn 9188446b206SNathan Whitehorn openfirmware(&args); 9198446b206SNathan Whitehorn for (;;) /* just in case */ 9208446b206SNathan Whitehorn ; 9218446b206SNathan Whitehorn } 9228446b206SNathan Whitehorn 923