xref: /netbsd-src/sys/arch/sparc/stand/ofwboot/Locore.c (revision 25ac767b16abfd17c10eb9c6ebbc1a6681d6d2eb)
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