1d84d862obrien/* $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai Exp $ */ 2d84d862obrien 3bd77e02imp/*- 4d84d862obrien * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5d84d862obrien * Copyright (C) 1995, 1996 TooLs GmbH. 6d84d862obrien * All rights reserved. 7d84d862obrien * 8d84d862obrien * Redistribution and use in source and binary forms, with or without 9d84d862obrien * modification, are permitted provided that the following conditions 10d84d862obrien * are met: 11d84d862obrien * 1. Redistributions of source code must retain the above copyright 12d84d862obrien * notice, this list of conditions and the following disclaimer. 13d84d862obrien * 2. Redistributions in binary form must reproduce the above copyright 14d84d862obrien * notice, this list of conditions and the following disclaimer in the 15d84d862obrien * documentation and/or other materials provided with the distribution. 16d84d862obrien * 3. All advertising materials mentioning features or use of this software 17d84d862obrien * must display the following acknowledgement: 18d84d862obrien * This product includes software developed by TooLs GmbH. 19d84d862obrien * 4. The name of TooLs GmbH may not be used to endorse or promote products 20d84d862obrien * derived from this software without specific prior written permission. 21d84d862obrien * 22d84d862obrien * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23d84d862obrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24d84d862obrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25d84d862obrien * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26d84d862obrien * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27d84d862obrien * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28d84d862obrien * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29d84d862obrien * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30d84d862obrien * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31d84d862obrien * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32d84d862obrien */ 33bd77e02imp/*- 34d84d862obrien * Copyright (C) 2000 Benno Rice. 35d84d862obrien * All rights reserved. 36d84d862obrien * 37d84d862obrien * Redistribution and use in source and binary forms, with or without 38d84d862obrien * modification, are permitted provided that the following conditions 39d84d862obrien * are met: 40d84d862obrien * 1. Redistributions of source code must retain the above copyright 41d84d862obrien * notice, this list of conditions and the following disclaimer. 42d84d862obrien * 2. Redistributions in binary form must reproduce the above copyright 43d84d862obrien * notice, this list of conditions and the following disclaimer in the 44d84d862obrien * documentation and/or other materials provided with the distribution. 45d84d862obrien * 46d84d862obrien * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 47d84d862obrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 48d84d862obrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49d84d862obrien * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 50d84d862obrien * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 51d84d862obrien * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 52d84d862obrien * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 53d84d862obrien * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 54d84d862obrien * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 55d84d862obrien * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56d84d862obrien */ 57d84d862obrien 5884dccedobrien#include <sys/cdefs.h> 5984dccedobrien__FBSDID("$FreeBSD$"); 6084dccedobrien 61d84d862obrien#include <machine/stdarg.h> 62d84d862obrien 637d73a33benno#include <stand.h> 647d73a33benno 65d84d862obrien#include "openfirm.h" 66d84d862obrien 6736e649fjakeint (*openfirmware)(void *); 6836e649fjake 69d6e6728mariusphandle_t chosen; 704442365bennoihandle_t mmu; 714442365bennoihandle_t memory; 72d0e1702andreastint real_mode = 0; 73994f797benno 74128f33dmarius/* Initialiser */ 75d84d862obrien 76d84d862obrienvoid 77d84d862obrienOF_init(int (*openfirm)(void *)) 78d84d862obrien{ 79d0e1702andreast phandle_t options; 8070881bcandreast char mode[sizeof("true")]; 81994f797benno 82d84d862obrien openfirmware = openfirm; 83994f797benno 84128f33dmarius if ((chosen = OF_finddevice("/chosen")) == -1) 85128f33dmarius OF_exit(); 864da7d60nwhitehorn if (OF_getprop(chosen, "memory", &memory, sizeof(memory)) == -1) { 874da7d60nwhitehorn memory = OF_open("/memory"); 884da7d60nwhitehorn if (memory == -1) 894da7d60nwhitehorn memory = OF_open("/memory@0"); 904da7d60nwhitehorn if (memory == -1) 914da7d60nwhitehorn OF_exit(); 924da7d60nwhitehorn } 93d6e6728marius if (OF_getprop(chosen, "mmu", &mmu, sizeof(mmu)) == -1) 94d6e6728marius OF_exit(); 95d0e1702andreast 9670881bcandreast /* 97d0e1702andreast * Check if we run in real mode. If so, we do not need to map 98d0e1702andreast * memory later on. 99d0e1702andreast */ 100d0e1702andreast options = OF_finddevice("/options"); 10170881bcandreast if (OF_getprop(options, "real-mode?", mode, sizeof(mode)) > 0 && 10270881bcandreast strcmp(mode, "true") == 0) 103d0e1702andreast real_mode = 1; 104e9d6f8ckmacy} 105e9d6f8ckmacy 106d84d862obrien/* 107d84d862obrien * Generic functions 108d84d862obrien */ 109d84d862obrien 110d84d862obrien/* Test to see if a service exists. */ 111d84d862obrienint 112d84d862obrienOF_test(char *name) 113d84d862obrien{ 114d84d862obrien static struct { 115128f33dmarius cell_t name; 116128f33dmarius cell_t nargs; 117128f33dmarius cell_t nreturns; 118128f33dmarius cell_t service; 119128f33dmarius cell_t missing; 120d84d862obrien } args = { 1210d8645drobert (cell_t)"test", 122d84d862obrien 1, 123d84d862obrien 1, 124d84d862obrien }; 125d84d862obrien 1260d8645drobert args.service = (cell_t)name; 127d84d862obrien if (openfirmware(&args) == -1) 128128f33dmarius return (-1); 129128f33dmarius return (args.missing); 130d84d862obrien} 131d84d862obrien 132d84d862obrien/* Return firmware millisecond count. */ 133d84d862obrienint 134d84d862obrienOF_milliseconds() 135d84d862obrien{ 136d84d862obrien static struct { 137128f33dmarius cell_t name; 138128f33dmarius cell_t nargs; 139128f33dmarius cell_t nreturns; 140128f33dmarius cell_t ms; 141d84d862obrien } args = { 1420d8645drobert (cell_t)"milliseconds", 143d84d862obrien 0, 144d84d862obrien 1, 145d84d862obrien }; 146128f33dmarius 147d84d862obrien openfirmware(&args); 148128f33dmarius return (args.ms); 149d84d862obrien} 150d84d862obrien 151d84d862obrien/* 152d84d862obrien * Device tree functions 153d84d862obrien */ 154d84d862obrien 155d84d862obrien/* Return the next sibling of this node or 0. */ 156d84d862obrienphandle_t 157d84d862obrienOF_peer(phandle_t node) 158d84d862obrien{ 159d84d862obrien static struct { 160128f33dmarius cell_t name; 161128f33dmarius cell_t nargs; 162128f33dmarius cell_t nreturns; 163128f33dmarius cell_t node; 164128f33dmarius cell_t next; 165d84d862obrien } args = { 1660d8645drobert (cell_t)"peer", 167d84d862obrien 1, 168d84d862obrien 1, 169d84d862obrien }; 170d84d862obrien 171128f33dmarius args.node = node; 172d84d862obrien if (openfirmware(&args) == -1) 173128f33dmarius return (-1); 174128f33dmarius return (args.next); 175d84d862obrien} 176d84d862obrien 177d84d862obrien/* Return the first child of this node or 0. */ 178d84d862obrienphandle_t 179d84d862obrienOF_child(phandle_t node) 180d84d862obrien{ 181d84d862obrien static struct { 182128f33dmarius cell_t name; 183128f33dmarius cell_t nargs; 184128f33dmarius cell_t nreturns; 185128f33dmarius cell_t node; 186128f33dmarius cell_t child; 187d84d862obrien } args = { 1880d8645drobert (cell_t)"child", 189d84d862obrien 1, 190d84d862obrien 1, 191d84d862obrien }; 192d84d862obrien 193128f33dmarius args.node = node; 194d84d862obrien if (openfirmware(&args) == -1) 195128f33dmarius return (-1); 196128f33dmarius return (args.child); 197d84d862obrien} 198d84d862obrien 199d84d862obrien/* Return the parent of this node or 0. */ 200d84d862obrienphandle_t 201d84d862obrienOF_parent(phandle_t node) 202d84d862obrien{ 203d84d862obrien static struct { 204128f33dmarius cell_t name; 205128f33dmarius cell_t nargs; 206128f33dmarius cell_t nreturns; 207128f33dmarius cell_t node; 208128f33dmarius cell_t parent; 209d84d862obrien } args = { 2100d8645drobert (cell_t)"parent", 211d84d862obrien 1, 212d84d862obrien 1, 213d84d862obrien }; 214d84d862obrien 215128f33dmarius args.node = node; 216d84d862obrien if (openfirmware(&args) == -1) 217128f33dmarius return (-1); 218128f33dmarius return (args.parent); 219d84d862obrien} 220d84d862obrien 221d84d862obrien/* Return the package handle that corresponds to an instance handle. */ 222d84d862obrienphandle_t 223d84d862obrienOF_instance_to_package(ihandle_t instance) 224d84d862obrien{ 225d84d862obrien static struct { 226128f33dmarius cell_t name; 227128f33dmarius cell_t nargs; 228128f33dmarius cell_t nreturns; 229128f33dmarius cell_t instance; 230128f33dmarius cell_t package; 231d84d862obrien } args = { 2320d8645drobert (cell_t)"instance-to-package", 233d84d862obrien 1, 234d84d862obrien 1, 235d84d862obrien }; 236128f33dmarius 237128f33dmarius args.instance = instance; 238d84d862obrien if (openfirmware(&args) == -1) 239128f33dmarius return (-1); 240128f33dmarius return (args.package); 241d84d862obrien} 242d84d862obrien 243d84d862obrien/* Get the length of a property of a package. */ 244d84d862obrienint 24525cf093impOF_getproplen(phandle_t package, const char *propname) 246d84d862obrien{ 247d84d862obrien static struct { 248128f33dmarius cell_t name; 249128f33dmarius cell_t nargs; 250128f33dmarius cell_t nreturns; 251128f33dmarius cell_t package; 252128f33dmarius cell_t propname; 253128f33dmarius cell_t proplen; 254d84d862obrien } args = { 2550d8645drobert (cell_t)"getproplen", 256d84d862obrien 2, 257d84d862obrien 1, 258d84d862obrien }; 259d84d862obrien 260128f33dmarius args.package = package; 2610d8645drobert args.propname = (cell_t)propname; 262d84d862obrien if (openfirmware(&args) == -1) 263128f33dmarius return (-1); 264128f33dmarius return (args.proplen); 265d84d862obrien} 266d84d862obrien 267d84d862obrien/* Get the value of a property of a package. */ 268d84d862obrienint 26925cf093impOF_getprop(phandle_t package, const char *propname, void *buf, int buflen) 270d84d862obrien{ 271d84d862obrien static struct { 272128f33dmarius cell_t name; 273128f33dmarius cell_t nargs; 274128f33dmarius cell_t nreturns; 275128f33dmarius cell_t package; 276128f33dmarius cell_t propname; 277128f33dmarius cell_t buf; 278128f33dmarius cell_t buflen; 279128f33dmarius cell_t size; 280d84d862obrien } args = { 2810d8645drobert (cell_t)"getprop", 282d84d862obrien 4, 283d84d862obrien 1, 284d84d862obrien }; 285128f33dmarius 286128f33dmarius args.package = package; 2870d8645drobert args.propname = (cell_t)propname; 2880d8645drobert args.buf = (cell_t)buf; 289128f33dmarius args.buflen = buflen; 290d84d862obrien if (openfirmware(&args) == -1) 291128f33dmarius return (-1); 292128f33dmarius return (args.size); 293d84d862obrien} 294d84d862obrien 295d84d862obrien/* Get the next property of a package. */ 296d84d862obrienint 29725cf093impOF_nextprop(phandle_t package, const char *previous, char *buf) 298d84d862obrien{ 299d84d862obrien static struct { 300128f33dmarius cell_t name; 301128f33dmarius cell_t nargs; 302128f33dmarius cell_t nreturns; 303128f33dmarius cell_t package; 304128f33dmarius cell_t previous; 305128f33dmarius cell_t buf; 306128f33dmarius cell_t flag; 307d84d862obrien } args = { 3080d8645drobert (cell_t)"nextprop", 309d84d862obrien 3, 310d84d862obrien 1, 311d84d862obrien }; 312d84d862obrien 313128f33dmarius args.package = package; 3140d8645drobert args.previous = (cell_t)previous; 3150d8645drobert args.buf = (cell_t)buf; 316d84d862obrien if (openfirmware(&args) == -1) 317128f33dmarius return (-1); 318128f33dmarius return (args.flag); 319d84d862obrien} 320d84d862obrien 321d84d862obrien/* Set the value of a property of a package. */ 322d84d862obrien/* XXX Has a bug on FirePower */ 323d84d862obrienint 32425cf093impOF_setprop(phandle_t package, const char *propname, void *buf, int len) 325d84d862obrien{ 326d84d862obrien static struct { 327128f33dmarius cell_t name; 328128f33dmarius cell_t nargs; 329128f33dmarius cell_t nreturns; 330128f33dmarius cell_t package; 331128f33dmarius cell_t propname; 332128f33dmarius cell_t buf; 333128f33dmarius cell_t len; 334128f33dmarius cell_t size; 335d84d862obrien } args = { 3360d8645drobert (cell_t)"setprop", 337d84d862obrien 4, 338d84d862obrien 1, 339d84d862obrien }; 340128f33dmarius 341128f33dmarius args.package = package; 3420d8645drobert args.propname = (cell_t)propname; 3430d8645drobert args.buf = (cell_t)buf; 344128f33dmarius args.len = len; 345d84d862obrien if (openfirmware(&args) == -1) 346128f33dmarius return (-1); 347128f33dmarius return (args.size); 348d84d862obrien} 349d84d862obrien 350d84d862obrien/* Convert a device specifier to a fully qualified pathname. */ 351d84d862obrienint 3527d73a33bennoOF_canon(const char *device, char *buf, int len) 353d84d862obrien{ 354d84d862obrien static struct { 355128f33dmarius cell_t name; 356128f33dmarius cell_t nargs; 357128f33dmarius cell_t nreturns; 358128f33dmarius cell_t device; 359128f33dmarius cell_t buf; 360128f33dmarius cell_t len; 361128f33dmarius cell_t size; 362d84d862obrien } args = { 3630d8645drobert (cell_t)"canon", 364d84d862obrien 3, 365d84d862obrien 1, 366d84d862obrien }; 367128f33dmarius 3680d8645drobert args.device = (cell_t)device; 3690d8645drobert args.buf = (cell_t)buf; 370128f33dmarius args.len = len; 371d84d862obrien if (openfirmware(&args) == -1) 372128f33dmarius return (-1); 373128f33dmarius return (args.size); 374d84d862obrien} 375d84d862obrien 376d84d862obrien/* Return a package handle for the specified device. */ 377d84d862obrienphandle_t 3787d73a33bennoOF_finddevice(const char *device) 379d84d862obrien{ 380d84d862obrien static struct { 381128f33dmarius cell_t name; 382128f33dmarius cell_t nargs; 383128f33dmarius cell_t nreturns; 384128f33dmarius cell_t device; 385128f33dmarius cell_t package; 386d84d862obrien } args = { 3870d8645drobert (cell_t)"finddevice", 388d84d862obrien 1, 389d84d862obrien 1, 390128f33dmarius }; 391128f33dmarius 3920d8645drobert args.device = (cell_t)device; 393d84d862obrien if (openfirmware(&args) == -1) 394128f33dmarius return (-1); 395128f33dmarius return (args.package); 396d84d862obrien} 397d84d862obrien 398d84d862obrien/* Return the fully qualified pathname corresponding to an instance. */ 399d84d862obrienint 400d84d862obrienOF_instance_to_path(ihandle_t instance, char *buf, int len) 401d84d862obrien{ 402d84d862obrien static struct { 403128f33dmarius cell_t name; 404128f33dmarius cell_t nargs; 405128f33dmarius cell_t nreturns; 406128f33dmarius cell_t instance; 407128f33dmarius cell_t buf; 408128f33dmarius cell_t len; 409128f33dmarius cell_t size; 410d84d862obrien } args = { 4110d8645drobert (cell_t)"instance-to-path", 412d84d862obrien 3, 413d84d862obrien 1, 414d84d862obrien }; 415d84d862obrien 416128f33dmarius args.instance = instance; 4170d8645drobert args.buf = (cell_t)buf; 418128f33dmarius args.len = len; 419d84d862obrien if (openfirmware(&args) == -1) 420128f33dmarius return (-1); 421128f33dmarius return (args.size); 422d84d862obrien} 423d84d862obrien 424d84d862obrien/* Return the fully qualified pathname corresponding to a package. */ 425d84d862obrienint 426d84d862obrienOF_package_to_path(phandle_t package, char *buf, int len) 427d84d862obrien{ 428d84d862obrien static struct { 429128f33dmarius cell_t name; 430128f33dmarius cell_t nargs; 431128f33dmarius cell_t nreturns; 432128f33dmarius cell_t package; 433128f33dmarius cell_t buf; 434128f33dmarius cell_t len; 435128f33dmarius cell_t size; 436d84d862obrien } args = { 4370d8645drobert (cell_t)"package-to-path", 438d84d862obrien 3, 439d84d862obrien 1, 440d84d862obrien }; 441d84d862obrien 442128f33dmarius args.package = package; 4430d8645drobert args.buf = (cell_t)buf; 444128f33dmarius args.len = len; 445d84d862obrien if (openfirmware(&args) == -1) 446128f33dmarius return (-1); 447128f33dmarius return (args.size); 448d84d862obrien} 449d84d862obrien 450d84d862obrien/* Call the method in the scope of a given instance. */ 451d84d862obrienint 452d84d862obrienOF_call_method(char *method, ihandle_t instance, int nargs, int nreturns, ...) 453d84d862obrien{ 454d84d862obrien va_list ap; 455d84d862obrien static struct { 456128f33dmarius cell_t name; 457128f33dmarius cell_t nargs; 458128f33dmarius cell_t nreturns; 459128f33dmarius cell_t method; 460128f33dmarius cell_t instance; 461128f33dmarius cell_t args_n_results[12]; 462d84d862obrien } args = { 4630d8645drobert (cell_t)"call-method", 464d84d862obrien 2, 465d84d862obrien 1, 466d84d862obrien }; 467d6e6728marius cell_t *cp; 468d6e6728marius int n; 469d84d862obrien 470d84d862obrien if (nargs > 6) 471128f33dmarius return (-1); 472d84d862obrien args.nargs = nargs + 2; 473d84d862obrien args.nreturns = nreturns + 1; 4740d8645drobert args.method = (cell_t)method; 475128f33dmarius args.instance = instance; 476d84d862obrien va_start(ap, nreturns); 477d6e6728marius for (cp = (cell_t *)(args.args_n_results + (n = nargs)); --n >= 0;) 478d6e6728marius *--cp = va_arg(ap, cell_t); 479d84d862obrien if (openfirmware(&args) == -1) 480128f33dmarius return (-1); 481d84d862obrien if (args.args_n_results[nargs]) 482128f33dmarius return (args.args_n_results[nargs]); 483d6e6728marius for (cp = (cell_t *)(args.args_n_results + nargs + (n = args.nreturns)); 4840d8645drobert --n > 0;) 485d6e6728marius *va_arg(ap, cell_t *) = *--cp; 486d84d862obrien va_end(ap); 487128f33dmarius return (0); 488d84d862obrien} 489d84d862obrien 490d84d862obrien/* 491128f33dmarius * Device I/O functions 492d84d862obrien */ 493d84d862obrien 494d84d862obrien/* Open an instance for a device. */ 495d84d862obrienihandle_t 496d84d862obrienOF_open(char *device) 497d84d862obrien{ 498d84d862obrien static struct { 499128f33dmarius cell_t name; 500128f33dmarius cell_t nargs; 501128f33dmarius cell_t nreturns; 502128f33dmarius cell_t device; 503128f33dmarius cell_t instance; 504d84d862obrien } args = { 5050d8645drobert (cell_t)"open", 506d84d862obrien 1, 507d84d862obrien 1, 508d84d862obrien }; 509128f33dmarius 5100d8645drobert args.device = (cell_t)device; 511d84d862obrien if (openfirmware(&args) == -1 || args.instance == 0) { 512128f33dmarius return (-1); 513d84d862obrien } 514128f33dmarius return (args.instance); 515d84d862obrien} 516d84d862obrien 517d84d862obrien/* Close an instance. */ 518d84d862obrienvoid 519d84d862obrienOF_close(ihandle_t instance) 520d84d862obrien{ 521d84d862obrien static struct { 522128f33dmarius cell_t name; 523128f33dmarius cell_t nargs; 524128f33dmarius cell_t nreturns; 525128f33dmarius cell_t instance; 526d84d862obrien } args = { 5270d8645drobert (cell_t)"close", 528d84d862obrien 1, 529d84d862obrien }; 530128f33dmarius 531128f33dmarius args.instance = instance; 532d84d862obrien openfirmware(&args); 533d84d862obrien} 534d84d862obrien 535d84d862obrien/* Read from an instance. */ 536d84d862obrienint 537d84d862obrienOF_read(ihandle_t instance, void *addr, int len) 538d84d862obrien{ 539d84d862obrien static struct { 540128f33dmarius cell_t name; 541128f33dmarius cell_t nargs; 542128f33dmarius cell_t nreturns; 543128f33dmarius cell_t instance; 544128f33dmarius cell_t addr; 545128f33dmarius cell_t len; 546128f33dmarius cell_t actual; 547d84d862obrien } args = { 5480d8645drobert (cell_t)"read", 549d84d862obrien 3, 550d84d862obrien 1, 551d84d862obrien }; 552d84d862obrien 553128f33dmarius args.instance = instance; 5540d8645drobert args.addr = (cell_t)addr; 555128f33dmarius args.len = len; 5567d73a33benno 5577d73a33benno#if defined(OPENFIRM_DEBUG) 5587d73a33benno printf("OF_read: called with instance=%08x, addr=%p, len=%d\n", 5597d73a33benno args.instance, args.addr, args.len); 5607d73a33benno#endif 5617d73a33benno 562d84d862obrien if (openfirmware(&args) == -1) 563128f33dmarius return (-1); 5647d73a33benno 5657d73a33benno#if defined(OPENFIRM_DEBUG) 5667d73a33benno printf("OF_read: returning instance=%d, addr=%p, len=%d, actual=%d\n", 5677d73a33benno args.instance, args.addr, args.len, args.actual); 5687d73a33benno#endif 5697d73a33benno 570128f33dmarius return (args.actual); 571d84d862obrien} 572d84d862obrien 573d84d862obrien/* Write to an instance. */ 574d84d862obrienint 575d84d862obrienOF_write(ihandle_t instance, void *addr, int len) 576d84d862obrien{ 577d84d862obrien static struct { 578128f33dmarius cell_t name; 579128f33dmarius cell_t nargs; 580128f33dmarius cell_t nreturns; 581128f33dmarius cell_t instance; 582128f33dmarius cell_t addr; 583128f33dmarius cell_t len; 584128f33dmarius cell_t actual; 585d84d862obrien } args = { 5860d8645drobert (cell_t)"write", 587d84d862obrien 3, 588d84d862obrien 1, 589d84d862obrien }; 590d84d862obrien 591128f33dmarius args.instance = instance; 5920d8645drobert args.addr = (cell_t)addr; 593128f33dmarius args.len = len; 594d84d862obrien if (openfirmware(&args) == -1) 595128f33dmarius return (-1); 596128f33dmarius return (args.actual); 597d84d862obrien} 598d84d862obrien 599d84d862obrien/* Seek to a position. */ 600d84d862obrienint 601cb38894impOF_seek(ihandle_t instance, uint64_t pos) 602d84d862obrien{ 603d84d862obrien static struct { 604128f33dmarius cell_t name; 605128f33dmarius cell_t nargs; 606128f33dmarius cell_t nreturns; 607128f33dmarius cell_t instance; 608128f33dmarius cell_t poshi; 609128f33dmarius cell_t poslo; 610128f33dmarius cell_t status; 611d84d862obrien } args = { 6120d8645drobert (cell_t)"seek", 613d84d862obrien 3, 614d84d862obrien 1, 615d84d862obrien }; 616128f33dmarius 617128f33dmarius args.instance = instance; 6180d8645drobert args.poshi = pos >> 32; 6190d8645drobert args.poslo = pos; 620d84d862obrien if (openfirmware(&args) == -1) 621128f33dmarius return (-1); 622128f33dmarius return (args.status); 623d84d862obrien} 624d84d862obrien 625697206dtsoome/* Blocks. */ 626697206dtsoomeunsigned int 627697206dtsoomeOF_blocks(ihandle_t instance) 628697206dtsoome{ 629697206dtsoome static struct { 630697206dtsoome cell_t name; 631697206dtsoome cell_t nargs; 632697206dtsoome cell_t nreturns; 633697206dtsoome cell_t instance; 634697206dtsoome cell_t result; 635697206dtsoome cell_t blocks; 636697206dtsoome } args = { 637697206dtsoome (cell_t)"#blocks", 638697206dtsoome 2, 639697206dtsoome 1, 640697206dtsoome }; 641697206dtsoome 642697206dtsoome args.instance = instance; 643697206dtsoome if (openfirmware(&args) == -1) 644697206dtsoome return ((unsigned int)-1); 645697206dtsoome return (args.blocks); 646697206dtsoome} 647697206dtsoome 648697206dtsoome/* Block size. */ 649697206dtsoomeint 650697206dtsoomeOF_block_size(ihandle_t instance) 651697206dtsoome{ 652697206dtsoome static struct { 653697206dtsoome cell_t name; 654697206dtsoome cell_t nargs; 655697206dtsoome cell_t nreturns; 656697206dtsoome cell_t instance; 657697206dtsoome cell_t result; 658697206dtsoome cell_t size; 659697206dtsoome } args = { 660697206dtsoome (cell_t)"block-size", 661697206dtsoome 2, 662697206dtsoome 1, 663697206dtsoome }; 664697206dtsoome 665697206dtsoome args.instance = instance; 666697206dtsoome if (openfirmware(&args) == -1) 667697206dtsoome return (512); 668697206dtsoome return (args.size); 669697206dtsoome} 670697206dtsoome 671697206dtsoome/* 672128f33dmarius * Memory functions 673d84d862obrien */ 674d84d862obrien 675d84d862obrien/* Claim an area of memory. */ 676d84d862obrienvoid * 677d84d862obrienOF_claim(void *virt, u_int size, u_int align) 678d84d862obrien{ 679d84d862obrien static struct { 680128f33dmarius cell_t name; 681128f33dmarius cell_t nargs; 682128f33dmarius cell_t nreturns; 683128f33dmarius cell_t virt; 684128f33dmarius cell_t size; 685128f33dmarius cell_t align; 686128f33dmarius cell_t baseaddr; 687d84d862obrien } args = { 6880d8645drobert (cell_t)"claim", 689d84d862obrien 3, 690d84d862obrien 1, 691d84d862obrien }; 692d84d862obrien 6930d8645drobert args.virt = (cell_t)virt; 694d84d862obrien args.size = size; 695d84d862obrien args.align = align; 696d84d862obrien if (openfirmware(&args) == -1) 697128f33dmarius return ((void *)-1); 698128f33dmarius return ((void *)args.baseaddr); 6990d8645drobert} 7000d8645drobert 701d84d862obrien/* Release an area of memory. */ 702d84d862obrienvoid 703d84d862obrienOF_release(void *virt, u_int size) 704d84d862obrien{ 705d84d862obrien static struct { 706128f33dmarius cell_t name; 707128f33dmarius cell_t nargs; 708128f33dmarius cell_t nreturns; 709128f33dmarius cell_t virt; 710128f33dmarius cell_t size; 711d84d862obrien } args = { 7120d8645drobert (cell_t)"release", 713d84d862obrien 2, 714d84d862obrien }; 715128f33dmarius 7160d8645drobert args.virt = (cell_t)virt; 717d84d862obrien args.size = size; 718d84d862obrien openfirmware(&args); 719d84d862obrien} 720d84d862obrien 721d84d862obrien/* 722128f33dmarius * Control transfer functions 723d84d862obrien */ 724d84d862obrien 725d84d862obrien/* Reset the system and call "boot <bootspec>". */ 726d84d862obrienvoid 727d84d862obrienOF_boot(char *bootspec) 728d84d862obrien{ 729d84d862obrien static struct { 730128f33dmarius cell_t name; 731128f33dmarius cell_t nargs; 732128f33dmarius cell_t nreturns; 733128f33dmarius cell_t bootspec; 734d84d862obrien } args = { 7350d8645drobert (cell_t)"boot", 736d84d862obrien 1, 737d84d862obrien }; 738d84d862obrien 7390d8645drobert args.bootspec = (cell_t)bootspec; 740d84d862obrien openfirmware(&args); 741128f33dmarius for (;;) /* just in case */ 742128f33dmarius ; 743d84d862obrien} 744d84d862obrien 74524ad8a9marius/* Suspend and drop back to the Open Firmware interface. */ 746d84d862obrienvoid 747d84d862obrienOF_enter() 748d84d862obrien{ 749d84d862obrien static struct { 750128f33dmarius cell_t name; 751128f33dmarius cell_t nargs; 752128f33dmarius cell_t nreturns; 753d84d862obrien } args = { 7540d8645drobert (cell_t)"enter", 755d84d862obrien }; 756d84d862obrien 757d84d862obrien openfirmware(&args); 758128f33dmarius /* We may come back. */ 759d84d862obrien} 760d84d862obrien 76124ad8a9marius/* Shut down and drop back to the Open Firmware interface. */ 7627d73a33bennovoid 763d84d862obrienOF_exit() 764d84d862obrien{ 765d84d862obrien static struct { 766128f33dmarius cell_t name; 767128f33dmarius cell_t nargs; 768128f33dmarius cell_t nreturns; 769d84d862obrien } args = { 7700d8645drobert (cell_t)"exit", 771d84d862obrien }; 772d84d862obrien 773d84d862obrien openfirmware(&args); 774128f33dmarius for (;;) /* just in case */ 775128f33dmarius ; 776d84d862obrien} 777d84d862obrien 77859b9a76nwhitehornvoid 77959b9a76nwhitehornOF_quiesce() 78059b9a76nwhitehorn{ 78159b9a76nwhitehorn static struct { 78259b9a76nwhitehorn cell_t name; 78359b9a76nwhitehorn cell_t nargs; 78459b9a76nwhitehorn cell_t nreturns; 78559b9a76nwhitehorn } args = { 78659b9a76nwhitehorn (cell_t)"quiesce", 78759b9a76nwhitehorn }; 78859b9a76nwhitehorn 78959b9a76nwhitehorn openfirmware(&args); 79059b9a76nwhitehorn} 79159b9a76nwhitehorn 792d84d862obrien/* Free <size> bytes starting at <virt>, then call <entry> with <arg>. */ 7936001ea5grehan#if 0 794d84d862obrienvoid 795d84d862obrienOF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) 796d84d862obrien{ 797d84d862obrien static struct { 798128f33dmarius cell_t name; 799128f33dmarius cell_t nargs; 800128f33dmarius cell_t nreturns; 801128f33dmarius cell_t virt; 802128f33dmarius cell_t size; 803128f33dmarius cell_t entry; 804128f33dmarius cell_t arg; 805128f33dmarius cell_t len; 806d84d862obrien } args = { 8070d8645drobert (cell_t)"chain", 808d84d862obrien 5, 809d84d862obrien }; 810d84d862obrien 8110d8645drobert args.virt = (cell_t)virt; 812d84d862obrien args.size = size; 8130d8645drobert args.entry = (cell_t)entry; 8140d8645drobert args.arg = (cell_t)arg; 815d84d862obrien args.len = len; 816d84d862obrien openfirmware(&args); 817d84d862obrien} 818d84d862obrien#else 819d84d862obrienvoid 820d84d862obrienOF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) 821d84d862obrien{ 822d84d862obrien /* 823d84d862obrien * This is a REALLY dirty hack till the firmware gets this going 824d84d862obrien */ 8256001ea5grehan#if 0 826994f797benno if (size > 0) 827994f797benno OF_release(virt, size); 8286001ea5grehan#endif 829d84d862obrien entry(0, 0, openfirmware, arg, len); 830d84d862obrien} 831d84d862obrien#endif 832