PERFORCE change 34226 for review

Marcel Moolenaar marcel at FreeBSD.org
Tue Jul 8 22:22:00 PDT 2003


http://perforce.freebsd.org/chv.cgi?CH=34226

Change 34226 by marcel at marcel_nfs on 2003/07/08 22:21:21

	Add OF_decode_addr(). This function traverses the OF device
	tree and translates an unit address to a physical address
	for use as bus handle.
	
	There's no header in which we can put the prototype without
	breaking the build. It's not important...
	
	Obtained from: tmm@

Affected files ...

.. //depot/projects/uart/sparc64/sparc64/ofw_machdep.c#2 edit

Differences ...

==== //depot/projects/uart/sparc64/sparc64/ofw_machdep.c#2 (text+ko) ====

@@ -36,9 +36,17 @@
 
 #include <ofw/openfirm.h>
 
+#include <machine/bus.h>
 #include <machine/idprom.h>
 #include <machine/ofw_machdep.h>
+#include <machine/ofw_upa.h>
+#include <machine/resource.h>
 
+#include <sparc64/pci/ofw_pci.h>
+#include <sparc64/isa/ofw_isa.h>
+
+int OF_decode_addr(phandle_t node, int *space, bus_addr_t *addr);
+
 void
 OF_getetheraddr(device_t dev, u_char *addr)
 {
@@ -50,3 +58,61 @@
 		panic("Could not determine the machine ethernet address");
 	bcopy(&idp.id_ether, addr, ETHER_ADDR_LEN);
 }
+
+int
+OF_decode_addr(phandle_t node, int *space, bus_addr_t *addr)
+{
+	char name[32];
+	struct isa_ranges ir[4];
+	struct isa_regs reg;
+	struct upa_ranges ur[4];
+	phandle_t bus, parent, pbus;
+	u_long child, dummy, phys;
+	int cs, i, rsz, type;
+
+	parent = OF_parent(node);
+	if (parent == NULL)
+		return (ENXIO);
+	rsz = OF_getprop(parent, "ranges", ir, sizeof(ir));
+	if (rsz == -1 || OF_getprop(node, "reg", &reg, sizeof(reg)) == -1)
+		return (ENXIO);
+	phys = ISA_REG_PHYS(&reg);
+	dummy = phys + 1;
+	type = ofw_isa_map_iorange(ir, rsz / sizeof(*ir), &phys, &dummy);
+	if (type == SYS_RES_MEMORY) {
+		cs = PCI_CS_MEM32;
+		*space = PCI_MEMORY_BUS_SPACE;
+	} else {
+		cs = PCI_CS_IO;
+		*space = PCI_IO_BUS_SPACE;
+	}
+	bus = OF_parent(parent);
+	if (OF_getprop(bus, "name", name, sizeof(name)) == -1)
+		return (ENXIO);
+	name[sizeof(name) - 1] = '\0';
+	if (strcmp(name, "pci") != 0)
+		return (ENXIO);
+
+	/* Find the topmost PCI node (the host bridge) */
+	while ((pbus = OF_parent(bus)) != 0) {
+		if (OF_getprop(pbus, "name", name, sizeof(name)) != -1) {
+			name[sizeof(name) - 1] = '\0';
+			if (strcmp(name, "pci") != 0)
+				break;
+		}
+		bus = pbus;
+	}
+	if (pbus == 0)
+		return (ENXIO);
+	if ((rsz = OF_getprop(bus, "ranges", ur, sizeof(ur))) == -1)
+		return (ENXIO);
+	for (i = 0; i < (rsz / sizeof(ur[0])); i++) {
+		child = UPA_RANGE_CHILD(&ur[i]);
+		if (UPA_RANGE_CS(&ur[i]) == cs && phys >= child &&
+		    phys - child < UPA_RANGE_SIZE(&ur[i])) {
+			*addr = UPA_RANGE_PHYS(&ur[i]) + phys;
+			return (0);
+		}
+	}
+	return (ENXIO);
+}


More information about the p4-projects mailing list