svn commit: r255596 - in head/sys: dev/ofw powerpc/ofw

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sun Sep 15 14:19:18 UTC 2013


Author: nwhitehorn
Date: Sun Sep 15 14:19:17 2013
New Revision: 255596
URL: http://svnweb.freebsd.org/changeset/base/255596

Log:
  Add a kernel interface (OF_xref_phandle()) for systems where phandles
  used as cross-references in the device tree and phandles as used by the
  Open Firmware client interface are in different namespaces. This include
  IBM pSeries hardware as well as FDT systems. FDT certainly abuses
  ihandles for this purpose and should be modified to use this API
  eventually. This changes no behavior on systems where FreeBSD already
  worked.
  
  Reviewed by:	marius
  Approved by:	re (kib)
  MFC after:	2 weeks

Modified:
  head/sys/dev/ofw/ofw_bus_subr.c
  head/sys/dev/ofw/openfirm.c
  head/sys/dev/ofw/openfirm.h
  head/sys/powerpc/ofw/ofw_pcibus.c

Modified: head/sys/dev/ofw/ofw_bus_subr.c
==============================================================================
--- head/sys/dev/ofw/ofw_bus_subr.c	Sun Sep 15 13:50:56 2013	(r255595)
+++ head/sys/dev/ofw/ofw_bus_subr.c	Sun Sep 15 14:19:17 2013	(r255596)
@@ -300,7 +300,7 @@ ofw_bus_search_intrmap(void *intr, int i
 	i = imapsz;
 	while (i > 0) {
 		bcopy(mptr + physsz + intrsz, &parent, sizeof(parent));
-		if (OF_searchprop(parent, "#interrupt-cells",
+		if (OF_searchprop(OF_xref_phandle(parent), "#interrupt-cells",
 		    &pintrsz, sizeof(pintrsz)) == -1)
 			pintrsz = 1;	/* default */
 		pintrsz *= sizeof(pcell_t);

Modified: head/sys/dev/ofw/openfirm.c
==============================================================================
--- head/sys/dev/ofw/openfirm.c	Sun Sep 15 13:50:56 2013	(r255595)
+++ head/sys/dev/ofw/openfirm.c	Sun Sep 15 14:19:17 2013	(r255596)
@@ -386,6 +386,48 @@ 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)
+{
+	phandle_t child, rxref;
+
+	/*
+	 * 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.
+	 */
+
+	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: head/sys/dev/ofw/openfirm.h
==============================================================================
--- head/sys/dev/ofw/openfirm.h	Sun Sep 15 13:50:56 2013	(r255595)
+++ head/sys/dev/ofw/openfirm.h	Sun Sep 15 14:19:17 2013	(r255596)
@@ -118,6 +118,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);

Modified: head/sys/powerpc/ofw/ofw_pcibus.c
==============================================================================
--- head/sys/powerpc/ofw/ofw_pcibus.c	Sun Sep 15 13:50:56 2013	(r255595)
+++ head/sys/powerpc/ofw/ofw_pcibus.c	Sun Sep 15 14:19:17 2013	(r255596)
@@ -210,11 +210,12 @@ ofw_pcibus_enum_devtree(device_t dev, u_
 				icells = 1;
 				OF_getprop(child, "interrupt-parent", &iparent,
 				    sizeof(iparent));
-				OF_getprop(iparent, "#interrupt-cells", &icells,
-				    sizeof(icells));
-
-				if (iparent != 0)
+				if (iparent != 0) {
+					OF_getprop(OF_xref_phandle(iparent),
+					    "#interrupt-cells", &icells,
+					    sizeof(icells));
 					intr[0] = MAP_IRQ(iparent, intr[0]);
+				}
 
 				if (iparent != 0 && icells > 1) {
 					powerpc_config_intr(intr[0],


More information about the svn-src-all mailing list