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