openfirm.c revision 100318
167204Sobrien/* $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai Exp $ */ 267204Sobrien 367204Sobrien/* 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 */ 3367204Sobrien/* 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 * $FreeBSD: head/sys/boot/ofw/libofw/openfirm.c 100318 2002-07-18 12:39:02Z benno $ 5867204Sobrien */ 5967204Sobrien 6067204Sobrien#include <machine/stdarg.h> 6167204Sobrien 6268548Sbenno#include <stand.h> 6368548Sbenno 6467204Sobrien#include "openfirm.h" 6567204Sobrien 6685717Sjakeint (*openfirmware)(void *); 6785717Sjake 6867204Sobrienstatic ihandle_t stdin; 6967204Sobrienstatic ihandle_t stdout; 7067204Sobrien 71100318Sbennoihandle_t mmu; 72100318Sbennoihandle_t memory; 7384617Sbenno 7467204Sobrien/* Initialiaser */ 7567204Sobrien 7667204Sobrienvoid 7767204SobrienOF_init(int (*openfirm)(void *)) 7867204Sobrien{ 7984617Sbenno phandle_t chosen; 8084617Sbenno 8167204Sobrien openfirmware = openfirm; 8284617Sbenno 8384617Sbenno chosen = OF_finddevice("/chosen"); 8484617Sbenno OF_getprop(chosen, "memory", &memory, sizeof(memory)); 8584617Sbenno if (memory == 0) 8684617Sbenno panic("failed to get memory ihandle"); 8784617Sbenno OF_getprop(chosen, "mmu", &mmu, sizeof(mmu)); 8884617Sbenno if (mmu == 0) 8984617Sbenno panic("failed to get mmu ihandle"); 9067204Sobrien} 9167204Sobrien 9267204Sobrien/* 9367204Sobrien * Generic functions 9467204Sobrien */ 9567204Sobrien 9667204Sobrien/* Test to see if a service exists. */ 9767204Sobrienint 9867204SobrienOF_test(char *name) 9967204Sobrien{ 10067204Sobrien static struct { 10184972Srobert cell_t name; 10284972Srobert cell_t nargs; 10384972Srobert cell_t nreturns; 10484972Srobert cell_t service; 10584972Srobert cell_t missing; 10667204Sobrien } args = { 10784972Srobert (cell_t)"test", 10867204Sobrien 1, 10967204Sobrien 1, 11084972Srobert 0, 11184972Srobert 0 11267204Sobrien }; 11367204Sobrien 11484972Srobert args.service = (cell_t)name; 11567204Sobrien if (openfirmware(&args) == -1) 11667204Sobrien return -1; 11784972Srobert return (int)args.missing; 11867204Sobrien} 11967204Sobrien 12067204Sobrien/* Return firmware millisecond count. */ 12167204Sobrienint 12267204SobrienOF_milliseconds() 12367204Sobrien{ 12467204Sobrien static struct { 12584972Srobert cell_t name; 12684972Srobert cell_t nargs; 12784972Srobert cell_t nreturns; 12884972Srobert cell_t ms; 12967204Sobrien } args = { 13084972Srobert (cell_t)"milliseconds", 13167204Sobrien 0, 13267204Sobrien 1, 13384972Srobert 0 13467204Sobrien }; 13567204Sobrien 13667204Sobrien openfirmware(&args); 13784972Srobert return (int)args.ms; 13867204Sobrien} 13967204Sobrien 14067204Sobrien/* 14167204Sobrien * Device tree functions 14267204Sobrien */ 14367204Sobrien 14467204Sobrien/* Return the next sibling of this node or 0. */ 14567204Sobrienphandle_t 14667204SobrienOF_peer(phandle_t node) 14767204Sobrien{ 14867204Sobrien static struct { 14984972Srobert cell_t name; 15084972Srobert cell_t nargs; 15184972Srobert cell_t nreturns; 15284972Srobert cell_t node; 15384972Srobert cell_t next; 15467204Sobrien } args = { 15584972Srobert (cell_t)"peer", 15667204Sobrien 1, 15767204Sobrien 1, 15884972Srobert 0, 15984972Srobert 0 16067204Sobrien }; 16167204Sobrien 16284972Srobert args.node = (u_int)node; 16367204Sobrien if (openfirmware(&args) == -1) 16467204Sobrien return -1; 16584972Srobert return (phandle_t)args.next; 16667204Sobrien} 16767204Sobrien 16867204Sobrien/* Return the first child of this node or 0. */ 16967204Sobrienphandle_t 17067204SobrienOF_child(phandle_t node) 17167204Sobrien{ 17267204Sobrien static struct { 17384972Srobert cell_t name; 17484972Srobert cell_t nargs; 17584972Srobert cell_t nreturns; 17684972Srobert cell_t node; 17784972Srobert cell_t child; 17867204Sobrien } args = { 17984972Srobert (cell_t)"child", 18067204Sobrien 1, 18167204Sobrien 1, 18284972Srobert 0, 18384972Srobert 0 18467204Sobrien }; 18567204Sobrien 18684972Srobert args.node = (u_int)node; 18767204Sobrien if (openfirmware(&args) == -1) 18867204Sobrien return -1; 18984972Srobert return (phandle_t)args.child; 19067204Sobrien} 19167204Sobrien 19267204Sobrien/* Return the parent of this node or 0. */ 19367204Sobrienphandle_t 19467204SobrienOF_parent(phandle_t node) 19567204Sobrien{ 19667204Sobrien static struct { 19784972Srobert cell_t name; 19884972Srobert cell_t nargs; 19984972Srobert cell_t nreturns; 20084972Srobert cell_t node; 20184972Srobert cell_t parent; 20267204Sobrien } args = { 20384972Srobert (cell_t)"parent", 20467204Sobrien 1, 20567204Sobrien 1, 20684972Srobert 0, 20784972Srobert 0 20867204Sobrien }; 20967204Sobrien 21084972Srobert args.node = (u_int)node; 21167204Sobrien if (openfirmware(&args) == -1) 21267204Sobrien return -1; 21384972Srobert return (phandle_t)args.parent; 21467204Sobrien} 21567204Sobrien 21667204Sobrien/* Return the package handle that corresponds to an instance handle. */ 21767204Sobrienphandle_t 21867204SobrienOF_instance_to_package(ihandle_t instance) 21967204Sobrien{ 22067204Sobrien static struct { 22184972Srobert cell_t name; 22284972Srobert cell_t nargs; 22384972Srobert cell_t nreturns; 22484972Srobert cell_t instance; 22584972Srobert cell_t package; 22667204Sobrien } args = { 22784972Srobert (cell_t)"instance-to-package", 22867204Sobrien 1, 22967204Sobrien 1, 23084972Srobert 0, 23184972Srobert 0 23267204Sobrien }; 23367204Sobrien 23484972Srobert args.instance = (u_int)instance; 23567204Sobrien if (openfirmware(&args) == -1) 23667204Sobrien return -1; 23784972Srobert return (phandle_t)args.package; 23867204Sobrien} 23967204Sobrien 24067204Sobrien/* Get the length of a property of a package. */ 24167204Sobrienint 24267204SobrienOF_getproplen(phandle_t package, char *propname) 24367204Sobrien{ 24467204Sobrien static struct { 24584972Srobert cell_t name; 24684972Srobert cell_t nargs; 24784972Srobert cell_t nreturns; 24884972Srobert cell_t package; 24984972Srobert cell_t propname; 25084972Srobert cell_t proplen; 25167204Sobrien } args = { 25284972Srobert (cell_t)"getproplen", 25367204Sobrien 2, 25467204Sobrien 1, 25584972Srobert 0, 25684972Srobert 0, 25784972Srobert 0 25867204Sobrien }; 25967204Sobrien 26084972Srobert args.package = (u_int)package; 26184972Srobert args.propname = (cell_t)propname; 26267204Sobrien if (openfirmware(&args) == -1) 26367204Sobrien return -1; 26484972Srobert return (int)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 { 27284972Srobert cell_t name; 27384972Srobert cell_t nargs; 27484972Srobert cell_t nreturns; 27584972Srobert cell_t package; 27684972Srobert cell_t propname; 27784972Srobert cell_t buf; 27884972Srobert cell_t buflen; 27984972Srobert cell_t size; 28067204Sobrien } args = { 28184972Srobert (cell_t)"getprop", 28267204Sobrien 4, 28367204Sobrien 1, 28484972Srobert 0, 28584972Srobert 0, 28684972Srobert 0, 28784972Srobert 0, 28884972Srobert 0 28967204Sobrien }; 29067204Sobrien 29184972Srobert args.package = (u_int)package; 29284972Srobert args.propname = (cell_t)propname; 29384972Srobert args.buf = (cell_t)buf; 29484972Srobert args.buflen = (u_int)buflen; 29567204Sobrien if (openfirmware(&args) == -1) 29667204Sobrien return -1; 29784972Srobert return (int)args.size; 29867204Sobrien} 29967204Sobrien 30067204Sobrien/* Get the next property of a package. */ 30167204Sobrienint 30267204SobrienOF_nextprop(phandle_t package, char *previous, char *buf) 30367204Sobrien{ 30467204Sobrien static struct { 30584972Srobert cell_t name; 30684972Srobert cell_t nargs; 30784972Srobert cell_t nreturns; 30884972Srobert cell_t package; 30984972Srobert cell_t previous; 31084972Srobert cell_t buf; 31184972Srobert cell_t flag; 31267204Sobrien } args = { 31384972Srobert (cell_t)"nextprop", 31467204Sobrien 3, 31567204Sobrien 1, 31684972Srobert 0, 31784972Srobert 0, 31884972Srobert 0, 31984972Srobert 0 32067204Sobrien }; 32167204Sobrien 32284972Srobert args.package = (u_int)package; 32384972Srobert args.previous = (cell_t)previous; 32484972Srobert args.buf = (cell_t)buf; 32567204Sobrien if (openfirmware(&args) == -1) 32667204Sobrien return -1; 32784972Srobert return (int)args.flag; 32867204Sobrien} 32967204Sobrien 33067204Sobrien/* Set the value of a property of a package. */ 33167204Sobrien/* XXX Has a bug on FirePower */ 33267204Sobrienint 33367204SobrienOF_setprop(phandle_t package, char *propname, void *buf, int len) 33467204Sobrien{ 33567204Sobrien static struct { 33684972Srobert cell_t name; 33784972Srobert cell_t nargs; 33884972Srobert cell_t nreturns; 33984972Srobert cell_t package; 34084972Srobert cell_t propname; 34184972Srobert cell_t buf; 34284972Srobert cell_t len; 34384972Srobert cell_t size; 34467204Sobrien } args = { 34584972Srobert (cell_t)"setprop", 34667204Sobrien 4, 34767204Sobrien 1, 34884972Srobert 0, 34984972Srobert 0, 35084972Srobert 0, 35184972Srobert 0, 35284972Srobert 0 35367204Sobrien }; 35467204Sobrien 35584972Srobert args.package = (u_int)package; 35684972Srobert args.propname = (cell_t)propname; 35784972Srobert args.buf = (cell_t)buf; 35884972Srobert args.len = (u_int)len; 35967204Sobrien if (openfirmware(&args) == -1) 36067204Sobrien return -1; 36184972Srobert return (int)args.size; 36267204Sobrien} 36367204Sobrien 36467204Sobrien/* Convert a device specifier to a fully qualified pathname. */ 36567204Sobrienint 36668548SbennoOF_canon(const char *device, char *buf, int len) 36767204Sobrien{ 36867204Sobrien static struct { 36984972Srobert cell_t name; 37084972Srobert cell_t nargs; 37184972Srobert cell_t nreturns; 37284972Srobert cell_t device; 37384972Srobert cell_t buf; 37484972Srobert cell_t len; 37584972Srobert cell_t size; 37667204Sobrien } args = { 37784972Srobert (cell_t)"canon", 37867204Sobrien 3, 37967204Sobrien 1, 38084972Srobert 0, 38184972Srobert 0, 38284972Srobert 0, 38384972Srobert 0 38467204Sobrien }; 38567204Sobrien 38684972Srobert args.device = (cell_t)device; 38784972Srobert args.buf = (cell_t)buf; 38884972Srobert args.len = (cell_t)len; 38967204Sobrien if (openfirmware(&args) == -1) 39067204Sobrien return -1; 39184972Srobert return (int)args.size; 39267204Sobrien} 39367204Sobrien 39467204Sobrien/* Return a package handle for the specified device. */ 39567204Sobrienphandle_t 39668548SbennoOF_finddevice(const char *device) 39767204Sobrien{ 39884972Srobert int i; 39967204Sobrien static struct { 40084972Srobert cell_t name; 40184972Srobert cell_t nargs; 40284972Srobert cell_t nreturns; 40384972Srobert cell_t device; 40484972Srobert cell_t package; 40567204Sobrien } args = { 40684972Srobert (cell_t)"finddevice", 40767204Sobrien 1, 40867204Sobrien 1, 40984972Srobert 0, 41084972Srobert 0 41167204Sobrien }; 41267204Sobrien 41384972Srobert args.device = (cell_t)device; 41467204Sobrien if (openfirmware(&args) == -1) 41567204Sobrien return -1; 41684972Srobert 41784972Srobert return (phandle_t)args.package; 41867204Sobrien} 41967204Sobrien 42067204Sobrien/* Return the fully qualified pathname corresponding to an instance. */ 42167204Sobrienint 42267204SobrienOF_instance_to_path(ihandle_t instance, char *buf, int len) 42367204Sobrien{ 42467204Sobrien static struct { 42584972Srobert cell_t name; 42684972Srobert cell_t nargs; 42784972Srobert cell_t nreturns; 42884972Srobert cell_t instance; 42984972Srobert cell_t buf; 43084972Srobert cell_t len; 43184972Srobert cell_t size; 43267204Sobrien } args = { 43384972Srobert (cell_t)"instance-to-path", 43467204Sobrien 3, 43567204Sobrien 1, 43684972Srobert 0, 43784972Srobert 0, 43884972Srobert 0, 43984972Srobert 0 44067204Sobrien }; 44167204Sobrien 44284972Srobert args.instance = (u_int)instance; 44384972Srobert args.buf = (cell_t)buf; 44484972Srobert args.len = (u_int)len; 44567204Sobrien if (openfirmware(&args) == -1) 44667204Sobrien return -1; 44784972Srobert return (int)args.size; 44867204Sobrien} 44967204Sobrien 45067204Sobrien/* Return the fully qualified pathname corresponding to a package. */ 45167204Sobrienint 45267204SobrienOF_package_to_path(phandle_t package, char *buf, int len) 45367204Sobrien{ 45467204Sobrien static struct { 45584972Srobert cell_t name; 45684972Srobert cell_t nargs; 45784972Srobert cell_t nreturns; 45884972Srobert cell_t package; 45984972Srobert cell_t buf; 46084972Srobert cell_t len; 46184972Srobert cell_t size; 46267204Sobrien } args = { 46384972Srobert (cell_t)"package-to-path", 46467204Sobrien 3, 46567204Sobrien 1, 46684972Srobert 0, 46784972Srobert 0, 46884972Srobert 0, 46984972Srobert 0 47067204Sobrien }; 47167204Sobrien 47284972Srobert args.package = (u_int)package; 47384972Srobert args.buf = (cell_t)buf; 47484972Srobert args.len = (u_int)len; 47567204Sobrien if (openfirmware(&args) == -1) 47667204Sobrien return -1; 47784972Srobert return (int)args.size; 47867204Sobrien} 47967204Sobrien 48067204Sobrien/* Call the method in the scope of a given instance. */ 48167204Sobrienint 48267204SobrienOF_call_method(char *method, ihandle_t instance, int nargs, int nreturns, ...) 48367204Sobrien{ 48467204Sobrien va_list ap; 48567204Sobrien static struct { 48684972Srobert cell_t name; 48784972Srobert cell_t nargs; 48884972Srobert cell_t nreturns; 48984972Srobert cell_t method; 49084972Srobert cell_t instance; 49184972Srobert cell_t args_n_results[12]; 49267204Sobrien } args = { 49384972Srobert (cell_t)"call-method", 49467204Sobrien 2, 49567204Sobrien 1, 49684972Srobert 0, 49784972Srobert 0, 49884972Srobert { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 49967204Sobrien }; 50067204Sobrien int *ip, n; 50167204Sobrien 50267204Sobrien if (nargs > 6) 50367204Sobrien return -1; 50467204Sobrien args.nargs = nargs + 2; 50567204Sobrien args.nreturns = nreturns + 1; 50684972Srobert args.method = (cell_t)method; 50784972Srobert args.instance = (u_int)instance; 50867204Sobrien va_start(ap, nreturns); 50984972Srobert for (ip = (int *)(args.args_n_results + (n = nargs)); --n >= 0;) 51067204Sobrien *--ip = va_arg(ap, int); 51167204Sobrien 51267204Sobrien if (openfirmware(&args) == -1) 51367204Sobrien return -1; 51467204Sobrien if (args.args_n_results[nargs]) 51584972Srobert return (int)args.args_n_results[nargs]; 51684972Srobert for (ip = (int *)(args.args_n_results + nargs + (n = args.nreturns)); 51784972Srobert --n > 0;) 51867204Sobrien *va_arg(ap, int *) = *--ip; 51967204Sobrien va_end(ap); 52067204Sobrien return 0; 52167204Sobrien} 52267204Sobrien 52367204Sobrien/* 52467204Sobrien * Device I/O functions. 52567204Sobrien */ 52667204Sobrien 52767204Sobrien/* Open an instance for a device. */ 52867204Sobrienihandle_t 52967204SobrienOF_open(char *device) 53067204Sobrien{ 53167204Sobrien static struct { 53284972Srobert cell_t name; 53384972Srobert cell_t nargs; 53484972Srobert cell_t nreturns; 53584972Srobert cell_t device; 53684972Srobert cell_t instance; 53767204Sobrien } args = { 53884972Srobert (cell_t)"open", 53967204Sobrien 1, 54067204Sobrien 1, 54184972Srobert 0, 54284972Srobert 0 54367204Sobrien }; 54467204Sobrien 54584972Srobert args.device = (cell_t)device; 54667204Sobrien if (openfirmware(&args) == -1 || args.instance == 0) { 54767204Sobrien return -1; 54867204Sobrien } 54984972Srobert return (ihandle_t)args.instance; 55067204Sobrien} 55167204Sobrien 55267204Sobrien/* Close an instance. */ 55367204Sobrienvoid 55467204SobrienOF_close(ihandle_t instance) 55567204Sobrien{ 55667204Sobrien static struct { 55784972Srobert cell_t name; 55884972Srobert cell_t nargs; 55984972Srobert cell_t nreturns; 56084972Srobert cell_t instance; 56167204Sobrien } args = { 56284972Srobert (cell_t)"close", 56367204Sobrien 1, 56467204Sobrien 0, 56584972Srobert 0 56667204Sobrien }; 56767204Sobrien 56884972Srobert args.instance = (u_int)instance; 56967204Sobrien openfirmware(&args); 57067204Sobrien} 57167204Sobrien 57267204Sobrien/* Read from an instance. */ 57367204Sobrienint 57467204SobrienOF_read(ihandle_t instance, void *addr, int len) 57567204Sobrien{ 57667204Sobrien static struct { 57784972Srobert cell_t name; 57884972Srobert cell_t nargs; 57984972Srobert cell_t nreturns; 58084972Srobert cell_t instance; 58184972Srobert cell_t addr; 58284972Srobert cell_t len; 58384972Srobert cell_t actual; 58467204Sobrien } args = { 58584972Srobert (cell_t)"read", 58667204Sobrien 3, 58767204Sobrien 1, 58884972Srobert 0, 58984972Srobert 0, 59084972Srobert 0, 59184972Srobert 0 59267204Sobrien }; 59367204Sobrien 59484972Srobert args.instance = (u_int)instance; 59584972Srobert args.addr = (cell_t)addr; 59684972Srobert args.len = (u_int)len; 59768548Sbenno 59868548Sbenno#if defined(OPENFIRM_DEBUG) 59968548Sbenno printf("OF_read: called with instance=%08x, addr=%p, len=%d\n", 60068548Sbenno args.instance, args.addr, args.len); 60168548Sbenno#endif 60268548Sbenno 60367204Sobrien if (openfirmware(&args) == -1) 60467204Sobrien return -1; 60568548Sbenno 60668548Sbenno#if defined(OPENFIRM_DEBUG) 60768548Sbenno printf("OF_read: returning instance=%d, addr=%p, len=%d, actual=%d\n", 60868548Sbenno args.instance, args.addr, args.len, args.actual); 60968548Sbenno#endif 61068548Sbenno 61184972Srobert return (int)args.actual; 61267204Sobrien} 61367204Sobrien 61467204Sobrien/* Write to an instance. */ 61567204Sobrienint 61667204SobrienOF_write(ihandle_t instance, void *addr, int len) 61767204Sobrien{ 61867204Sobrien static struct { 61984972Srobert cell_t name; 62084972Srobert cell_t nargs; 62184972Srobert cell_t nreturns; 62284972Srobert cell_t instance; 62384972Srobert cell_t addr; 62484972Srobert cell_t len; 62584972Srobert cell_t actual; 62667204Sobrien } args = { 62784972Srobert (cell_t)"write", 62867204Sobrien 3, 62967204Sobrien 1, 63084972Srobert 0, 63184972Srobert 0, 63284972Srobert 0, 63384972Srobert 0 63467204Sobrien }; 63567204Sobrien 63684972Srobert args.instance = (u_int)instance; 63784972Srobert args.addr = (cell_t)addr; 63884972Srobert args.len = (u_int)len; 63967204Sobrien if (openfirmware(&args) == -1) 64067204Sobrien return -1; 64184972Srobert return (int)args.actual; 64267204Sobrien} 64367204Sobrien 64467204Sobrien/* Seek to a position. */ 64567204Sobrienint 64668548SbennoOF_seek(ihandle_t instance, u_int64_t pos) 64767204Sobrien{ 64867204Sobrien static struct { 64984972Srobert cell_t name; 65084972Srobert cell_t nargs; 65184972Srobert cell_t nreturns; 65284972Srobert cell_t instance; 65384972Srobert cell_t poshi; 65484972Srobert cell_t poslo; 65584972Srobert cell_t status; 65667204Sobrien } args = { 65784972Srobert (cell_t)"seek", 65867204Sobrien 3, 65967204Sobrien 1, 66084972Srobert 0, 66184972Srobert 0, 66284972Srobert 0, 66384972Srobert 0 66467204Sobrien }; 66567204Sobrien 66684972Srobert args.instance = (u_int)instance; 66784972Srobert args.poshi = pos >> 32; 66884972Srobert args.poslo = pos; 66967204Sobrien if (openfirmware(&args) == -1) 67067204Sobrien return -1; 67184972Srobert return (int)args.status; 67267204Sobrien} 67367204Sobrien 67467204Sobrien/* 67567204Sobrien * Memory functions. 67667204Sobrien */ 67767204Sobrien 67867204Sobrien/* Claim an area of memory. */ 67967204Sobrienvoid * 68067204SobrienOF_claim(void *virt, u_int size, u_int align) 68167204Sobrien{ 68267204Sobrien static struct { 68384972Srobert cell_t name; 68484972Srobert cell_t nargs; 68584972Srobert cell_t nreturns; 68684972Srobert cell_t virt; 68784972Srobert cell_t size; 68884972Srobert cell_t align; 68984972Srobert cell_t baseaddr; 69067204Sobrien } args = { 69184972Srobert (cell_t)"claim", 69267204Sobrien 3, 69367204Sobrien 1, 69484972Srobert 0, 69584972Srobert 0, 69684972Srobert 0, 69784972Srobert 0 69867204Sobrien }; 69967204Sobrien 70084972Srobert args.virt = (cell_t)virt; 70167204Sobrien args.size = size; 70267204Sobrien args.align = align; 70367204Sobrien if (openfirmware(&args) == -1) 70467204Sobrien return (void *)-1; 70584972Srobert return (void *)args.baseaddr; 70667204Sobrien} 70767204Sobrien 70884972Srobert/* Allocate an area of physical memory */ 70991108Sjakevm_offset_t 71091108SjakeOF_claim_virt(vm_offset_t virt, size_t size, int align) 71191108Sjake{ 71291108Sjake static struct { 71391108Sjake cell_t name; 71491108Sjake cell_t nargs; 71591108Sjake cell_t nret; 71691108Sjake cell_t method; 71791108Sjake cell_t ihandle; 71891108Sjake cell_t align; 71991108Sjake cell_t size; 72091108Sjake cell_t virt; 72191108Sjake cell_t status; 72291108Sjake cell_t ret; 72391108Sjake } args = { 72491108Sjake (cell_t)"call-method", 72591108Sjake 5, 72691108Sjake 2, 72791108Sjake (cell_t)"claim", 72891108Sjake 0, 72991108Sjake 0, 73091108Sjake 0, 73191108Sjake 0, 73291108Sjake 0, /* ret */ 73391108Sjake 0, 73491108Sjake }; 73591108Sjake 73691108Sjake args.ihandle = mmu; 73791108Sjake args.align = align; 73891108Sjake args.size = size; 73991108Sjake args.virt = virt; 74091108Sjake 74191108Sjake if (openfirmware(&args) == -1) 74291108Sjake return (vm_offset_t)-1; 74391108Sjake 74491108Sjake return (vm_offset_t)args.ret; 74591108Sjake} 74691108Sjake 74791108Sjake/* Allocate an area of physical memory */ 74884972Srobertvoid * 74984972SrobertOF_alloc_phys(size_t size, int align) 75084972Srobert{ 75184972Srobert static struct { 75284972Srobert cell_t name; 75384972Srobert cell_t nargs; 75484972Srobert cell_t nret; 75584972Srobert cell_t method; 75684972Srobert cell_t ihandle; 75784972Srobert cell_t align; 75884972Srobert cell_t size; 75984972Srobert cell_t status; 76084972Srobert cell_t phys_hi; 76184972Srobert cell_t phys_low; 76284972Srobert } args = { 76384972Srobert (cell_t)"call-method", 76484972Srobert 4, 76584972Srobert 3, 76684972Srobert (cell_t)"claim", 76784972Srobert 0, 76884972Srobert 0, 76984972Srobert 0, 77084972Srobert 0, /* ret */ 77184972Srobert 0, 77284972Srobert 0, 77384972Srobert }; 77484972Srobert 77584972Srobert args.ihandle = memory; 77684972Srobert args.size = size; 77784972Srobert args.align = align; 77884972Srobert 77984972Srobert if (openfirmware(&args) == -1) 78084972Srobert return (void *)-1; 78184972Srobert 78284972Srobert return (void *)(args.phys_hi << 32 | args.phys_low); 78384972Srobert} 78484972Srobert 78567204Sobrien/* Release an area of memory. */ 78667204Sobrienvoid 78767204SobrienOF_release(void *virt, u_int size) 78867204Sobrien{ 78967204Sobrien static struct { 79084972Srobert cell_t name; 79184972Srobert cell_t nargs; 79284972Srobert cell_t nreturns; 79384972Srobert cell_t virt; 79484972Srobert cell_t size; 79567204Sobrien } args = { 79684972Srobert (cell_t)"release", 79767204Sobrien 2, 79867204Sobrien 0, 79984972Srobert 0, 80084972Srobert 0 80167204Sobrien }; 80267204Sobrien 80384972Srobert args.virt = (cell_t)virt; 80467204Sobrien args.size = size; 80567204Sobrien openfirmware(&args); 80667204Sobrien} 80767204Sobrien 80891108Sjake/* Release an area of physical memory. */ 80991108Sjakevoid 81091108SjakeOF_release_phys(vm_offset_t phys, u_int size) 81191108Sjake{ 81291108Sjake static struct { 81391108Sjake cell_t name; 81491108Sjake cell_t nargs; 81591108Sjake cell_t nret; 81691108Sjake cell_t method; 81791108Sjake cell_t ihandle; 81891108Sjake cell_t size; 81991108Sjake cell_t phys_hi; 82091108Sjake cell_t phys_lo; 82191108Sjake } args = { 82291108Sjake (cell_t)"call-method", 82391108Sjake 5, 82491108Sjake 0, 82591108Sjake (cell_t)"release", 82691108Sjake 0, 82791108Sjake 0, 82891108Sjake 0, 82991108Sjake 0 83091108Sjake }; 83191108Sjake 83291108Sjake args.ihandle = memory; 83391108Sjake args.phys_hi = (u_int32_t)(phys >> 32); 83491108Sjake args.phys_lo = (u_int32_t)phys; 83591108Sjake args.size = size; 83691108Sjake openfirmware(&args); 83791108Sjake} 83891108Sjake 83967204Sobrien/* 84067204Sobrien * Control transfer functions. 84167204Sobrien */ 84267204Sobrien 84367204Sobrien/* Reset the system and call "boot <bootspec>". */ 84467204Sobrienvoid 84567204SobrienOF_boot(char *bootspec) 84667204Sobrien{ 84767204Sobrien static struct { 84884972Srobert cell_t name; 84984972Srobert cell_t nargs; 85084972Srobert cell_t nreturns; 85184972Srobert cell_t bootspec; 85267204Sobrien } args = { 85384972Srobert (cell_t)"boot", 85467204Sobrien 1, 85567204Sobrien 0, 85684972Srobert 0 85767204Sobrien }; 85867204Sobrien 85984972Srobert args.bootspec = (cell_t)bootspec; 86067204Sobrien openfirmware(&args); 86167204Sobrien for (;;); /* just in case */ 86267204Sobrien} 86367204Sobrien 86467204Sobrien/* Suspend and drop back to the OpenFirmware interface. */ 86567204Sobrienvoid 86667204SobrienOF_enter() 86767204Sobrien{ 86867204Sobrien static struct { 86984972Srobert cell_t name; 87084972Srobert cell_t nargs; 87184972Srobert cell_t nreturns; 87267204Sobrien } args = { 87384972Srobert (cell_t)"enter", 87467204Sobrien 0, 87567204Sobrien 0 87667204Sobrien }; 87767204Sobrien 87867204Sobrien openfirmware(&args); 87967204Sobrien} 88067204Sobrien 88167204Sobrien/* Shut down and drop back to the OpenFirmware interface. */ 88268548Sbennovoid 88367204SobrienOF_exit() 88467204Sobrien{ 88567204Sobrien static struct { 88684972Srobert cell_t name; 88784972Srobert cell_t nargs; 88884972Srobert cell_t nreturns; 88967204Sobrien } args = { 89084972Srobert (cell_t)"exit", 89167204Sobrien 0, 89267204Sobrien 0 89367204Sobrien }; 89467204Sobrien 89567204Sobrien openfirmware(&args); 89667204Sobrien for (;;); /* just in case */ 89767204Sobrien} 89867204Sobrien 89967204Sobrien/* Free <size> bytes starting at <virt>, then call <entry> with <arg>. */ 90084972Srobert#ifdef __notyet__ 90167204Sobrienvoid 90267204SobrienOF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) 90367204Sobrien{ 90467204Sobrien static struct { 90584972Srobert cell_t name; 90684972Srobert cell_t nargs; 90784972Srobert cell_t nreturns; 90884972Srobert cell_t virt; 90984972Srobert cell_t size; 91084972Srobert cell_t entry; 91184972Srobert cell_t arg; 91284972Srobert cell_t len; 91367204Sobrien } args = { 91484972Srobert (cell_t)"chain", 91567204Sobrien 5, 91667204Sobrien 0, 91784972Srobert 0, 91884972Srobert 0, 91984972Srobert 0, 92084972Srobert 0, 92184972Srobert 0 92267204Sobrien }; 92367204Sobrien 92484972Srobert args.virt = (cell_t)virt; 92567204Sobrien args.size = size; 92684972Srobert args.entry = (cell_t)entry; 92784972Srobert args.arg = (cell_t)arg; 92867204Sobrien args.len = len; 92967204Sobrien openfirmware(&args); 93067204Sobrien} 93167204Sobrien#else 93267204Sobrienvoid 93367204SobrienOF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) 93467204Sobrien{ 93567204Sobrien /* 93667204Sobrien * This is a REALLY dirty hack till the firmware gets this going 93767204Sobrien */ 93884617Sbenno if (size > 0) 93984617Sbenno OF_release(virt, size); 94084617Sbenno 94167204Sobrien entry(0, 0, openfirmware, arg, len); 94267204Sobrien} 94367204Sobrien#endif 944