167204Sobrien/* $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai Exp $ */ 267204Sobrien 3139738Simp/*- 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 */ 33139738Simp/*- 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 58124140Sobrien#include <sys/cdefs.h> 59124140Sobrien__FBSDID("$FreeBSD: releng/10.3/sys/boot/ofw/libofw/openfirm.c 215577 2010-11-20 19:23:16Z andreast $"); 60124140Sobrien 6167204Sobrien#include <machine/stdarg.h> 6267204Sobrien 6368548Sbenno#include <stand.h> 6468548Sbenno 6567204Sobrien#include "openfirm.h" 6667204Sobrien 6785717Sjakeint (*openfirmware)(void *); 6885717Sjake 69170854Smariusphandle_t chosen; 70100318Sbennoihandle_t mmu; 71100318Sbennoihandle_t memory; 72215438Sandreastint real_mode = 0; 7384617Sbenno 74170838Smarius/* Initialiser */ 7567204Sobrien 7667204Sobrienvoid 7767204SobrienOF_init(int (*openfirm)(void *)) 7867204Sobrien{ 79215438Sandreast phandle_t options; 80215577Sandreast char mode[sizeof("true")]; 8184617Sbenno 8267204Sobrien openfirmware = openfirm; 8384617Sbenno 84170838Smarius if ((chosen = OF_finddevice("/chosen")) == -1) 85170838Smarius OF_exit(); 86214493Snwhitehorn if (OF_getprop(chosen, "memory", &memory, sizeof(memory)) == -1) { 87214493Snwhitehorn memory = OF_open("/memory"); 88214493Snwhitehorn if (memory == -1) 89214493Snwhitehorn memory = OF_open("/memory@0"); 90214493Snwhitehorn if (memory == -1) 91214493Snwhitehorn OF_exit(); 92214493Snwhitehorn } 93170854Smarius if (OF_getprop(chosen, "mmu", &mmu, sizeof(mmu)) == -1) 94170854Smarius OF_exit(); 95215438Sandreast 96215577Sandreast /* 97215438Sandreast * Check if we run in real mode. If so, we do not need to map 98215438Sandreast * memory later on. 99215438Sandreast */ 100215438Sandreast options = OF_finddevice("/options"); 101215577Sandreast if (OF_getprop(options, "real-mode?", mode, sizeof(mode)) > 0 && 102215577Sandreast strcmp(mode, "true") == 0) 103215438Sandreast real_mode = 1; 104163145Skmacy} 105163145Skmacy 10667204Sobrien/* 10767204Sobrien * Generic functions 10867204Sobrien */ 10967204Sobrien 11067204Sobrien/* Test to see if a service exists. */ 11167204Sobrienint 11267204SobrienOF_test(char *name) 11367204Sobrien{ 11467204Sobrien static struct { 115170838Smarius cell_t name; 116170838Smarius cell_t nargs; 117170838Smarius cell_t nreturns; 118170838Smarius cell_t service; 119170838Smarius cell_t missing; 12067204Sobrien } args = { 12184972Srobert (cell_t)"test", 12267204Sobrien 1, 12367204Sobrien 1, 12467204Sobrien }; 12567204Sobrien 12684972Srobert args.service = (cell_t)name; 12767204Sobrien if (openfirmware(&args) == -1) 128170838Smarius return (-1); 129170838Smarius return (args.missing); 13067204Sobrien} 13167204Sobrien 13267204Sobrien/* Return firmware millisecond count. */ 13367204Sobrienint 13467204SobrienOF_milliseconds() 13567204Sobrien{ 13667204Sobrien static struct { 137170838Smarius cell_t name; 138170838Smarius cell_t nargs; 139170838Smarius cell_t nreturns; 140170838Smarius cell_t ms; 14167204Sobrien } args = { 14284972Srobert (cell_t)"milliseconds", 14367204Sobrien 0, 14467204Sobrien 1, 14567204Sobrien }; 146170838Smarius 14767204Sobrien openfirmware(&args); 148170838Smarius return (args.ms); 14967204Sobrien} 15067204Sobrien 15167204Sobrien/* 15267204Sobrien * Device tree functions 15367204Sobrien */ 15467204Sobrien 15567204Sobrien/* Return the next sibling of this node or 0. */ 15667204Sobrienphandle_t 15767204SobrienOF_peer(phandle_t node) 15867204Sobrien{ 15967204Sobrien static struct { 160170838Smarius cell_t name; 161170838Smarius cell_t nargs; 162170838Smarius cell_t nreturns; 163170838Smarius cell_t node; 164170838Smarius cell_t next; 16567204Sobrien } args = { 16684972Srobert (cell_t)"peer", 16767204Sobrien 1, 16867204Sobrien 1, 16967204Sobrien }; 17067204Sobrien 171170838Smarius args.node = node; 17267204Sobrien if (openfirmware(&args) == -1) 173170838Smarius return (-1); 174170838Smarius return (args.next); 17567204Sobrien} 17667204Sobrien 17767204Sobrien/* Return the first child of this node or 0. */ 17867204Sobrienphandle_t 17967204SobrienOF_child(phandle_t node) 18067204Sobrien{ 18167204Sobrien static struct { 182170838Smarius cell_t name; 183170838Smarius cell_t nargs; 184170838Smarius cell_t nreturns; 185170838Smarius cell_t node; 186170838Smarius cell_t child; 18767204Sobrien } args = { 18884972Srobert (cell_t)"child", 18967204Sobrien 1, 19067204Sobrien 1, 19167204Sobrien }; 19267204Sobrien 193170838Smarius args.node = node; 19467204Sobrien if (openfirmware(&args) == -1) 195170838Smarius return (-1); 196170838Smarius return (args.child); 19767204Sobrien} 19867204Sobrien 19967204Sobrien/* Return the parent of this node or 0. */ 20067204Sobrienphandle_t 20167204SobrienOF_parent(phandle_t node) 20267204Sobrien{ 20367204Sobrien static struct { 204170838Smarius cell_t name; 205170838Smarius cell_t nargs; 206170838Smarius cell_t nreturns; 207170838Smarius cell_t node; 208170838Smarius cell_t parent; 20967204Sobrien } args = { 21084972Srobert (cell_t)"parent", 21167204Sobrien 1, 21267204Sobrien 1, 21367204Sobrien }; 21467204Sobrien 215170838Smarius args.node = node; 21667204Sobrien if (openfirmware(&args) == -1) 217170838Smarius return (-1); 218170838Smarius return (args.parent); 21967204Sobrien} 22067204Sobrien 22167204Sobrien/* Return the package handle that corresponds to an instance handle. */ 22267204Sobrienphandle_t 22367204SobrienOF_instance_to_package(ihandle_t instance) 22467204Sobrien{ 22567204Sobrien static struct { 226170838Smarius cell_t name; 227170838Smarius cell_t nargs; 228170838Smarius cell_t nreturns; 229170838Smarius cell_t instance; 230170838Smarius cell_t package; 23167204Sobrien } args = { 23284972Srobert (cell_t)"instance-to-package", 23367204Sobrien 1, 23467204Sobrien 1, 23567204Sobrien }; 236170838Smarius 237170838Smarius args.instance = instance; 23867204Sobrien if (openfirmware(&args) == -1) 239170838Smarius return (-1); 240170838Smarius return (args.package); 24167204Sobrien} 24267204Sobrien 24367204Sobrien/* Get the length of a property of a package. */ 24467204Sobrienint 24567204SobrienOF_getproplen(phandle_t package, char *propname) 24667204Sobrien{ 24767204Sobrien static struct { 248170838Smarius cell_t name; 249170838Smarius cell_t nargs; 250170838Smarius cell_t nreturns; 251170838Smarius cell_t package; 252170838Smarius cell_t propname; 253170838Smarius cell_t proplen; 25467204Sobrien } args = { 25584972Srobert (cell_t)"getproplen", 25667204Sobrien 2, 25767204Sobrien 1, 25867204Sobrien }; 25967204Sobrien 260170838Smarius args.package = package; 26184972Srobert args.propname = (cell_t)propname; 26267204Sobrien if (openfirmware(&args) == -1) 263170838Smarius return (-1); 264170838Smarius return (args.proplen); 26567204Sobrien} 26667204Sobrien 26767204Sobrien/* Get the value of a property of a package. */ 26867204Sobrienint 26967204SobrienOF_getprop(phandle_t package, char *propname, void *buf, int buflen) 27067204Sobrien{ 27167204Sobrien static struct { 272170838Smarius cell_t name; 273170838Smarius cell_t nargs; 274170838Smarius cell_t nreturns; 275170838Smarius cell_t package; 276170838Smarius cell_t propname; 277170838Smarius cell_t buf; 278170838Smarius cell_t buflen; 279170838Smarius cell_t size; 28067204Sobrien } args = { 28184972Srobert (cell_t)"getprop", 28267204Sobrien 4, 28367204Sobrien 1, 28467204Sobrien }; 285170838Smarius 286170838Smarius args.package = package; 28784972Srobert args.propname = (cell_t)propname; 28884972Srobert args.buf = (cell_t)buf; 289170838Smarius args.buflen = buflen; 29067204Sobrien if (openfirmware(&args) == -1) 291170838Smarius return (-1); 292170838Smarius return (args.size); 29367204Sobrien} 29467204Sobrien 29567204Sobrien/* Get the next property of a package. */ 29667204Sobrienint 29767204SobrienOF_nextprop(phandle_t package, char *previous, char *buf) 29867204Sobrien{ 29967204Sobrien static struct { 300170838Smarius cell_t name; 301170838Smarius cell_t nargs; 302170838Smarius cell_t nreturns; 303170838Smarius cell_t package; 304170838Smarius cell_t previous; 305170838Smarius cell_t buf; 306170838Smarius cell_t flag; 30767204Sobrien } args = { 30884972Srobert (cell_t)"nextprop", 30967204Sobrien 3, 31067204Sobrien 1, 31167204Sobrien }; 31267204Sobrien 313170838Smarius args.package = package; 31484972Srobert args.previous = (cell_t)previous; 31584972Srobert args.buf = (cell_t)buf; 31667204Sobrien if (openfirmware(&args) == -1) 317170838Smarius return (-1); 318170838Smarius return (args.flag); 31967204Sobrien} 32067204Sobrien 32167204Sobrien/* Set the value of a property of a package. */ 32267204Sobrien/* XXX Has a bug on FirePower */ 32367204Sobrienint 32467204SobrienOF_setprop(phandle_t package, char *propname, void *buf, int len) 32567204Sobrien{ 32667204Sobrien static struct { 327170838Smarius cell_t name; 328170838Smarius cell_t nargs; 329170838Smarius cell_t nreturns; 330170838Smarius cell_t package; 331170838Smarius cell_t propname; 332170838Smarius cell_t buf; 333170838Smarius cell_t len; 334170838Smarius cell_t size; 33567204Sobrien } args = { 33684972Srobert (cell_t)"setprop", 33767204Sobrien 4, 33867204Sobrien 1, 33967204Sobrien }; 340170838Smarius 341170838Smarius args.package = package; 34284972Srobert args.propname = (cell_t)propname; 34384972Srobert args.buf = (cell_t)buf; 344170838Smarius args.len = len; 34567204Sobrien if (openfirmware(&args) == -1) 346170838Smarius return (-1); 347170838Smarius return (args.size); 34867204Sobrien} 34967204Sobrien 35067204Sobrien/* Convert a device specifier to a fully qualified pathname. */ 35167204Sobrienint 35268548SbennoOF_canon(const char *device, char *buf, int len) 35367204Sobrien{ 35467204Sobrien static struct { 355170838Smarius cell_t name; 356170838Smarius cell_t nargs; 357170838Smarius cell_t nreturns; 358170838Smarius cell_t device; 359170838Smarius cell_t buf; 360170838Smarius cell_t len; 361170838Smarius cell_t size; 36267204Sobrien } args = { 36384972Srobert (cell_t)"canon", 36467204Sobrien 3, 36567204Sobrien 1, 36667204Sobrien }; 367170838Smarius 36884972Srobert args.device = (cell_t)device; 36984972Srobert args.buf = (cell_t)buf; 370170838Smarius args.len = len; 37167204Sobrien if (openfirmware(&args) == -1) 372170838Smarius return (-1); 373170838Smarius return (args.size); 37467204Sobrien} 37567204Sobrien 37667204Sobrien/* Return a package handle for the specified device. */ 37767204Sobrienphandle_t 37868548SbennoOF_finddevice(const char *device) 37967204Sobrien{ 38067204Sobrien static struct { 381170838Smarius cell_t name; 382170838Smarius cell_t nargs; 383170838Smarius cell_t nreturns; 384170838Smarius cell_t device; 385170838Smarius cell_t package; 38667204Sobrien } args = { 38784972Srobert (cell_t)"finddevice", 38867204Sobrien 1, 38967204Sobrien 1, 390170838Smarius }; 391170838Smarius 39284972Srobert args.device = (cell_t)device; 39367204Sobrien if (openfirmware(&args) == -1) 394170838Smarius return (-1); 395170838Smarius return (args.package); 39667204Sobrien} 39767204Sobrien 39867204Sobrien/* Return the fully qualified pathname corresponding to an instance. */ 39967204Sobrienint 40067204SobrienOF_instance_to_path(ihandle_t instance, char *buf, int len) 40167204Sobrien{ 40267204Sobrien static struct { 403170838Smarius cell_t name; 404170838Smarius cell_t nargs; 405170838Smarius cell_t nreturns; 406170838Smarius cell_t instance; 407170838Smarius cell_t buf; 408170838Smarius cell_t len; 409170838Smarius cell_t size; 41067204Sobrien } args = { 41184972Srobert (cell_t)"instance-to-path", 41267204Sobrien 3, 41367204Sobrien 1, 41467204Sobrien }; 41567204Sobrien 416170838Smarius args.instance = instance; 41784972Srobert args.buf = (cell_t)buf; 418170838Smarius args.len = len; 41967204Sobrien if (openfirmware(&args) == -1) 420170838Smarius return (-1); 421170838Smarius return (args.size); 42267204Sobrien} 42367204Sobrien 42467204Sobrien/* Return the fully qualified pathname corresponding to a package. */ 42567204Sobrienint 42667204SobrienOF_package_to_path(phandle_t package, char *buf, int len) 42767204Sobrien{ 42867204Sobrien static struct { 429170838Smarius cell_t name; 430170838Smarius cell_t nargs; 431170838Smarius cell_t nreturns; 432170838Smarius cell_t package; 433170838Smarius cell_t buf; 434170838Smarius cell_t len; 435170838Smarius cell_t size; 43667204Sobrien } args = { 43784972Srobert (cell_t)"package-to-path", 43867204Sobrien 3, 43967204Sobrien 1, 44067204Sobrien }; 44167204Sobrien 442170838Smarius args.package = package; 44384972Srobert args.buf = (cell_t)buf; 444170838Smarius args.len = len; 44567204Sobrien if (openfirmware(&args) == -1) 446170838Smarius return (-1); 447170838Smarius return (args.size); 44867204Sobrien} 44967204Sobrien 45067204Sobrien/* Call the method in the scope of a given instance. */ 45167204Sobrienint 45267204SobrienOF_call_method(char *method, ihandle_t instance, int nargs, int nreturns, ...) 45367204Sobrien{ 45467204Sobrien va_list ap; 45567204Sobrien static struct { 456170838Smarius cell_t name; 457170838Smarius cell_t nargs; 458170838Smarius cell_t nreturns; 459170838Smarius cell_t method; 460170838Smarius cell_t instance; 461170838Smarius cell_t args_n_results[12]; 46267204Sobrien } args = { 46384972Srobert (cell_t)"call-method", 46467204Sobrien 2, 46567204Sobrien 1, 46667204Sobrien }; 467170854Smarius cell_t *cp; 468170854Smarius int n; 46967204Sobrien 47067204Sobrien if (nargs > 6) 471170838Smarius return (-1); 47267204Sobrien args.nargs = nargs + 2; 47367204Sobrien args.nreturns = nreturns + 1; 47484972Srobert args.method = (cell_t)method; 475170838Smarius args.instance = instance; 47667204Sobrien va_start(ap, nreturns); 477170854Smarius for (cp = (cell_t *)(args.args_n_results + (n = nargs)); --n >= 0;) 478170854Smarius *--cp = va_arg(ap, cell_t); 47967204Sobrien if (openfirmware(&args) == -1) 480170838Smarius return (-1); 48167204Sobrien if (args.args_n_results[nargs]) 482170838Smarius return (args.args_n_results[nargs]); 483170854Smarius for (cp = (cell_t *)(args.args_n_results + nargs + (n = args.nreturns)); 48484972Srobert --n > 0;) 485170854Smarius *va_arg(ap, cell_t *) = *--cp; 48667204Sobrien va_end(ap); 487170838Smarius return (0); 48867204Sobrien} 48967204Sobrien 49067204Sobrien/* 491170838Smarius * Device I/O functions 49267204Sobrien */ 49367204Sobrien 49467204Sobrien/* Open an instance for a device. */ 49567204Sobrienihandle_t 49667204SobrienOF_open(char *device) 49767204Sobrien{ 49867204Sobrien static struct { 499170838Smarius cell_t name; 500170838Smarius cell_t nargs; 501170838Smarius cell_t nreturns; 502170838Smarius cell_t device; 503170838Smarius cell_t instance; 50467204Sobrien } args = { 50584972Srobert (cell_t)"open", 50667204Sobrien 1, 50767204Sobrien 1, 50867204Sobrien }; 509170838Smarius 51084972Srobert args.device = (cell_t)device; 51167204Sobrien if (openfirmware(&args) == -1 || args.instance == 0) { 512170838Smarius return (-1); 51367204Sobrien } 514170838Smarius return (args.instance); 51567204Sobrien} 51667204Sobrien 51767204Sobrien/* Close an instance. */ 51867204Sobrienvoid 51967204SobrienOF_close(ihandle_t instance) 52067204Sobrien{ 52167204Sobrien static struct { 522170838Smarius cell_t name; 523170838Smarius cell_t nargs; 524170838Smarius cell_t nreturns; 525170838Smarius cell_t instance; 52667204Sobrien } args = { 52784972Srobert (cell_t)"close", 52867204Sobrien 1, 52967204Sobrien }; 530170838Smarius 531170838Smarius args.instance = instance; 53267204Sobrien openfirmware(&args); 53367204Sobrien} 53467204Sobrien 53567204Sobrien/* Read from an instance. */ 53667204Sobrienint 53767204SobrienOF_read(ihandle_t instance, void *addr, int len) 53867204Sobrien{ 53967204Sobrien static struct { 540170838Smarius cell_t name; 541170838Smarius cell_t nargs; 542170838Smarius cell_t nreturns; 543170838Smarius cell_t instance; 544170838Smarius cell_t addr; 545170838Smarius cell_t len; 546170838Smarius cell_t actual; 54767204Sobrien } args = { 54884972Srobert (cell_t)"read", 54967204Sobrien 3, 55067204Sobrien 1, 55167204Sobrien }; 55267204Sobrien 553170838Smarius args.instance = instance; 55484972Srobert args.addr = (cell_t)addr; 555170838Smarius args.len = len; 55668548Sbenno 55768548Sbenno#if defined(OPENFIRM_DEBUG) 55868548Sbenno printf("OF_read: called with instance=%08x, addr=%p, len=%d\n", 55968548Sbenno args.instance, args.addr, args.len); 56068548Sbenno#endif 56168548Sbenno 56267204Sobrien if (openfirmware(&args) == -1) 563170838Smarius return (-1); 56468548Sbenno 56568548Sbenno#if defined(OPENFIRM_DEBUG) 56668548Sbenno printf("OF_read: returning instance=%d, addr=%p, len=%d, actual=%d\n", 56768548Sbenno args.instance, args.addr, args.len, args.actual); 56868548Sbenno#endif 56968548Sbenno 570170838Smarius return (args.actual); 57167204Sobrien} 57267204Sobrien 57367204Sobrien/* Write to an instance. */ 57467204Sobrienint 57567204SobrienOF_write(ihandle_t instance, void *addr, int len) 57667204Sobrien{ 57767204Sobrien static struct { 578170838Smarius cell_t name; 579170838Smarius cell_t nargs; 580170838Smarius cell_t nreturns; 581170838Smarius cell_t instance; 582170838Smarius cell_t addr; 583170838Smarius cell_t len; 584170838Smarius cell_t actual; 58567204Sobrien } args = { 58684972Srobert (cell_t)"write", 58767204Sobrien 3, 58867204Sobrien 1, 58967204Sobrien }; 59067204Sobrien 591170838Smarius args.instance = instance; 59284972Srobert args.addr = (cell_t)addr; 593170838Smarius args.len = len; 59467204Sobrien if (openfirmware(&args) == -1) 595170838Smarius return (-1); 596170838Smarius return (args.actual); 59767204Sobrien} 59867204Sobrien 59967204Sobrien/* Seek to a position. */ 60067204Sobrienint 60168548SbennoOF_seek(ihandle_t instance, u_int64_t pos) 60267204Sobrien{ 60367204Sobrien static struct { 604170838Smarius cell_t name; 605170838Smarius cell_t nargs; 606170838Smarius cell_t nreturns; 607170838Smarius cell_t instance; 608170838Smarius cell_t poshi; 609170838Smarius cell_t poslo; 610170838Smarius cell_t status; 61167204Sobrien } args = { 61284972Srobert (cell_t)"seek", 61367204Sobrien 3, 61467204Sobrien 1, 61567204Sobrien }; 616170838Smarius 617170838Smarius args.instance = instance; 61884972Srobert args.poshi = pos >> 32; 61984972Srobert args.poslo = pos; 62067204Sobrien if (openfirmware(&args) == -1) 621170838Smarius return (-1); 622170838Smarius return (args.status); 62367204Sobrien} 62467204Sobrien 62567204Sobrien/* 626170838Smarius * Memory functions 62767204Sobrien */ 62867204Sobrien 62967204Sobrien/* Claim an area of memory. */ 63067204Sobrienvoid * 63167204SobrienOF_claim(void *virt, u_int size, u_int align) 63267204Sobrien{ 63367204Sobrien static struct { 634170838Smarius cell_t name; 635170838Smarius cell_t nargs; 636170838Smarius cell_t nreturns; 637170838Smarius cell_t virt; 638170838Smarius cell_t size; 639170838Smarius cell_t align; 640170838Smarius cell_t baseaddr; 64167204Sobrien } args = { 64284972Srobert (cell_t)"claim", 64367204Sobrien 3, 64467204Sobrien 1, 64567204Sobrien }; 64667204Sobrien 64784972Srobert args.virt = (cell_t)virt; 64867204Sobrien args.size = size; 64967204Sobrien args.align = align; 65067204Sobrien if (openfirmware(&args) == -1) 651170838Smarius return ((void *)-1); 652170838Smarius return ((void *)args.baseaddr); 65367204Sobrien} 65467204Sobrien 65567204Sobrien/* Release an area of memory. */ 65667204Sobrienvoid 65767204SobrienOF_release(void *virt, u_int size) 65867204Sobrien{ 65967204Sobrien static struct { 660170838Smarius cell_t name; 661170838Smarius cell_t nargs; 662170838Smarius cell_t nreturns; 663170838Smarius cell_t virt; 664170838Smarius cell_t size; 66567204Sobrien } args = { 66684972Srobert (cell_t)"release", 66767204Sobrien 2, 66867204Sobrien }; 669170838Smarius 67084972Srobert args.virt = (cell_t)virt; 67167204Sobrien args.size = size; 67267204Sobrien openfirmware(&args); 67367204Sobrien} 67467204Sobrien 67567204Sobrien/* 676170838Smarius * Control transfer functions 67767204Sobrien */ 67867204Sobrien 67967204Sobrien/* Reset the system and call "boot <bootspec>". */ 68067204Sobrienvoid 68167204SobrienOF_boot(char *bootspec) 68267204Sobrien{ 68367204Sobrien static struct { 684170838Smarius cell_t name; 685170838Smarius cell_t nargs; 686170838Smarius cell_t nreturns; 687170838Smarius cell_t bootspec; 68867204Sobrien } args = { 68984972Srobert (cell_t)"boot", 69067204Sobrien 1, 69167204Sobrien }; 69267204Sobrien 69384972Srobert args.bootspec = (cell_t)bootspec; 69467204Sobrien openfirmware(&args); 695170838Smarius for (;;) /* just in case */ 696170838Smarius ; 69767204Sobrien} 69867204Sobrien 699133862Smarius/* Suspend and drop back to the Open Firmware interface. */ 70067204Sobrienvoid 70167204SobrienOF_enter() 70267204Sobrien{ 70367204Sobrien static struct { 704170838Smarius cell_t name; 705170838Smarius cell_t nargs; 706170838Smarius cell_t nreturns; 70767204Sobrien } args = { 70884972Srobert (cell_t)"enter", 70967204Sobrien }; 71067204Sobrien 71167204Sobrien openfirmware(&args); 712170838Smarius /* We may come back. */ 71367204Sobrien} 71467204Sobrien 715133862Smarius/* Shut down and drop back to the Open Firmware interface. */ 71668548Sbennovoid 71767204SobrienOF_exit() 71867204Sobrien{ 71967204Sobrien static struct { 720170838Smarius cell_t name; 721170838Smarius cell_t nargs; 722170838Smarius cell_t nreturns; 72367204Sobrien } args = { 72484972Srobert (cell_t)"exit", 72567204Sobrien }; 72667204Sobrien 72767204Sobrien openfirmware(&args); 728170838Smarius for (;;) /* just in case */ 729170838Smarius ; 73067204Sobrien} 73167204Sobrien 73267204Sobrien/* Free <size> bytes starting at <virt>, then call <entry> with <arg>. */ 733131783Sgrehan#if 0 73467204Sobrienvoid 73567204SobrienOF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) 73667204Sobrien{ 73767204Sobrien static struct { 738170838Smarius cell_t name; 739170838Smarius cell_t nargs; 740170838Smarius cell_t nreturns; 741170838Smarius cell_t virt; 742170838Smarius cell_t size; 743170838Smarius cell_t entry; 744170838Smarius cell_t arg; 745170838Smarius cell_t len; 74667204Sobrien } args = { 74784972Srobert (cell_t)"chain", 74867204Sobrien 5, 74967204Sobrien }; 75067204Sobrien 75184972Srobert args.virt = (cell_t)virt; 75267204Sobrien args.size = size; 75384972Srobert args.entry = (cell_t)entry; 75484972Srobert args.arg = (cell_t)arg; 75567204Sobrien args.len = len; 75667204Sobrien openfirmware(&args); 75767204Sobrien} 75867204Sobrien#else 75967204Sobrienvoid 76067204SobrienOF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) 76167204Sobrien{ 76267204Sobrien /* 76367204Sobrien * This is a REALLY dirty hack till the firmware gets this going 76467204Sobrien */ 765131783Sgrehan#if 0 76684617Sbenno if (size > 0) 76784617Sbenno OF_release(virt, size); 768131783Sgrehan#endif 76967204Sobrien entry(0, 0, openfirmware, arg, len); 77067204Sobrien} 77167204Sobrien#endif 772