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