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