1 /* $NetBSD: Locore.c,v 1.10 2007/10/17 19:57:16 garbled Exp $ */
4 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 * Copyright (C) 1995, 1996 TooLs GmbH.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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>
37 #include <machine/cpu.h>
39 extern int openfirmware(void *);
49 void __attribute__((__noreturn__
))
58 args
.name
= ADR2CELL("exit");
63 printf("OF_exit failed");
77 args
.name
= ADR2CELL("enter");
84 OF_finddevice(const char *name
)
94 args
.name
= ADR2CELL("finddevice");
97 args
.device
= ADR2CELL(name
);
98 if (openfirmware(&args
) == -1)
104 OF_instance_to_package(int ihandle
)
114 args
.name
= ADR2CELL("instance-to-package");
117 args
.ihandle
= HDL2CELL(ihandle
);
118 if (openfirmware(&args
) == -1)
124 OF_instance_to_path(int ihandle
, char *buf
, int buflen
)
136 args
.name
= ADR2CELL("instance-to-path");
139 args
.ihandle
= HDL2CELL(ihandle
);
140 args
.buf
= ADR2CELL(buf
);
141 args
.buflen
= buflen
;
142 if (openfirmware(&args
) < 0)
148 OF_getprop(int handle
, const char *prop
, void *buf
, int buflen
)
161 args
.name
= ADR2CELL("getprop");
164 args
.phandle
= HDL2CELL(handle
);
165 args
.prop
= ADR2CELL(prop
);
166 args
.buf
= ADR2CELL(buf
);
167 args
.buflen
= buflen
;
168 if (openfirmware(&args
) == -1)
173 #ifdef __notyet__ /* Has a bug on FirePower */
175 OF_setprop(u_int handle
, char *prop
, void *buf
, int len
)
188 args
.name
= ADR2CELL("setprop");
191 args
.phandle
= HDL2CELL(handle
);
192 args
.prop
= ADR2CELL(prop
);
193 args
.buf
= ADR2CELL(buf
);
195 if (openfirmware(&args
) == -1)
202 OF_open(const char *dname
)
212 args
.name
= ADR2CELL("open");
215 args
.dname
= ADR2CELL(dname
);
216 if (openfirmware(&args
) == -1 ||
232 args
.name
= ADR2CELL("close");
235 args
.handle
= HDL2CELL(handle
);
240 OF_write(int handle
, const void *addr
, int len
)
252 args
.name
= ADR2CELL("write");
255 args
.ihandle
= HDL2CELL(handle
);
256 args
.addr
= ADR2CELL(addr
);
258 if (openfirmware(&args
) == -1)
264 OF_read(int handle
, void *addr
, int len
)
276 args
.name
= ADR2CELL("read");
279 args
.ihandle
= HDL2CELL(handle
);
280 args
.addr
= ADR2CELL(addr
);
282 if (openfirmware(&args
) == -1) {
289 OF_seek(int handle
, u_quad_t pos
)
301 args
.name
= ADR2CELL("seek");
304 args
.handle
= HDL2CELL(handle
);
305 args
.poshi
= HDL2CELL(pos
>> 32);
306 args
.poslo
= HDL2CELL(pos
);
307 if (openfirmware(&args
) == -1) {
314 OF_release(void *virt
, u_int size
)
324 args
.name
= ADR2CELL("release");
327 args
.virt
= ADR2CELL(virt
);
333 OF_milliseconds(void)
342 args
.name
= ADR2CELL("milliseconds");
360 args
.name
= ADR2CELL("peer");
363 args
.phandle
= HDL2CELL(phandle
);
364 if (openfirmware(&args
) == -1)
370 OF_child(int phandle
)
380 args
.name
= ADR2CELL("child");
383 args
.phandle
= HDL2CELL(phandle
);
384 if (openfirmware(&args
) == -1)
389 static u_int mmuh
= -1;
390 static u_int memh
= -1;
397 if ( (chosen
= OF_finddevice("/chosen")) == -1) {
400 if (OF_getprop(chosen
, "mmu", &mmuh
, sizeof(mmuh
)) != sizeof(mmuh
)
401 || OF_getprop(chosen
, "memory", &memh
, sizeof(memh
)) != sizeof(memh
))
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.
415 OF_claim_virt(vaddr_t vaddr
, int len
)
431 if (mmuh
== -1 && ((mmuh
= get_mmu_handle()) == -1)) {
432 OF_printf("OF_claim_virt: cannot get mmuh\r\n");
436 args
.name
= ADR2CELL("call-method");
439 args
.method
= ADR2CELL("claim");
440 args
.ihandle
= HDL2CELL(mmuh
);
443 args
.vaddr
= ADR2CELL(vaddr
);
444 if (openfirmware(&args
) != 0)
446 return (vaddr_t
)args
.retaddr
;
450 * Request some address space from the prom
452 * Only works while the prom is actively mapping us.
455 OF_alloc_virt(int len
, int align
)
471 if (mmuh
== -1 && ((mmuh
= get_mmu_handle()) == -1)) {
472 OF_printf("OF_alloc_virt: cannot get mmuh\r\n");
476 args
.name
= ADR2CELL("call-method");
479 args
.method
= ADR2CELL("claim");
480 args
.ihandle
= HDL2CELL(mmuh
);
483 args
.retaddr
= ADR2CELL(&retaddr
);
484 if (openfirmware(&args
) != 0)
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
)
508 if (mmuh
== -1 && ((mmuh
= get_mmu_handle()) == -1)) {
509 OF_printf("OF_claim_virt: cannot get mmuh\r\n");
513 args
.name
= ADR2CELL("call-method");
516 args
.method
= ADR2CELL("release");
517 args
.ihandle
= HDL2CELL(mmuh
);
518 args
.vaddr
= ADR2CELL(vaddr
);
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
)
543 if (mmuh
== -1 && ((mmuh
= get_mmu_handle()) == -1)) {
544 OF_printf("OF_claim_virt: cannot get mmuh\r\n");
548 args
.name
= ADR2CELL("call-method");
551 args
.method
= ADR2CELL("unmap");
552 args
.ihandle
= HDL2CELL(mmuh
);
553 args
.vaddr
= ADR2CELL(vaddr
);
555 return openfirmware(&args
);
559 * Have prom map in some memory
561 * Only works while the prom is actively mapping us.
564 OF_map_phys(paddr_t paddr
, off_t size
, vaddr_t vaddr
, int mode
)
582 if (mmuh
== -1 && ((mmuh
= get_mmu_handle()) == -1)) {
583 OF_printf("OF_map_phys: cannot get mmuh\r\n");
587 args
.name
= ADR2CELL("call-method");
590 args
.method
= ADR2CELL("map");
591 args
.ihandle
= HDL2CELL(mmuh
);
594 args
.vaddr
= ADR2CELL(vaddr
);
595 args
.paddr_hi
= HDQ2CELL_HI(paddr
);
596 args
.paddr_lo
= HDQ2CELL_LO(paddr
);
598 if (openfirmware(&args
) == -1)
602 return (vaddr_t
)args
.retaddr
;
607 * Request some RAM from the prom
609 * Only works while the prom is actively mapping us.
612 OF_alloc_phys(int len
, int align
)
628 if (memh
== -1 && ((memh
= get_memory_handle()) == -1)) {
629 OF_printf("OF_alloc_phys: cannot get memh\r\n");
633 args
.name
= ADR2CELL("call-method");
636 args
.method
= ADR2CELL("claim");
637 args
.ihandle
= HDL2CELL(memh
);
640 if (openfirmware(&args
) != 0)
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.
651 OF_claim_phys(paddr_t phys
, int len
)
670 if (memh
== -1 && ((memh
= get_memory_handle()) == -1)) {
671 OF_printf("OF_alloc_phys: cannot get memh\r\n");
675 args
.name
= ADR2CELL("call-method");
678 args
.method
= ADR2CELL("claim");
679 args
.ihandle
= HDL2CELL(memh
);
682 args
.phys_hi
= HDQ2CELL_HI(phys
);
683 args
.phys_lo
= HDQ2CELL_LO(phys
);
684 if (openfirmware(&args
) != 0)
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
)
709 if (memh
== -1 && ((memh
= get_memory_handle()) == -1)) {
710 OF_printf("OF_free_phys: cannot get memh\r\n");
714 args
.name
= ADR2CELL("call-method");
717 args
.method
= ADR2CELL("release");
718 args
.ihandle
= HDL2CELL(memh
);
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.
731 OF_claim(void *virt
, u_int size
, u_int align
)
746 args
.name
= ADR2CELL("claim");
752 if (openfirmware(&args
) == -1)
754 return args
.baseaddr
;
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.
763 void* newvirt
= 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
);
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
);
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
);
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
);