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