The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ofw/openfirm.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai Exp $        */
    2 
    3 /*-
    4  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
    5  * Copyright (C) 1995, 1996 TooLs GmbH.
    6  * All rights reserved.
    7  *
    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.
   21  *
   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.
   32  */
   33 /*-
   34  * Copyright (C) 2000 Benno Rice.
   35  * All rights reserved.
   36  *
   37  * Redistribution and use in source and binary forms, with or without
   38  * modification, are permitted provided that the following conditions
   39  * are met:
   40  * 1. Redistributions of source code must retain the above copyright
   41  *    notice, this list of conditions and the following disclaimer.
   42  * 2. Redistributions in binary form must reproduce the above copyright
   43  *    notice, this list of conditions and the following disclaimer in the
   44  *    documentation and/or other materials provided with the distribution.
   45  *
   46  * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
   47  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   48  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   49  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   50  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   51  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   52  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   53  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   54  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   55  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   56  */
   57 
   58 #include <sys/cdefs.h>
   59 __FBSDID("$FreeBSD: releng/9.0/sys/dev/ofw/openfirm.c 227712 2011-11-19 12:55:34Z marius $");
   60 
   61 #include "opt_platform.h"
   62 
   63 #include <sys/param.h>
   64 #include <sys/kernel.h>
   65 #include <sys/malloc.h>
   66 #include <sys/systm.h>
   67 
   68 #include <machine/stdarg.h>
   69 
   70 #include <dev/ofw/ofwvar.h>
   71 #include <dev/ofw/openfirm.h>
   72 
   73 #include "ofw_if.h"
   74 
   75 MALLOC_DEFINE(M_OFWPROP, "openfirm", "Open Firmware properties");
   76 
   77 static ihandle_t stdout;
   78 
   79 static ofw_def_t        *ofw_def_impl = NULL;
   80 static ofw_t            ofw_obj;
   81 static struct ofw_kobj  ofw_kernel_obj;
   82 static struct kobj_ops  ofw_kernel_kops;
   83 
   84 /*
   85  * OFW install routines. Highest priority wins, equal priority also
   86  * overrides allowing last-set to win.
   87  */
   88 SET_DECLARE(ofw_set, ofw_def_t);
   89 
   90 boolean_t
   91 OF_install(char *name, int prio)
   92 {
   93         ofw_def_t *ofwp, **ofwpp;
   94         static int curr_prio = 0;
   95 
   96         /*
   97          * Try and locate the OFW kobj corresponding to the name.
   98          */
   99         SET_FOREACH(ofwpp, ofw_set) {
  100                 ofwp = *ofwpp;
  101 
  102                 if (ofwp->name &&
  103                     !strcmp(ofwp->name, name) &&
  104                     prio >= curr_prio) {
  105                         curr_prio = prio;
  106                         ofw_def_impl = ofwp;
  107                         return (TRUE);
  108                 }
  109         }
  110 
  111         return (FALSE);
  112 }
  113 
  114 /* Initializer */
  115 int
  116 OF_init(void *cookie)
  117 {
  118         phandle_t chosen;
  119         int rv;
  120 
  121         if (ofw_def_impl == NULL)
  122                 return (-1);
  123 
  124         ofw_obj = &ofw_kernel_obj;
  125         /*
  126          * Take care of compiling the selected class, and
  127          * then statically initialize the OFW object.
  128          */
  129         kobj_class_compile_static(ofw_def_impl, &ofw_kernel_kops);
  130         kobj_init_static((kobj_t)ofw_obj, ofw_def_impl);
  131 
  132         rv = OFW_INIT(ofw_obj, cookie);
  133 
  134         if ((chosen = OF_finddevice("/chosen")) > 0)
  135                 if (OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) == -1)
  136                         stdout = -1;
  137 
  138         return (rv);
  139 }
  140 
  141 void
  142 OF_printf(const char *fmt, ...)
  143 {
  144         va_list va;
  145         char buf[1024];
  146 
  147         va_start(va, fmt);
  148         vsprintf(buf, fmt, va);
  149         OF_write(stdout, buf, strlen(buf));
  150         va_end(va);
  151 }
  152 
  153 /*
  154  * Generic functions
  155  */
  156 
  157 /* Test to see if a service exists. */
  158 int
  159 OF_test(const char *name)
  160 {
  161 
  162         if (ofw_def_impl == NULL)
  163                 return (-1);
  164 
  165         return (OFW_TEST(ofw_obj, name));
  166 }
  167 
  168 int
  169 OF_interpret(const char *cmd, int nreturns, ...)
  170 {
  171         va_list ap;
  172         cell_t slots[16];
  173         int i = 0;
  174         int status;
  175 
  176         if (ofw_def_impl == NULL)
  177                 return (-1);
  178 
  179         status = OFW_INTERPRET(ofw_obj, cmd, nreturns, slots);
  180         if (status == -1)
  181                 return (status);
  182 
  183         va_start(ap, nreturns);
  184         while (i < nreturns)
  185                 *va_arg(ap, cell_t *) = slots[i++];
  186         va_end(ap);
  187 
  188         return (status);
  189 }
  190 
  191 /*
  192  * Device tree functions
  193  */
  194 
  195 /* Return the next sibling of this node or 0. */
  196 phandle_t
  197 OF_peer(phandle_t node)
  198 {
  199 
  200         if (ofw_def_impl == NULL)
  201                 return (0);
  202 
  203         return (OFW_PEER(ofw_obj, node));
  204 }
  205 
  206 /* Return the first child of this node or 0. */
  207 phandle_t
  208 OF_child(phandle_t node)
  209 {
  210 
  211         if (ofw_def_impl == NULL)
  212                 return (0);
  213 
  214         return (OFW_CHILD(ofw_obj, node));
  215 }
  216 
  217 /* Return the parent of this node or 0. */
  218 phandle_t
  219 OF_parent(phandle_t node)
  220 {
  221 
  222         if (ofw_def_impl == NULL)
  223                 return (0);
  224 
  225         return (OFW_PARENT(ofw_obj, node));
  226 }
  227 
  228 /* Return the package handle that corresponds to an instance handle. */
  229 phandle_t
  230 OF_instance_to_package(ihandle_t instance)
  231 {
  232 
  233         if (ofw_def_impl == NULL)
  234                 return (-1);
  235 
  236         return (OFW_INSTANCE_TO_PACKAGE(ofw_obj, instance));
  237 }
  238 
  239 /* Get the length of a property of a package. */
  240 ssize_t
  241 OF_getproplen(phandle_t package, const char *propname)
  242 {
  243 
  244         if (ofw_def_impl == NULL)
  245                 return (-1);
  246 
  247         return (OFW_GETPROPLEN(ofw_obj, package, propname));
  248 }
  249 
  250 /* Get the value of a property of a package. */
  251 ssize_t
  252 OF_getprop(phandle_t package, const char *propname, void *buf, size_t buflen)
  253 {
  254 
  255         if (ofw_def_impl == NULL)
  256                 return (-1);
  257 
  258         return (OFW_GETPROP(ofw_obj, package, propname, buf, buflen));
  259 }
  260 
  261 /*
  262  * Recursively search the node and its parent for the given property, working
  263  * downward from the node to the device tree root.  Returns the value of the
  264  * first match.
  265  */
  266 ssize_t
  267 OF_searchprop(phandle_t node, const char *propname, void *buf, size_t len)
  268 {
  269         ssize_t rv;
  270 
  271         for (; node != 0; node = OF_parent(node))
  272                 if ((rv = OF_getprop(node, propname, buf, len)) != -1)
  273                         return (rv);
  274         return (-1);
  275 }
  276 
  277 /*
  278  * Store the value of a property of a package into newly allocated memory
  279  * (using the M_OFWPROP malloc pool and M_WAITOK).  elsz is the size of a
  280  * single element, the number of elements is return in number.
  281  */
  282 ssize_t
  283 OF_getprop_alloc(phandle_t package, const char *propname, int elsz, void **buf)
  284 {
  285         int len;
  286 
  287         *buf = NULL;
  288         if ((len = OF_getproplen(package, propname)) == -1 ||
  289             len % elsz != 0)
  290                 return (-1);
  291 
  292         *buf = malloc(len, M_OFWPROP, M_WAITOK);
  293         if (OF_getprop(package, propname, *buf, len) == -1) {
  294                 free(*buf, M_OFWPROP);
  295                 *buf = NULL;
  296                 return (-1);
  297         }
  298         return (len / elsz);
  299 }
  300 
  301 /* Get the next property of a package. */
  302 int
  303 OF_nextprop(phandle_t package, const char *previous, char *buf, size_t size)
  304 {
  305 
  306         if (ofw_def_impl == NULL)
  307                 return (-1);
  308 
  309         return (OFW_NEXTPROP(ofw_obj, package, previous, buf, size));
  310 }
  311 
  312 /* Set the value of a property of a package. */
  313 int
  314 OF_setprop(phandle_t package, const char *propname, const void *buf, size_t len)
  315 {
  316 
  317         if (ofw_def_impl == NULL)
  318                 return (-1);
  319 
  320         return (OFW_SETPROP(ofw_obj, package, propname, buf,len));
  321 }
  322 
  323 /* Convert a device specifier to a fully qualified pathname. */
  324 ssize_t
  325 OF_canon(const char *device, char *buf, size_t len)
  326 {
  327 
  328         if (ofw_def_impl == NULL)
  329                 return (-1);
  330 
  331         return (OFW_CANON(ofw_obj, device, buf, len));
  332 }
  333 
  334 /* Return a package handle for the specified device. */
  335 phandle_t
  336 OF_finddevice(const char *device)
  337 {
  338 
  339         if (ofw_def_impl == NULL)
  340                 return (-1);
  341 
  342         return (OFW_FINDDEVICE(ofw_obj, device));
  343 }
  344 
  345 /* Return the fully qualified pathname corresponding to an instance. */
  346 ssize_t
  347 OF_instance_to_path(ihandle_t instance, char *buf, size_t len)
  348 {
  349 
  350         if (ofw_def_impl == NULL)
  351                 return (-1);
  352 
  353         return (OFW_INSTANCE_TO_PATH(ofw_obj, instance, buf, len));
  354 }
  355 
  356 /* Return the fully qualified pathname corresponding to a package. */
  357 ssize_t
  358 OF_package_to_path(phandle_t package, char *buf, size_t len)
  359 {
  360 
  361         if (ofw_def_impl == NULL)
  362                 return (-1);
  363 
  364         return (OFW_PACKAGE_TO_PATH(ofw_obj, package, buf, len));
  365 }
  366 
  367 /*  Call the method in the scope of a given instance. */
  368 int
  369 OF_call_method(const char *method, ihandle_t instance, int nargs, int nreturns,
  370     ...)
  371 {
  372         va_list ap;
  373         cell_t args_n_results[12];
  374         int n, status;
  375 
  376         if (nargs > 6 || ofw_def_impl == NULL)
  377                 return (-1);
  378         va_start(ap, nreturns);
  379         for (n = 0; n < nargs; n++)
  380                 args_n_results[n] = va_arg(ap, cell_t);
  381 
  382         status = OFW_CALL_METHOD(ofw_obj, instance, method, nargs, nreturns,
  383             args_n_results);
  384         if (status != 0)
  385                 return (status);
  386 
  387         for (; n < nargs + nreturns; n++)
  388                 *va_arg(ap, cell_t *) = args_n_results[n];
  389         va_end(ap);
  390         return (0);
  391 }
  392 
  393 /*
  394  * Device I/O functions
  395  */
  396 
  397 /* Open an instance for a device. */
  398 ihandle_t
  399 OF_open(const char *device)
  400 {
  401 
  402         if (ofw_def_impl == NULL)
  403                 return (0);
  404 
  405         return (OFW_OPEN(ofw_obj, device));
  406 }
  407 
  408 /* Close an instance. */
  409 void
  410 OF_close(ihandle_t instance)
  411 {
  412 
  413         if (ofw_def_impl == NULL)
  414                 return;
  415 
  416         OFW_CLOSE(ofw_obj, instance);
  417 }
  418 
  419 /* Read from an instance. */
  420 ssize_t
  421 OF_read(ihandle_t instance, void *addr, size_t len)
  422 {
  423 
  424         if (ofw_def_impl == NULL)
  425                 return (-1);
  426 
  427         return (OFW_READ(ofw_obj, instance, addr, len));
  428 }
  429 
  430 /* Write to an instance. */
  431 ssize_t
  432 OF_write(ihandle_t instance, const void *addr, size_t len)
  433 {
  434 
  435         if (ofw_def_impl == NULL)
  436                 return (-1);
  437 
  438         return (OFW_WRITE(ofw_obj, instance, addr, len));
  439 }
  440 
  441 /* Seek to a position. */
  442 int
  443 OF_seek(ihandle_t instance, uint64_t pos)
  444 {
  445 
  446         if (ofw_def_impl == NULL)
  447                 return (-1);
  448 
  449         return (OFW_SEEK(ofw_obj, instance, pos));
  450 }
  451 
  452 /*
  453  * Memory functions
  454  */
  455 
  456 /* Claim an area of memory. */
  457 void *
  458 OF_claim(void *virt, size_t size, u_int align)
  459 {
  460 
  461         if (ofw_def_impl == NULL)
  462                 return ((void *)-1);
  463 
  464         return (OFW_CLAIM(ofw_obj, virt, size, align));
  465 }
  466 
  467 /* Release an area of memory. */
  468 void
  469 OF_release(void *virt, size_t size)
  470 {
  471 
  472         if (ofw_def_impl == NULL)
  473                 return;
  474 
  475         OFW_RELEASE(ofw_obj, virt, size);
  476 }
  477 
  478 /*
  479  * Control transfer functions
  480  */
  481 
  482 /* Suspend and drop back to the Open Firmware interface. */
  483 void
  484 OF_enter()
  485 {
  486 
  487         if (ofw_def_impl == NULL)
  488                 return;
  489 
  490         OFW_ENTER(ofw_obj);
  491 }
  492 
  493 /* Shut down and drop back to the Open Firmware interface. */
  494 void
  495 OF_exit()
  496 {
  497 
  498         if (ofw_def_impl == NULL)
  499                 panic("OF_exit: Open Firmware not available");
  500 
  501         /* Should not return */
  502         OFW_EXIT(ofw_obj);
  503 
  504         for (;;)                        /* just in case */
  505                 ;
  506 }

Cache object: 7eddadd5785a2e9e86b7758450f3c0bf


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.