Home | History | Annotate | Line # | Download | only in ofwboot
Locore.c revision 1.13.6.2
      1 /*	$NetBSD: Locore.c,v 1.13.6.2 2015/12/27 12:09:43 skrll 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 /*
     40  * We are trying to boot a sparc v9 cpu, so openfirmware has to be 64bit,
     41  * and the kernel we load will be dealing with 64bits too (even if it is
     42  * a 32bit kernel.
     43  * Make sure we picked up the right defines:
     44  */
     45 __CTASSERT(sizeof(cell_t)==8);
     46 __CTASSERT(sizeof(paddr_t)==8);
     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 = 0;
    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 = HDQ2CELL_HI(pos);
    315 	args.poslo = HDQ2CELL_LO(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 (vaddr_t)args.retaddr;
    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 = HDL2CELL(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;
    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 = HDQ2CELL_HI(paddr);
    605 	args.paddr_lo = HDQ2CELL_LO(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 	struct {
    624 		cell_t name;
    625 		cell_t nargs;
    626 		cell_t nreturns;
    627 		cell_t method;
    628 		cell_t ihandle;
    629 		cell_t align;
    630 		cell_t len;
    631 		cell_t status;
    632 		cell_t phys_hi;
    633 		cell_t phys_lo;
    634 	} args;
    635 
    636 #ifdef	__notyet
    637 	if (memh == -1 && ((memh = get_memory_handle()) == -1)) {
    638 		OF_printf("OF_alloc_phys: cannot get memh\r\n");
    639 		return -1LL;
    640 	}
    641 #endif
    642 	args.name = ADR2CELL("call-method");
    643 	args.nargs = 4;
    644 	args.nreturns = 3;
    645 	args.method = ADR2CELL("claim");
    646 	args.ihandle = HDL2CELL(memh);
    647 	args.align = align;
    648 	args.len = len;
    649 	if (openfirmware(&args) != 0)
    650 		return -1LL;
    651 	return (paddr_t)CELL2HDQ(args.phys_hi, args.phys_lo);
    652 }
    653 
    654 /*
    655  * Request some specific RAM from the prom
    656  *
    657  * Only works while the prom is actively mapping us.
    658  */
    659 paddr_t
    660 OF_claim_phys(paddr_t phys, int len)
    661 {
    662 	struct {
    663 		cell_t name;
    664 		cell_t nargs;
    665 		cell_t nreturns;
    666 		cell_t method;
    667 		cell_t ihandle;
    668 		cell_t align;
    669 		cell_t len;
    670 		cell_t phys_hi;
    671 		cell_t phys_lo;
    672 		cell_t status;
    673 		cell_t res;
    674 		cell_t rphys_hi;
    675 		cell_t rphys_lo;
    676 	} args;
    677 
    678 #ifdef	__notyet
    679 	if (memh == -1 && ((memh = get_memory_handle()) == -1)) {
    680 		OF_printf("OF_alloc_phys: cannot get memh\r\n");
    681 		return 0LL;
    682 	}
    683 #endif
    684 	args.name = ADR2CELL("call-method");
    685 	args.nargs = 6;
    686 	args.nreturns = 4;
    687 	args.method = ADR2CELL("claim");
    688 	args.ihandle = HDL2CELL(memh);
    689 	args.align = 0;
    690 	args.len = len;
    691 	args.phys_hi = HDQ2CELL_HI(phys);
    692 	args.phys_lo = HDQ2CELL_LO(phys);
    693 	if (openfirmware(&args) != 0)
    694 		return 0LL;
    695 	return (paddr_t)CELL2HDQ(args.rphys_hi, args.rphys_lo);
    696 }
    697 
    698 /*
    699  * Free some RAM to prom
    700  *
    701  * Only works while the prom is actively mapping us.
    702  */
    703 int
    704 OF_free_phys(paddr_t phys, int len)
    705 {
    706 	struct {
    707 		cell_t name;
    708 		cell_t nargs;
    709 		cell_t nreturns;
    710 		cell_t method;
    711 		cell_t ihandle;
    712 		cell_t len;
    713 		cell_t phys_hi;
    714 		cell_t phys_lo;
    715 	} args;
    716 
    717 #ifdef	__notyet
    718 	if (memh == -1 && ((memh = get_memory_handle()) == -1)) {
    719 		OF_printf("OF_free_phys: cannot get memh\r\n");
    720 		return -1;
    721 	}
    722 #endif
    723 	args.name = ADR2CELL("call-method");
    724 	args.nargs = 5;
    725 	args.nreturns = 0;
    726 	args.method = ADR2CELL("release");
    727 	args.ihandle = HDL2CELL(memh);
    728 	args.len = len;
    729 	args.phys_hi = HDQ2CELL_HI(phys);
    730 	args.phys_lo = HDQ2CELL_LO(phys);
    731 	return openfirmware(&args);
    732 }
    733 
    734 
    735 /*
    736  * Claim virtual memory -- does not map it in.
    737  */
    738 
    739 void *
    740 OF_claim(void *virt, u_int size, u_int align)
    741 {
    742 #define SUNVMOF
    743 #ifndef SUNVMOF
    744 	struct {
    745 		cell_t name;
    746 		cell_t nargs;
    747 		cell_t nreturns;
    748 		cell_t virt;
    749 		cell_t size;
    750 		cell_t align;
    751 		cell_t baseaddr;
    752 	} args;
    753 
    754 
    755 	args.name = ADR2CELL("claim");
    756 	args.nargs = 3;
    757 	args.nreturns = 1;
    758 	args.virt = virt;
    759 	args.size = size;
    760 	args.align = align;
    761 	if (openfirmware(&args) == -1)
    762 		return (void *)-1;
    763 	return args.baseaddr;
    764 #else
    765 /*
    766  * Sun Ultra machines run the firmware with VM enabled,
    767  * so you need to handle allocating and mapping both
    768  * virtual and physical memory.  Ugh.
    769  */
    770 
    771 	paddr_t paddr;
    772 	void* newvirt = NULL;
    773 
    774 	if (virt == NULL) {
    775 		if ((virt = (void*)OF_alloc_virt(size, align)) == (void*)-1) {
    776 			printf("OF_alloc_virt(%d,%d) failed w/%p\n", size, align, virt);
    777 			return (void *)-1;
    778 		}
    779 	} else {
    780 		if ((newvirt = (void*)OF_claim_virt((vaddr_t)virt, size)) == (void*)-1) {
    781 			printf("OF_claim_virt(%p,%d) failed w/%p\n", virt, size, newvirt);
    782 			return (void *)-1;
    783 		}
    784 	}
    785 	if ((paddr = OF_alloc_phys(size, align)) == (paddr_t)-1) {
    786 		printf("OF_alloc_phys(%d,%d) failed\n", size, align);
    787 		OF_free_virt((vaddr_t)virt, size);
    788 		return (void *)-1;
    789 	}
    790 	if (OF_map_phys(paddr, size, (vaddr_t)virt, -1) == -1) {
    791 		printf("OF_map_phys(0x%lx,%d,%p,%d) failed\n",
    792 		    (u_long)paddr, size, virt, -1);
    793 		OF_free_phys((paddr_t)paddr, size);
    794 		OF_free_virt((vaddr_t)virt, size);
    795 		return (void *)-1;
    796 	}
    797 	return (void *)virt;
    798 #endif
    799 }
    800