summaryrefslogtreecommitdiffstats
path: root/sys/sparc64/isa
diff options
context:
space:
mode:
Diffstat (limited to 'sys/sparc64/isa')
-rw-r--r--sys/sparc64/isa/isa.c62
-rw-r--r--sys/sparc64/isa/ofw_isa.c33
-rw-r--r--sys/sparc64/isa/ofw_isa.h18
3 files changed, 84 insertions, 29 deletions
diff --git a/sys/sparc64/isa/isa.c b/sys/sparc64/isa/isa.c
index 2df0257d..4916b1e 100644
--- a/sys/sparc64/isa/isa.c
+++ b/sys/sparc64/isa/isa.c
@@ -29,6 +29,8 @@
* $FreeBSD$
*/
+#include "opt_ofw_pci.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -57,8 +59,6 @@
#include <sparc64/pci/ofw_pci.h>
#include <sparc64/isa/ofw_isa.h>
-#include "sparcbus_if.h"
-
/* There can be only one ISA bus, so it is safe to use globals. */
bus_space_tag_t isa_io_bt = NULL;
bus_space_handle_t isa_io_hdl;
@@ -73,7 +73,11 @@ u_int64_t isa_mem_limit;
device_t isa_bus_device;
static phandle_t isab_node;
-static u_int32_t isa_ino[8];
+static ofw_pci_intr_t isa_ino[8];
+
+#ifdef OFW_NEWPCI
+struct ofw_bus_iinfo isa_iinfo;
+#endif
/*
* XXX: This is really partly partly PCI-specific, but unfortunately is
@@ -98,9 +102,9 @@ isa_irq_pending(void)
/* XXX: Is this correct? */
for (i = 7, pending = 0; i >= 0; i--) {
- pending <<= 1;
- if (isa_ino[i] != ORIR_NOTFOUND) {
- pending |= (SPARCBUS_INTR_PENDING(isa_bus_device,
+ pending <<= 1;
+ if (isa_ino[i] != PCI_INVALID_IRQ) {
+ pending |= (OFW_PCI_INTR_PENDING(isa_bus_device,
isa_ino[i]) == 0) ? 0 : 1;
}
}
@@ -112,29 +116,47 @@ isa_init(device_t dev)
{
device_t bridge;
phandle_t node;
- u_int32_t ino;
+ ofw_isa_intr_t ino;
+#ifndef OFW_NEWPCI
+ ofw_pci_intr_t rino;
+#endif
struct isa_ranges *br;
int nbr, i;
/* The parent of the bus must be a PCI-ISA bridge. */
bridge = device_get_parent(dev);
+#ifdef OFW_NEWPCI
+ isab_node = ofw_pci_get_node(bridge);
+#else
isab_node = ofw_pci_node(bridge);
+#endif
nbr = OF_getprop_alloc(isab_node, "ranges", sizeof(*br), (void **)&br);
if (nbr <= 0)
panic("isa_init: cannot get bridge range property");
+
+#ifdef OFW_NEWPCI
+ ofw_bus_setup_iinfo(isab_node, &isa_iinfo, sizeof(ofw_isa_intr_t));
+#endif
+
/*
- * This is really a bad kluge; however, it is needed to provide
- * isa_irq_pending().
+ * This is really a bad kludge; however, it is needed to provide
+ * isa_irq_pending(), which is unfortunately still used by some
+ * drivers.
*/
for (i = 0; i < 8; i++)
- isa_ino[i] = ORIR_NOTFOUND;
+ isa_ino[i] = PCI_INVALID_IRQ;
for (node = OF_child(isab_node); node != 0; node = OF_peer(node)) {
if (OF_getprop(node, "interrupts", &ino, sizeof(ino)) == -1)
continue;
if (ino > 7)
panic("isa_init: XXX: ino too large");
- isa_ino[ino] = ofw_bus_route_intr(node, ino,
- ofw_pci_orb_callback, dev);
+#ifdef OFW_NEWPCI
+ isa_ino[ino] = ofw_isa_route_intr(bridge, node, &isa_iinfo,
+ ino);
+#else
+ rino = ofw_bus_route_intr(node, ino, ofw_pci_orb_callback, dev);
+ isa_ino[ino] = rino == ORIR_NOTFOUND ? PCI_INVALID_IRQ : rino;
+#endif
}
for (nbr -= 1; nbr >= 0; nbr--) {
@@ -143,15 +165,15 @@ isa_init(device_t dev)
/* This is probably always 0. */
isa_io_base = ISAB_RANGE_PHYS(&br[nbr]);
isa_io_limit = br[nbr].size;
- isa_io_hdl = SPARCBUS_GET_BUS_HANDLE(bridge, SBBT_IO,
- isa_io_base, &isa_io_bt);
+ isa_io_hdl = OFW_PCI_GET_BUS_HANDLE(bridge,
+ SYS_RES_IOPORT, isa_io_base, &isa_io_bt);
break;
case ISAR_SPACE_MEM:
/* This is probably always 0. */
isa_mem_base = ISAB_RANGE_PHYS(&br[nbr]);
isa_mem_limit = br[nbr].size;
- isa_mem_hdl = SPARCBUS_GET_BUS_HANDLE(bridge, SBBT_MEM,
- isa_mem_base, &isa_mem_bt);
+ isa_mem_hdl = OFW_PCI_GET_BUS_HANDLE(bridge,
+ SYS_RES_MEMORY, isa_mem_base, &isa_mem_bt);
break;
}
}
@@ -170,7 +192,7 @@ isa_route_intr_res(device_t bus, u_long start, u_long end)
if (start > 7)
panic("isa_route_intr_res: start out of isa range");
res = isa_ino[start];
- if (res == ORIR_NOTFOUND)
+ if (res == PCI_INVALID_IRQ)
device_printf(bus, "could not map interrupt %d\n", res);
return (res);
}
@@ -244,7 +266,7 @@ isa_alloc_resource(device_t bus, device_t child, int type, int *rid,
"irq allocation");
if (!isdefault) {
start = end = isa_route_intr_res(bus, start, end);
- if (start == 255)
+ if (start == PCI_INVALID_IRQ)
return (NULL);
}
break;
@@ -255,7 +277,7 @@ isa_alloc_resource(device_t bus, device_t child, int type, int *rid,
start = ulmin(start + base, limit);
end = ulmin(end + base, limit);
}
-
+
/*
* This inlines a modified resource_list_alloc(); this is needed
* because the resources need to have offsets added to them, which
@@ -289,7 +311,7 @@ isa_alloc_resource(device_t bus, device_t child, int type, int *rid,
break;
case SYS_RES_IRQ:
start = end = isa_route_intr_res(bus, start, end);
- if (start == 255)
+ if (start == PCI_INVALID_IRQ)
return (NULL);
break;
}
diff --git a/sys/sparc64/isa/ofw_isa.c b/sys/sparc64/isa/ofw_isa.c
index a87665e..986220d 100644
--- a/sys/sparc64/isa/ofw_isa.c
+++ b/sys/sparc64/isa/ofw_isa.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1999, 2000 Matthew R. Green
- * Copyright (c) 2001 Thomas Moestl <tmm@FreeBSD.org>
+ * Copyright (c) 2001, 2003 Thomas Moestl <tmm@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,8 @@
* Helper functions which can be used in both ISA and EBus code.
*/
+#include "opt_ofw_pci.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
@@ -42,11 +44,14 @@
#include <ofw/openfirm.h>
#include <ofw/ofw_pci.h>
+#include <machine/bus.h>
#include <machine/resource.h>
#include <machine/ofw_bus.h>
-#include <sparc64/isa/ofw_isa.h>
#include <sparc64/pci/ofw_pci.h>
+#include <sparc64/isa/ofw_isa.h>
+
+#include "pcib_if.h"
/* XXX: this only supports PCI as parent bus right now. */
int
@@ -86,3 +91,27 @@ ofw_isa_map_iorange(struct isa_ranges *range, int nrange, u_long *start,
panic("ofw_isa_map_iorange: could not map range %#lx - %#lx",
*start, *end);
}
+
+#ifdef OFW_NEWPCI
+ofw_pci_intr_t
+ofw_isa_route_intr(device_t bridge, phandle_t node, struct ofw_bus_iinfo *ii,
+ ofw_isa_intr_t intr)
+{
+ struct isa_regs reg;
+ u_int8_t maskbuf[sizeof(reg) + sizeof(intr)];
+ device_t pbridge;
+ ofw_isa_intr_t mintr;
+
+ pbridge = device_get_parent(device_get_parent(bridge));
+ /*
+ * If we get a match from using the map, the resulting INO is
+ * fully specified, so we may not continue to map.
+ */
+ if (!ofw_bus_lookup_imap(node, ii, &reg, sizeof(reg),
+ &intr, sizeof(intr), &mintr, sizeof(mintr), maskbuf)) {
+ /* Try routing at the parent bridge. */
+ mintr = PCIB_ROUTE_INTERRUPT(pbridge, bridge, intr);
+ }
+ return (mintr);
+}
+#endif /* OFW_NEWPCI */
diff --git a/sys/sparc64/isa/ofw_isa.h b/sys/sparc64/isa/ofw_isa.h
index 9402657..dd534ad 100644
--- a/sys/sparc64/isa/ofw_isa.h
+++ b/sys/sparc64/isa/ofw_isa.h
@@ -60,24 +60,28 @@ struct isa_ranges {
((((u_int64_t)((r)->child_hi)) << 32) | ((u_int64_t)(r)->child_lo))
#define ISA_RANGE_PS(r) (((r)->phys_hi >> 24) & 0x03)
+typedef u_int32_t ofw_isa_intr_t;
+
struct isa_imap {
u_int32_t phys_hi; /* high phys addr mask */
u_int32_t phys_lo; /* low phys addr mask */
- u_int32_t intr; /* interrupt mask */
- int32_t cnode; /* child node */
- u_int32_t cintr; /* child interrupt */
+ ofw_isa_intr_t intr; /* interrupt mask */
+ phandle_t cnode; /* child node */
+ ofw_pci_intr_t cintr; /* child interrupt */
};
struct isa_imap_msk {
u_int32_t phys_hi; /* high phys addr */
u_int32_t phys_lo; /* low phys addr */
- u_int32_t intr; /* interrupt */
+ ofw_isa_intr_t intr; /* interrupt */
};
-/* Map an interrupt property to an INO */
-int ofw_isa_map_intr(struct isa_imap *, int, struct isa_imap_msk *, int,
- struct isa_regs *, int);
/* Map an IO range. Returns the resource type of the range. */
int ofw_isa_map_iorange(struct isa_ranges *, int, u_long *, u_long *);
+#ifdef OFW_NEWPCI
+ofw_pci_intr_t ofw_isa_route_intr(device_t, phandle_t, struct ofw_bus_iinfo *,
+ ofw_isa_intr_t);
+#endif
+
#endif /* !_SPARC64_ISA_OFW_ISA_H_ */
OpenPOWER on IntegriCloud