Date: Wed, 2 Nov 2011 16:39:11 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r227021 - projects/pseries/dev/ofw Message-ID: <201111021639.pA2GdBmM029494@svn.freebsd.org>
index | next in thread | raw e-mail
Author: nwhitehorn Date: Wed Nov 2 16:39:10 2011 New Revision: 227021 URL: http://svn.freebsd.org/changeset/base/227021 Log: Add an interface for the strange PAPR/FDT concept of phandles by adding a rountine to look up client interface phandles from device tree cross references. This can be optimized further, but works and should eventually replace the abuse of ihandles in ofw_fdt. Modified: projects/pseries/dev/ofw/ofw_bus_subr.c projects/pseries/dev/ofw/openfirm.c projects/pseries/dev/ofw/openfirm.h Modified: projects/pseries/dev/ofw/ofw_bus_subr.c ============================================================================== --- projects/pseries/dev/ofw/ofw_bus_subr.c Wed Nov 2 14:28:36 2011 (r227020) +++ projects/pseries/dev/ofw/ofw_bus_subr.c Wed Nov 2 16:39:10 2011 (r227021) @@ -285,6 +285,7 @@ ofw_bus_search_intrmap(void *intr, int i i = imapsz; while (i > 0) { bcopy(mptr + physsz + intrsz, &parent, sizeof(parent)); + parent = OF_xref_phandle(parent); if (OF_searchprop(parent, "#interrupt-cells", &pintrsz, sizeof(pintrsz)) == -1) pintrsz = 1; /* default */ @@ -292,7 +293,10 @@ ofw_bus_search_intrmap(void *intr, int i /* Compute the map stride size. */ tsz = physsz + intrsz + sizeof(phandle_t) + pintrsz; - KASSERT(i >= tsz, ("ofw_bus_search_intrmap: truncated map")); + KASSERT(i >= tsz, ("ofw_bus_search_intrmap: truncated map " + "(imapsz: %d, tsz: %d, physsz: %d, intrsz: %d, " + "sizeof(phandle_t): %zd, pintrsz: %d)", imapsz, tsz, + physsz, intrsz, sizeof(phandle_t), pintrsz)); /* * XXX: Apple hardware uses a second cell to set information Modified: projects/pseries/dev/ofw/openfirm.c ============================================================================== --- projects/pseries/dev/ofw/openfirm.c Wed Nov 2 14:28:36 2011 (r227020) +++ projects/pseries/dev/ofw/openfirm.c Wed Nov 2 16:39:10 2011 (r227021) @@ -364,6 +364,47 @@ OF_package_to_path(phandle_t package, ch return (OFW_PACKAGE_TO_PATH(ofw_obj, package, buf, len)); } +/* Look up effective phandle (see FDT/PAPR spec) */ +static phandle_t +OF_child_xref_phandle(phandle_t parent, phandle_t xref) +{ + /* + * Recursively descend from parent, looking for a node with a property + * named either "phandle", "ibm,phandle", or "linux,phandle" that + * matches the xref we are looking for. + */ + phandle_t child, rxref; + + for (child = OF_child(parent); child != 0; child = OF_peer(child)) { + rxref = OF_child_xref_phandle(child, xref); + if (rxref != -1) + return (rxref); + + if (OF_getprop(child, "phandle", &rxref, sizeof(rxref)) == -1 && + OF_getprop(child, "ibm,phandle", &rxref, + sizeof(rxref)) == -1 && OF_getprop(child, + "linux,phandle", &rxref, sizeof(rxref)) == -1) + continue; + + if (rxref == xref) + return (child); + } + + return (-1); +} + +phandle_t +OF_xref_phandle(phandle_t xref) +{ + phandle_t node; + + node = OF_child_xref_phandle(OF_peer(0), xref); + if (node == -1) + return (xref); + + return (node); +} + /* Call the method in the scope of a given instance. */ int OF_call_method(const char *method, ihandle_t instance, int nargs, int nreturns, Modified: projects/pseries/dev/ofw/openfirm.h ============================================================================== --- projects/pseries/dev/ofw/openfirm.h Wed Nov 2 14:28:36 2011 (r227020) +++ projects/pseries/dev/ofw/openfirm.h Wed Nov 2 16:39:10 2011 (r227021) @@ -117,6 +117,14 @@ ssize_t OF_canon(const char *path, char phandle_t OF_finddevice(const char *path); ssize_t OF_package_to_path(phandle_t node, char *buf, size_t len); +/* + * Some OF implementations (IBM, FDT) have a concept of effective phandles + * used for device-tree cross-references. Given one of these, returns the + * real phandle. If one can't be found (or running on OF implementations + * without this property), returns its input. + */ +phandle_t OF_xref_phandle(phandle_t xref); + /* Device I/O functions */ ihandle_t OF_open(const char *path); void OF_close(ihandle_t instance);help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201111021639.pA2GdBmM029494>
