1 /* $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai Exp $ */
4 * SPDX-License-Identifier:BSD-4-Clause AND BSD-2-Clause-FreeBSD
6 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
7 * Copyright (C) 1995, 1996 TooLs GmbH.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by TooLs GmbH.
21 * 4. The name of TooLs GmbH may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
30 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 * Copyright (C) 2000 Benno Rice.
37 * All rights reserved.
39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions
42 * 1. Redistributions of source code must retain the above copyright
43 * notice, this list of conditions and the following disclaimer.
44 * 2. Redistributions in binary form must reproduce the above copyright
45 * notice, this list of conditions and the following disclaimer in the
46 * documentation and/or other materials provided with the distribution.
48 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
49 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
50 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
51 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
53 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
54 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
55 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
56 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
57 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60 #include <sys/cdefs.h>
61 __FBSDID("$FreeBSD$");
63 #include <sys/param.h>
64 #include <sys/kernel.h>
66 #include <sys/mutex.h>
67 #include <sys/systm.h>
70 #include <vm/vm_page.h>
73 #include <machine/bus.h>
74 #include <machine/md_var.h>
75 #include <machine/ofw_machdep.h>
76 #include <machine/stdarg.h>
78 #include <dev/ofw/openfirm.h>
79 #include <dev/ofw/ofwvar.h>
82 static int ofw_real_init(ofw_t, void *openfirm);
83 static int ofw_real_test(ofw_t, const char *name);
84 static phandle_t ofw_real_peer(ofw_t, phandle_t node);
85 static phandle_t ofw_real_child(ofw_t, phandle_t node);
86 static phandle_t ofw_real_parent(ofw_t, phandle_t node);
87 static phandle_t ofw_real_instance_to_package(ofw_t, ihandle_t instance);
88 static ssize_t ofw_real_getproplen(ofw_t, phandle_t package,
89 const char *propname);
90 static ssize_t ofw_real_getprop(ofw_t, phandle_t package, const char *propname,
91 void *buf, size_t buflen);
92 static int ofw_real_nextprop(ofw_t, phandle_t package, const char *previous,
94 static int ofw_real_setprop(ofw_t, phandle_t package, const char *propname,
95 const void *buf, size_t len);
96 static ssize_t ofw_real_canon(ofw_t, const char *device, char *buf, size_t len);
97 static phandle_t ofw_real_finddevice(ofw_t, const char *device);
98 static ssize_t ofw_real_instance_to_path(ofw_t, ihandle_t instance, char *buf,
100 static ssize_t ofw_real_package_to_path(ofw_t, phandle_t package, char *buf,
102 static int ofw_real_call_method(ofw_t, ihandle_t instance, const char *method,
103 int nargs, int nreturns, cell_t *args_and_returns);
104 static int ofw_real_interpret(ofw_t ofw, const char *cmd, int nreturns,
106 static ihandle_t ofw_real_open(ofw_t, const char *device);
107 static void ofw_real_close(ofw_t, ihandle_t instance);
108 static ssize_t ofw_real_read(ofw_t, ihandle_t instance, void *addr, size_t len);
109 static ssize_t ofw_real_write(ofw_t, ihandle_t instance, const void *addr,
111 static int ofw_real_seek(ofw_t, ihandle_t instance, u_int64_t pos);
112 static caddr_t ofw_real_claim(ofw_t, void *virt, size_t size, u_int align);
113 static void ofw_real_release(ofw_t, void *virt, size_t size);
114 static void ofw_real_enter(ofw_t);
115 static void ofw_real_exit(ofw_t);
117 static ofw_method_t ofw_real_methods[] = {
118 OFWMETHOD(ofw_init, ofw_real_init),
119 OFWMETHOD(ofw_peer, ofw_real_peer),
120 OFWMETHOD(ofw_child, ofw_real_child),
121 OFWMETHOD(ofw_parent, ofw_real_parent),
122 OFWMETHOD(ofw_instance_to_package, ofw_real_instance_to_package),
123 OFWMETHOD(ofw_getproplen, ofw_real_getproplen),
124 OFWMETHOD(ofw_getprop, ofw_real_getprop),
125 OFWMETHOD(ofw_nextprop, ofw_real_nextprop),
126 OFWMETHOD(ofw_setprop, ofw_real_setprop),
127 OFWMETHOD(ofw_canon, ofw_real_canon),
128 OFWMETHOD(ofw_finddevice, ofw_real_finddevice),
129 OFWMETHOD(ofw_instance_to_path, ofw_real_instance_to_path),
130 OFWMETHOD(ofw_package_to_path, ofw_real_package_to_path),
132 OFWMETHOD(ofw_test, ofw_real_test),
133 OFWMETHOD(ofw_call_method, ofw_real_call_method),
134 OFWMETHOD(ofw_interpret, ofw_real_interpret),
135 OFWMETHOD(ofw_open, ofw_real_open),
136 OFWMETHOD(ofw_close, ofw_real_close),
137 OFWMETHOD(ofw_read, ofw_real_read),
138 OFWMETHOD(ofw_write, ofw_real_write),
139 OFWMETHOD(ofw_seek, ofw_real_seek),
140 OFWMETHOD(ofw_claim, ofw_real_claim),
141 OFWMETHOD(ofw_release, ofw_real_release),
142 OFWMETHOD(ofw_enter, ofw_real_enter),
143 OFWMETHOD(ofw_exit, ofw_real_exit),
148 static ofw_def_t ofw_real = {
155 static ofw_def_t ofw_32bit = {
162 static MALLOC_DEFINE(M_OFWREAL, "ofwreal",
163 "Open Firmware Real Mode Bounce Page");
165 static int (*openfirmware)(void *);
167 static vm_offset_t of_bounce_phys;
168 static caddr_t of_bounce_virt;
169 static off_t of_bounce_offset;
170 static size_t of_bounce_size;
173 * To be able to use OFW console on PPC, that requires real mode OFW,
174 * the mutex that guards the mapping/unmapping of virtual to physical
175 * buffers (of_real_mtx) must be of SPIN type. This is needed because
176 * kernel console first locks a SPIN mutex before calling OFW real.
177 * By default, of_real_mtx is a sleepable mutex. To make it of SPIN
178 * type, use the following tunnable:
179 * machdep.ofw.mtx_spin=1
181 * Besides that, a few more tunables are needed to select and use the
182 * OFW console with real mode OFW.
184 * In order to disable the use of OFW FrameBuffer and fallback to the
188 * To disable the use of FDT (that doesn't support OFW read/write methods)
189 * and use real OFW instead, unset the following loader variable:
192 * OFW is put in quiesce state in early kernel boot, which usually disables
193 * OFW read/write capabilities (in QEMU write continue to work, but
194 * read doesn't). To avoid OFW quiesce, use:
195 * debug.quiesce_ofw=0
197 * Note that disabling OFW quiesce can cause conflicts between kernel and
198 * OFW trying to control the same hardware. Thus, it must be used with care.
199 * Some conflicts can be avoided by disabling kernel drivers with hints.
200 * For instance, to disable a xhci controller and an USB keyboard connected
201 * to it, that may be already being used for input by OFW, use:
202 * hint.xhci.0.disabled=1
205 static struct mtx of_bounce_mtx;
206 static struct mtx of_spin_mtx;
207 static struct mtx *of_real_mtx;
208 static void (*of_mtx_lock)(void);
209 static void (*of_mtx_unlock)(void);
211 extern int ofw_real_mode;
214 * After the VM is up, allocate a wired, low memory bounce page.
217 static void ofw_real_bounce_alloc(void *);
219 SYSINIT(ofw_real_bounce_alloc, SI_SUB_KMEM, SI_ORDER_ANY,
220 ofw_real_bounce_alloc, NULL);
223 ofw_real_mtx_lock_spin(void)
225 mtx_lock_spin(of_real_mtx);
229 ofw_real_mtx_lock(void)
231 mtx_lock(of_real_mtx);
235 ofw_real_mtx_unlock_spin(void)
237 mtx_unlock_spin(of_real_mtx);
241 ofw_real_mtx_unlock(void)
243 mtx_unlock(of_real_mtx);
250 of_bounce_offset = 0;
260 ofw_real_bounce_alloc(void *junk)
265 * Check that ofw_real is actually in use before allocating wads
266 * of memory. Do this by checking if our mutex has been set up.
268 if (!mtx_initialized(&of_bounce_mtx))
272 * Allocate a page of contiguous, wired physical memory that can
273 * fit into a 32-bit address space and accessed from real mode.
275 temp = contigmalloc(4 * PAGE_SIZE, M_OFWREAL, 0, 0,
276 ulmin(platform_real_maxaddr(), BUS_SPACE_MAXADDR_32BIT), PAGE_SIZE,
279 panic("%s: Not able to allocated contiguous memory\n", __func__);
281 mtx_lock(&of_bounce_mtx);
283 of_bounce_virt = temp;
285 of_bounce_phys = vtophys(of_bounce_virt);
286 of_bounce_size = 4 * PAGE_SIZE;
289 * For virtual-mode OF, direct map this physical address so that
290 * we have a 32-bit virtual address to give OF.
293 if (!ofw_real_mode && (!hw_direct_map || DMAP_BASE_ADDRESS != 0))
294 pmap_kenter(of_bounce_phys, of_bounce_phys);
296 mtx_unlock(&of_bounce_mtx);
300 ofw_real_map(const void *buf, size_t len)
302 static char emergency_buffer[255];
305 mtx_assert(of_real_mtx, MA_OWNED);
307 if (of_bounce_virt == NULL) {
309 * If we haven't set up the MMU, then buf is guaranteed
310 * to be accessible to OF, because the only memory we
311 * can use right now is memory mapped by firmware.
313 if (!pmap_bootstrapped)
314 return (cell_t)((uintptr_t)buf & ~DMAP_BASE_ADDRESS);
317 * XXX: It is possible for us to get called before the VM has
318 * come online, but after the MMU is up. We don't have the
319 * bounce buffer yet, but can no longer presume a 1:1 mapping.
320 * Copy into the emergency buffer, and reset at the end.
322 of_bounce_virt = emergency_buffer;
323 of_bounce_phys = (vm_offset_t)of_bounce_virt &
325 of_bounce_size = sizeof(emergency_buffer);
329 * Make sure the bounce page offset satisfies any reasonable
330 * alignment constraint.
332 of_bounce_offset += sizeof(register_t) -
333 (of_bounce_offset % sizeof(register_t));
335 if (of_bounce_offset + len > of_bounce_size) {
336 panic("Oversize Open Firmware call!");
341 memcpy(of_bounce_virt + of_bounce_offset, buf, len);
345 phys = of_bounce_phys + of_bounce_offset;
347 of_bounce_offset += len;
353 ofw_real_unmap(cell_t physaddr, void *buf, size_t len)
355 mtx_assert(of_real_mtx, MA_OWNED);
357 if (of_bounce_virt == NULL)
363 memcpy(buf,of_bounce_virt + (physaddr - of_bounce_phys),len);
369 ofw_real_init(ofw_t ofw, void *openfirm)
373 openfirmware = (int (*)(void *))openfirm;
374 mtx_init(&of_bounce_mtx, "OF Bounce Page", NULL, MTX_DEF);
377 TUNABLE_INT_FETCH("machdep.ofw.mtx_spin", &mtx_spin);
379 mtx_init(&of_spin_mtx, "OF Real", NULL, MTX_SPIN);
380 of_real_mtx = &of_spin_mtx;
381 of_mtx_lock = ofw_real_mtx_lock_spin;
382 of_mtx_unlock = ofw_real_mtx_unlock_spin;
384 of_real_mtx = &of_bounce_mtx;
385 of_mtx_lock = ofw_real_mtx_lock;
386 of_mtx_unlock = ofw_real_mtx_unlock;
389 of_bounce_virt = NULL;
397 /* Test to see if a service exists. */
399 ofw_real_test(ofw_t ofw, const char *name)
410 args.name = (cell_t)(uintptr_t)"test";
416 args.service = ofw_real_map(name, strlen(name) + 1);
417 argsptr = ofw_real_map(&args, sizeof(args));
418 if (args.service == 0 || openfirmware((void *)argsptr) == -1) {
422 ofw_real_unmap(argsptr, &args, sizeof(args));
424 return (args.missing);
428 * Device tree functions
431 /* Return the next sibling of this node or 0. */
433 ofw_real_peer(ofw_t ofw, phandle_t node)
444 args.name = (cell_t)(uintptr_t)"peer";
450 argsptr = ofw_real_map(&args, sizeof(args));
451 if (openfirmware((void *)argsptr) == -1) {
455 ofw_real_unmap(argsptr, &args, sizeof(args));
460 /* Return the first child of this node or 0. */
462 ofw_real_child(ofw_t ofw, phandle_t node)
473 args.name = (cell_t)(uintptr_t)"child";
479 argsptr = ofw_real_map(&args, sizeof(args));
480 if (openfirmware((void *)argsptr) == -1) {
484 ofw_real_unmap(argsptr, &args, sizeof(args));
489 /* Return the parent of this node or 0. */
491 ofw_real_parent(ofw_t ofw, phandle_t node)
502 args.name = (cell_t)(uintptr_t)"parent";
508 argsptr = ofw_real_map(&args, sizeof(args));
509 if (openfirmware((void *)argsptr) == -1) {
513 ofw_real_unmap(argsptr, &args, sizeof(args));
515 return (args.parent);
518 /* Return the package handle that corresponds to an instance handle. */
520 ofw_real_instance_to_package(ofw_t ofw, ihandle_t instance)
531 args.name = (cell_t)(uintptr_t)"instance-to-package";
535 args.instance = instance;
537 argsptr = ofw_real_map(&args, sizeof(args));
538 if (openfirmware((void *)argsptr) == -1) {
542 ofw_real_unmap(argsptr, &args, sizeof(args));
544 return (args.package);
547 /* Get the length of a property of a package. */
549 ofw_real_getproplen(ofw_t ofw, phandle_t package, const char *propname)
561 args.name = (cell_t)(uintptr_t)"getproplen";
567 args.package = package;
568 args.propname = ofw_real_map(propname, strlen(propname) + 1);
569 argsptr = ofw_real_map(&args, sizeof(args));
570 if (args.propname == 0 || openfirmware((void *)argsptr) == -1) {
574 ofw_real_unmap(argsptr, &args, sizeof(args));
576 return (args.proplen);
579 /* Get the value of a property of a package. */
581 ofw_real_getprop(ofw_t ofw, phandle_t package, const char *propname, void *buf,
596 args.name = (cell_t)(uintptr_t)"getprop";
602 args.package = package;
603 args.propname = ofw_real_map(propname, strlen(propname) + 1);
604 args.buf = ofw_real_map(buf, buflen);
605 args.buflen = buflen;
606 argsptr = ofw_real_map(&args, sizeof(args));
607 if (args.propname == 0 || args.buf == 0 ||
608 openfirmware((void *)argsptr) == -1) {
612 ofw_real_unmap(argsptr, &args, sizeof(args));
613 ofw_real_unmap(args.buf, buf, buflen);
619 /* Get the next property of a package. */
621 ofw_real_nextprop(ofw_t ofw, phandle_t package, const char *previous,
622 char *buf, size_t size)
635 args.name = (cell_t)(uintptr_t)"nextprop";
641 args.package = package;
642 args.previous = ofw_real_map(previous, (previous != NULL) ? (strlen(previous) + 1) : 0);
643 args.buf = ofw_real_map(buf, size);
644 argsptr = ofw_real_map(&args, sizeof(args));
645 if (args.buf == 0 || openfirmware((void *)argsptr) == -1) {
649 ofw_real_unmap(argsptr, &args, sizeof(args));
650 ofw_real_unmap(args.buf, buf, size);
656 /* Set the value of a property of a package. */
657 /* XXX Has a bug on FirePower */
659 ofw_real_setprop(ofw_t ofw, phandle_t package, const char *propname,
660 const void *buf, size_t len)
674 args.name = (cell_t)(uintptr_t)"setprop";
680 args.package = package;
681 args.propname = ofw_real_map(propname, strlen(propname) + 1);
682 args.buf = ofw_real_map(buf, len);
684 argsptr = ofw_real_map(&args, sizeof(args));
685 if (args.propname == 0 || args.buf == 0 ||
686 openfirmware((void *)argsptr) == -1) {
690 ofw_real_unmap(argsptr, &args, sizeof(args));
695 /* Convert a device specifier to a fully qualified pathname. */
697 ofw_real_canon(ofw_t ofw, const char *device, char *buf, size_t len)
710 args.name = (cell_t)(uintptr_t)"canon";
716 args.device = ofw_real_map(device, strlen(device) + 1);
717 args.buf = ofw_real_map(buf, len);
719 argsptr = ofw_real_map(&args, sizeof(args));
720 if (args.device == 0 || args.buf == 0 ||
721 openfirmware((void *)argsptr) == -1) {
725 ofw_real_unmap(argsptr, &args, sizeof(args));
726 ofw_real_unmap(args.buf, buf, len);
732 /* Return a package handle for the specified device. */
734 ofw_real_finddevice(ofw_t ofw, const char *device)
745 args.name = (cell_t)(uintptr_t)"finddevice";
751 args.device = ofw_real_map(device, strlen(device) + 1);
752 argsptr = ofw_real_map(&args, sizeof(args));
753 if (args.device == 0 ||
754 openfirmware((void *)argsptr) == -1) {
758 ofw_real_unmap(argsptr, &args, sizeof(args));
760 return (args.package);
763 /* Return the fully qualified pathname corresponding to an instance. */
765 ofw_real_instance_to_path(ofw_t ofw, ihandle_t instance, char *buf, size_t len)
778 args.name = (cell_t)(uintptr_t)"instance-to-path";
784 args.instance = instance;
785 args.buf = ofw_real_map(buf, len);
787 argsptr = ofw_real_map(&args, sizeof(args));
789 openfirmware((void *)argsptr) == -1) {
793 ofw_real_unmap(argsptr, &args, sizeof(args));
794 ofw_real_unmap(args.buf, buf, len);
800 /* Return the fully qualified pathname corresponding to a package. */
802 ofw_real_package_to_path(ofw_t ofw, phandle_t package, char *buf, size_t len)
815 args.name = (cell_t)(uintptr_t)"package-to-path";
821 args.package = package;
822 args.buf = ofw_real_map(buf, len);
824 argsptr = ofw_real_map(&args, sizeof(args));
826 openfirmware((void *)argsptr) == -1) {
830 ofw_real_unmap(argsptr, &args, sizeof(args));
831 ofw_real_unmap(args.buf, buf, len);
837 /* Call the method in the scope of a given instance. */
839 ofw_real_call_method(ofw_t ofw, ihandle_t instance, const char *method,
840 int nargs, int nreturns, cell_t *args_and_returns)
849 cell_t args_n_results[12];
854 args.name = (cell_t)(uintptr_t)"call-method";
862 args.nargs = nargs + 2;
863 args.nreturns = nreturns + 1;
864 args.method = ofw_real_map(method, strlen(method) + 1);
865 args.instance = instance;
867 ap = args_and_returns;
868 for (cp = args.args_n_results + (n = nargs); --n >= 0;)
870 argsptr = ofw_real_map(&args, sizeof(args));
871 if (args.method == 0 ||
872 openfirmware((void *)argsptr) == -1) {
876 ofw_real_unmap(argsptr, &args, sizeof(args));
878 if (args.args_n_results[nargs])
879 return (args.args_n_results[nargs]);
880 for (cp = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
886 ofw_real_interpret(ofw_t ofw, const char *cmd, int nreturns, cell_t *returns)
898 args.name = (cell_t)(uintptr_t)"interpret";
902 args.nreturns = ++nreturns;
903 args.slot[i++] = ofw_real_map(cmd, strlen(cmd) + 1);
904 argsptr = ofw_real_map(&args, sizeof(args));
905 if (openfirmware((void *)argsptr) == -1) {
909 ofw_real_unmap(argsptr, &args, sizeof(args));
911 status = args.slot[i++];
912 while (i < 1 + nreturns)
913 returns[j++] = args.slot[i++];
918 * Device I/O functions
921 /* Open an instance for a device. */
923 ofw_real_open(ofw_t ofw, const char *device)
934 args.name = (cell_t)(uintptr_t)"open";
940 args.device = ofw_real_map(device, strlen(device) + 1);
941 argsptr = ofw_real_map(&args, sizeof(args));
942 if (args.device == 0 || openfirmware((void *)argsptr) == -1
943 || args.instance == 0) {
947 ofw_real_unmap(argsptr, &args, sizeof(args));
949 return (args.instance);
952 /* Close an instance. */
954 ofw_real_close(ofw_t ofw, ihandle_t instance)
964 args.name = (cell_t)(uintptr_t)"close";
967 args.instance = instance;
969 argsptr = ofw_real_map(&args, sizeof(args));
970 openfirmware((void *)argsptr);
974 /* Read from an instance. */
976 ofw_real_read(ofw_t ofw, ihandle_t instance, void *addr, size_t len)
989 args.name = (cell_t)(uintptr_t)"read";
995 args.instance = instance;
996 args.addr = ofw_real_map(addr, len);
998 argsptr = ofw_real_map(&args, sizeof(args));
999 if (args.addr == 0 || openfirmware((void *)argsptr) == -1) {
1003 ofw_real_unmap(argsptr, &args, sizeof(args));
1004 ofw_real_unmap(args.addr, addr, len);
1007 return (args.actual);
1010 /* Write to an instance. */
1012 ofw_real_write(ofw_t ofw, ihandle_t instance, const void *addr, size_t len)
1014 vm_offset_t argsptr;
1025 args.name = (cell_t)(uintptr_t)"write";
1031 args.instance = instance;
1032 args.addr = ofw_real_map(addr, len);
1034 argsptr = ofw_real_map(&args, sizeof(args));
1035 if (args.addr == 0 || openfirmware((void *)argsptr) == -1) {
1039 ofw_real_unmap(argsptr, &args, sizeof(args));
1041 return (args.actual);
1044 /* Seek to a position. */
1046 ofw_real_seek(ofw_t ofw, ihandle_t instance, u_int64_t pos)
1048 vm_offset_t argsptr;
1059 args.name = (cell_t)(uintptr_t)"seek";
1063 args.instance = instance;
1064 args.poshi = pos >> 32;
1067 argsptr = ofw_real_map(&args, sizeof(args));
1068 if (openfirmware((void *)argsptr) == -1) {
1072 ofw_real_unmap(argsptr, &args, sizeof(args));
1074 return (args.status);
1081 /* Claim an area of memory. */
1083 ofw_real_claim(ofw_t ofw, void *virt, size_t size, u_int align)
1085 vm_offset_t argsptr;
1096 args.name = (cell_t)(uintptr_t)"claim";
1100 args.virt = (cell_t)(uintptr_t)virt;
1104 argsptr = ofw_real_map(&args, sizeof(args));
1105 if (openfirmware((void *)argsptr) == -1) {
1107 return ((void *)-1);
1109 ofw_real_unmap(argsptr, &args, sizeof(args));
1111 return ((void *)(uintptr_t)args.baseaddr);
1114 /* Release an area of memory. */
1116 ofw_real_release(ofw_t ofw, void *virt, size_t size)
1118 vm_offset_t argsptr;
1127 args.name = (cell_t)(uintptr_t)"release";
1131 args.virt = (cell_t)(uintptr_t)virt;
1134 argsptr = ofw_real_map(&args, sizeof(args));
1135 openfirmware((void *)argsptr);
1140 * Control transfer functions
1143 /* Suspend and drop back to the Open Firmware interface. */
1145 ofw_real_enter(ofw_t ofw)
1147 vm_offset_t argsptr;
1154 args.name = (cell_t)(uintptr_t)"enter";
1159 argsptr = ofw_real_map(&args, sizeof(args));
1160 openfirmware((void *)argsptr);
1161 /* We may come back. */
1165 /* Shut down and drop back to the Open Firmware interface. */
1167 ofw_real_exit(ofw_t ofw)
1169 vm_offset_t argsptr;
1176 args.name = (cell_t)(uintptr_t)"exit";
1181 argsptr = ofw_real_map(&args, sizeof(args));
1182 openfirmware((void *)argsptr);
1183 for (;;) /* just in case */