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