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
49 extern int openfirmware(void *);
50
51
52 __dead void
_rtt(void)53 _rtt(void)
54 {
55
56 OF_exit();
57 }
58
59 void __attribute__((__noreturn__))
OF_exit(void)60 OF_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
78 void
OF_enter(void)79 OF_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
93 int
OF_finddevice(const char * name)94 OF_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
113 int
OF_instance_to_package(int ihandle)114 OF_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
133 int
OF_instance_to_path(int ihandle,char * buf,int buflen)134 OF_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
157 int
OF_parent(int phandle)158 OF_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
177 int
OF_getprop(int handle,const char * prop,void * buf,int buflen)178 OF_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 */
204 int
OF_setprop(u_int handle,char * prop,void * buf,int len)205 OF_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
231 int
OF_interpret(const char * cmd,int nargs,int nreturns,...)232 OF_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
265 int
OF_package_to_path(int phandle,char * buf,int buflen)266 OF_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
291 int
OF_open(const char * dname)292 OF_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
312 void
OF_close(int handle)313 OF_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
329 int
OF_write(int handle,const void * addr,int len)330 OF_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
353 int
OF_read(int handle,void * addr,int len)354 OF_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
378 int
OF_seek(int handle,u_quad_t pos)379 OF_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
403 void
OF_release(void * virt,u_int size)404 OF_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
422 int
OF_milliseconds(void)423 OF_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
439 int
OF_peer(int phandle)440 OF_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
459 int
OF_child(int phandle)460 OF_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
479 static u_int mmuh = -1;
480 static u_int memh = -1;
481
482 void
OF_initialize(void)483 OF_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 */
504 vaddr_t
OF_claim_virt(vaddr_t vaddr,int len)505 OF_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 */
544 vaddr_t
OF_alloc_virt(int len,int align)545 OF_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 */
584 int
OF_free_virt(vaddr_t vaddr,int len)585 OF_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 */
619 int
OF_unmap_virt(vaddr_t vaddr,int len)620 OF_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 */
653 vaddr_t
OF_map_phys(paddr_t paddr,off_t size,vaddr_t vaddr,int mode)654 OF_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 */
697 paddr_t
OF_alloc_phys(int len,int align)698 OF_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 */
736 paddr_t
OF_claim_phys(paddr_t phys,int len)737 OF_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 */
780 int
OF_free_phys(paddr_t phys,int len)781 OF_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
816 void *
OF_claim(void * virt,u_int size,u_int align)817 OF_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