Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / sparc / stand / ofwboot / Locore.c
bloba013cefcfc699862e8c611627a98e4489280c726
1 /* $NetBSD: Locore.c,v 1.10 2007/10/17 19:57:16 garbled Exp $ */
3 /*
4 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 * Copyright (C) 1995, 1996 TooLs GmbH.
6 * All rights reserved.
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.
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.
34 #include <lib/libsa/stand.h>
35 #include "openfirm.h"
37 #include <machine/cpu.h>
39 extern int openfirmware(void *);
42 __dead void
43 _rtt(void)
46 OF_exit();
49 void __attribute__((__noreturn__))
50 OF_exit(void)
52 struct {
53 cell_t name;
54 cell_t nargs;
55 cell_t nreturns;
56 } args;
58 args.name = ADR2CELL("exit");
59 args.nargs = 0;
60 args.nreturns = 0;
61 openfirmware(&args);
63 printf("OF_exit failed");
64 for (;;)
65 continue;
68 void
69 OF_enter(void)
71 struct {
72 cell_t name;
73 cell_t nargs;
74 cell_t nreturns;
75 } args;
77 args.name = ADR2CELL("enter");
78 args.nargs = 0;
79 args.nreturns = 0;
80 openfirmware(&args);
83 int
84 OF_finddevice(const char *name)
86 struct {
87 cell_t name;
88 cell_t nargs;
89 cell_t nreturns;
90 cell_t device;
91 cell_t phandle;
92 } args;
94 args.name = ADR2CELL("finddevice");
95 args.nargs = 1;
96 args.nreturns = 1;
97 args.device = ADR2CELL(name);
98 if (openfirmware(&args) == -1)
99 return -1;
100 return args.phandle;
104 OF_instance_to_package(int ihandle)
106 struct {
107 cell_t name;
108 cell_t nargs;
109 cell_t nreturns;
110 cell_t ihandle;
111 cell_t phandle;
112 } args;
114 args.name = ADR2CELL("instance-to-package");
115 args.nargs = 1;
116 args.nreturns = 1;
117 args.ihandle = HDL2CELL(ihandle);
118 if (openfirmware(&args) == -1)
119 return -1;
120 return args.phandle;
124 OF_instance_to_path(int ihandle, char *buf, int buflen)
126 struct {
127 cell_t name;
128 cell_t nargs;
129 cell_t nreturns;
130 cell_t ihandle;
131 cell_t buf;
132 cell_t buflen;
133 cell_t length;
134 } args;
136 args.name = ADR2CELL("instance-to-path");
137 args.nargs = 3;
138 args.nreturns = 1;
139 args.ihandle = HDL2CELL(ihandle);
140 args.buf = ADR2CELL(buf);
141 args.buflen = buflen;
142 if (openfirmware(&args) < 0)
143 return -1;
144 return args.length;
148 OF_getprop(int handle, const char *prop, void *buf, int buflen)
150 struct {
151 cell_t name;
152 cell_t nargs;
153 cell_t nreturns;
154 cell_t phandle;
155 cell_t prop;
156 cell_t buf;
157 cell_t buflen;
158 cell_t size;
159 } args;
161 args.name = ADR2CELL("getprop");
162 args.nargs = 4;
163 args.nreturns = 1;
164 args.phandle = HDL2CELL(handle);
165 args.prop = ADR2CELL(prop);
166 args.buf = ADR2CELL(buf);
167 args.buflen = buflen;
168 if (openfirmware(&args) == -1)
169 return -1;
170 return args.size;
173 #ifdef __notyet__ /* Has a bug on FirePower */
175 OF_setprop(u_int handle, char *prop, void *buf, int len)
177 struct {
178 cell_t name;
179 cell_t nargs;
180 cell_t nreturns;
181 cell_t phandle;
182 cell_t prop;
183 cell_t buf;
184 cell_t len;
185 cell_t size;
186 } args;
188 args.name = ADR2CELL("setprop");
189 args.nargs = 4;
190 args.nreturns = 1;
191 args.phandle = HDL2CELL(handle);
192 args.prop = ADR2CELL(prop);
193 args.buf = ADR2CELL(buf);
194 args.len = len;
195 if (openfirmware(&args) == -1)
196 return -1;
197 return args.size;
199 #endif
202 OF_open(const char *dname)
204 struct {
205 cell_t name;
206 cell_t nargs;
207 cell_t nreturns;
208 cell_t dname;
209 cell_t handle;
210 } args;
212 args.name = ADR2CELL("open");
213 args.nargs = 1;
214 args.nreturns = 1;
215 args.dname = ADR2CELL(dname);
216 if (openfirmware(&args) == -1 ||
217 args.handle == 0)
218 return -1;
219 return args.handle;
222 void
223 OF_close(int handle)
225 struct {
226 cell_t name;
227 cell_t nargs;
228 cell_t nreturns;
229 cell_t handle;
230 } args;
232 args.name = ADR2CELL("close");
233 args.nargs = 1;
234 args.nreturns = 1;
235 args.handle = HDL2CELL(handle);
236 openfirmware(&args);
240 OF_write(int handle, const void *addr, int len)
242 struct {
243 cell_t name;
244 cell_t nargs;
245 cell_t nreturns;
246 cell_t ihandle;
247 cell_t addr;
248 cell_t len;
249 cell_t actual;
250 } args;
252 args.name = ADR2CELL("write");
253 args.nargs = 3;
254 args.nreturns = 1;
255 args.ihandle = HDL2CELL(handle);
256 args.addr = ADR2CELL(addr);
257 args.len = len;
258 if (openfirmware(&args) == -1)
259 return -1;
260 return args.actual;
264 OF_read(int handle, void *addr, int len)
266 struct {
267 cell_t name;
268 cell_t nargs;
269 cell_t nreturns;
270 cell_t ihandle;
271 cell_t addr;
272 cell_t len;
273 cell_t actual;
274 } args;
276 args.name = ADR2CELL("read");
277 args.nargs = 3;
278 args.nreturns = 1;
279 args.ihandle = HDL2CELL(handle);
280 args.addr = ADR2CELL(addr);
281 args.len = len;
282 if (openfirmware(&args) == -1) {
283 return -1;
285 return args.actual;
289 OF_seek(int handle, u_quad_t pos)
291 struct {
292 cell_t name;
293 cell_t nargs;
294 cell_t nreturns;
295 cell_t handle;
296 cell_t poshi;
297 cell_t poslo;
298 cell_t status;
299 } args;
301 args.name = ADR2CELL("seek");
302 args.nargs = 3;
303 args.nreturns = 1;
304 args.handle = HDL2CELL(handle);
305 args.poshi = HDL2CELL(pos >> 32);
306 args.poslo = HDL2CELL(pos);
307 if (openfirmware(&args) == -1) {
308 return -1;
310 return args.status;
313 void
314 OF_release(void *virt, u_int size)
316 struct {
317 cell_t name;
318 cell_t nargs;
319 cell_t nreturns;
320 cell_t virt;
321 cell_t size;
322 } args;
324 args.name = ADR2CELL("release");
325 args.nargs = 2;
326 args.nreturns = 0;
327 args.virt = ADR2CELL(virt);
328 args.size = size;
329 openfirmware(&args);
333 OF_milliseconds(void)
335 struct {
336 cell_t name;
337 cell_t nargs;
338 cell_t nreturns;
339 cell_t ms;
340 } args;
342 args.name = ADR2CELL("milliseconds");
343 args.nargs = 0;
344 args.nreturns = 1;
345 openfirmware(&args);
346 return args.ms;
350 OF_peer(int phandle)
352 struct {
353 cell_t name;
354 cell_t nargs;
355 cell_t nreturns;
356 cell_t phandle;
357 cell_t sibling;
358 } args;
360 args.name = ADR2CELL("peer");
361 args.nargs = 1;
362 args.nreturns = 1;
363 args.phandle = HDL2CELL(phandle);
364 if (openfirmware(&args) == -1)
365 return 0;
366 return args.sibling;
370 OF_child(int phandle)
372 struct {
373 cell_t name;
374 cell_t nargs;
375 cell_t nreturns;
376 cell_t phandle;
377 cell_t child;
378 } args;
380 args.name = ADR2CELL("child");
381 args.nargs = 1;
382 args.nreturns = 1;
383 args.phandle = HDL2CELL(phandle);
384 if (openfirmware(&args) == -1)
385 return 0;
386 return args.child;
389 static u_int mmuh = -1;
390 static u_int memh = -1;
392 void
393 OF_initialize(void)
395 u_int chosen;
397 if ( (chosen = OF_finddevice("/chosen")) == -1) {
398 OF_exit();
400 if (OF_getprop(chosen, "mmu", &mmuh, sizeof(mmuh)) != sizeof(mmuh)
401 || OF_getprop(chosen, "memory", &memh, sizeof(memh)) != sizeof(memh))
402 OF_exit();
406 * The following need either the handle to memory or the handle to the MMU.
410 * Grab some address space from the prom
412 * Only works while the prom is actively mapping us.
414 vaddr_t
415 OF_claim_virt(vaddr_t vaddr, int len)
417 struct {
418 cell_t name;
419 cell_t nargs;
420 cell_t nreturns;
421 cell_t method;
422 cell_t ihandle;
423 cell_t align;
424 cell_t len;
425 cell_t vaddr;
426 cell_t status;
427 cell_t retaddr;
428 } args;
430 #ifdef __notyet
431 if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
432 OF_printf("OF_claim_virt: cannot get mmuh\r\n");
433 return -1LL;
435 #endif
436 args.name = ADR2CELL("call-method");
437 args.nargs = 5;
438 args.nreturns = 2;
439 args.method = ADR2CELL("claim");
440 args.ihandle = HDL2CELL(mmuh);
441 args.align = 0;
442 args.len = len;
443 args.vaddr = ADR2CELL(vaddr);
444 if (openfirmware(&args) != 0)
445 return -1LL;
446 return (vaddr_t)args.retaddr;
450 * Request some address space from the prom
452 * Only works while the prom is actively mapping us.
454 vaddr_t
455 OF_alloc_virt(int len, int align)
457 int retaddr=-1;
458 struct {
459 cell_t name;
460 cell_t nargs;
461 cell_t nreturns;
462 cell_t method;
463 cell_t ihandle;
464 cell_t align;
465 cell_t len;
466 cell_t status;
467 cell_t retaddr;
468 } args;
470 #ifdef __notyet
471 if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
472 OF_printf("OF_alloc_virt: cannot get mmuh\r\n");
473 return -1LL;
475 #endif
476 args.name = ADR2CELL("call-method");
477 args.nargs = 4;
478 args.nreturns = 2;
479 args.method = ADR2CELL("claim");
480 args.ihandle = HDL2CELL(mmuh);
481 args.align = align;
482 args.len = len;
483 args.retaddr = ADR2CELL(&retaddr);
484 if (openfirmware(&args) != 0)
485 return -1LL;
486 return (vaddr_t)args.retaddr;
490 * Release some address space to the prom
492 * Only works while the prom is actively mapping us.
495 OF_free_virt(vaddr_t vaddr, int len)
497 struct {
498 cell_t name;
499 cell_t nargs;
500 cell_t nreturns;
501 cell_t method;
502 cell_t ihandle;
503 cell_t len;
504 cell_t vaddr;
505 } args;
507 #ifdef __notyet
508 if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
509 OF_printf("OF_claim_virt: cannot get mmuh\r\n");
510 return -1;
512 #endif
513 args.name = ADR2CELL("call-method");
514 args.nargs = 4;
515 args.nreturns = 0;
516 args.method = ADR2CELL("release");
517 args.ihandle = HDL2CELL(mmuh);
518 args.vaddr = ADR2CELL(vaddr);
519 args.len = len;
520 return openfirmware(&args);
525 * Unmap some address space
527 * Only works while the prom is actively mapping us.
530 OF_unmap_virt(vaddr_t vaddr, int len)
532 struct {
533 cell_t name;
534 cell_t nargs;
535 cell_t nreturns;
536 cell_t method;
537 cell_t ihandle;
538 cell_t len;
539 cell_t vaddr;
540 } args;
542 #ifdef __notyet
543 if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
544 OF_printf("OF_claim_virt: cannot get mmuh\r\n");
545 return -1;
547 #endif
548 args.name = ADR2CELL("call-method");
549 args.nargs = 4;
550 args.nreturns = 0;
551 args.method = ADR2CELL("unmap");
552 args.ihandle = HDL2CELL(mmuh);
553 args.vaddr = ADR2CELL(vaddr);
554 args.len = len;
555 return openfirmware(&args);
559 * Have prom map in some memory
561 * Only works while the prom is actively mapping us.
563 vaddr_t
564 OF_map_phys(paddr_t paddr, off_t size, vaddr_t vaddr, int mode)
566 struct {
567 cell_t name;
568 cell_t nargs;
569 cell_t nreturns;
570 cell_t method;
571 cell_t ihandle;
572 cell_t mode;
573 cell_t size;
574 cell_t vaddr;
575 cell_t paddr_hi;
576 cell_t paddr_lo;
577 cell_t status;
578 cell_t retaddr;
579 } args;
581 #ifdef __notyet
582 if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
583 OF_printf("OF_map_phys: cannot get mmuh\r\n");
584 return 0LL;
586 #endif
587 args.name = ADR2CELL("call-method");
588 args.nargs = 7;
589 args.nreturns = 1;
590 args.method = ADR2CELL("map");
591 args.ihandle = HDL2CELL(mmuh);
592 args.mode = mode;
593 args.size = size;
594 args.vaddr = ADR2CELL(vaddr);
595 args.paddr_hi = HDQ2CELL_HI(paddr);
596 args.paddr_lo = HDQ2CELL_LO(paddr);
598 if (openfirmware(&args) == -1)
599 return -1;
600 if (args.status)
601 return -1;
602 return (vaddr_t)args.retaddr;
607 * Request some RAM from the prom
609 * Only works while the prom is actively mapping us.
611 paddr_t
612 OF_alloc_phys(int len, int align)
614 struct {
615 cell_t name;
616 cell_t nargs;
617 cell_t nreturns;
618 cell_t method;
619 cell_t ihandle;
620 cell_t align;
621 cell_t len;
622 cell_t status;
623 cell_t phys_hi;
624 cell_t phys_lo;
625 } args;
627 #ifdef __notyet
628 if (memh == -1 && ((memh = get_memory_handle()) == -1)) {
629 OF_printf("OF_alloc_phys: cannot get memh\r\n");
630 return -1LL;
632 #endif
633 args.name = ADR2CELL("call-method");
634 args.nargs = 4;
635 args.nreturns = 3;
636 args.method = ADR2CELL("claim");
637 args.ihandle = HDL2CELL(memh);
638 args.align = align;
639 args.len = len;
640 if (openfirmware(&args) != 0)
641 return -1LL;
642 return (paddr_t)CELL2HDQ(args.phys_hi, args.phys_lo);
646 * Request some specific RAM from the prom
648 * Only works while the prom is actively mapping us.
650 paddr_t
651 OF_claim_phys(paddr_t phys, int len)
653 struct {
654 cell_t name;
655 cell_t nargs;
656 cell_t nreturns;
657 cell_t method;
658 cell_t ihandle;
659 cell_t align;
660 cell_t len;
661 cell_t phys_hi;
662 cell_t phys_lo;
663 cell_t status;
664 cell_t res;
665 cell_t rphys_hi;
666 cell_t rphys_lo;
667 } args;
669 #ifdef __notyet
670 if (memh == -1 && ((memh = get_memory_handle()) == -1)) {
671 OF_printf("OF_alloc_phys: cannot get memh\r\n");
672 return 0LL;
674 #endif
675 args.name = ADR2CELL("call-method");
676 args.nargs = 6;
677 args.nreturns = 4;
678 args.method = ADR2CELL("claim");
679 args.ihandle = HDL2CELL(memh);
680 args.align = 0;
681 args.len = len;
682 args.phys_hi = HDQ2CELL_HI(phys);
683 args.phys_lo = HDQ2CELL_LO(phys);
684 if (openfirmware(&args) != 0)
685 return 0LL;
686 return (paddr_t)CELL2HDQ(args.rphys_hi, args.rphys_lo);
690 * Free some RAM to prom
692 * Only works while the prom is actively mapping us.
695 OF_free_phys(paddr_t phys, int len)
697 struct {
698 cell_t name;
699 cell_t nargs;
700 cell_t nreturns;
701 cell_t method;
702 cell_t ihandle;
703 cell_t len;
704 cell_t phys_hi;
705 cell_t phys_lo;
706 } args;
708 #ifdef __notyet
709 if (memh == -1 && ((memh = get_memory_handle()) == -1)) {
710 OF_printf("OF_free_phys: cannot get memh\r\n");
711 return -1;
713 #endif
714 args.name = ADR2CELL("call-method");
715 args.nargs = 5;
716 args.nreturns = 0;
717 args.method = ADR2CELL("release");
718 args.ihandle = HDL2CELL(memh);
719 args.len = len;
720 args.phys_hi = HDQ2CELL_HI(phys);
721 args.phys_lo = HDQ2CELL_LO(phys);
722 return openfirmware(&args);
727 * Claim virtual memory -- does not map it in.
730 void *
731 OF_claim(void *virt, u_int size, u_int align)
733 #define SUNVMOF
734 #ifndef SUNVMOF
735 struct {
736 cell_t name;
737 cell_t nargs;
738 cell_t nreturns;
739 cell_t virt;
740 cell_t size;
741 cell_t align;
742 cell_t baseaddr;
743 } args;
746 args.name = ADR2CELL("claim");
747 args.nargs = 3;
748 args.nreturns = 1;
749 args.virt = virt;
750 args.size = size;
751 args.align = align;
752 if (openfirmware(&args) == -1)
753 return (void *)-1;
754 return args.baseaddr;
755 #else
757 * Sun Ultra machines run the firmware with VM enabled,
758 * so you need to handle allocating and mapping both
759 * virtual and physical memory. Ugh.
762 paddr_t paddr;
763 void* newvirt = NULL;
765 if (virt == NULL) {
766 if ((virt = (void*)OF_alloc_virt(size, align)) == (void*)-1) {
767 printf("OF_alloc_virt(%d,%d) failed w/%x\n", size, align, virt);
768 return (void *)-1;
770 } else {
771 if ((newvirt = (void*)OF_claim_virt((vaddr_t)virt, size)) == (void*)-1) {
772 printf("OF_claim_virt(%x,%d) failed w/%x\n", virt, size, newvirt);
773 return (void *)-1;
776 if ((paddr = OF_alloc_phys(size, align)) == (paddr_t)-1) {
777 printf("OF_alloc_phys(%d,%d) failed\n", size, align);
778 OF_free_virt((vaddr_t)virt, size);
779 return (void *)-1;
781 if (OF_map_phys(paddr, size, (vaddr_t)virt, -1) == -1) {
782 printf("OF_map_phys(%x,%d,%x,%d) failed\n", paddr, size, virt, -1);
783 OF_free_phys((paddr_t)paddr, size);
784 OF_free_virt((vaddr_t)virt, size);
785 return (void *)-1;
787 return (void *)virt;
788 #endif