Home | History | Annotate | Line # | Download | only in ofwboot
Locore.c revision 1.1
      1 /*	$NetBSD: Locore.c,v 1.1 2000/08/20 14:58:36 mrg Exp $	*/
      2 
      3 /*
      4  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
      5  * Copyright (C) 1995, 1996 TooLs GmbH.
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. All advertising materials mentioning features or use of this software
     17  *    must display the following acknowledgement:
     18  *	This product includes software developed by TooLs GmbH.
     19  * 4. The name of TooLs GmbH may not be used to endorse or promote products
     20  *    derived from this software without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
     23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     28  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 
     34 #include <lib/libsa/stand.h>
     35 #include "openfirm.h"
     36 
     37 #include <machine/cpu.h>
     38 
     39 vaddr_t OF_claim_virt __P((vaddr_t vaddr, int len));
     40 vaddr_t OF_alloc_virt __P((int len, int align));
     41 int OF_free_virt __P((vaddr_t vaddr, int len));
     42 int OF_unmap_virt __P((vaddr_t vaddr, int len));
     43 vaddr_t OF_map_phys __P((paddr_t paddr, off_t size, vaddr_t vaddr, int mode));
     44 paddr_t OF_alloc_phys __P((int len, int align));
     45 paddr_t OF_claim_phys __P((paddr_t phys, int len));
     46 int OF_free_phys __P((paddr_t paddr, int len));
     47 
     48 extern int openfirmware(void *);
     49 
     50 void setup __P((void));
     51 
     52 #if 0
     53 #ifdef XCOFF_GLUE
     54 asm (".text; .globl _entry; _entry: .long _start,0,0");
     55 #endif
     56 
     57 __dead void
     58 _start(vpd, res, openfirm, arg, argl)
     59 	void *vpd;
     60 	int res;
     61 	int (*openfirm)(void *);
     62 	char *arg;
     63 	int argl;
     64 {
     65 	extern char etext[];
     66 
     67 #ifdef	FIRMWORKSBUGS
     68 	syncicache((void *)RELOC, etext - (char *)RELOC);
     69 #endif
     70 	openfirmware = openfirm;	/* Save entry to Open Firmware */
     71 	setup();
     72 	main(arg, argl);
     73 	exit();
     74 }
     75 #endif
     76 
     77 __dead void
     78 _rtt()
     79 {
     80 	struct {
     81 		cell_t name;
     82 		cell_t nargs;
     83 		cell_t nreturns;
     84 	} args;
     85 
     86 	args.name = ADR2CELL("exit");
     87 	args.nargs = 0;
     88 	args.nreturns = 0;
     89 	openfirmware(&args);
     90 	while (1);			/* just in case */
     91 }
     92 
     93 void
     94 OF_enter()
     95 {
     96 	struct {
     97 		cell_t name;
     98 		cell_t nargs;
     99 		cell_t nreturns;
    100 	} args;
    101 
    102 	args.name = ADR2CELL("enter");
    103 	args.nargs = 0;
    104 	args.nreturns = 0;
    105 	openfirmware(&args);
    106 }
    107 
    108 int
    109 OF_finddevice(name)
    110 	char *name;
    111 {
    112 	struct {
    113 		cell_t name;
    114 		cell_t nargs;
    115 		cell_t nreturns;
    116 		cell_t device;
    117 		cell_t phandle;
    118 	} args;
    119 
    120 	args.name = ADR2CELL("finddevice");
    121 	args.nargs = 1;
    122 	args.nreturns = 1;
    123 	args.device = ADR2CELL(name);
    124 	if (openfirmware(&args) == -1)
    125 		return -1;
    126 	return args.phandle;
    127 }
    128 
    129 int
    130 OF_instance_to_package(ihandle)
    131 	int ihandle;
    132 {
    133 	struct {
    134 		cell_t name;
    135 		cell_t nargs;
    136 		cell_t nreturns;
    137 		cell_t ihandle;
    138 		cell_t phandle;
    139 	} args;
    140 
    141 	args.name = ADR2CELL("instance-to-package");
    142 	args.nargs = 1;
    143 	args.nreturns = 1;
    144 	args.ihandle = HDL2CELL(ihandle);
    145 	if (openfirmware(&args) == -1)
    146 		return -1;
    147 	return args.phandle;
    148 }
    149 
    150 int
    151 OF_getprop(handle, prop, buf, buflen)
    152 	int handle;
    153 	char *prop;
    154 	void *buf;
    155 	int buflen;
    156 {
    157 	struct {
    158 		cell_t name;
    159 		cell_t nargs;
    160 		cell_t nreturns;
    161 		cell_t phandle;
    162 		cell_t prop;
    163 		cell_t buf;
    164 		cell_t buflen;
    165 		cell_t size;
    166 	} args;
    167 
    168 	args.name = ADR2CELL("getprop");
    169 	args.nargs = 4;
    170 	args.nreturns = 1;
    171 	args.phandle = HDL2CELL(handle);
    172 	args.prop = ADR2CELL(prop);
    173 	args.buf = ADR2CELL(buf);
    174 	args.buflen = buflen;
    175 	if (openfirmware(&args) == -1)
    176 		return -1;
    177 	return args.size;
    178 }
    179 
    180 #ifdef	__notyet__	/* Has a bug on FirePower */
    181 int
    182 OF_setprop(handle, prop, buf, len)
    183 	u_int handle;
    184 	char *prop;
    185 	void *buf;
    186 	int len;
    187 {
    188 	struct {
    189 		cell_t name;
    190 		cell_t nargs;
    191 		cell_t nreturns;
    192 		cell_t phandle;
    193 		cell_t prop;
    194 		cell_t buf;
    195 		cell_t len;
    196 		cell_t size;
    197 	} args;
    198 
    199 	args.name = ADR2CELL("setprop");
    200 	args.nargs = 4;
    201 	args.nreturns = 1;
    202 	args.phandle = HDL2CELL(handle);
    203 	args.prop = ADR2CELL(prop);
    204 	args.buf = ADR2CELL(buf);
    205 	args.len = len;
    206 	if (openfirmware(&args) == -1)
    207 		return -1;
    208 	return args.size;
    209 }
    210 #endif
    211 
    212 int
    213 OF_open(dname)
    214 	char *dname;
    215 {
    216 	struct {
    217 		cell_t name;
    218 		cell_t nargs;
    219 		cell_t nreturns;
    220 		cell_t dname;
    221 		cell_t handle;
    222 	} args;
    223 
    224 	args.name = ADR2CELL("open");
    225 	args.nargs = 1;
    226 	args.nreturns = 1;
    227 	args.dname = ADR2CELL(dname);
    228 	if (openfirmware(&args) == -1 ||
    229 	    args.handle == 0)
    230 		return -1;
    231 	return args.handle;
    232 }
    233 
    234 void
    235 OF_close(handle)
    236 	int handle;
    237 {
    238 	struct {
    239 		cell_t name;
    240 		cell_t nargs;
    241 		cell_t nreturns;
    242 		cell_t handle;
    243 	} args;
    244 
    245 	args.name = ADR2CELL("close");
    246 	args.nargs = 1;
    247 	args.nreturns = 1;
    248 	args.handle = HDL2CELL(handle);
    249 	openfirmware(&args);
    250 }
    251 
    252 int
    253 OF_write(handle, addr, len)
    254 	int handle;
    255 	void *addr;
    256 	int len;
    257 {
    258 	struct {
    259 		cell_t name;
    260 		cell_t nargs;
    261 		cell_t nreturns;
    262 		cell_t ihandle;
    263 		cell_t addr;
    264 		cell_t len;
    265 		cell_t actual;
    266 	} args;
    267 
    268 	args.name = ADR2CELL("write");
    269 	args.nargs = 3;
    270 	args.nreturns = 1;
    271 	args.ihandle = HDL2CELL(handle);
    272 	args.addr = ADR2CELL(addr);
    273 	args.len = len;
    274 	if (openfirmware(&args) == -1)
    275 		return -1;
    276 	return args.actual;
    277 }
    278 
    279 int
    280 OF_read(handle, addr, len)
    281 	int handle;
    282 	void *addr;
    283 	int len;
    284 {
    285 	struct {
    286 		cell_t name;
    287 		cell_t nargs;
    288 		cell_t nreturns;
    289 		cell_t ihandle;
    290 		cell_t addr;
    291 		cell_t len;
    292 		cell_t actual;
    293 	} args;
    294 
    295 	args.name = ADR2CELL("read");
    296 	args.nargs = 3;
    297 	args.nreturns = 1;
    298 	args.ihandle = HDL2CELL(handle);
    299 	args.addr = ADR2CELL(addr);
    300 	args.len = len;
    301 	if (openfirmware(&args) == -1) {
    302 		return -1;
    303 	}
    304 	return args.actual;
    305 }
    306 
    307 int
    308 OF_seek(handle, pos)
    309 	int handle;
    310 	u_quad_t pos;
    311 {
    312 	struct {
    313 		cell_t name;
    314 		cell_t nargs;
    315 		cell_t nreturns;
    316 		cell_t handle;
    317 		cell_t poshi;
    318 		cell_t poslo;
    319 		cell_t status;
    320 	} args;
    321 
    322 	args.name = ADR2CELL("seek");
    323 	args.nargs = 3;
    324 	args.nreturns = 1;
    325 	args.handle = HDL2CELL(handle);
    326 	args.poshi = HDL2CELL(pos >> 32);
    327 	args.poslo = HDL2CELL(pos);
    328 	if (openfirmware(&args) == -1) {
    329 		return -1;
    330 	}
    331 	return args.status;
    332 }
    333 
    334 void
    335 OF_release(virt, size)
    336 	void *virt;
    337 	u_int size;
    338 {
    339 	struct {
    340 		cell_t name;
    341 		cell_t nargs;
    342 		cell_t nreturns;
    343 		cell_t virt;
    344 		cell_t size;
    345 	} args;
    346 
    347 	args.name = ADR2CELL("release");
    348 	args.nargs = 2;
    349 	args.nreturns = 0;
    350 	args.virt = ADR2CELL(virt);
    351 	args.size = size;
    352 	openfirmware(&args);
    353 }
    354 
    355 int
    356 OF_milliseconds()
    357 {
    358 	struct {
    359 		cell_t name;
    360 		cell_t nargs;
    361 		cell_t nreturns;
    362 		cell_t ms;
    363 	} args;
    364 
    365 	args.name = ADR2CELL("milliseconds");
    366 	args.nargs = 0;
    367 	args.nreturns = 1;
    368 	openfirmware(&args);
    369 	return args.ms;
    370 }
    371 
    372 void
    373 OF_chain(virt, size, entry, arg, len)
    374 	void *virt;
    375 	u_int size;
    376 	void (*entry)();
    377 	void *arg;
    378 	u_int len;
    379 {
    380 	extern int64_t romp;
    381 	extern int debug;
    382 	struct {
    383 		cell_t name;
    384 		cell_t nargs;
    385 		cell_t nreturns;
    386 		cell_t virt;
    387 		cell_t size;
    388 		cell_t entry;
    389 		cell_t arg;
    390 		cell_t len;
    391 	} args;
    392 
    393 	args.name = ADR2CELL("chain");
    394 	args.nargs = 5;
    395 	args.nreturns = 0;
    396 	args.virt = ADR2CELL(virt);
    397 	args.size = size;
    398 	args.entry = ADR2CELL(entry);
    399 	args.arg = ADR2CELL(arg);
    400 	args.len = len;
    401 	openfirmware(&args);
    402 	if (debug) {
    403 		printf("OF_chain: prom returned!\n");
    404 
    405 	/* OK, firmware failed us.  Try calling prog directly */
    406 		printf("Calling entry(0, %p, %x, %lx, %lx)\n", arg, len,
    407 			(unsigned long)romp, (unsigned long)romp);
    408 	}
    409 	entry(0, arg, len, (unsigned long)romp, (unsigned long)romp);
    410 	panic("OF_chain: kernel returned!\n");
    411 	__asm("ta 2" : :);
    412 }
    413 
    414 static u_int stdin;
    415 static u_int stdout;
    416 static u_int mmuh = -1;
    417 static u_int memh = -1;
    418 
    419 void
    420 setup()
    421 {
    422 	u_int chosen;
    423 
    424 	if ((chosen = OF_finddevice("/chosen")) == -1)
    425 		_rtt();
    426 	if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) != sizeof(stdin)
    427 	    || OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) != sizeof(stdout)
    428 	    || OF_getprop(chosen, "mmu", &mmuh, sizeof(mmuh)) != sizeof(mmuh)
    429 	    || OF_getprop(chosen, "memory", &memh, sizeof(memh)) != sizeof(memh))
    430 		_rtt();
    431 }
    432 
    433 /*
    434  * The following need either the handle to memory or the handle to the MMU.
    435  */
    436 
    437 /*
    438  * Grab some address space from the prom
    439  *
    440  * Only works while the prom is actively mapping us.
    441  */
    442 vaddr_t
    443 OF_claim_virt(vaddr, len)
    444 vaddr_t vaddr;
    445 int len;
    446 {
    447 	struct {
    448 		cell_t name;
    449 		cell_t nargs;
    450 		cell_t nreturns;
    451 		cell_t method;
    452 		cell_t ihandle;
    453 		cell_t align;
    454 		cell_t len;
    455 		cell_t vaddr;
    456 		cell_t status;
    457 		cell_t retaddr;
    458 	} args;
    459 
    460 #ifdef	__notyet
    461 	if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
    462 		OF_printf("OF_claim_virt: cannot get mmuh\r\n");
    463 		return -1LL;
    464 	}
    465 #endif
    466 	args.name = ADR2CELL("call-method");
    467 	args.nargs = 5;
    468 	args.nreturns = 2;
    469 	args.method = ADR2CELL("claim");
    470 	args.ihandle = HDL2CELL(mmuh);
    471 	args.align = 0;
    472 	args.len = len;
    473 	args.vaddr = ADR2CELL(vaddr);
    474 	if(openfirmware(&args) != 0)
    475 		return -1LL;
    476 	return args.retaddr; /* Kluge till we go 64-bit */
    477 }
    478 
    479 /*
    480  * Request some address space from the prom
    481  *
    482  * Only works while the prom is actively mapping us.
    483  */
    484 vaddr_t
    485 OF_alloc_virt(len, align)
    486 int len;
    487 int align;
    488 {
    489 	int retaddr=-1;
    490 	struct {
    491 		cell_t name;
    492 		cell_t nargs;
    493 		cell_t nreturns;
    494 		cell_t method;
    495 		cell_t ihandle;
    496 		cell_t align;
    497 		cell_t len;
    498 		cell_t status;
    499 		cell_t retaddr;
    500 	} args;
    501 
    502 #ifdef	__notyet
    503 	if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
    504 		OF_printf("OF_alloc_virt: cannot get mmuh\r\n");
    505 		return -1LL;
    506 	}
    507 #endif
    508 	args.name = ADR2CELL("call-method");
    509 	args.nargs = 4;
    510 	args.nreturns = 2;
    511 	args.method = ADR2CELL("claim");
    512 	args.ihandle = mmuh;
    513 	args.align = align;
    514 	args.len = len;
    515 	args.retaddr = ADR2CELL(&retaddr);
    516 	if(openfirmware(&args) != 0)
    517 		return -1LL;
    518 	return (vaddr_t)args.retaddr; /* Kluge till we go 64-bit */
    519 }
    520 
    521 /*
    522  * Release some address space to the prom
    523  *
    524  * Only works while the prom is actively mapping us.
    525  */
    526 int
    527 OF_free_virt(vaddr, len)
    528 vaddr_t vaddr;
    529 int len;
    530 {
    531 	struct {
    532 		cell_t name;
    533 		cell_t nargs;
    534 		cell_t nreturns;
    535 		cell_t method;
    536 		cell_t ihandle;
    537 		cell_t len;
    538 		cell_t vaddr;
    539 	} args;
    540 
    541 #ifdef	__notyet
    542 	if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
    543 		OF_printf("OF_claim_virt: cannot get mmuh\r\n");
    544 		return -1;
    545 	}
    546 #endif
    547 	args.name = ADR2CELL("call-method");
    548 	args.nargs = 4;
    549 	args.nreturns = 0;
    550 	args.method = ADR2CELL("release");
    551 	args.ihandle = HDL2CELL(mmuh);
    552 	args.vaddr = ADR2CELL(vaddr);
    553 	args.len = len;
    554 	return openfirmware(&args);
    555 }
    556 
    557 
    558 /*
    559  * Unmap some address space
    560  *
    561  * Only works while the prom is actively mapping us.
    562  */
    563 int
    564 OF_unmap_virt(vaddr, len)
    565 vaddr_t vaddr;
    566 int len;
    567 {
    568 	struct {
    569 		cell_t name;
    570 		cell_t nargs;
    571 		cell_t nreturns;
    572 		cell_t method;
    573 		cell_t ihandle;
    574 		cell_t len;
    575 		cell_t vaddr;
    576 	} args;
    577 
    578 #ifdef	__notyet
    579 	if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
    580 		OF_printf("OF_claim_virt: cannot get mmuh\r\n");
    581 		return -1;
    582 	}
    583 #endif
    584 	args.name = ADR2CELL("call-method");
    585 	args.nargs = 4;
    586 	args.nreturns = 0;
    587 	args.method = ADR2CELL("unmap");
    588 	args.ihandle = HDL2CELL(mmuh);
    589 	args.vaddr = ADR2CELL(vaddr);
    590 	args.len = len;
    591 	return openfirmware(&args);
    592 }
    593 
    594 /*
    595  * Have prom map in some memory
    596  *
    597  * Only works while the prom is actively mapping us.
    598  */
    599 vaddr_t
    600 OF_map_phys(paddr, size, vaddr, mode)
    601 paddr_t paddr;
    602 off_t size;
    603 vaddr_t vaddr;
    604 int mode;
    605 {
    606 	struct {
    607 		cell_t name;
    608 		cell_t nargs;
    609 		cell_t nreturns;
    610 		cell_t method;
    611 		cell_t ihandle;
    612 		cell_t mode;
    613 		cell_t size;
    614 		cell_t vaddr;
    615 		cell_t paddr_hi;
    616 		cell_t paddr_lo;
    617 		cell_t status;
    618 		cell_t retaddr;
    619 	} args;
    620 
    621 #ifdef	__notyet
    622 	if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
    623 		OF_printf("OF_map_phys: cannot get mmuh\r\n");
    624 		return 0LL;
    625 	}
    626 #endif
    627 	args.name = ADR2CELL("call-method");
    628 	args.nargs = 7;
    629 	args.nreturns = 1;
    630 	args.method = ADR2CELL("map");
    631 	args.ihandle = HDL2CELL(mmuh);
    632 	args.mode = mode;
    633 	args.size = size;
    634 	args.vaddr = ADR2CELL(vaddr);
    635 	args.paddr_hi = ADR2CELL(paddr>>32);
    636 	args.paddr_lo = ADR2CELL(paddr);
    637 
    638 	if (openfirmware(&args) == -1)
    639 		return -1;
    640 	if (args.status)
    641 		return -1;
    642 	return (vaddr_t)args.retaddr;
    643 }
    644 
    645 
    646 /*
    647  * Request some RAM from the prom
    648  *
    649  * Only works while the prom is actively mapping us.
    650  */
    651 paddr_t
    652 OF_alloc_phys(len, align)
    653 int len;
    654 int align;
    655 {
    656 	paddr_t paddr;
    657 	struct {
    658 		cell_t name;
    659 		cell_t nargs;
    660 		cell_t nreturns;
    661 		cell_t method;
    662 		cell_t ihandle;
    663 		cell_t align;
    664 		cell_t len;
    665 		cell_t status;
    666 		cell_t phys_hi;
    667 		cell_t phys_lo;
    668 	} args;
    669 
    670 #ifdef	__notyet
    671 	if (memh == -1 && ((memh = get_memory_handle()) == -1)) {
    672 		OF_printf("OF_alloc_phys: cannot get memh\r\n");
    673 		return -1LL;
    674 	}
    675 #endif
    676 	args.name = ADR2CELL("call-method");
    677 	args.nargs = 4;
    678 	args.nreturns = 3;
    679 	args.method = ADR2CELL("claim");
    680 	args.ihandle = HDL2CELL(memh);
    681 	args.align = align;
    682 	args.len = len;
    683 	if(openfirmware(&args) != 0)
    684 		return -1LL;
    685 	paddr = (paddr_t)(args.phys_hi<<32)|((unsigned int)(args.phys_lo));
    686 	return paddr; /* Kluge till we go 64-bit */
    687 }
    688 
    689 /*
    690  * Request some specific RAM from the prom
    691  *
    692  * Only works while the prom is actively mapping us.
    693  */
    694 paddr_t
    695 OF_claim_phys(phys, len)
    696 paddr_t phys;
    697 int len;
    698 {
    699 	paddr_t paddr;
    700 	struct {
    701 		cell_t name;
    702 		cell_t nargs;
    703 		cell_t nreturns;
    704 		cell_t method;
    705 		cell_t ihandle;
    706 		cell_t align;
    707 		cell_t len;
    708 		cell_t phys_hi;
    709 		cell_t phys_lo;
    710 		cell_t status;
    711 		cell_t res;
    712 		cell_t rphys_hi;
    713 		cell_t rphys_lo;
    714 	} args;
    715 
    716 #ifdef	__notyet
    717 	if (memh == -1 && ((memh = get_memory_handle()) == -1)) {
    718 		OF_printf("OF_alloc_phys: cannot get memh\r\n");
    719 		return 0LL;
    720 	}
    721 #endif
    722 	args.name = ADR2CELL("call-method");
    723 	args.nargs = 6;
    724 	args.nreturns = 4;
    725 	args.method = ADR2CELL("claim");
    726 	args.ihandle = HDL2CELL(memh);
    727 	args.align = 0;
    728 	args.len = len;
    729 	args.phys_hi = HDL2CELL(phys>>32);
    730 	args.phys_lo = HDL2CELL(phys);
    731 	if(openfirmware(&args) != 0)
    732 		return 0LL;
    733 	paddr = (paddr_t)(args.rphys_hi<<32)|((unsigned int)(args.rphys_lo));
    734 	return paddr;
    735 }
    736 
    737 /*
    738  * Free some RAM to prom
    739  *
    740  * Only works while the prom is actively mapping us.
    741  */
    742 int
    743 OF_free_phys(phys, len)
    744 paddr_t phys;
    745 int len;
    746 {
    747 	struct {
    748 		cell_t name;
    749 		cell_t nargs;
    750 		cell_t nreturns;
    751 		cell_t method;
    752 		cell_t ihandle;
    753 		cell_t len;
    754 		cell_t phys_hi;
    755 		cell_t phys_lo;
    756 	} args;
    757 
    758 #ifdef	__notyet
    759 	if (memh == -1 && ((memh = get_memory_handle()) == -1)) {
    760 		OF_printf("OF_free_phys: cannot get memh\r\n");
    761 		return -1;
    762 	}
    763 #endif
    764 	args.name = ADR2CELL("call-method");
    765 	args.nargs = 5;
    766 	args.nreturns = 0;
    767 	args.method = ADR2CELL("release");
    768 	args.ihandle = HDL2CELL(memh);
    769 	args.len = len;
    770 	args.phys_hi = HDL2CELL(phys>>32);
    771 	args.phys_lo = HDL2CELL(phys);
    772 	return openfirmware(&args);
    773 }
    774 
    775 
    776 /*
    777  * Claim virtual memory -- does not map it in.
    778  */
    779 
    780 void *
    781 OF_claim(virt, size, align)
    782 	void *virt;
    783 	u_int size;
    784 	u_int align;
    785 {
    786 #define SUNVMOF
    787 #ifndef SUNVMOF
    788 	struct {
    789 		cell_t name;
    790 		cell_t nargs;
    791 		cell_t nreturns;
    792 		cell_t virt;
    793 		cell_t size;
    794 		cell_t align;
    795 		cell_t baseaddr;
    796 	} args;
    797 
    798 
    799 	args.name = ADR2CELL("claim");
    800 	args.nargs = 3;
    801 	args.nreturns = 1;
    802 	args.virt = virt;
    803 	args.size = size;
    804 	args.align = align;
    805 	if (openfirmware(&args) == -1)
    806 		return (void *)-1;
    807 	return args.baseaddr;
    808 #else
    809 /*
    810  * Sun Ultra machines run the firmware with VM enabled,
    811  * so you need to handle allocating and mapping both
    812  * virtual and physical memory.  Ugh.
    813  */
    814 
    815 	paddr_t paddr;
    816 	void* newvirt = NULL;
    817 
    818 	if (virt == NULL) {
    819 		if ((virt = (void*)OF_alloc_virt(size, align)) == (void*)-1) {
    820 			printf("OF_alloc_virt(%d,%d) failed w/%x\n", size, align, virt);
    821 			return (void *)-1;
    822 		}
    823 	} else {
    824 		if ((newvirt = (void*)OF_claim_virt((vaddr_t)virt, size)) == (void*)-1) {
    825 			printf("OF_claim_virt(%x,%d) failed w/%x\n", virt, size, newvirt);
    826 			return (void *)-1;
    827 		}
    828 	}
    829 	if ((paddr = OF_alloc_phys(size, align)) == -1) {
    830 		printf("OF_alloc_phys(%d,%d) failed\n", size, align);
    831 		OF_free_virt((vaddr_t)virt, size);
    832 		return (void *)-1;
    833 	}
    834 	if (OF_map_phys(paddr, size, (vaddr_t)virt, -1) == -1) {
    835 		printf("OF_map_phys(%x,%d,%x,%d) failed\n", paddr, size, virt, -1);
    836 		OF_free_phys((paddr_t)paddr, size);
    837 		OF_free_virt((vaddr_t)virt, size);
    838 		return (void *)-1;
    839 	}
    840 	return (void *)virt;
    841 #endif
    842 }
    843 
    844 
    845 void
    846 putchar(c)
    847 	int c;
    848 {
    849 	char ch = c;
    850 
    851 	if (c == '\n')
    852 		putchar('\r');
    853 	OF_write(stdout, &ch, 1);
    854 }
    855 
    856 int
    857 getchar()
    858 {
    859 	unsigned char ch = '\0';
    860 	int l;
    861 
    862 	while ((l = OF_read(stdin, &ch, 1)) != 1)
    863 		if (l != -2 && l != 0)
    864 			return -1;
    865 	return ch;
    866 }
    867