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