summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2009-09-09 20:42:42 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2009-09-09 20:42:42 +0000
commitc65e960499bfe8bc88c832ed2784b6c396a4062b (patch)
tree37b90c46e86dc6649662a43fa34bf19f90bf85a4 /sys/arch
parentb8214251e0d8ce0bcc0241eb63bddc328e979bff (diff)
Use information from the FDT to set up bus tags and extents.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/socppc/dev/socpcic.c61
1 files changed, 51 insertions, 10 deletions
diff --git a/sys/arch/socppc/dev/socpcic.c b/sys/arch/socppc/dev/socpcic.c
index 00f6507d2e0..69836d3b9d4 100644
--- a/sys/arch/socppc/dev/socpcic.c
+++ b/sys/arch/socppc/dev/socpcic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: socpcic.c,v 1.7 2009/09/06 20:09:34 kettenis Exp $ */
+/* $OpenBSD: socpcic.c,v 1.8 2009/09/09 20:42:41 kettenis Exp $ */
/*
* Copyright (c) 2008 Mark Kettenis
@@ -24,6 +24,7 @@
#include <machine/bus.h>
#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_pci.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
@@ -45,6 +46,10 @@ struct socpcic_softc {
int sc_map_mask[4];
int *sc_map;
int sc_map_len;
+
+ /* Addres space. */
+ uint32_t *sc_ranges;
+ int sc_ranges_len;
};
int socpcic_mainbus_match(struct device *, void *, void *);
@@ -167,6 +172,9 @@ socpcic_attach(struct socpcic_softc *sc)
struct pcibus_attach_args pba;
struct extent *io_ex;
struct extent *mem_ex;
+ bus_addr_t io_base, mem_base;
+ bus_size_t io_size, mem_size;
+ uint32_t *ranges;
int len;
if (OF_getprop(sc->sc_node, "interrupt-map-mask", sc->sc_map_mask,
@@ -186,12 +194,45 @@ socpcic_attach(struct socpcic_softc *sc)
KASSERT(len == sc->sc_map_len);
}
- sc->sc_mem_bus_space.bus_base = 0x80000000;
- sc->sc_mem_bus_space.bus_size = 0x21000000;
- sc->sc_mem_bus_space.bus_io = 0;
- sc->sc_io_bus_space.bus_base = 0xe2000000;
- sc->sc_io_bus_space.bus_size = 0x01000000;
- sc->sc_io_bus_space.bus_io = 1;
+ sc->sc_ranges_len = OF_getproplen(sc->sc_node, "ranges");
+ if (sc->sc_ranges_len <= 0) {
+ printf(": missing ranges\n");
+ return;
+ }
+
+ sc->sc_ranges = malloc(sc->sc_ranges_len, M_DEVBUF, M_NOWAIT);
+ if (ranges == NULL)
+ panic("out of memory");
+
+ len = OF_getprop(sc->sc_node, "ranges", sc->sc_ranges,
+ sc->sc_ranges_len);
+ KASSERT(len == sc->sc_ranges_len);
+
+ ranges = sc->sc_ranges;
+ while (len >= 6 * sizeof(uint32_t)) {
+ switch (ranges[0] & OFW_PCI_PHYS_HI_SPACEMASK) {
+ case OFW_PCI_PHYS_HI_SPACE_IO:
+ KASSERT(ranges[1] == 0);
+ KASSERT(ranges[4] == 0);
+ sc->sc_io_bus_space.bus_base = ranges[3];
+ sc->sc_io_bus_space.bus_size = ranges[5];
+ sc->sc_io_bus_space.bus_io = 1;
+ io_base = ranges[2];
+ io_size = ranges[5];
+ break;
+ case OFW_PCI_PHYS_HI_SPACE_MEM32:
+ KASSERT(ranges[1] == 0);
+ KASSERT(ranges[4] == 0);
+ sc->sc_mem_bus_space.bus_base = ranges[3];
+ sc->sc_mem_bus_space.bus_size = ranges[5];
+ sc->sc_mem_bus_space.bus_io = 0;
+ mem_base = ranges[2];
+ mem_size = ranges[5];
+ break;
+ }
+ len -= 6 * sizeof(uint32_t);
+ ranges += 6;
+ }
sc->sc_pc.pc_conf_v = sc;
sc->sc_pc.pc_attach_hook = socpcic_attach_hook;
@@ -211,12 +252,12 @@ socpcic_attach(struct socpcic_softc *sc)
io_ex = extent_create("pciio", 0, 0xffffffff, M_DEVBUF, NULL, 0,
EX_NOWAIT | EX_FILLED);
- if (io_ex != NULL)
- extent_free(io_ex, 0x00000000, 0x01000000, EX_NOWAIT);
+ if (io_ex != NULL && io_size)
+ extent_free(io_ex, io_base, io_size, EX_NOWAIT);
mem_ex = extent_create("pcimem", 0, 0xffffffff, M_DEVBUF, NULL, 0,
EX_NOWAIT | EX_FILLED);
if (mem_ex != NULL)
- extent_free(mem_ex, 0x80000000, 0x20000000, EX_NOWAIT);
+ extent_free(mem_ex, mem_base, mem_size, EX_NOWAIT);
bzero(&pba, sizeof(pba));
pba.pba_busname = "pci";