2 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
3 * Copyright (C) 1995, 1996 TooLs GmbH.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by TooLs GmbH.
17 * 4. The name of TooLs GmbH may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * Copyright (C) 2000 Benno Rice.
33 * All rights reserved.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
44 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
46 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
47 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
49 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
50 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
52 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
53 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 * $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai Exp $
56 * $FreeBSD: src/sys/boot/ofw/libofw/openfirm.c,v 1.7 2002/07/18 12:39:02 benno Exp $
57 * $DragonFly: src/sys/boot/ofw/libofw/openfirm.c,v 1.1 2003/11/10 06:08:37 dillon Exp $
60 #include <machine/stdarg.h>
66 int (*openfirmware
)(void *);
68 static ihandle_t stdin
;
69 static ihandle_t stdout
;
77 OF_init(int (*openfirm
)(void *))
81 openfirmware
= openfirm
;
83 chosen
= OF_finddevice("/chosen");
84 OF_getprop(chosen
, "memory", &memory
, sizeof(memory
));
86 panic("failed to get memory ihandle");
87 OF_getprop(chosen
, "mmu", &mmu
, sizeof(mmu
));
89 panic("failed to get mmu ihandle");
96 /* Test to see if a service exists. */
114 args
.service
= (cell_t
)name
;
115 if (openfirmware(&args
) == -1)
117 return (int)args
.missing
;
120 /* Return firmware millisecond count. */
130 (cell_t
)"milliseconds",
141 * Device tree functions
144 /* Return the next sibling of this node or 0. */
146 OF_peer(phandle_t node
)
162 args
.node
= (u_int
)node
;
163 if (openfirmware(&args
) == -1)
165 return (phandle_t
)args
.next
;
168 /* Return the first child of this node or 0. */
170 OF_child(phandle_t node
)
186 args
.node
= (u_int
)node
;
187 if (openfirmware(&args
) == -1)
189 return (phandle_t
)args
.child
;
192 /* Return the parent of this node or 0. */
194 OF_parent(phandle_t node
)
210 args
.node
= (u_int
)node
;
211 if (openfirmware(&args
) == -1)
213 return (phandle_t
)args
.parent
;
216 /* Return the package handle that corresponds to an instance handle. */
218 OF_instance_to_package(ihandle_t instance
)
227 (cell_t
)"instance-to-package",
234 args
.instance
= (u_int
)instance
;
235 if (openfirmware(&args
) == -1)
237 return (phandle_t
)args
.package
;
240 /* Get the length of a property of a package. */
242 OF_getproplen(phandle_t package
, char *propname
)
252 (cell_t
)"getproplen",
260 args
.package
= (u_int
)package
;
261 args
.propname
= (cell_t
)propname
;
262 if (openfirmware(&args
) == -1)
264 return (int)args
.proplen
;
267 /* Get the value of a property of a package. */
269 OF_getprop(phandle_t package
, char *propname
, void *buf
, int buflen
)
291 args
.package
= (u_int
)package
;
292 args
.propname
= (cell_t
)propname
;
293 args
.buf
= (cell_t
)buf
;
294 args
.buflen
= (u_int
)buflen
;
295 if (openfirmware(&args
) == -1)
297 return (int)args
.size
;
300 /* Get the next property of a package. */
302 OF_nextprop(phandle_t package
, char *previous
, char *buf
)
322 args
.package
= (u_int
)package
;
323 args
.previous
= (cell_t
)previous
;
324 args
.buf
= (cell_t
)buf
;
325 if (openfirmware(&args
) == -1)
327 return (int)args
.flag
;
330 /* Set the value of a property of a package. */
331 /* XXX Has a bug on FirePower */
333 OF_setprop(phandle_t package
, char *propname
, void *buf
, int len
)
355 args
.package
= (u_int
)package
;
356 args
.propname
= (cell_t
)propname
;
357 args
.buf
= (cell_t
)buf
;
358 args
.len
= (u_int
)len
;
359 if (openfirmware(&args
) == -1)
361 return (int)args
.size
;
364 /* Convert a device specifier to a fully qualified pathname. */
366 OF_canon(const char *device
, char *buf
, int len
)
386 args
.device
= (cell_t
)device
;
387 args
.buf
= (cell_t
)buf
;
388 args
.len
= (cell_t
)len
;
389 if (openfirmware(&args
) == -1)
391 return (int)args
.size
;
394 /* Return a package handle for the specified device. */
396 OF_finddevice(const char *device
)
406 (cell_t
)"finddevice",
413 args
.device
= (cell_t
)device
;
414 if (openfirmware(&args
) == -1)
417 return (phandle_t
)args
.package
;
420 /* Return the fully qualified pathname corresponding to an instance. */
422 OF_instance_to_path(ihandle_t instance
, char *buf
, int len
)
433 (cell_t
)"instance-to-path",
442 args
.instance
= (u_int
)instance
;
443 args
.buf
= (cell_t
)buf
;
444 args
.len
= (u_int
)len
;
445 if (openfirmware(&args
) == -1)
447 return (int)args
.size
;
450 /* Return the fully qualified pathname corresponding to a package. */
452 OF_package_to_path(phandle_t package
, char *buf
, int len
)
463 (cell_t
)"package-to-path",
472 args
.package
= (u_int
)package
;
473 args
.buf
= (cell_t
)buf
;
474 args
.len
= (u_int
)len
;
475 if (openfirmware(&args
) == -1)
477 return (int)args
.size
;
480 /* Call the method in the scope of a given instance. */
482 OF_call_method(char *method
, ihandle_t instance
, int nargs
, int nreturns
, ...)
491 cell_t args_n_results
[12];
493 (cell_t
)"call-method",
498 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
504 args
.nargs
= nargs
+ 2;
505 args
.nreturns
= nreturns
+ 1;
506 args
.method
= (cell_t
)method
;
507 args
.instance
= (u_int
)instance
;
508 va_start(ap
, nreturns
);
509 for (ip
= (int *)(args
.args_n_results
+ (n
= nargs
)); --n
>= 0;)
510 *--ip
= va_arg(ap
, int);
512 if (openfirmware(&args
) == -1)
514 if (args
.args_n_results
[nargs
])
515 return (int)args
.args_n_results
[nargs
];
516 for (ip
= (int *)(args
.args_n_results
+ nargs
+ (n
= args
.nreturns
));
518 *va_arg(ap
, int *) = *--ip
;
524 * Device I/O functions.
527 /* Open an instance for a device. */
529 OF_open(char *device
)
545 args
.device
= (cell_t
)device
;
546 if (openfirmware(&args
) == -1 || args
.instance
== 0) {
549 return (ihandle_t
)args
.instance
;
552 /* Close an instance. */
554 OF_close(ihandle_t instance
)
568 args
.instance
= (u_int
)instance
;
572 /* Read from an instance. */
574 OF_read(ihandle_t instance
, void *addr
, int len
)
594 args
.instance
= (u_int
)instance
;
595 args
.addr
= (cell_t
)addr
;
596 args
.len
= (u_int
)len
;
598 #if defined(OPENFIRM_DEBUG)
599 printf("OF_read: called with instance=%08x, addr=%p, len=%d\n",
600 args
.instance
, args
.addr
, args
.len
);
603 if (openfirmware(&args
) == -1)
606 #if defined(OPENFIRM_DEBUG)
607 printf("OF_read: returning instance=%d, addr=%p, len=%d, actual=%d\n",
608 args
.instance
, args
.addr
, args
.len
, args
.actual
);
611 return (int)args
.actual
;
614 /* Write to an instance. */
616 OF_write(ihandle_t instance
, void *addr
, int len
)
636 args
.instance
= (u_int
)instance
;
637 args
.addr
= (cell_t
)addr
;
638 args
.len
= (u_int
)len
;
639 if (openfirmware(&args
) == -1)
641 return (int)args
.actual
;
644 /* Seek to a position. */
646 OF_seek(ihandle_t instance
, u_int64_t pos
)
666 args
.instance
= (u_int
)instance
;
667 args
.poshi
= pos
>> 32;
669 if (openfirmware(&args
) == -1)
671 return (int)args
.status
;
678 /* Claim an area of memory. */
680 OF_claim(void *virt
, u_int size
, u_int align
)
700 args
.virt
= (cell_t
)virt
;
703 if (openfirmware(&args
) == -1)
705 return (void *)args
.baseaddr
;
708 /* Allocate an area of physical memory */
710 OF_claim_virt(vm_offset_t virt
, size_t size
, int align
)
724 (cell_t
)"call-method",
741 if (openfirmware(&args
) == -1)
742 return (vm_offset_t
)-1;
744 return (vm_offset_t
)args
.ret
;
747 /* Allocate an area of physical memory */
749 OF_alloc_phys(size_t size
, int align
)
763 (cell_t
)"call-method",
775 args
.ihandle
= memory
;
779 if (openfirmware(&args
) == -1)
782 return (void *)(args
.phys_hi
<< 32 | args
.phys_low
);
785 /* Release an area of memory. */
787 OF_release(void *virt
, u_int size
)
803 args
.virt
= (cell_t
)virt
;
808 /* Release an area of physical memory. */
810 OF_release_phys(vm_offset_t phys
, u_int size
)
822 (cell_t
)"call-method",
832 args
.ihandle
= memory
;
833 args
.phys_hi
= (u_int32_t
)(phys
>> 32);
834 args
.phys_lo
= (u_int32_t
)phys
;
840 * Control transfer functions.
843 /* Reset the system and call "boot <bootspec>". */
845 OF_boot(char *bootspec
)
859 args
.bootspec
= (cell_t
)bootspec
;
861 for (;;); /* just in case */
864 /* Suspend and drop back to the OpenFirmware interface. */
881 /* Shut down and drop back to the OpenFirmware interface. */
896 for (;;); /* just in case */
899 /* Free <size> bytes starting at <virt>, then call <entry> with <arg>. */
902 OF_chain(void *virt
, u_int size
, void (*entry
)(), void *arg
, u_int len
)
924 args
.virt
= (cell_t
)virt
;
926 args
.entry
= (cell_t
)entry
;
927 args
.arg
= (cell_t
)arg
;
933 OF_chain(void *virt
, u_int size
, void (*entry
)(), void *arg
, u_int len
)
936 * This is a REALLY dirty hack till the firmware gets this going
939 OF_release(virt
, size
);
941 entry(0, 0, openfirmware
, arg
, len
);