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", ®, sizeof(reg)) == -1)
+ return (ENXIO);
+ phys = ISA_REG_PHYS(®);
+ 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