On Fri, Jul 08, 2016 at 09:56:46PM +0200, Mark Kettenis wrote:
> FDTs use phandles as a way to have pointers to nodes in the tree.  For
> example, nodes may have an "interrupt-parent" property that contains a
> phandle that points to the node that defines the interrupt controller
> for the interrupts of the device that corresponds to the node.  This
> phandle is a simple 32-bit integer.  The interrupt controller node
> will have a "phandle" (or "linux,phandle") property with that same
> 32-bit integer.
> 
> The diff provides both a fdt-style and on OF-style interface.  These
> interfaces will be used in the armv7 port to do the necessary phandle
> lookups.
> 
> ok?

I think I had something like this in one of my diffs as well.  I like
it, go ahead.

> 
> 
> Index: dev/ofw/fdt.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/ofw/fdt.c,v
> retrieving revision 1.16
> diff -u -p -r1.16 fdt.c
> --- dev/ofw/fdt.c     8 Jul 2016 18:20:48 -0000       1.16
> +++ dev/ofw/fdt.c     8 Jul 2016 19:49:37 -0000
> @@ -35,6 +35,7 @@ void        *skip_node_name(u_int32_t *);
>  void *skip_node(void *);
>  void *skip_nops(u_int32_t *);
>  void *fdt_parent_node_recurse(void *, void *);
> +void *fdt_find_phandle_recurse(void *, uint32_t);
>  int   fdt_node_property_int(void *, char *, int *);
>  int   fdt_node_property_ints(void *, char *, int *, int);
>  int   fdt_translate_memory_address(void *, struct fdt_memory *);
> @@ -443,6 +444,34 @@ fdt_parent_node(void *node)
>       return fdt_parent_node_recurse(pnode, node);
>  }
>  
> +void *
> +fdt_find_phandle_recurse(void *node, uint32_t phandle)
> +{
> +     void *child;
> +     char *data;
> +     void *tmp;
> +     int len;
> +
> +     len = fdt_node_property(node, "phandle", &data);
> +     if (len < 0)
> +             len = fdt_node_property(node, "linux,phandle", &data);
> +
> +     if (len == sizeof(uint32_t) && bemtoh32(data) == phandle)
> +             return node;
> +
> +     for (child = fdt_child_node(node); child; child = fdt_next_node(child))
> +             if ((tmp = fdt_find_phandle_recurse(child, phandle)))
> +                     return tmp;
> +
> +     return NULL;
> +}
> +
> +void *
> +fdt_find_phandle(uint32_t phandle)
> +{
> +     return fdt_find_phandle_recurse(fdt_next_node(0), phandle);
> +}
> +
>  /*
>   * Translate memory address depending on parent's range.
>   *
> @@ -748,6 +777,15 @@ OF_getnodebyname(int handle, const char 
>               node = fdt_next_node(node);
>       }
>  
> +     return node ? ((char *)node - (char *)tree.header) : 0;
> +}
> +
> +int
> +OF_getnodebyphandle(uint32_t phandle)
> +{
> +     void *node;
> +
> +     node = fdt_find_phandle(phandle);
>       return node ? ((char *)node - (char *)tree.header) : 0;
>  }
>  
> Index: dev/ofw/fdt.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/ofw/fdt.h,v
> retrieving revision 1.3
> diff -u -p -r1.3 fdt.h
> --- dev/ofw/fdt.h     8 Jun 2016 15:27:05 -0000       1.3
> +++ dev/ofw/fdt.h     8 Jul 2016 19:49:37 -0000
> @@ -60,6 +60,7 @@ char        *fdt_node_name(void *);
>  void *fdt_find_node(char *);
>  int   fdt_node_property(void *, char *, char **);
>  void *fdt_parent_node(void *);
> +void *fdt_find_phandle(uint32_t);
>  int   fdt_get_memory_address(void *, int, struct fdt_memory *);
>  int   fdt_is_compatible(void *, const char *);
>  #ifdef DEBUG
> Index: dev/ofw/openfirm.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/ofw/openfirm.h,v
> retrieving revision 1.12
> diff -u -p -r1.12 openfirm.h
> --- dev/ofw/openfirm.h        12 Jun 2016 12:55:42 -0000      1.12
> +++ dev/ofw/openfirm.h        8 Jul 2016 19:49:37 -0000
> @@ -71,6 +71,7 @@ int OF_interpret(char *cmd, int nreturns
>  void (*OF_set_callback(void (*newfunc)(void *))) ();
>  #endif
>  int OF_getnodebyname(int, const char *);
> +int OF_getnodebyphandle(uint32_t);
>  
>  /*
>   * Some generic routines for OpenFirmware handling.
> 

Reply via email to