167204Sobrien/* $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai Exp $ */ 267204Sobrien 3139749Simp/*- 467204Sobrien * Copyright (C) 1995, 1996 Wolfgang Solfrank. 567204Sobrien * Copyright (C) 1995, 1996 TooLs GmbH. 667204Sobrien * All rights reserved. 767204Sobrien * 867204Sobrien * Redistribution and use in source and binary forms, with or without 967204Sobrien * modification, are permitted provided that the following conditions 1067204Sobrien * are met: 1167204Sobrien * 1. Redistributions of source code must retain the above copyright 1267204Sobrien * notice, this list of conditions and the following disclaimer. 1367204Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1467204Sobrien * notice, this list of conditions and the following disclaimer in the 1567204Sobrien * documentation and/or other materials provided with the distribution. 1667204Sobrien * 3. All advertising materials mentioning features or use of this software 1767204Sobrien * must display the following acknowledgement: 1867204Sobrien * This product includes software developed by TooLs GmbH. 1967204Sobrien * 4. The name of TooLs GmbH may not be used to endorse or promote products 2067204Sobrien * derived from this software without specific prior written permission. 2167204Sobrien * 2267204Sobrien * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 2367204Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2467204Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2567204Sobrien * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2667204Sobrien * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2767204Sobrien * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2867204Sobrien * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2967204Sobrien * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 3067204Sobrien * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 3167204Sobrien * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3267204Sobrien */ 33139749Simp/*- 3467204Sobrien * Copyright (C) 2000 Benno Rice. 3567204Sobrien * All rights reserved. 3667204Sobrien * 3767204Sobrien * Redistribution and use in source and binary forms, with or without 3867204Sobrien * modification, are permitted provided that the following conditions 3967204Sobrien * are met: 4067204Sobrien * 1. Redistributions of source code must retain the above copyright 4167204Sobrien * notice, this list of conditions and the following disclaimer. 4267204Sobrien * 2. Redistributions in binary form must reproduce the above copyright 4367204Sobrien * notice, this list of conditions and the following disclaimer in the 4467204Sobrien * documentation and/or other materials provided with the distribution. 4567204Sobrien * 4667204Sobrien * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 4767204Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 4867204Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 4967204Sobrien * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 5067204Sobrien * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 5167204Sobrien * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 5267204Sobrien * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 5367204Sobrien * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 5467204Sobrien * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 5567204Sobrien * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 5667204Sobrien */ 5767204Sobrien 58170838Smarius#include <sys/cdefs.h> 59170838Smarius__FBSDID("$FreeBSD$"); 60170838Smarius 6180697Sjake#include <sys/param.h> 6286557Stmm#include <sys/kernel.h> 6386557Stmm#include <sys/malloc.h> 6478346Sbenno#include <sys/systm.h> 6578346Sbenno 6667204Sobrien#include <machine/stdarg.h> 6767204Sobrien 68194138Smarius#include <dev/ofw/ofwvar.h> 6978346Sbenno#include <dev/ofw/openfirm.h> 70194138Smarius 71186347Snwhitehorn#include "ofw_if.h" 7268548Sbenno 73208614Srajstatic int ofw_std_init(ofw_t ofw, void *openfirm); 74186347Snwhitehornstatic int ofw_std_test(ofw_t ofw, const char *name); 75186347Snwhitehornstatic int ofw_std_interpret(ofw_t ofw, const char *cmd, int nreturns, 76212477Smarius cell_t *returns); 77186347Snwhitehornstatic phandle_t ofw_std_peer(ofw_t ofw, phandle_t node); 78186347Snwhitehornstatic phandle_t ofw_std_child(ofw_t ofw, phandle_t node); 79186347Snwhitehornstatic phandle_t ofw_std_parent(ofw_t ofw, phandle_t node); 80186347Snwhitehornstatic phandle_t ofw_std_instance_to_package(ofw_t ofw, ihandle_t instance); 81186347Snwhitehornstatic ssize_t ofw_std_getproplen(ofw_t ofw, phandle_t package, 82186347Snwhitehorn const char *propname); 83186347Snwhitehornstatic ssize_t ofw_std_getprop(ofw_t ofw, phandle_t package, 84186347Snwhitehorn const char *propname, void *buf, size_t buflen); 85186347Snwhitehornstatic int ofw_std_nextprop(ofw_t ofw, phandle_t package, const char *previous, 86186347Snwhitehorn char *buf, size_t); 87194025Savgstatic int ofw_std_setprop(ofw_t ofw, phandle_t package, const char *propname, 88194025Savg const void *buf, size_t len); 89186347Snwhitehornstatic ssize_t ofw_std_canon(ofw_t ofw, const char *device, char *buf, 90186347Snwhitehorn size_t len); 91186347Snwhitehornstatic phandle_t ofw_std_finddevice(ofw_t ofw, const char *device); 92186347Snwhitehornstatic ssize_t ofw_std_instance_to_path(ofw_t ofw, ihandle_t instance, 93186347Snwhitehorn char *buf, size_t len); 94186347Snwhitehornstatic ssize_t ofw_std_package_to_path(ofw_t ofw, phandle_t package, char *buf, 95186347Snwhitehorn size_t len); 96186347Snwhitehornstatic int ofw_std_call_method(ofw_t ofw, ihandle_t instance, 97212477Smarius const char *method, int nargs, int nreturns, cell_t *args_and_returns); 98186347Snwhitehornstatic ihandle_t ofw_std_open(ofw_t ofw, const char *device); 99186347Snwhitehornstatic void ofw_std_close(ofw_t ofw, ihandle_t instance); 100186347Snwhitehornstatic ssize_t ofw_std_read(ofw_t ofw, ihandle_t instance, void *addr, 101186347Snwhitehorn size_t len); 102186347Snwhitehornstatic ssize_t ofw_std_write(ofw_t ofw, ihandle_t instance, const void *addr, 103186347Snwhitehorn size_t len); 104194138Smariusstatic int ofw_std_seek(ofw_t ofw, ihandle_t instance, uint64_t pos); 105186347Snwhitehornstatic caddr_t ofw_std_claim(ofw_t ofw, void *virt, size_t size, u_int align); 106186347Snwhitehornstatic void ofw_std_release(ofw_t ofw, void *virt, size_t size); 107186347Snwhitehornstatic void ofw_std_enter(ofw_t ofw); 108186347Snwhitehornstatic void ofw_std_exit(ofw_t ofw); 10986557Stmm 110186347Snwhitehornstatic ofw_method_t ofw_std_methods[] = { 111186347Snwhitehorn OFWMETHOD(ofw_init, ofw_std_init), 112186347Snwhitehorn OFWMETHOD(ofw_peer, ofw_std_peer), 113186347Snwhitehorn OFWMETHOD(ofw_child, ofw_std_child), 114186347Snwhitehorn OFWMETHOD(ofw_parent, ofw_std_parent), 115186347Snwhitehorn OFWMETHOD(ofw_instance_to_package, ofw_std_instance_to_package), 116186347Snwhitehorn OFWMETHOD(ofw_getproplen, ofw_std_getproplen), 117186347Snwhitehorn OFWMETHOD(ofw_getprop, ofw_std_getprop), 118186347Snwhitehorn OFWMETHOD(ofw_nextprop, ofw_std_nextprop), 119186347Snwhitehorn OFWMETHOD(ofw_setprop, ofw_std_setprop), 120186347Snwhitehorn OFWMETHOD(ofw_canon, ofw_std_canon), 121186347Snwhitehorn OFWMETHOD(ofw_finddevice, ofw_std_finddevice), 122186347Snwhitehorn OFWMETHOD(ofw_instance_to_path, ofw_std_instance_to_path), 123186347Snwhitehorn OFWMETHOD(ofw_package_to_path, ofw_std_package_to_path), 12467204Sobrien 125186347Snwhitehorn OFWMETHOD(ofw_test, ofw_std_test), 126186347Snwhitehorn OFWMETHOD(ofw_call_method, ofw_std_call_method), 127186347Snwhitehorn OFWMETHOD(ofw_interpret, ofw_std_interpret), 128186347Snwhitehorn OFWMETHOD(ofw_open, ofw_std_open), 129186347Snwhitehorn OFWMETHOD(ofw_close, ofw_std_close), 130186347Snwhitehorn OFWMETHOD(ofw_read, ofw_std_read), 131186347Snwhitehorn OFWMETHOD(ofw_write, ofw_std_write), 132186347Snwhitehorn OFWMETHOD(ofw_seek, ofw_std_seek), 133186347Snwhitehorn OFWMETHOD(ofw_claim, ofw_std_claim), 134186347Snwhitehorn OFWMETHOD(ofw_release, ofw_std_release), 135186347Snwhitehorn OFWMETHOD(ofw_enter, ofw_std_enter), 136186347Snwhitehorn OFWMETHOD(ofw_exit, ofw_std_exit), 13767204Sobrien 138186347Snwhitehorn { 0, 0 } 139186347Snwhitehorn}; 14078346Sbenno 141186347Snwhitehornstatic ofw_def_t ofw_std = { 142186347Snwhitehorn OFW_STD_DIRECT, 143186347Snwhitehorn ofw_std_methods, 144186347Snwhitehorn 0 145186347Snwhitehorn}; 146186347SnwhitehornOFW_DEF(ofw_std); 14767204Sobrien 148186347Snwhitehornstatic int (*openfirmware)(void *); 149186347Snwhitehorn 150194138Smarius/* Initializer */ 151186347Snwhitehorn 152208614Srajstatic int 153186347Snwhitehornofw_std_init(ofw_t ofw, void *openfirm) 15478346Sbenno{ 155194138Smarius 156186347Snwhitehorn openfirmware = (int (*)(void *))openfirm; 157208614Sraj return (0); 15878346Sbenno} 15978346Sbenno 16067204Sobrien/* 16167204Sobrien * Generic functions 16267204Sobrien */ 16367204Sobrien 16467204Sobrien/* Test to see if a service exists. */ 165186347Snwhitehornstatic int 166186347Snwhitehornofw_std_test(ofw_t ofw, const char *name) 16767204Sobrien{ 168205496Snwhitehorn struct { 169170838Smarius cell_t name; 170170838Smarius cell_t nargs; 171170838Smarius cell_t nreturns; 172170838Smarius cell_t service; 173170838Smarius cell_t missing; 17467204Sobrien } args = { 17580697Sjake (cell_t)"test", 17667204Sobrien 1, 17767204Sobrien 1, 17867204Sobrien }; 17967204Sobrien 18080697Sjake args.service = (cell_t)name; 18167204Sobrien if (openfirmware(&args) == -1) 182170838Smarius return (-1); 183170838Smarius return (args.missing); 18467204Sobrien} 18567204Sobrien 186186347Snwhitehornstatic int 187212477Smariusofw_std_interpret(ofw_t ofw, const char *cmd, int nreturns, cell_t *returns) 188115973Sjake{ 189205496Snwhitehorn struct { 190115973Sjake cell_t name; 191115973Sjake cell_t nargs; 192115973Sjake cell_t nreturns; 193115973Sjake cell_t slot[16]; 194115973Sjake } args = { 195115973Sjake (cell_t)"interpret", 196170838Smarius 1, 197115973Sjake }; 198115973Sjake cell_t status; 199186347Snwhitehorn int i = 0, j = 0; 200115973Sjake 201115973Sjake args.nreturns = ++nreturns; 202115973Sjake args.slot[i++] = (cell_t)cmd; 203194138Smarius if (openfirmware(&args) == -1) 204115973Sjake return (-1); 205115973Sjake status = args.slot[i++]; 206115973Sjake while (i < 1 + nreturns) 207190522Smarius returns[j++] = args.slot[i++]; 208115973Sjake return (status); 209115973Sjake} 210115973Sjake 21167204Sobrien/* 21267204Sobrien * Device tree functions 21367204Sobrien */ 21467204Sobrien 21567204Sobrien/* Return the next sibling of this node or 0. */ 216186347Snwhitehornstatic phandle_t 217186347Snwhitehornofw_std_peer(ofw_t ofw, phandle_t node) 21867204Sobrien{ 219205496Snwhitehorn struct { 220170838Smarius cell_t name; 221170838Smarius cell_t nargs; 222170838Smarius cell_t nreturns; 223170838Smarius cell_t node; 224170838Smarius cell_t next; 22567204Sobrien } args = { 22680697Sjake (cell_t)"peer", 22767204Sobrien 1, 22867204Sobrien 1, 22967204Sobrien }; 23067204Sobrien 231170838Smarius args.node = node; 23267204Sobrien if (openfirmware(&args) == -1) 233170838Smarius return (-1); 234170838Smarius return (args.next); 23567204Sobrien} 23667204Sobrien 23767204Sobrien/* Return the first child of this node or 0. */ 238186347Snwhitehornstatic phandle_t 239186347Snwhitehornofw_std_child(ofw_t ofw, phandle_t node) 24067204Sobrien{ 241205496Snwhitehorn struct { 242170838Smarius cell_t name; 243170838Smarius cell_t nargs; 244170838Smarius cell_t nreturns; 245170838Smarius cell_t node; 246170838Smarius cell_t child; 24767204Sobrien } args = { 24880697Sjake (cell_t)"child", 24967204Sobrien 1, 25067204Sobrien 1, 25167204Sobrien }; 25267204Sobrien 253170838Smarius args.node = node; 25467204Sobrien if (openfirmware(&args) == -1) 255170838Smarius return (-1); 256170838Smarius return (args.child); 25767204Sobrien} 25867204Sobrien 25967204Sobrien/* Return the parent of this node or 0. */ 260186347Snwhitehornstatic phandle_t 261186347Snwhitehornofw_std_parent(ofw_t ofw, phandle_t node) 26267204Sobrien{ 263205496Snwhitehorn struct { 264170838Smarius cell_t name; 265170838Smarius cell_t nargs; 266170838Smarius cell_t nreturns; 267170838Smarius cell_t node; 268170838Smarius cell_t parent; 26967204Sobrien } args = { 27080697Sjake (cell_t)"parent", 27167204Sobrien 1, 27267204Sobrien 1, 27367204Sobrien }; 27467204Sobrien 275170838Smarius args.node = node; 27667204Sobrien if (openfirmware(&args) == -1) 277170838Smarius return (-1); 278170838Smarius return (args.parent); 27967204Sobrien} 28067204Sobrien 28167204Sobrien/* Return the package handle that corresponds to an instance handle. */ 282186347Snwhitehornstatic phandle_t 283186347Snwhitehornofw_std_instance_to_package(ofw_t ofw, ihandle_t instance) 28467204Sobrien{ 285205496Snwhitehorn struct { 286170838Smarius cell_t name; 287170838Smarius cell_t nargs; 288170838Smarius cell_t nreturns; 289170838Smarius cell_t instance; 290170838Smarius cell_t package; 29167204Sobrien } args = { 29280697Sjake (cell_t)"instance-to-package", 29367204Sobrien 1, 29467204Sobrien 1, 29567204Sobrien }; 296170838Smarius 297170838Smarius args.instance = instance; 29867204Sobrien if (openfirmware(&args) == -1) 299170838Smarius return (-1); 300170838Smarius return (args.package); 30167204Sobrien} 30267204Sobrien 30367204Sobrien/* Get the length of a property of a package. */ 304186347Snwhitehornstatic ssize_t 305186347Snwhitehornofw_std_getproplen(ofw_t ofw, phandle_t package, const char *propname) 30667204Sobrien{ 307205496Snwhitehorn struct { 308170838Smarius cell_t name; 309170838Smarius cell_t nargs; 310170838Smarius cell_t nreturns; 311170838Smarius cell_t package; 312170838Smarius cell_t propname; 313170838Smarius cell_t proplen; 31467204Sobrien } args = { 31580697Sjake (cell_t)"getproplen", 31667204Sobrien 2, 31767204Sobrien 1, 31867204Sobrien }; 31967204Sobrien 320170838Smarius args.package = package; 32180697Sjake args.propname = (cell_t)propname; 32267204Sobrien if (openfirmware(&args) == -1) 323170838Smarius return (-1); 324170838Smarius return (args.proplen); 32567204Sobrien} 32667204Sobrien 32767204Sobrien/* Get the value of a property of a package. */ 328186347Snwhitehornstatic ssize_t 329186347Snwhitehornofw_std_getprop(ofw_t ofw, phandle_t package, const char *propname, void *buf, 330186347Snwhitehorn size_t buflen) 33167204Sobrien{ 332205496Snwhitehorn struct { 333170838Smarius cell_t name; 334170838Smarius cell_t nargs; 335170838Smarius cell_t nreturns; 336170838Smarius cell_t package; 337170838Smarius cell_t propname; 338170838Smarius cell_t buf; 339170838Smarius cell_t buflen; 340170838Smarius cell_t size; 34167204Sobrien } args = { 34280697Sjake (cell_t)"getprop", 34367204Sobrien 4, 34467204Sobrien 1, 34567204Sobrien }; 346170838Smarius 347170838Smarius args.package = package; 34880697Sjake args.propname = (cell_t)propname; 34980697Sjake args.buf = (cell_t)buf; 350170838Smarius args.buflen = buflen; 35167204Sobrien if (openfirmware(&args) == -1) 352170838Smarius return (-1); 353170838Smarius return (args.size); 35467204Sobrien} 35567204Sobrien 35667204Sobrien/* Get the next property of a package. */ 357186347Snwhitehornstatic int 358186347Snwhitehornofw_std_nextprop(ofw_t ofw, phandle_t package, const char *previous, char *buf, 359186347Snwhitehorn size_t size) 36067204Sobrien{ 361205496Snwhitehorn struct { 362170838Smarius cell_t name; 363170838Smarius cell_t nargs; 364170838Smarius cell_t nreturns; 365170838Smarius cell_t package; 366170838Smarius cell_t previous; 367170838Smarius cell_t buf; 368170838Smarius cell_t flag; 36967204Sobrien } args = { 37080697Sjake (cell_t)"nextprop", 37167204Sobrien 3, 37267204Sobrien 1, 37367204Sobrien }; 37467204Sobrien 375170838Smarius args.package = package; 37680697Sjake args.previous = (cell_t)previous; 37780697Sjake args.buf = (cell_t)buf; 37867204Sobrien if (openfirmware(&args) == -1) 379170838Smarius return (-1); 380170838Smarius return (args.flag); 38167204Sobrien} 38267204Sobrien 38367204Sobrien/* Set the value of a property of a package. */ 38467204Sobrien/* XXX Has a bug on FirePower */ 385186347Snwhitehornstatic int 386194025Savgofw_std_setprop(ofw_t ofw, phandle_t package, const char *propname, 387194025Savg const void *buf, size_t len) 38867204Sobrien{ 389205496Snwhitehorn struct { 390170838Smarius cell_t name; 391170838Smarius cell_t nargs; 392170838Smarius cell_t nreturns; 393170838Smarius cell_t package; 394170838Smarius cell_t propname; 395170838Smarius cell_t buf; 396170838Smarius cell_t len; 397170838Smarius cell_t size; 39867204Sobrien } args = { 39980697Sjake (cell_t)"setprop", 40067204Sobrien 4, 40167204Sobrien 1, 40267204Sobrien }; 403170838Smarius 404170838Smarius args.package = package; 40580697Sjake args.propname = (cell_t)propname; 40680697Sjake args.buf = (cell_t)buf; 407170838Smarius args.len = len; 40867204Sobrien if (openfirmware(&args) == -1) 409170838Smarius return (-1); 410170838Smarius return (args.size); 41167204Sobrien} 41267204Sobrien 41367204Sobrien/* Convert a device specifier to a fully qualified pathname. */ 414186347Snwhitehornstatic ssize_t 415186347Snwhitehornofw_std_canon(ofw_t ofw, const char *device, char *buf, size_t len) 41667204Sobrien{ 417205496Snwhitehorn struct { 418170838Smarius cell_t name; 419170838Smarius cell_t nargs; 420170838Smarius cell_t nreturns; 421170838Smarius cell_t device; 422170838Smarius cell_t buf; 423170838Smarius cell_t len; 424170838Smarius cell_t size; 42567204Sobrien } args = { 42680697Sjake (cell_t)"canon", 42767204Sobrien 3, 42867204Sobrien 1, 42967204Sobrien }; 430170838Smarius 43180697Sjake args.device = (cell_t)device; 43280697Sjake args.buf = (cell_t)buf; 433170838Smarius args.len = len; 43467204Sobrien if (openfirmware(&args) == -1) 435170838Smarius return (-1); 436170838Smarius return (args.size); 43767204Sobrien} 43867204Sobrien 43967204Sobrien/* Return a package handle for the specified device. */ 440186347Snwhitehornstatic phandle_t 441186347Snwhitehornofw_std_finddevice(ofw_t ofw, const char *device) 44267204Sobrien{ 443205496Snwhitehorn struct { 444170838Smarius cell_t name; 445170838Smarius cell_t nargs; 446170838Smarius cell_t nreturns; 447170838Smarius cell_t device; 448170838Smarius cell_t package; 44967204Sobrien } args = { 45080697Sjake (cell_t)"finddevice", 45167204Sobrien 1, 45267204Sobrien 1, 453170838Smarius }; 454170838Smarius 45580697Sjake args.device = (cell_t)device; 45667204Sobrien if (openfirmware(&args) == -1) 457170838Smarius return (-1); 458170838Smarius return (args.package); 45967204Sobrien} 46067204Sobrien 46167204Sobrien/* Return the fully qualified pathname corresponding to an instance. */ 462186347Snwhitehornstatic ssize_t 463186347Snwhitehornofw_std_instance_to_path(ofw_t ofw, ihandle_t instance, char *buf, size_t len) 46467204Sobrien{ 465205496Snwhitehorn struct { 466170838Smarius cell_t name; 467170838Smarius cell_t nargs; 468170838Smarius cell_t nreturns; 469170838Smarius cell_t instance; 470170838Smarius cell_t buf; 471170838Smarius cell_t len; 472170838Smarius cell_t size; 47367204Sobrien } args = { 47480697Sjake (cell_t)"instance-to-path", 47567204Sobrien 3, 47667204Sobrien 1, 47767204Sobrien }; 47867204Sobrien 479170838Smarius args.instance = instance; 48080697Sjake args.buf = (cell_t)buf; 481170838Smarius args.len = len; 48267204Sobrien if (openfirmware(&args) == -1) 483170838Smarius return (-1); 484170838Smarius return (args.size); 48567204Sobrien} 48667204Sobrien 48767204Sobrien/* Return the fully qualified pathname corresponding to a package. */ 488186347Snwhitehornstatic ssize_t 489186347Snwhitehornofw_std_package_to_path(ofw_t ofw, phandle_t package, char *buf, size_t len) 49067204Sobrien{ 491205496Snwhitehorn struct { 492170838Smarius cell_t name; 493170838Smarius cell_t nargs; 494170838Smarius cell_t nreturns; 495170838Smarius cell_t package; 496170838Smarius cell_t buf; 497170838Smarius cell_t len; 498170838Smarius cell_t size; 49967204Sobrien } args = { 50080697Sjake (cell_t)"package-to-path", 50167204Sobrien 3, 50267204Sobrien 1, 50367204Sobrien }; 50467204Sobrien 505170838Smarius args.package = package; 50680697Sjake args.buf = (cell_t)buf; 507170838Smarius args.len = len; 50867204Sobrien if (openfirmware(&args) == -1) 509170838Smarius return (-1); 510170838Smarius return (args.size); 51167204Sobrien} 51267204Sobrien 51367204Sobrien/* Call the method in the scope of a given instance. */ 514186347Snwhitehornstatic int 515186347Snwhitehornofw_std_call_method(ofw_t ofw, ihandle_t instance, const char *method, 516209801Snwhitehorn int nargs, int nreturns, cell_t *args_and_returns) 51767204Sobrien{ 518205496Snwhitehorn struct { 519170838Smarius cell_t name; 520170838Smarius cell_t nargs; 521170838Smarius cell_t nreturns; 522170838Smarius cell_t method; 523170838Smarius cell_t instance; 524170838Smarius cell_t args_n_results[12]; 52567204Sobrien } args = { 52680697Sjake (cell_t)"call-method", 52767204Sobrien 2, 52867204Sobrien 1, 52967204Sobrien }; 530212477Smarius cell_t *ap, *cp; 53180697Sjake int n; 53267204Sobrien 53367204Sobrien if (nargs > 6) 534170838Smarius return (-1); 535170838Smarius args.nargs = nargs + 2; 536170838Smarius args.nreturns = nreturns + 1; 53780697Sjake args.method = (cell_t)method; 538170838Smarius args.instance = instance; 539186347Snwhitehorn 540186347Snwhitehorn ap = args_and_returns; 541170838Smarius for (cp = args.args_n_results + (n = nargs); --n >= 0;) 542186347Snwhitehorn *--cp = *(ap++); 54367204Sobrien if (openfirmware(&args) == -1) 544170838Smarius return (-1); 54567204Sobrien if (args.args_n_results[nargs]) 546170838Smarius return (args.args_n_results[nargs]); 547170838Smarius for (cp = args.args_n_results + nargs + (n = args.nreturns); --n > 0;) 548186347Snwhitehorn *(ap++) = *--cp; 549170838Smarius return (0); 55067204Sobrien} 55167204Sobrien 55267204Sobrien/* 553170838Smarius * Device I/O functions 55467204Sobrien */ 55567204Sobrien 55667204Sobrien/* Open an instance for a device. */ 557186347Snwhitehornstatic ihandle_t 558186347Snwhitehornofw_std_open(ofw_t ofw, const char *device) 55967204Sobrien{ 560205496Snwhitehorn struct { 561170838Smarius cell_t name; 562170838Smarius cell_t nargs; 563170838Smarius cell_t nreturns; 564170838Smarius cell_t device; 565170838Smarius cell_t instance; 56667204Sobrien } args = { 56780697Sjake (cell_t)"open", 56867204Sobrien 1, 56967204Sobrien 1, 57067204Sobrien }; 571170838Smarius 57280697Sjake args.device = (cell_t)device; 573194138Smarius if (openfirmware(&args) == -1 || args.instance == 0) 574170838Smarius return (-1); 575170838Smarius return (args.instance); 57667204Sobrien} 57767204Sobrien 57867204Sobrien/* Close an instance. */ 579186347Snwhitehornstatic void 580186347Snwhitehornofw_std_close(ofw_t ofw, ihandle_t instance) 58167204Sobrien{ 582205496Snwhitehorn struct { 583170838Smarius cell_t name; 584170838Smarius cell_t nargs; 585170838Smarius cell_t nreturns; 586170838Smarius cell_t instance; 58767204Sobrien } args = { 58880697Sjake (cell_t)"close", 58967204Sobrien 1, 590206116Smarius 0, 59167204Sobrien }; 592170838Smarius 593170838Smarius args.instance = instance; 59467204Sobrien openfirmware(&args); 59567204Sobrien} 59667204Sobrien 59767204Sobrien/* Read from an instance. */ 598186347Snwhitehornstatic ssize_t 599186347Snwhitehornofw_std_read(ofw_t ofw, ihandle_t instance, void *addr, size_t len) 60067204Sobrien{ 601205496Snwhitehorn struct { 602170838Smarius cell_t name; 603170838Smarius cell_t nargs; 604170838Smarius cell_t nreturns; 605170838Smarius cell_t instance; 606170838Smarius cell_t addr; 607170838Smarius cell_t len; 608170838Smarius cell_t actual; 60967204Sobrien } args = { 61080697Sjake (cell_t)"read", 61167204Sobrien 3, 61267204Sobrien 1, 61367204Sobrien }; 61467204Sobrien 615170838Smarius args.instance = instance; 61680697Sjake args.addr = (cell_t)addr; 617170838Smarius args.len = len; 61867204Sobrien if (openfirmware(&args) == -1) 619170838Smarius return (-1); 62068548Sbenno 621170838Smarius return (args.actual); 62267204Sobrien} 62367204Sobrien 62467204Sobrien/* Write to an instance. */ 625186347Snwhitehornstatic ssize_t 626186347Snwhitehornofw_std_write(ofw_t ofw, ihandle_t instance, const void *addr, size_t len) 62767204Sobrien{ 628205496Snwhitehorn struct { 629170838Smarius cell_t name; 630170838Smarius cell_t nargs; 631170838Smarius cell_t nreturns; 632170838Smarius cell_t instance; 633170838Smarius cell_t addr; 634170838Smarius cell_t len; 635170838Smarius cell_t actual; 63667204Sobrien } args = { 63780697Sjake (cell_t)"write", 63867204Sobrien 3, 63967204Sobrien 1, 64067204Sobrien }; 64167204Sobrien 642170838Smarius args.instance = instance; 64380697Sjake args.addr = (cell_t)addr; 644170838Smarius args.len = len; 64567204Sobrien if (openfirmware(&args) == -1) 646170838Smarius return (-1); 647170838Smarius return (args.actual); 64867204Sobrien} 64967204Sobrien 65067204Sobrien/* Seek to a position. */ 651186347Snwhitehornstatic int 652194138Smariusofw_std_seek(ofw_t ofw, ihandle_t instance, uint64_t pos) 65367204Sobrien{ 654205496Snwhitehorn struct { 655170838Smarius cell_t name; 656170838Smarius cell_t nargs; 657170838Smarius cell_t nreturns; 658170838Smarius cell_t instance; 659170838Smarius cell_t poshi; 660170838Smarius cell_t poslo; 661170838Smarius cell_t status; 66267204Sobrien } args = { 66380697Sjake (cell_t)"seek", 66467204Sobrien 3, 66567204Sobrien 1, 66667204Sobrien }; 667170838Smarius 668170838Smarius args.instance = instance; 669170838Smarius args.poshi = pos >> 32; 670170838Smarius args.poslo = pos; 67167204Sobrien if (openfirmware(&args) == -1) 672170838Smarius return (-1); 673170838Smarius return (args.status); 67467204Sobrien} 67567204Sobrien 67667204Sobrien/* 677170838Smarius * Memory functions 67867204Sobrien */ 67967204Sobrien 68067204Sobrien/* Claim an area of memory. */ 681186347Snwhitehornstatic caddr_t 682186347Snwhitehornofw_std_claim(ofw_t ofw, void *virt, size_t size, u_int align) 68367204Sobrien{ 684205496Snwhitehorn struct { 685170838Smarius cell_t name; 686170838Smarius cell_t nargs; 687170838Smarius cell_t nreturns; 688170838Smarius cell_t virt; 689170838Smarius cell_t size; 690170838Smarius cell_t align; 691170838Smarius cell_t baseaddr; 69267204Sobrien } args = { 69380697Sjake (cell_t)"claim", 69467204Sobrien 3, 69567204Sobrien 1, 69667204Sobrien }; 69767204Sobrien 69880697Sjake args.virt = (cell_t)virt; 699170838Smarius args.size = size; 700170838Smarius args.align = align; 70167204Sobrien if (openfirmware(&args) == -1) 702170838Smarius return ((void *)-1); 703170838Smarius return ((void *)args.baseaddr); 70467204Sobrien} 70567204Sobrien 70667204Sobrien/* Release an area of memory. */ 707186347Snwhitehornstatic void 708186347Snwhitehornofw_std_release(ofw_t ofw, void *virt, size_t size) 70967204Sobrien{ 710205496Snwhitehorn struct { 711170838Smarius cell_t name; 712170838Smarius cell_t nargs; 713170838Smarius cell_t nreturns; 714170838Smarius cell_t virt; 715170838Smarius cell_t size; 71667204Sobrien } args = { 71780697Sjake (cell_t)"release", 71867204Sobrien 2, 719206116Smarius 0, 72067204Sobrien }; 721170838Smarius 72280697Sjake args.virt = (cell_t)virt; 723170838Smarius args.size = size; 72467204Sobrien openfirmware(&args); 72567204Sobrien} 72667204Sobrien 72767204Sobrien/* 728170838Smarius * Control transfer functions 72967204Sobrien */ 73067204Sobrien 731133862Smarius/* Suspend and drop back to the Open Firmware interface. */ 732186347Snwhitehornstatic void 733186347Snwhitehornofw_std_enter(ofw_t ofw) 73467204Sobrien{ 735205496Snwhitehorn struct { 73680697Sjake cell_t name; 73780697Sjake cell_t nargs; 73880697Sjake cell_t nreturns; 73967204Sobrien } args = { 74080697Sjake (cell_t)"enter", 741206116Smarius 0, 742206116Smarius 0, 74367204Sobrien }; 74467204Sobrien 74567204Sobrien openfirmware(&args); 746170838Smarius /* We may come back. */ 74767204Sobrien} 74867204Sobrien 749133862Smarius/* Shut down and drop back to the Open Firmware interface. */ 750186347Snwhitehornstatic void 751186347Snwhitehornofw_std_exit(ofw_t ofw) 75267204Sobrien{ 753205496Snwhitehorn struct { 75480697Sjake cell_t name; 75580697Sjake cell_t nargs; 75680697Sjake cell_t nreturns; 75767204Sobrien } args = { 75880697Sjake (cell_t)"exit", 759206116Smarius 0, 760206116Smarius 0, 76167204Sobrien }; 76267204Sobrien 76367204Sobrien openfirmware(&args); 764170838Smarius for (;;) /* just in case */ 765170838Smarius ; 76667204Sobrien} 767