xref: /netbsd-src/sys/arch/sparc/stand/ofwboot/Locore.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
1 /*	$NetBSD: Locore.c,v 1.10 2007/10/17 19:57:16 garbled 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