source: rtems-libbsd/freebsd/sys/dev/ofw/openfirm.c

6-freebsd-12
Last change on this file was bcdce02, checked in by Sebastian Huber <sebastian.huber@…>, on 08/21/18 at 11:47:02

Update to FreeBSD head 2018-06-01

Git mirror commit fb63610a69b0eb7f69a201ba05c4c1a7a2739cf9.

Update #3472.

  • Property mode set to 100644
File size: 19.2 KB
Line 
1#include <machine/rtems-bsd-kernel-space.h>
2
3/*      $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai Exp $        */
4
5/*-
6 * SPDX-License-Identifier: BSD-4-Clause
7 *
8 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
9 * Copyright (C) 1995, 1996 TooLs GmbH.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 *    must display the following acknowledgement:
22 *      This product includes software developed by TooLs GmbH.
23 * 4. The name of TooLs GmbH may not be used to endorse or promote products
24 *    derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
32 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37/*-
38 * Copyright (C) 2000 Benno Rice.
39 * All rights reserved.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 *    notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 *    notice, this list of conditions and the following disclaimer in the
48 *    documentation and/or other materials provided with the distribution.
49 *
50 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
51 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
52 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
53 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
54 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
55 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
56 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
57 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
58 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
59 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60 */
61
62#include <sys/cdefs.h>
63__FBSDID("$FreeBSD$");
64
65#include <rtems/bsd/local/opt_platform.h>
66
67#include <sys/param.h>
68#include <sys/kernel.h>
69#include <sys/lock.h>
70#include <sys/malloc.h>
71#include <sys/mutex.h>
72#include <sys/queue.h>
73#include <sys/systm.h>
74#include <sys/endian.h>
75
76#include <machine/stdarg.h>
77
78#include <dev/ofw/ofwvar.h>
79#include <dev/ofw/openfirm.h>
80
81#include <rtems/bsd/local/ofw_if.h>
82
83static void OF_putchar(int c, void *arg);
84
85MALLOC_DEFINE(M_OFWPROP, "openfirm", "Open Firmware properties");
86
87static ihandle_t stdout;
88
89#ifndef __rtems__
90static ofw_def_t        *ofw_def_impl = NULL;
91#else /* __rtems__ */
92#define ofw_def_impl (&ofw_fdt)
93#endif /* __rtems__ */
94static ofw_t            ofw_obj;
95static struct ofw_kobj  ofw_kernel_obj;
96static struct kobj_ops  ofw_kernel_kops;
97
98struct xrefinfo {
99        phandle_t       xref;
100        phandle_t       node;
101        device_t        dev;
102        SLIST_ENTRY(xrefinfo) next_entry;
103};
104
105static SLIST_HEAD(, xrefinfo) xreflist = SLIST_HEAD_INITIALIZER(xreflist);
106static struct mtx xreflist_lock;
107static boolean_t xref_init_done;
108
109#define FIND_BY_XREF    0
110#define FIND_BY_NODE    1
111#define FIND_BY_DEV     2
112
113/*
114 * xref-phandle-device lookup helper routines.
115 *
116 * As soon as we are able to use malloc(), walk the node tree and build a list
117 * of info that cross-references node handles, xref handles, and device_t
118 * instances.  This list exists primarily to allow association of a device_t
119 * with an xref handle, but it is also used to speed up translation between xref
120 * and node handles.  Before malloc() is available we have to recursively search
121 * the node tree each time we want to translate between a node and xref handle.
122 * Afterwards we can do the translations by searching this much shorter list.
123 */
124static void
125xrefinfo_create(phandle_t node)
126{
127        struct xrefinfo * xi;
128        phandle_t child, xref;
129
130        /*
131         * Recursively descend from parent, looking for nodes with a property
132         * named either "phandle", "ibm,phandle", or "linux,phandle".  For each
133         * such node found create an entry in the xreflist.
134         */
135        for (child = OF_child(node); child != 0; child = OF_peer(child)) {
136                xrefinfo_create(child);
137                if (OF_getencprop(child, "phandle", &xref, sizeof(xref)) ==
138                    -1 && OF_getencprop(child, "ibm,phandle", &xref,
139                    sizeof(xref)) == -1 && OF_getencprop(child,
140                    "linux,phandle", &xref, sizeof(xref)) == -1)
141                        continue;
142                xi = malloc(sizeof(*xi), M_OFWPROP, M_WAITOK | M_ZERO);
143                xi->node = child;
144                xi->xref = xref;
145                SLIST_INSERT_HEAD(&xreflist, xi, next_entry);
146        }
147}
148
149static void
150xrefinfo_init(void *unsed)
151{
152
153#ifdef __rtems__
154        if (OF_init(__DECONST(void *, bsp_fdt_get())) != 0)
155                return (ENXIO);
156#endif /* __rtems__ */
157        /*
158         * There is no locking during this init because it runs much earlier
159         * than any of the clients/consumers of the xref list data, but we do
160         * initialize the mutex that will be used for access later.
161         */
162        mtx_init(&xreflist_lock, "OF xreflist lock", NULL, MTX_DEF);
163        xrefinfo_create(OF_peer(0));
164        xref_init_done = true;
165}
166SYSINIT(xrefinfo, SI_SUB_KMEM, SI_ORDER_ANY, xrefinfo_init, NULL);
167
168static struct xrefinfo *
169xrefinfo_find(uintptr_t key, int find_by)
170{
171        struct xrefinfo *rv, *xi;
172
173        rv = NULL;
174        mtx_lock(&xreflist_lock);
175        SLIST_FOREACH(xi, &xreflist, next_entry) {
176                if ((find_by == FIND_BY_XREF && (phandle_t)key == xi->xref) ||
177                    (find_by == FIND_BY_NODE && (phandle_t)key == xi->node) ||
178                    (find_by == FIND_BY_DEV && key == (uintptr_t)xi->dev)) {
179                        rv = xi;
180                        break;
181                }
182        }
183        mtx_unlock(&xreflist_lock);
184        return (rv);
185}
186
187static struct xrefinfo *
188xrefinfo_add(phandle_t node, phandle_t xref, device_t dev)
189{
190        struct xrefinfo *xi;
191
192        xi = malloc(sizeof(*xi), M_OFWPROP, M_WAITOK);
193        xi->node = node;
194        xi->xref = xref;
195        xi->dev  = dev;
196        mtx_lock(&xreflist_lock);
197        SLIST_INSERT_HEAD(&xreflist, xi, next_entry);
198        mtx_unlock(&xreflist_lock);
199        return (xi);
200}
201
202/*
203 * OFW install routines.  Highest priority wins, equal priority also
204 * overrides allowing last-set to win.
205 */
206SET_DECLARE(ofw_set, ofw_def_t);
207
208boolean_t
209OF_install(char *name, int prio)
210{
211#ifndef __rtems__
212        ofw_def_t *ofwp, **ofwpp;
213        static int curr_prio = 0;
214
215        /* Allow OF layer to be uninstalled */
216        if (name == NULL) {
217                ofw_def_impl = NULL;
218                return (FALSE);
219        }
220
221        /*
222         * Try and locate the OFW kobj corresponding to the name.
223         */
224        SET_FOREACH(ofwpp, ofw_set) {
225                ofwp = *ofwpp;
226
227                if (ofwp->name &&
228                    !strcmp(ofwp->name, name) &&
229                    prio >= curr_prio) {
230                        curr_prio = prio;
231                        ofw_def_impl = ofwp;
232                        return (TRUE);
233                }
234        }
235
236        return (FALSE);
237#else /* __rtems__ */
238        return (TRUE);
239#endif /* __rtems__ */
240}
241
242/* Initializer */
243int
244OF_init(void *cookie)
245{
246        phandle_t chosen;
247        int rv;
248
249        if (ofw_def_impl == NULL)
250                return (-1);
251
252        ofw_obj = &ofw_kernel_obj;
253        /*
254         * Take care of compiling the selected class, and
255         * then statically initialize the OFW object.
256         */
257        kobj_class_compile_static(ofw_def_impl, &ofw_kernel_kops);
258        kobj_init_static((kobj_t)ofw_obj, ofw_def_impl);
259
260        rv = OFW_INIT(ofw_obj, cookie);
261
262        if ((chosen = OF_finddevice("/chosen")) != -1)
263                if (OF_getencprop(chosen, "stdout", &stdout,
264                    sizeof(stdout)) == -1)
265                        stdout = -1;
266
267        return (rv);
268}
269
270static void
271OF_putchar(int c, void *arg __unused)
272{
273        char cbuf;
274
275        if (c == '\n') {
276                cbuf = '\r';
277                OF_write(stdout, &cbuf, 1);
278        }
279
280        cbuf = c;
281        OF_write(stdout, &cbuf, 1);
282}
283
284void
285OF_printf(const char *fmt, ...)
286{
287        va_list va;
288
289        va_start(va, fmt);
290        (void)kvprintf(fmt, OF_putchar, NULL, 10, va);
291        va_end(va);
292}
293
294/*
295 * Generic functions
296 */
297
298/* Test to see if a service exists. */
299int
300OF_test(const char *name)
301{
302
303        if (ofw_def_impl == NULL)
304                return (-1);
305
306        return (OFW_TEST(ofw_obj, name));
307}
308
309int
310OF_interpret(const char *cmd, int nreturns, ...)
311{
312        va_list ap;
313        cell_t slots[16];
314        int i = 0;
315        int status;
316
317        if (ofw_def_impl == NULL)
318                return (-1);
319
320        status = OFW_INTERPRET(ofw_obj, cmd, nreturns, slots);
321        if (status == -1)
322                return (status);
323
324        va_start(ap, nreturns);
325        while (i < nreturns)
326                *va_arg(ap, cell_t *) = slots[i++];
327        va_end(ap);
328
329        return (status);
330}
331
332/*
333 * Device tree functions
334 */
335
336/* Return the next sibling of this node or 0. */
337phandle_t
338OF_peer(phandle_t node)
339{
340
341        if (ofw_def_impl == NULL)
342                return (0);
343
344        return (OFW_PEER(ofw_obj, node));
345}
346
347/* Return the first child of this node or 0. */
348phandle_t
349OF_child(phandle_t node)
350{
351
352        if (ofw_def_impl == NULL)
353                return (0);
354
355        return (OFW_CHILD(ofw_obj, node));
356}
357
358/* Return the parent of this node or 0. */
359phandle_t
360OF_parent(phandle_t node)
361{
362
363        if (ofw_def_impl == NULL)
364                return (0);
365
366        return (OFW_PARENT(ofw_obj, node));
367}
368
369/* Return the package handle that corresponds to an instance handle. */
370phandle_t
371OF_instance_to_package(ihandle_t instance)
372{
373
374        if (ofw_def_impl == NULL)
375                return (-1);
376
377        return (OFW_INSTANCE_TO_PACKAGE(ofw_obj, instance));
378}
379
380/* Get the length of a property of a package. */
381ssize_t
382OF_getproplen(phandle_t package, const char *propname)
383{
384
385        if (ofw_def_impl == NULL)
386                return (-1);
387
388        return (OFW_GETPROPLEN(ofw_obj, package, propname));
389}
390
391/* Check existence of a property of a package. */
392int
393OF_hasprop(phandle_t package, const char *propname)
394{
395
396        return (OF_getproplen(package, propname) >= 0 ? 1 : 0);
397}
398
399/* Get the value of a property of a package. */
400ssize_t
401OF_getprop(phandle_t package, const char *propname, void *buf, size_t buflen)
402{
403
404        if (ofw_def_impl == NULL)
405                return (-1);
406
407        return (OFW_GETPROP(ofw_obj, package, propname, buf, buflen));
408}
409
410ssize_t
411OF_getencprop(phandle_t node, const char *propname, pcell_t *buf, size_t len)
412{
413        ssize_t retval;
414        int i;
415
416        KASSERT(len % 4 == 0, ("Need a multiple of 4 bytes"));
417
418        retval = OF_getprop(node, propname, buf, len);
419        if (retval <= 0)
420                return (retval);
421
422        for (i = 0; i < len/4; i++)
423                buf[i] = be32toh(buf[i]);
424
425        return (retval);
426}
427
428/*
429 * Recursively search the node and its parent for the given property, working
430 * downward from the node to the device tree root.  Returns the value of the
431 * first match.
432 */
433ssize_t
434OF_searchprop(phandle_t node, const char *propname, void *buf, size_t len)
435{
436        ssize_t rv;
437
438        for (; node != 0; node = OF_parent(node))
439                if ((rv = OF_getprop(node, propname, buf, len)) != -1)
440                        return (rv);
441        return (-1);
442}
443
444ssize_t
445OF_searchencprop(phandle_t node, const char *propname, pcell_t *buf, size_t len)
446{
447        ssize_t rv;
448
449        for (; node != 0; node = OF_parent(node))
450                if ((rv = OF_getencprop(node, propname, buf, len)) != -1)
451                        return (rv);
452        return (-1);
453}
454
455/*
456 * Store the value of a property of a package into newly allocated memory
457 * (using the M_OFWPROP malloc pool and M_WAITOK).
458 */
459ssize_t
460OF_getprop_alloc(phandle_t package, const char *propname, void **buf)
461{
462        int len;
463
464        *buf = NULL;
465        if ((len = OF_getproplen(package, propname)) == -1)
466                return (-1);
467
468        if (len > 0) {
469                *buf = malloc(len, M_OFWPROP, M_WAITOK);
470                if (OF_getprop(package, propname, *buf, len) == -1) {
471                        free(*buf, M_OFWPROP);
472                        *buf = NULL;
473                        return (-1);
474                }
475        }
476        return (len);
477}
478
479/*
480 * Store the value of a property of a package into newly allocated memory
481 * (using the M_OFWPROP malloc pool and M_WAITOK).  elsz is the size of a
482 * single element, the number of elements is return in number.
483 */
484ssize_t
485OF_getprop_alloc_multi(phandle_t package, const char *propname, int elsz, void **buf)
486{
487        int len;
488
489        *buf = NULL;
490        if ((len = OF_getproplen(package, propname)) == -1 ||
491            len % elsz != 0)
492                return (-1);
493
494        if (len > 0) {
495                *buf = malloc(len, M_OFWPROP, M_WAITOK);
496                if (OF_getprop(package, propname, *buf, len) == -1) {
497                        free(*buf, M_OFWPROP);
498                        *buf = NULL;
499                        return (-1);
500                }
501        }
502        return (len / elsz);
503}
504
505ssize_t
506OF_getencprop_alloc(phandle_t package, const char *name, void **buf)
507{
508        ssize_t ret;
509
510        ret = OF_getencprop_alloc_multi(package, name, sizeof(pcell_t),
511            buf);
512        if (ret < 0)
513                return (ret);
514        else
515                return (ret * sizeof(pcell_t));
516}
517
518ssize_t
519OF_getencprop_alloc_multi(phandle_t package, const char *name, int elsz,
520    void **buf)
521{
522        ssize_t retval;
523        pcell_t *cell;
524        int i;
525
526        retval = OF_getprop_alloc_multi(package, name, elsz, buf);
527        if (retval == -1)
528                return (-1);
529
530        cell = *buf;
531        for (i = 0; i < retval * elsz / 4; i++)
532                cell[i] = be32toh(cell[i]);
533
534        return (retval);
535}
536
537/* Free buffer allocated by OF_getencprop_alloc or OF_getprop_alloc */
538void OF_prop_free(void *buf)
539{
540
541        free(buf, M_OFWPROP);
542}
543
544/* Get the next property of a package. */
545int
546OF_nextprop(phandle_t package, const char *previous, char *buf, size_t size)
547{
548
549        if (ofw_def_impl == NULL)
550                return (-1);
551
552        return (OFW_NEXTPROP(ofw_obj, package, previous, buf, size));
553}
554
555/* Set the value of a property of a package. */
556int
557OF_setprop(phandle_t package, const char *propname, const void *buf, size_t len)
558{
559
560        if (ofw_def_impl == NULL)
561                return (-1);
562
563        return (OFW_SETPROP(ofw_obj, package, propname, buf,len));
564}
565
566/* Convert a device specifier to a fully qualified pathname. */
567ssize_t
568OF_canon(const char *device, char *buf, size_t len)
569{
570
571        if (ofw_def_impl == NULL)
572                return (-1);
573
574        return (OFW_CANON(ofw_obj, device, buf, len));
575}
576
577/* Return a package handle for the specified device. */
578phandle_t
579OF_finddevice(const char *device)
580{
581
582        if (ofw_def_impl == NULL)
583                return (-1);
584
585        return (OFW_FINDDEVICE(ofw_obj, device));
586}
587
588/* Return the fully qualified pathname corresponding to an instance. */
589ssize_t
590OF_instance_to_path(ihandle_t instance, char *buf, size_t len)
591{
592
593        if (ofw_def_impl == NULL)
594                return (-1);
595
596        return (OFW_INSTANCE_TO_PATH(ofw_obj, instance, buf, len));
597}
598
599/* Return the fully qualified pathname corresponding to a package. */
600ssize_t
601OF_package_to_path(phandle_t package, char *buf, size_t len)
602{
603
604        if (ofw_def_impl == NULL)
605                return (-1);
606
607        return (OFW_PACKAGE_TO_PATH(ofw_obj, package, buf, len));
608}
609
610/* Look up effective phandle (see FDT/PAPR spec) */
611static phandle_t
612OF_child_xref_phandle(phandle_t parent, phandle_t xref)
613{
614        phandle_t child, rxref;
615
616        /*
617         * Recursively descend from parent, looking for a node with a property
618         * named either "phandle", "ibm,phandle", or "linux,phandle" that
619         * matches the xref we are looking for.
620         */
621
622        for (child = OF_child(parent); child != 0; child = OF_peer(child)) {
623                rxref = OF_child_xref_phandle(child, xref);
624                if (rxref != -1)
625                        return (rxref);
626
627                if (OF_getencprop(child, "phandle", &rxref, sizeof(rxref)) ==
628                    -1 && OF_getencprop(child, "ibm,phandle", &rxref,
629                    sizeof(rxref)) == -1 && OF_getencprop(child,
630                    "linux,phandle", &rxref, sizeof(rxref)) == -1)
631                        continue;
632
633                if (rxref == xref)
634                        return (child);
635        }
636
637        return (-1);
638}
639
640phandle_t
641OF_node_from_xref(phandle_t xref)
642{
643        struct xrefinfo *xi;
644        phandle_t node;
645
646        if (xref_init_done) {
647                if ((xi = xrefinfo_find(xref, FIND_BY_XREF)) == NULL)
648                        return (xref);
649                return (xi->node);
650        }
651
652        if ((node = OF_child_xref_phandle(OF_peer(0), xref)) == -1)
653                return (xref);
654        return (node);
655}
656
657phandle_t
658OF_xref_from_node(phandle_t node)
659{
660        struct xrefinfo *xi;
661        phandle_t xref;
662
663        if (xref_init_done) {
664                if ((xi = xrefinfo_find(node, FIND_BY_NODE)) == NULL)
665                        return (node);
666                return (xi->xref);
667        }
668
669        if (OF_getencprop(node, "phandle", &xref, sizeof(xref)) == -1 &&
670            OF_getencprop(node, "ibm,phandle", &xref, sizeof(xref)) == -1 &&
671            OF_getencprop(node, "linux,phandle", &xref, sizeof(xref)) == -1)
672                return (node);
673        return (xref);
674}
675
676device_t
677OF_device_from_xref(phandle_t xref)
678{
679        struct xrefinfo *xi;
680
681        if (xref_init_done) {
682                if ((xi = xrefinfo_find(xref, FIND_BY_XREF)) == NULL)
683                        return (NULL);
684                return (xi->dev);
685        }
686        panic("Attempt to find device before xreflist_init");
687}
688
689phandle_t
690OF_xref_from_device(device_t dev)
691{
692        struct xrefinfo *xi;
693
694        if (xref_init_done) {
695                if ((xi = xrefinfo_find((uintptr_t)dev, FIND_BY_DEV)) == NULL)
696                        return (0);
697                return (xi->xref);
698        }
699        panic("Attempt to find xref before xreflist_init");
700}
701
702int
703OF_device_register_xref(phandle_t xref, device_t dev)
704{
705        struct xrefinfo *xi;
706
707        /*
708         * If the given xref handle doesn't already exist in the list then we
709         * add a list entry.  In theory this can only happen on a system where
710         * nodes don't contain phandle properties and xref and node handles are
711         * synonymous, so the xref handle is added as the node handle as well.
712         */
713        if (xref_init_done) {
714                if ((xi = xrefinfo_find(xref, FIND_BY_XREF)) == NULL)
715                        xrefinfo_add(xref, xref, dev);
716                else
717                        xi->dev = dev;
718                return (0);
719        }
720        panic("Attempt to register device before xreflist_init");
721}
722
723/*  Call the method in the scope of a given instance. */
724int
725OF_call_method(const char *method, ihandle_t instance, int nargs, int nreturns,
726    ...)
727{
728        va_list ap;
729        cell_t args_n_results[12];
730        int n, status;
731
732        if (nargs > 6 || ofw_def_impl == NULL)
733                return (-1);
734        va_start(ap, nreturns);
735        for (n = 0; n < nargs; n++)
736                args_n_results[n] = va_arg(ap, cell_t);
737
738        status = OFW_CALL_METHOD(ofw_obj, instance, method, nargs, nreturns,
739            args_n_results);
740        if (status != 0)
741                return (status);
742
743        for (; n < nargs + nreturns; n++)
744                *va_arg(ap, cell_t *) = args_n_results[n];
745        va_end(ap);
746        return (0);
747}
748
749/*
750 * Device I/O functions
751 */
752
753/* Open an instance for a device. */
754ihandle_t
755OF_open(const char *device)
756{
757
758        if (ofw_def_impl == NULL)
759                return (0);
760
761        return (OFW_OPEN(ofw_obj, device));
762}
763
764/* Close an instance. */
765void
766OF_close(ihandle_t instance)
767{
768
769        if (ofw_def_impl == NULL)
770                return;
771
772        OFW_CLOSE(ofw_obj, instance);
773}
774
775/* Read from an instance. */
776ssize_t
777OF_read(ihandle_t instance, void *addr, size_t len)
778{
779
780        if (ofw_def_impl == NULL)
781                return (-1);
782
783        return (OFW_READ(ofw_obj, instance, addr, len));
784}
785
786/* Write to an instance. */
787ssize_t
788OF_write(ihandle_t instance, const void *addr, size_t len)
789{
790
791        if (ofw_def_impl == NULL)
792                return (-1);
793
794        return (OFW_WRITE(ofw_obj, instance, addr, len));
795}
796
797/* Seek to a position. */
798int
799OF_seek(ihandle_t instance, uint64_t pos)
800{
801
802        if (ofw_def_impl == NULL)
803                return (-1);
804
805        return (OFW_SEEK(ofw_obj, instance, pos));
806}
807
808/*
809 * Memory functions
810 */
811
812/* Claim an area of memory. */
813void *
814OF_claim(void *virt, size_t size, u_int align)
815{
816
817        if (ofw_def_impl == NULL)
818                return ((void *)-1);
819
820        return (OFW_CLAIM(ofw_obj, virt, size, align));
821}
822
823/* Release an area of memory. */
824void
825OF_release(void *virt, size_t size)
826{
827
828        if (ofw_def_impl == NULL)
829                return;
830
831        OFW_RELEASE(ofw_obj, virt, size);
832}
833
834/*
835 * Control transfer functions
836 */
837
838/* Suspend and drop back to the Open Firmware interface. */
839void
840OF_enter()
841{
842
843        if (ofw_def_impl == NULL)
844                return;
845
846        OFW_ENTER(ofw_obj);
847}
848
849/* Shut down and drop back to the Open Firmware interface. */
850void
851OF_exit()
852{
853
854        if (ofw_def_impl == NULL)
855                panic("OF_exit: Open Firmware not available");
856
857        /* Should not return */
858        OFW_EXIT(ofw_obj);
859
860        for (;;)                        /* just in case */
861                ;
862}
Note: See TracBrowser for help on using the repository browser.